feat: I-1 미지급비용 관리 API 개발

- ExpectedExpense 모델 및 마이그레이션 생성
- ExpectedExpenseService 구현 (CRUD, 일괄삭제, 지급일 변경, 요약)
- ExpectedExpenseController REST API 구현
- FormRequest 검증 클래스 3개 생성
- Swagger API 문서 작성
- 라우트 추가 (8개 엔드포인트)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-26 13:23:07 +09:00
parent 0fef26f42a
commit 1f5539db32
9 changed files with 1097 additions and 0 deletions

View File

@@ -34,6 +34,7 @@
use App\Http\Controllers\Api\V1\Design\DesignModelController;
use App\Http\Controllers\Api\V1\Design\ModelVersionController as DesignModelVersionController;
use App\Http\Controllers\Api\V1\EmployeeController;
use App\Http\Controllers\Api\V1\ExpectedExpenseController;
use App\Http\Controllers\Api\V1\EstimateController;
use App\Http\Controllers\Api\V1\FileStorageController;
use App\Http\Controllers\Api\V1\FolderController;
@@ -66,6 +67,7 @@
use App\Http\Controllers\Api\V1\PostController;
use App\Http\Controllers\Api\V1\PricingController;
use App\Http\Controllers\Api\V1\PurchaseController;
use App\Http\Controllers\Api\V1\ReceivingController;
use App\Http\Controllers\Api\V1\PushNotificationController;
use App\Http\Controllers\Api\V1\QuoteController;
use App\Http\Controllers\Api\V1\RefreshController;
@@ -89,6 +91,7 @@
use App\Http\Controllers\Api\V1\UserInvitationController;
use App\Http\Controllers\Api\V1\UserRoleController;
use App\Http\Controllers\Api\V1\WithdrawalController;
use App\Http\Controllers\Api\V1\WorkOrderController;
use App\Http\Controllers\Api\V1\WorkSettingController;
use Illuminate\Support\Facades\Route;
@@ -445,6 +448,18 @@
Route::patch('/{id}/status', [SalaryController::class, 'updateStatus'])->whereNumber('id')->name('v1.salaries.update-status');
});
// Expected Expense API (미지급비용 관리)
Route::prefix('expected-expenses')->group(function () {
Route::get('', [ExpectedExpenseController::class, 'index'])->name('v1.expected-expenses.index');
Route::post('', [ExpectedExpenseController::class, 'store'])->name('v1.expected-expenses.store');
Route::get('/summary', [ExpectedExpenseController::class, 'summary'])->name('v1.expected-expenses.summary');
Route::delete('', [ExpectedExpenseController::class, 'destroyMany'])->name('v1.expected-expenses.destroy-many');
Route::put('/update-payment-date', [ExpectedExpenseController::class, 'updateExpectedPaymentDate'])->name('v1.expected-expenses.update-payment-date');
Route::get('/{id}', [ExpectedExpenseController::class, 'show'])->whereNumber('id')->name('v1.expected-expenses.show');
Route::put('/{id}', [ExpectedExpenseController::class, 'update'])->whereNumber('id')->name('v1.expected-expenses.update');
Route::delete('/{id}', [ExpectedExpenseController::class, 'destroy'])->whereNumber('id')->name('v1.expected-expenses.destroy');
});
// Loan API (가지급금 관리)
Route::prefix('loans')->group(function () {
Route::get('', [LoanController::class, 'index'])->name('v1.loans.index');
@@ -533,6 +548,17 @@
Route::post('/{id}/confirm', [PurchaseController::class, 'confirm'])->whereNumber('id')->name('v1.purchases.confirm');
});
// Receiving API (입고 관리)
Route::prefix('receivings')->group(function () {
Route::get('', [ReceivingController::class, 'index'])->name('v1.receivings.index');
Route::post('', [ReceivingController::class, 'store'])->name('v1.receivings.store');
Route::get('/stats', [ReceivingController::class, 'stats'])->name('v1.receivings.stats');
Route::get('/{id}', [ReceivingController::class, 'show'])->whereNumber('id')->name('v1.receivings.show');
Route::put('/{id}', [ReceivingController::class, 'update'])->whereNumber('id')->name('v1.receivings.update');
Route::delete('/{id}', [ReceivingController::class, 'destroy'])->whereNumber('id')->name('v1.receivings.destroy');
Route::post('/{id}/process', [ReceivingController::class, 'process'])->whereNumber('id')->name('v1.receivings.process');
});
// Barobill Setting API (바로빌 설정)
Route::prefix('barobill-settings')->group(function () {
Route::get('', [BarobillSettingController::class, 'show'])->name('v1.barobill-settings.show');
@@ -926,6 +952,28 @@
Route::post('/preview/{model_set_id}', [EstimateController::class, 'previewCalculation'])->name('v1.estimates.preview'); // 견적 계산 미리보기
});
// 작업지시 관리 API (Production)
Route::prefix('work-orders')->group(function () {
// 기본 CRUD
Route::get('', [WorkOrderController::class, 'index'])->name('v1.work-orders.index'); // 목록
Route::get('/stats', [WorkOrderController::class, 'stats'])->name('v1.work-orders.stats'); // 통계
Route::post('', [WorkOrderController::class, 'store'])->name('v1.work-orders.store'); // 생성
Route::get('/{id}', [WorkOrderController::class, 'show'])->whereNumber('id')->name('v1.work-orders.show'); // 상세
Route::put('/{id}', [WorkOrderController::class, 'update'])->whereNumber('id')->name('v1.work-orders.update'); // 수정
Route::delete('/{id}', [WorkOrderController::class, 'destroy'])->whereNumber('id')->name('v1.work-orders.destroy'); // 삭제
// 상태 및 담당자 관리
Route::patch('/{id}/status', [WorkOrderController::class, 'updateStatus'])->whereNumber('id')->name('v1.work-orders.status'); // 상태 변경
Route::patch('/{id}/assign', [WorkOrderController::class, 'assign'])->whereNumber('id')->name('v1.work-orders.assign'); // 담당자 배정
// 벤딩 공정 상세 토글
Route::patch('/{id}/bending/toggle', [WorkOrderController::class, 'toggleBendingField'])->whereNumber('id')->name('v1.work-orders.bending-toggle');
// 이슈 관리
Route::post('/{id}/issues', [WorkOrderController::class, 'addIssue'])->whereNumber('id')->name('v1.work-orders.issues.store'); // 이슈 등록
Route::patch('/{id}/issues/{issueId}/resolve', [WorkOrderController::class, 'resolveIssue'])->whereNumber('id')->name('v1.work-orders.issues.resolve'); // 이슈 해결
});
// 파일 저장소 API
Route::prefix('files')->group(function () {
Route::post('/upload', [FileStorageController::class, 'upload'])->name('v1.files.upload'); // 파일 업로드 (임시)