group(function () { Route::get('', [ClientController::class, 'index'])->name('v1.clients.index'); Route::post('', [ClientController::class, 'store'])->name('v1.clients.store'); Route::get('/active', [ClientController::class, 'active'])->name('v1.clients.active'); Route::get('/stats', [ClientController::class, 'stats'])->name('v1.clients.stats'); Route::get('/{id}', [ClientController::class, 'show'])->whereNumber('id')->name('v1.clients.show'); Route::put('/{id}', [ClientController::class, 'update'])->whereNumber('id')->name('v1.clients.update'); Route::delete('/{id}', [ClientController::class, 'destroy'])->whereNumber('id')->name('v1.clients.destroy'); Route::patch('/{id}/toggle', [ClientController::class, 'toggle'])->whereNumber('id')->name('v1.clients.toggle'); }); // Client Group API (거래처 그룹 관리) Route::prefix('client-groups')->group(function () { Route::get('', [ClientGroupController::class, 'index'])->name('v1.client-groups.index'); Route::post('', [ClientGroupController::class, 'store'])->name('v1.client-groups.store'); Route::get('/{id}', [ClientGroupController::class, 'show'])->whereNumber('id')->name('v1.client-groups.show'); Route::put('/{id}', [ClientGroupController::class, 'update'])->whereNumber('id')->name('v1.client-groups.update'); Route::delete('/{id}', [ClientGroupController::class, 'destroy'])->whereNumber('id')->name('v1.client-groups.destroy'); }); // Quote API (견적 관리) Route::prefix('quotes')->group(function () { Route::get('', [QuoteController::class, 'index'])->name('v1.quotes.index'); Route::get('/stats', [QuoteController::class, 'stats'])->name('v1.quotes.stats'); Route::get('/stage-counts', [QuoteController::class, 'stageCounts'])->name('v1.quotes.stage-counts'); Route::post('', [QuoteController::class, 'store'])->name('v1.quotes.store'); Route::delete('/bulk', [QuoteController::class, 'bulkDestroy'])->name('v1.quotes.bulk-destroy'); Route::get('/{id}', [QuoteController::class, 'show'])->whereNumber('id')->name('v1.quotes.show'); Route::put('/{id}', [QuoteController::class, 'update'])->whereNumber('id')->name('v1.quotes.update'); Route::delete('/{id}', [QuoteController::class, 'destroy'])->whereNumber('id')->name('v1.quotes.destroy'); Route::post('/{id}/clone', [QuoteController::class, 'clone'])->whereNumber('id')->name('v1.quotes.clone'); Route::put('/{id}/stage', [QuoteController::class, 'updateStage'])->whereNumber('id')->name('v1.quotes.stage'); Route::put('/{id}/items', [QuoteController::class, 'updateItems'])->whereNumber('id')->name('v1.quotes.items'); Route::get('/{id}/histories', [QuoteController::class, 'histories'])->whereNumber('id')->name('v1.quotes.histories'); Route::post('/{id}/histories', [QuoteController::class, 'addHistory'])->whereNumber('id')->name('v1.quotes.histories.store'); Route::put('/{id}/histories/{historyId}', [QuoteController::class, 'updateHistory'])->whereNumber('id')->whereNumber('historyId')->name('v1.quotes.histories.update'); Route::delete('/{id}/histories/{historyId}', [QuoteController::class, 'deleteHistory'])->whereNumber('id')->whereNumber('historyId')->name('v1.quotes.histories.destroy'); // 견적서 관련 API Route::get('/{id}/document', [QuoteController::class, 'getDocument'])->whereNumber('id')->name('v1.quotes.document.show'); Route::post('/{id}/document/issue', [QuoteController::class, 'issueDocument'])->whereNumber('id')->name('v1.quotes.document.issue'); Route::post('/{id}/document/send', [QuoteController::class, 'sendDocument'])->whereNumber('id')->name('v1.quotes.document.send'); Route::post('/bulk-issue-document', [QuoteController::class, 'bulkIssueDocument'])->name('v1.quotes.bulk-issue-document'); }); // Bidding API (입찰 관리) Route::prefix('biddings')->group(function () { Route::get('', [BiddingController::class, 'index'])->name('v1.biddings.index'); Route::post('', [BiddingController::class, 'store'])->name('v1.biddings.store'); Route::get('/stats', [BiddingController::class, 'stats'])->name('v1.biddings.stats'); Route::delete('/bulk', [BiddingController::class, 'bulkDestroy'])->name('v1.biddings.bulk-destroy'); Route::get('/{id}', [BiddingController::class, 'show'])->whereNumber('id')->name('v1.biddings.show'); Route::put('/{id}', [BiddingController::class, 'update'])->whereNumber('id')->name('v1.biddings.update'); Route::delete('/{id}', [BiddingController::class, 'destroy'])->whereNumber('id')->name('v1.biddings.destroy'); }); // Pricing API (단가 관리) Route::prefix('pricing')->group(function () { Route::get('', [PricingController::class, 'index'])->name('v1.pricing.index'); Route::post('', [PricingController::class, 'store'])->name('v1.pricing.store'); Route::get('/types', [PricingController::class, 'types'])->name('v1.pricing.types'); Route::get('/summary', [PricingController::class, 'summary'])->name('v1.pricing.summary'); Route::get('/history/{itemId}', [PricingController::class, 'history'])->whereNumber('itemId')->name('v1.pricing.history'); Route::post('/bulk-upsert', [PricingController::class, 'bulkUpsert'])->name('v1.pricing.bulk-upsert'); Route::get('/{id}', [PricingController::class, 'show'])->whereNumber('id')->name('v1.pricing.show'); Route::put('/{id}', [PricingController::class, 'update'])->whereNumber('id')->name('v1.pricing.update'); Route::delete('/{id}', [PricingController::class, 'destroy'])->whereNumber('id')->name('v1.pricing.destroy'); }); // Estimate API (견적/설계) Route::prefix('estimates')->group(function () { Route::get('', [EstimateController::class, 'index'])->name('v1.estimates.index'); // 견적 목록 Route::get('/stats', [EstimateController::class, 'stats'])->name('v1.estimates.stats'); // 견적 통계 Route::post('', [EstimateController::class, 'store'])->name('v1.estimates.store'); // 견적 생성 Route::get('/{id}', [EstimateController::class, 'show'])->whereNumber('id')->name('v1.estimates.show'); // 견적 상세 Route::put('/{id}', [EstimateController::class, 'update'])->whereNumber('id')->name('v1.estimates.update'); // 견적 수정 Route::delete('/{id}', [EstimateController::class, 'destroy'])->whereNumber('id')->name('v1.estimates.destroy'); // 견적 삭제 Route::post('/{id}/clone', [EstimateController::class, 'clone'])->name('v1.estimates.clone'); // 견적 복제 Route::put('/{id}/status', [EstimateController::class, 'changeStatus'])->name('v1.estimates.status'); // 견적 상태 변경 // 견적 폼 및 계산 기능 Route::get('/form-schema/{model_set_id}', [EstimateController::class, 'getFormSchema'])->name('v1.estimates.form-schema'); // 견적 폼 스키마 Route::post('/preview/{model_set_id}', [EstimateController::class, 'previewCalculation'])->name('v1.estimates.preview'); // 견적 계산 미리보기 }); // Order API (수주관리) Route::prefix('orders')->group(function () { // 기본 CRUD Route::get('', [OrderController::class, 'index'])->name('v1.orders.index'); // 목록 Route::get('/stats', [OrderController::class, 'stats'])->name('v1.orders.stats'); // 통계 Route::post('', [OrderController::class, 'store'])->name('v1.orders.store'); // 생성 Route::get('/{id}', [OrderController::class, 'show'])->whereNumber('id')->name('v1.orders.show'); // 상세 Route::put('/{id}', [OrderController::class, 'update'])->whereNumber('id')->name('v1.orders.update'); // 수정 Route::delete('/{id}', [OrderController::class, 'destroy'])->whereNumber('id')->name('v1.orders.destroy'); // 삭제 // 상태 관리 Route::patch('/{id}/status', [OrderController::class, 'updateStatus'])->whereNumber('id')->name('v1.orders.status'); // 상태 변경 // 견적에서 수주 생성 Route::post('/from-quote/{quoteId}', [OrderController::class, 'createFromQuote'])->whereNumber('quoteId')->name('v1.orders.from-quote'); // 생산지시 생성 Route::post('/{id}/production-order', [OrderController::class, 'createProductionOrder'])->whereNumber('id')->name('v1.orders.production-order'); // 수주확정 되돌리기 Route::post('/{id}/revert-confirmation', [OrderController::class, 'revertOrderConfirmation'])->whereNumber('id')->name('v1.orders.revert-confirmation'); // 생산지시 되돌리기 Route::post('/{id}/revert-production', [OrderController::class, 'revertProductionOrder'])->whereNumber('id')->name('v1.orders.revert-production'); }); // Sale API (매출 관리) Route::prefix('sales')->group(function () { Route::get('', [SaleController::class, 'index'])->name('v1.sales.index'); Route::post('', [SaleController::class, 'store'])->name('v1.sales.store'); Route::get('/summary', [SaleController::class, 'summary'])->name('v1.sales.summary'); Route::get('/{id}', [SaleController::class, 'show'])->whereNumber('id')->name('v1.sales.show'); Route::put('/{id}', [SaleController::class, 'update'])->whereNumber('id')->name('v1.sales.update'); Route::delete('/{id}', [SaleController::class, 'destroy'])->whereNumber('id')->name('v1.sales.destroy'); Route::post('/{id}/confirm', [SaleController::class, 'confirm'])->whereNumber('id')->name('v1.sales.confirm'); Route::put('/bulk-update-account', [SaleController::class, 'bulkUpdateAccountCode'])->name('v1.sales.bulk-update-account'); // 거래명세서 API Route::get('/{id}/statement', [SaleController::class, 'getStatement'])->whereNumber('id')->name('v1.sales.statement.show'); Route::post('/{id}/statement/issue', [SaleController::class, 'issueStatement'])->whereNumber('id')->name('v1.sales.statement.issue'); Route::post('/{id}/statement/send', [SaleController::class, 'sendStatement'])->whereNumber('id')->name('v1.sales.statement.send'); Route::post('/bulk-issue-statement', [SaleController::class, 'bulkIssueStatement'])->name('v1.sales.bulk-issue-statement'); }); // Company API (회사 추가 관리) Route::prefix('companies')->group(function () { Route::post('/check', [CompanyController::class, 'check'])->name('v1.companies.check'); // 사업자등록번호 검증 Route::post('/request', [CompanyController::class, 'request'])->name('v1.companies.request'); // 회사 추가 신청 Route::get('/requests', [CompanyController::class, 'requests'])->name('v1.companies.requests.index'); // 신청 목록 (관리자) Route::get('/requests/{id}', [CompanyController::class, 'showRequest'])->whereNumber('id')->name('v1.companies.requests.show'); // 신청 상세 Route::post('/requests/{id}/approve', [CompanyController::class, 'approve'])->whereNumber('id')->name('v1.companies.requests.approve'); // 승인 Route::post('/requests/{id}/reject', [CompanyController::class, 'reject'])->whereNumber('id')->name('v1.companies.requests.reject'); // 반려 Route::get('/my-requests', [CompanyController::class, 'myRequests'])->name('v1.companies.my-requests'); // 내 신청 목록 });