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, ], ], ]); } }