header('HX-Request')) { return response('', 200)->header('HX-Redirect', route('finance.vehicle-logs')); } $tenantId = session('tenant_id', 1); $vehicles = CorporateVehicle::where('tenant_id', $tenantId) ->where('status', 'active') ->orderBy('plate_number') ->get(); return view('finance.vehicle-logs', [ 'vehicles' => $vehicles, 'tripTypes' => VehicleLog::tripTypeLabels(), 'locationTypes' => VehicleLog::locationTypeLabels(), ]); } public function list(Request $request): JsonResponse { $tenantId = session('tenant_id', 1); $request->validate([ 'vehicle_id' => 'required|integer', 'start_date' => 'required|date', 'end_date' => 'required|date|after_or_equal:start_date', ]); $vehicleId = $request->vehicle_id; $startDate = $request->start_date; $endDate = $request->end_date; // 차량 정보 $vehicle = CorporateVehicle::where('tenant_id', $tenantId) ->findOrFail($vehicleId); // 전체 운행기록 수 (해당 차량) $totalCount = VehicleLog::where('tenant_id', $tenantId) ->where('vehicle_id', $vehicleId) ->count(); $logs = VehicleLog::where('tenant_id', $tenantId) ->where('vehicle_id', $vehicleId) ->whereBetween('log_date', [$startDate, $endDate]) ->orderBy('log_date') ->orderBy('id') ->get(); // 월별 합계 $totals = [ 'business_km' => $logs->whereIn('trip_type', ['commute_to', 'commute_from', 'business'])->sum('distance_km'), 'personal_km' => $logs->where('trip_type', 'personal')->sum('distance_km'), 'total_km' => $logs->sum('distance_km'), ]; return response()->json([ 'success' => true, 'data' => [ 'vehicle' => $vehicle, 'logs' => $logs, 'totals' => $totals, 'totalCount' => $totalCount, ], ]); } public function store(Request $request): JsonResponse { $tenantId = session('tenant_id', 1); $request->validate([ 'vehicle_id' => 'required|integer|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', ]); // 해당 차량이 현재 테넌트의 것인지 확인 CorporateVehicle::where('tenant_id', $tenantId) ->findOrFail($request->vehicle_id); $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([ '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([ '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 export(Request $request): StreamedResponse { $tenantId = session('tenant_id', 1); $request->validate([ 'vehicle_id' => 'required|integer', 'start_date' => 'required|date', 'end_date' => 'required|date|after_or_equal:start_date', ]); $vehicleId = $request->vehicle_id; $startDate = $request->start_date; $endDate = $request->end_date; $vehicle = CorporateVehicle::where('tenant_id', $tenantId) ->findOrFail($vehicleId); $logs = VehicleLog::where('tenant_id', $tenantId) ->where('vehicle_id', $vehicleId) ->whereBetween('log_date', [$startDate, $endDate]) ->orderBy('log_date') ->orderBy('id') ->get(); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setTitle('운행기록부'); // 기본 정보 $sheet->setCellValue('A1', '업무용승용차 운행기록부'); $sheet->setCellValue('A3', '차량번호'); $sheet->setCellValue('B3', $vehicle->plate_number); $sheet->setCellValue('C3', '차종'); $sheet->setCellValue('D3', $vehicle->model); $sheet->setCellValue('E3', '구분'); $sheet->setCellValue('F3', $this->getOwnershipTypeLabel($vehicle->ownership_type)); $sheet->setCellValue('A4', '조회기간'); $sheet->setCellValue('B4', sprintf('%s ~ %s', $startDate, $endDate)); // 헤더 $headers = ['일자', '부서', '성명', '구분', '출발지', '도착지', '주행km', '비고']; $col = 'A'; foreach ($headers as $header) { $sheet->setCellValue($col . '6', $header); $col++; } // 데이터 $row = 7; $tripTypeLabels = VehicleLog::tripTypeLabels(); foreach ($logs as $log) { $sheet->setCellValue('A' . $row, $log->log_date->format('Y-m-d')); $sheet->setCellValue('B' . $row, $log->department ?? ''); $sheet->setCellValue('C' . $row, $log->driver_name); $sheet->setCellValue('D' . $row, $tripTypeLabels[$log->trip_type] ?? $log->trip_type); $sheet->setCellValue('E' . $row, $log->departure_name ?? ''); $sheet->setCellValue('F' . $row, $log->arrival_name ?? ''); $sheet->setCellValue('G' . $row, $log->distance_km); $sheet->setCellValue('H' . $row, $log->note ?? ''); $row++; } // 합계 $businessKm = $logs->whereIn('trip_type', ['commute_to', 'commute_from', 'business'])->sum('distance_km'); $personalKm = $logs->where('trip_type', 'personal')->sum('distance_km'); $totalKm = $logs->sum('distance_km'); $sheet->setCellValue('A' . $row, '합계'); $sheet->setCellValue('F' . $row, '업무용: ' . number_format($businessKm) . 'km'); $sheet->setCellValue('G' . $row, number_format($totalKm)); $sheet->setCellValue('H' . $row, '비업무: ' . number_format($personalKm) . 'km'); $filename = sprintf('운행기록부_%s_%s_%s.xlsx', $vehicle->plate_number, $startDate, $endDate); return response()->streamDownload(function () use ($spreadsheet) { $writer = new Xlsx($spreadsheet); $writer->save('php://output'); }, $filename, [ 'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ]); } private function getOwnershipTypeLabel(string $type): string { return match ($type) { 'corporate' => '회사', 'rent' => '렌트', 'lease' => '리스', default => $type, }; } }