feat:차량정비이력 실제 DB 연동 구현
This commit is contained in:
200
app/Http/Controllers/Finance/VehicleMaintenanceController.php
Normal file
200
app/Http/Controllers/Finance/VehicleMaintenanceController.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Finance;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\CorporateVehicle;
|
||||
use App\Models\VehicleMaintenance;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class VehicleMaintenanceController extends Controller
|
||||
{
|
||||
public function index(Request $request): View|Response
|
||||
{
|
||||
if ($request->header('HX-Request')) {
|
||||
return response('', 200)->header('HX-Redirect', route('finance.vehicle-maintenance'));
|
||||
}
|
||||
|
||||
return view('finance.vehicle-maintenance');
|
||||
}
|
||||
|
||||
/**
|
||||
* 차량 목록 조회
|
||||
*/
|
||||
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 = VehicleMaintenance::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('category') && $request->category !== 'all') {
|
||||
$query->where('category', $request->category);
|
||||
}
|
||||
|
||||
// 날짜 범위 필터
|
||||
if ($request->filled('start_date')) {
|
||||
$query->whereDate('date', '>=', $request->start_date);
|
||||
}
|
||||
if ($request->filled('end_date')) {
|
||||
$query->whereDate('date', '<=', $request->end_date);
|
||||
}
|
||||
|
||||
// 검색어
|
||||
if ($request->filled('search')) {
|
||||
$search = $request->search;
|
||||
$query->where(function ($q) use ($search) {
|
||||
$q->where('description', 'like', "%{$search}%")
|
||||
->orWhere('vendor', 'like', "%{$search}%")
|
||||
->orWhere('memo', 'like', "%{$search}%");
|
||||
});
|
||||
}
|
||||
|
||||
$maintenances = $query->orderBy('date', 'desc')->get();
|
||||
|
||||
// 응답 포맷팅
|
||||
$data = $maintenances->map(function ($m) {
|
||||
return [
|
||||
'id' => $m->id,
|
||||
'date' => $m->date->format('Y-m-d'),
|
||||
'vehicleId' => $m->vehicle_id,
|
||||
'plateNumber' => $m->vehicle?->plate_number,
|
||||
'model' => $m->vehicle?->model,
|
||||
'category' => $m->category,
|
||||
'description' => $m->description,
|
||||
'amount' => $m->amount,
|
||||
'mileage' => $m->mileage,
|
||||
'vendor' => $m->vendor,
|
||||
'memo' => $m->memo,
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 정비 이력 등록
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'vehicle_id' => 'required|exists:corporate_vehicles,id',
|
||||
'date' => 'required|date',
|
||||
'category' => 'required|string|max:20',
|
||||
'amount' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
$tenantId = session('tenant_id', 1);
|
||||
|
||||
$maintenance = VehicleMaintenance::create([
|
||||
'tenant_id' => $tenantId,
|
||||
'vehicle_id' => $request->vehicle_id,
|
||||
'date' => $request->date,
|
||||
'category' => $request->category,
|
||||
'description' => $request->description,
|
||||
'amount' => $request->amount ?? 0,
|
||||
'mileage' => $request->mileage,
|
||||
'vendor' => $request->vendor,
|
||||
'memo' => $request->memo,
|
||||
]);
|
||||
|
||||
// 차량 주행거리 업데이트
|
||||
if ($request->filled('mileage')) {
|
||||
CorporateVehicle::where('id', $request->vehicle_id)
|
||||
->where('tenant_id', $tenantId)
|
||||
->update(['mileage' => $request->mileage]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '정비 이력이 등록되었습니다.',
|
||||
'data' => $maintenance,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 정비 이력 수정
|
||||
*/
|
||||
public function update(Request $request, int $id): JsonResponse
|
||||
{
|
||||
$tenantId = session('tenant_id', 1);
|
||||
|
||||
$maintenance = VehicleMaintenance::where('tenant_id', $tenantId)->findOrFail($id);
|
||||
|
||||
$request->validate([
|
||||
'vehicle_id' => 'required|exists:corporate_vehicles,id',
|
||||
'date' => 'required|date',
|
||||
'category' => 'required|string|max:20',
|
||||
'amount' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
$maintenance->update([
|
||||
'vehicle_id' => $request->vehicle_id,
|
||||
'date' => $request->date,
|
||||
'category' => $request->category,
|
||||
'description' => $request->description,
|
||||
'amount' => $request->amount ?? 0,
|
||||
'mileage' => $request->mileage,
|
||||
'vendor' => $request->vendor,
|
||||
'memo' => $request->memo,
|
||||
]);
|
||||
|
||||
// 차량 주행거리 업데이트
|
||||
if ($request->filled('mileage')) {
|
||||
CorporateVehicle::where('id', $request->vehicle_id)
|
||||
->where('tenant_id', $tenantId)
|
||||
->update(['mileage' => $request->mileage]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '정비 이력이 수정되었습니다.',
|
||||
'data' => $maintenance,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 정비 이력 삭제
|
||||
*/
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
$tenantId = session('tenant_id', 1);
|
||||
|
||||
$maintenance = VehicleMaintenance::where('tenant_id', $tenantId)->findOrFail($id);
|
||||
$maintenance->delete();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => '정비 이력이 삭제되었습니다.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
55
app/Models/VehicleMaintenance.php
Normal file
55
app/Models/VehicleMaintenance.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class VehicleMaintenance extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'tenant_id',
|
||||
'vehicle_id',
|
||||
'date',
|
||||
'category',
|
||||
'description',
|
||||
'amount',
|
||||
'mileage',
|
||||
'vendor',
|
||||
'memo',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'date' => 'date',
|
||||
'amount' => 'integer',
|
||||
'mileage' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* 차량 관계
|
||||
*/
|
||||
public function vehicle(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CorporateVehicle::class, 'vehicle_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* 테넌트 관계
|
||||
*/
|
||||
public function tenant(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Tenant::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 카테고리 목록
|
||||
*/
|
||||
public static function getCategories(): array
|
||||
{
|
||||
return ['주유', '정비', '보험', '세차', '주차', '통행료', '검사', '기타'];
|
||||
}
|
||||
}
|
||||
@@ -48,23 +48,64 @@
|
||||
function VehicleMaintenanceManagement() {
|
||||
// 탭 상태
|
||||
const [activeTab, setActiveTab] = useState('maintenance');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
|
||||
// 차량 목록 (동적 관리)
|
||||
const [vehicles, setVehicles] = useState([
|
||||
{ id: 1, plateNumber: '12가 3456', model: '제네시스 G80', ownershipType: 'corporate', purchaseDate: '2023-05-15', purchasePrice: '', currentMileage: 15000 },
|
||||
{ id: 2, plateNumber: '34나 5678', model: '현대 스타렉스', ownershipType: 'corporate', purchaseDate: '2022-03-10', purchasePrice: '', currentMileage: 48000 },
|
||||
{ id: 3, plateNumber: '56다 7890', model: '기아 레이', ownershipType: 'rent', contractDate: '2024-01-01', rentCompany: '롯데렌터카', rentCompanyTel: '1588-1234', rentPeriod: '36개월', agreedMileage: '30000', vehiclePrice: '25000000', residualValue: '15000000', deposit: '3000000', monthlyRent: '450000', monthlyRentTax: '45000', insuranceCompany: '삼성화재', insuranceCompanyTel: '1588-5114', currentMileage: 62000 },
|
||||
{ id: 4, plateNumber: '78라 1234', model: '포터2', ownershipType: 'lease', contractDate: '2023-06-01', rentCompany: '현대캐피탈', rentCompanyTel: '1588-1234', rentPeriod: '48개월', agreedMileage: '60000', vehiclePrice: '32000000', residualValue: '12000000', deposit: '5000000', monthlyRent: '520000', monthlyRentTax: '52000', insuranceCompany: 'DB손해보험', insuranceCompanyTel: '1588-0100', currentMileage: 95000 },
|
||||
]);
|
||||
// 차량 목록 (API에서 로드)
|
||||
const [vehicles, setVehicles] = useState([]);
|
||||
|
||||
const [maintenances, setMaintenances] = useState([
|
||||
{ id: 1, date: '2026-01-20', vehicleId: 1, category: '주유', description: '휘발유', amount: 120000, mileage: 15000, vendor: 'GS칼텍스', memo: '' },
|
||||
{ id: 2, date: '2026-01-18', vehicleId: 2, category: '주유', description: '경유', amount: 95000, mileage: 48000, vendor: 'SK에너지', memo: '' },
|
||||
{ id: 3, date: '2026-01-15', vehicleId: 4, category: '정비', description: '엔진오일 교환', amount: 150000, mileage: 95000, vendor: '현대오토', memo: '정기 점검' },
|
||||
{ id: 4, date: '2026-01-10', vehicleId: 3, category: '보험', description: '자동차보험 연납', amount: 850000, mileage: 62000, vendor: '삼성화재', memo: '2025.01~2026.01' },
|
||||
{ id: 5, date: '2026-01-05', vehicleId: 1, category: '세차', description: '세차 및 실내크리닝', amount: 50000, mileage: 14500, vendor: '카와시', memo: '' },
|
||||
{ id: 6, date: '2025-12-20', vehicleId: 2, category: '정비', description: '타이어 교체', amount: 480000, mileage: 45000, vendor: '한국타이어', memo: '4개 교체' },
|
||||
]);
|
||||
// 정비 이력 (API에서 로드)
|
||||
const [maintenances, setMaintenances] = useState([]);
|
||||
|
||||
// 데이터 로드
|
||||
const loadVehicles = async () => {
|
||||
try {
|
||||
const response = await fetch('/finance/vehicle-maintenance/vehicles');
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
setVehicles(result.data.map(v => ({
|
||||
id: v.id,
|
||||
plateNumber: v.plate_number,
|
||||
model: v.model,
|
||||
ownershipType: v.ownership_type,
|
||||
currentMileage: v.mileage || 0
|
||||
})));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('차량 로드 실패:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const loadMaintenances = async () => {
|
||||
try {
|
||||
const params = new URLSearchParams({
|
||||
start_date: dateRange.start,
|
||||
end_date: dateRange.end,
|
||||
category: filterCategory,
|
||||
vehicle_id: filterVehicle,
|
||||
search: searchTerm
|
||||
});
|
||||
const response = await fetch(`/finance/vehicle-maintenance/list?${params}`);
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
setMaintenances(result.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('정비 이력 로드 실패:', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
loadVehicles();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (vehicles.length > 0 || !loading) {
|
||||
loadMaintenances();
|
||||
}
|
||||
}, [dateRange, filterCategory, filterVehicle]);
|
||||
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [filterCategory, setFilterCategory] = useState('all');
|
||||
@@ -96,6 +137,14 @@ function VehicleMaintenanceManagement() {
|
||||
return v ? `${v.plateNumber} (${v.model})` : '-';
|
||||
};
|
||||
|
||||
// API 응답에서 차량 정보 표시 (plateNumber가 직접 포함된 경우)
|
||||
const getVehicleDisplayFromItem = (item) => {
|
||||
if (item.plateNumber && item.model) {
|
||||
return `${item.plateNumber} (${item.model})`;
|
||||
}
|
||||
return getVehicleDisplay(item.vehicleId);
|
||||
};
|
||||
|
||||
const getOwnershipLabel = (type) => {
|
||||
const found = ownershipTypes.find(t => t.value === type);
|
||||
return found ? found.label : type;
|
||||
@@ -154,13 +203,13 @@ function VehicleMaintenanceManagement() {
|
||||
};
|
||||
const parseInputCurrency = (value) => String(value).replace(/[^\d]/g, '');
|
||||
|
||||
// API에서 이미 필터링된 데이터를 받으므로 클라이언트 측에서는 검색어만 필터링
|
||||
const filteredMaintenances = maintenances.filter(item => {
|
||||
const matchesSearch = item.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
item.vendor.toLowerCase().includes(searchTerm.toLowerCase());
|
||||
const matchesCategory = filterCategory === 'all' || item.category === filterCategory;
|
||||
const matchesVehicle = filterVehicle === 'all' || item.vehicleId === parseInt(filterVehicle);
|
||||
const matchesDate = item.date >= dateRange.start && item.date <= dateRange.end;
|
||||
return matchesSearch && matchesCategory && matchesVehicle && matchesDate;
|
||||
if (!searchTerm) return true;
|
||||
const search = searchTerm.toLowerCase();
|
||||
return (item.description || '').toLowerCase().includes(search) ||
|
||||
(item.vendor || '').toLowerCase().includes(search) ||
|
||||
(item.plateNumber || '').toLowerCase().includes(search);
|
||||
});
|
||||
|
||||
const totalAmount = filteredMaintenances.reduce((sum, item) => sum + item.amount, 0);
|
||||
@@ -171,36 +220,131 @@ function VehicleMaintenanceManagement() {
|
||||
// 유지비 등록/수정
|
||||
const handleAdd = () => { setModalMode('add'); setFormData({...initialFormState, vehicleId: vehicles[0]?.id || ''}); setShowModal(true); };
|
||||
const handleEdit = (item) => { setModalMode('edit'); setEditingItem(item); setFormData({ ...item }); setShowModal(true); };
|
||||
const handleSave = () => {
|
||||
const handleSave = async () => {
|
||||
if (!formData.description || !formData.amount) { alert('필수 항목을 입력해주세요.'); return; }
|
||||
const amount = parseInt(formData.amount) || 0;
|
||||
const mileage = parseInt(formData.mileage) || 0;
|
||||
if (modalMode === 'add') {
|
||||
setMaintenances(prev => [{ id: Date.now(), ...formData, vehicleId: parseInt(formData.vehicleId), amount, mileage }, ...prev]);
|
||||
} else {
|
||||
setMaintenances(prev => prev.map(item => item.id === editingItem.id ? { ...item, ...formData, vehicleId: parseInt(formData.vehicleId), amount, mileage } : item));
|
||||
setSaving(true);
|
||||
try {
|
||||
const payload = {
|
||||
vehicle_id: parseInt(formData.vehicleId),
|
||||
date: formData.date,
|
||||
category: formData.category,
|
||||
description: formData.description,
|
||||
amount: parseInt(String(formData.amount).replace(/[^\d]/g, '')) || 0,
|
||||
mileage: parseInt(String(formData.mileage).replace(/[^\d]/g, '')) || null,
|
||||
vendor: formData.vendor,
|
||||
memo: formData.memo
|
||||
};
|
||||
const url = modalMode === 'add' ? '/finance/vehicle-maintenance' : `/finance/vehicle-maintenance/${editingItem.id}`;
|
||||
const method = modalMode === 'add' ? 'POST' : 'PUT';
|
||||
const response = await fetch(url, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
await loadMaintenances();
|
||||
setShowModal(false);
|
||||
setEditingItem(null);
|
||||
} else {
|
||||
alert(result.message || '저장에 실패했습니다.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('저장 오류:', error);
|
||||
alert('저장 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
const handleDelete = async (id) => {
|
||||
if (!confirm('정말 삭제하시겠습니까?')) return;
|
||||
try {
|
||||
const response = await fetch(`/finance/vehicle-maintenance/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
await loadMaintenances();
|
||||
setShowModal(false);
|
||||
} else {
|
||||
alert(result.message || '삭제에 실패했습니다.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('삭제 오류:', error);
|
||||
alert('삭제 중 오류가 발생했습니다.');
|
||||
}
|
||||
setShowModal(false); setEditingItem(null);
|
||||
};
|
||||
const handleDelete = (id) => { if (confirm('정말 삭제하시겠습니까?')) { setMaintenances(prev => prev.filter(item => item.id !== id)); setShowModal(false); } };
|
||||
|
||||
// 차량 등록/수정
|
||||
// 차량 등록/수정 - corporate-vehicles API 사용
|
||||
const handleAddVehicle = () => { setVehicleModalMode('add'); setVehicleFormData(initialVehicleFormState); setShowVehicleModal(true); };
|
||||
const handleEditVehicle = (vehicle) => { setVehicleModalMode('edit'); setEditingVehicle(vehicle); setVehicleFormData({ ...vehicle }); setShowVehicleModal(true); };
|
||||
const handleSaveVehicle = () => {
|
||||
const handleSaveVehicle = async () => {
|
||||
if (!vehicleFormData.plateNumber || !vehicleFormData.model) { alert('차량번호와 모델명은 필수입니다.'); return; }
|
||||
if (vehicleModalMode === 'add') {
|
||||
setVehicles(prev => [{ id: Date.now(), ...vehicleFormData }, ...prev]);
|
||||
} else {
|
||||
setVehicles(prev => prev.map(v => v.id === editingVehicle.id ? { ...v, ...vehicleFormData } : v));
|
||||
setSaving(true);
|
||||
try {
|
||||
const payload = {
|
||||
plate_number: vehicleFormData.plateNumber,
|
||||
model: vehicleFormData.model,
|
||||
vehicle_type: '승용차',
|
||||
ownership_type: vehicleFormData.ownershipType,
|
||||
year: new Date().getFullYear(),
|
||||
mileage: parseInt(String(vehicleFormData.currentMileage).replace(/[^\d]/g, '')) || 0,
|
||||
purchase_date: vehicleFormData.purchaseDate,
|
||||
purchase_price: parseInt(String(vehicleFormData.purchasePrice).replace(/[^\d]/g, '')) || 0,
|
||||
contract_date: vehicleFormData.contractDate,
|
||||
rent_company: vehicleFormData.rentCompany,
|
||||
rent_company_tel: vehicleFormData.rentCompanyTel,
|
||||
rent_period: vehicleFormData.rentPeriod,
|
||||
agreed_mileage: vehicleFormData.agreedMileage,
|
||||
vehicle_price: parseInt(String(vehicleFormData.vehiclePrice).replace(/[^\d]/g, '')) || 0,
|
||||
residual_value: parseInt(String(vehicleFormData.residualValue).replace(/[^\d]/g, '')) || 0,
|
||||
deposit: parseInt(String(vehicleFormData.deposit).replace(/[^\d]/g, '')) || 0,
|
||||
monthly_rent: parseInt(String(vehicleFormData.monthlyRent).replace(/[^\d]/g, '')) || 0,
|
||||
monthly_rent_tax: parseInt(String(vehicleFormData.monthlyRentTax).replace(/[^\d]/g, '')) || 0,
|
||||
insurance_company: vehicleFormData.insuranceCompany,
|
||||
insurance_company_tel: vehicleFormData.insuranceCompanyTel
|
||||
};
|
||||
const url = vehicleModalMode === 'add' ? '/finance/corporate-vehicles' : `/finance/corporate-vehicles/${editingVehicle.id}`;
|
||||
const method = vehicleModalMode === 'add' ? 'POST' : 'PUT';
|
||||
const response = await fetch(url, {
|
||||
method,
|
||||
headers: { 'Content-Type': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content },
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
await loadVehicles();
|
||||
setShowVehicleModal(false);
|
||||
setEditingVehicle(null);
|
||||
} else {
|
||||
alert(result.message || '저장에 실패했습니다.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('저장 오류:', error);
|
||||
alert('저장 중 오류가 발생했습니다.');
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
setShowVehicleModal(false); setEditingVehicle(null);
|
||||
};
|
||||
const handleDeleteVehicle = (id) => {
|
||||
if (confirm('차량을 삭제하시겠습니까? 관련 유지비 기록도 함께 삭제됩니다.')) {
|
||||
setVehicles(prev => prev.filter(v => v.id !== id));
|
||||
setMaintenances(prev => prev.filter(m => m.vehicleId !== id));
|
||||
setShowVehicleModal(false);
|
||||
const handleDeleteVehicle = async (id) => {
|
||||
if (!confirm('차량을 삭제하시겠습니까? 관련 유지비 기록도 함께 삭제됩니다.')) return;
|
||||
try {
|
||||
const response = await fetch(`/finance/corporate-vehicles/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content }
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
await loadVehicles();
|
||||
await loadMaintenances();
|
||||
setShowVehicleModal(false);
|
||||
} else {
|
||||
alert(result.message || '삭제에 실패했습니다.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('삭제 오류:', error);
|
||||
alert('삭제 중 오류가 발생했습니다.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -834,13 +834,13 @@
|
||||
Route::delete('/vehicle-logs/{id}', [\App\Http\Controllers\Finance\VehicleLogController::class, 'destroy'])->name('vehicle-logs.destroy');
|
||||
Route::get('/vehicle-logs/export', [\App\Http\Controllers\Finance\VehicleLogController::class, 'export'])->name('vehicle-logs.export');
|
||||
|
||||
Route::get('/vehicle-maintenance', function () {
|
||||
if (request()->header('HX-Request')) {
|
||||
return response('', 200)->header('HX-Redirect', route('finance.vehicle-maintenance'));
|
||||
}
|
||||
|
||||
return view('finance.vehicle-maintenance');
|
||||
})->name('vehicle-maintenance');
|
||||
// 차량정비이력
|
||||
Route::get('/vehicle-maintenance', [\App\Http\Controllers\Finance\VehicleMaintenanceController::class, 'index'])->name('vehicle-maintenance');
|
||||
Route::get('/vehicle-maintenance/vehicles', [\App\Http\Controllers\Finance\VehicleMaintenanceController::class, 'vehicles'])->name('vehicle-maintenance.vehicles');
|
||||
Route::get('/vehicle-maintenance/list', [\App\Http\Controllers\Finance\VehicleMaintenanceController::class, 'list'])->name('vehicle-maintenance.list');
|
||||
Route::post('/vehicle-maintenance', [\App\Http\Controllers\Finance\VehicleMaintenanceController::class, 'store'])->name('vehicle-maintenance.store');
|
||||
Route::put('/vehicle-maintenance/{id}', [\App\Http\Controllers\Finance\VehicleMaintenanceController::class, 'update'])->name('vehicle-maintenance.update');
|
||||
Route::delete('/vehicle-maintenance/{id}', [\App\Http\Controllers\Finance\VehicleMaintenanceController::class, 'destroy'])->name('vehicle-maintenance.destroy');
|
||||
|
||||
// 거래처관리
|
||||
Route::get('/customers', function () {
|
||||
|
||||
Reference in New Issue
Block a user