270 lines
8.5 KiB
PHP
270 lines
8.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Finance;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\CorporateVehicle;
|
|
use App\Models\VehicleLog;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\View\View;
|
|
|
|
class VehicleLogController extends Controller
|
|
{
|
|
public function index(Request $request): View|Response
|
|
{
|
|
if ($request->header('HX-Request')) {
|
|
return response('', 200)->header('HX-Redirect', route('finance.vehicle-logs'));
|
|
}
|
|
|
|
return view('finance.vehicle-logs');
|
|
}
|
|
|
|
/**
|
|
* 차량 목록 조회
|
|
*/
|
|
public function vehicles(Request $request): JsonResponse
|
|
{
|
|
$tenantId = session('tenant_id', 1);
|
|
|
|
$vehicles = CorporateVehicle::where('tenant_id', $tenantId)
|
|
->orderBy('plate_number')
|
|
->get();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $vehicles,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 운행기록 목록 조회
|
|
*/
|
|
public function list(Request $request): JsonResponse
|
|
{
|
|
$tenantId = session('tenant_id', 1);
|
|
|
|
$query = VehicleLog::with('vehicle')
|
|
->where('tenant_id', $tenantId);
|
|
|
|
// 차량 필터
|
|
if ($request->filled('vehicle_id') && $request->vehicle_id !== 'all') {
|
|
$query->where('vehicle_id', $request->vehicle_id);
|
|
}
|
|
|
|
// 년/월 필터
|
|
if ($request->filled('year')) {
|
|
$query->whereYear('log_date', $request->year);
|
|
}
|
|
if ($request->filled('month')) {
|
|
$query->whereMonth('log_date', $request->month);
|
|
}
|
|
|
|
// 구분 필터
|
|
if ($request->filled('trip_type') && $request->trip_type !== 'all') {
|
|
$query->where('trip_type', $request->trip_type);
|
|
}
|
|
|
|
// 검색어
|
|
if ($request->filled('search')) {
|
|
$search = $request->search;
|
|
$query->where(function ($q) use ($search) {
|
|
$q->where('driver_name', 'like', "%{$search}%")
|
|
->orWhere('department', 'like', "%{$search}%")
|
|
->orWhere('departure_name', 'like', "%{$search}%")
|
|
->orWhere('arrival_name', 'like', "%{$search}%")
|
|
->orWhere('note', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
$logs = $query->orderBy('log_date', 'desc')
|
|
->orderBy('id', 'desc')
|
|
->get();
|
|
|
|
// 응답 포맷팅
|
|
$data = $logs->map(function ($log) {
|
|
return [
|
|
'id' => $log->id,
|
|
'logDate' => $log->log_date->format('Y-m-d'),
|
|
'vehicleId' => $log->vehicle_id,
|
|
'plateNumber' => $log->vehicle?->plate_number,
|
|
'model' => $log->vehicle?->model,
|
|
'department' => $log->department,
|
|
'driverName' => $log->driver_name,
|
|
'tripType' => $log->trip_type,
|
|
'departureType' => $log->departure_type,
|
|
'departureName' => $log->departure_name,
|
|
'departureAddress' => $log->departure_address,
|
|
'arrivalType' => $log->arrival_type,
|
|
'arrivalName' => $log->arrival_name,
|
|
'arrivalAddress' => $log->arrival_address,
|
|
'distanceKm' => $log->distance_km,
|
|
'note' => $log->note,
|
|
];
|
|
});
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $data,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 운행기록 등록
|
|
*/
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
$request->validate([
|
|
'vehicle_id' => 'required|exists:corporate_vehicles,id',
|
|
'log_date' => 'required|date',
|
|
'driver_name' => 'required|string|max:50',
|
|
'trip_type' => 'required|in:commute_to,commute_from,business,personal',
|
|
'distance_km' => 'required|integer|min:0',
|
|
]);
|
|
|
|
$tenantId = session('tenant_id', 1);
|
|
|
|
$log = VehicleLog::create([
|
|
'tenant_id' => $tenantId,
|
|
'vehicle_id' => $request->vehicle_id,
|
|
'log_date' => $request->log_date,
|
|
'department' => $request->department,
|
|
'driver_name' => $request->driver_name,
|
|
'trip_type' => $request->trip_type,
|
|
'departure_type' => $request->departure_type,
|
|
'departure_name' => $request->departure_name,
|
|
'departure_address' => $request->departure_address,
|
|
'arrival_type' => $request->arrival_type,
|
|
'arrival_name' => $request->arrival_name,
|
|
'arrival_address' => $request->arrival_address,
|
|
'distance_km' => $request->distance_km,
|
|
'note' => $request->note,
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => '운행기록이 등록되었습니다.',
|
|
'data' => $log,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 운행기록 수정
|
|
*/
|
|
public function update(Request $request, int $id): JsonResponse
|
|
{
|
|
$tenantId = session('tenant_id', 1);
|
|
|
|
$log = VehicleLog::where('tenant_id', $tenantId)->findOrFail($id);
|
|
|
|
$request->validate([
|
|
'vehicle_id' => 'required|exists:corporate_vehicles,id',
|
|
'log_date' => 'required|date',
|
|
'driver_name' => 'required|string|max:50',
|
|
'trip_type' => 'required|in:commute_to,commute_from,business,personal',
|
|
'distance_km' => 'required|integer|min:0',
|
|
]);
|
|
|
|
$log->update([
|
|
'vehicle_id' => $request->vehicle_id,
|
|
'log_date' => $request->log_date,
|
|
'department' => $request->department,
|
|
'driver_name' => $request->driver_name,
|
|
'trip_type' => $request->trip_type,
|
|
'departure_type' => $request->departure_type,
|
|
'departure_name' => $request->departure_name,
|
|
'departure_address' => $request->departure_address,
|
|
'arrival_type' => $request->arrival_type,
|
|
'arrival_name' => $request->arrival_name,
|
|
'arrival_address' => $request->arrival_address,
|
|
'distance_km' => $request->distance_km,
|
|
'note' => $request->note,
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => '운행기록이 수정되었습니다.',
|
|
'data' => $log,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 운행기록 삭제
|
|
*/
|
|
public function destroy(int $id): JsonResponse
|
|
{
|
|
$tenantId = session('tenant_id', 1);
|
|
|
|
$log = VehicleLog::where('tenant_id', $tenantId)->findOrFail($id);
|
|
$log->delete();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => '운행기록이 삭제되었습니다.',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 월간 통계 조회
|
|
*/
|
|
public function summary(Request $request): JsonResponse
|
|
{
|
|
$tenantId = session('tenant_id', 1);
|
|
|
|
$query = VehicleLog::where('tenant_id', $tenantId);
|
|
|
|
// 차량 필터
|
|
if ($request->filled('vehicle_id') && $request->vehicle_id !== 'all') {
|
|
$query->where('vehicle_id', $request->vehicle_id);
|
|
}
|
|
|
|
// 년/월 필터
|
|
if ($request->filled('year')) {
|
|
$query->whereYear('log_date', $request->year);
|
|
}
|
|
if ($request->filled('month')) {
|
|
$query->whereMonth('log_date', $request->month);
|
|
}
|
|
|
|
// 구분별 주행거리 합계
|
|
$summary = $query->selectRaw('
|
|
trip_type,
|
|
COUNT(*) as count,
|
|
SUM(distance_km) as total_distance
|
|
')
|
|
->groupBy('trip_type')
|
|
->get()
|
|
->keyBy('trip_type');
|
|
|
|
$tripTypes = VehicleLog::getTripTypes();
|
|
$result = [];
|
|
$totalCount = 0;
|
|
$totalDistance = 0;
|
|
|
|
foreach ($tripTypes as $type => $label) {
|
|
$data = $summary->get($type);
|
|
$count = $data ? $data->count : 0;
|
|
$distance = $data ? $data->total_distance : 0;
|
|
$result[$type] = [
|
|
'label' => $label,
|
|
'count' => $count,
|
|
'distance' => $distance,
|
|
];
|
|
$totalCount += $count;
|
|
$totalDistance += $distance;
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [
|
|
'byType' => $result,
|
|
'total' => [
|
|
'count' => $totalCount,
|
|
'distance' => $totalDistance,
|
|
],
|
|
],
|
|
]);
|
|
}
|
|
}
|