diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php index 8a78555..13bdd0b 100644 --- a/app/Services/OrderService.php +++ b/app/Services/OrderService.php @@ -2,14 +2,19 @@ namespace App\Services; +use App\Models\Documents\Document; +use App\Models\Documents\DocumentApproval; +use App\Models\Documents\DocumentData; use App\Models\Items\Item; use App\Models\Orders\Order; use App\Models\Orders\OrderHistory; use App\Models\Orders\OrderNode; use App\Models\Production\WorkOrder; +use App\Models\Production\WorkOrderMaterialInput; use App\Models\Quote\Quote; use App\Models\Tenants\Sale; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -1289,25 +1294,87 @@ public function revertProductionOrder(int $orderId): array 'work_results' => 0, 'work_order_items' => 0, 'work_orders' => 0, + 'material_inputs' => 0, + 'documents' => 0, + 'step_progress' => 0, + 'assignees' => 0, + 'bending_details' => 0, + 'issues' => 0, ]; if (count($workOrderIds) > 0) { - // 1. 작업결과 삭제 + // 1. 자재 투입 재고 복구 + 삭제 + $materialInputs = WorkOrderMaterialInput::whereIn('work_order_id', $workOrderIds)->get(); + if ($materialInputs->isNotEmpty()) { + $stockService = app(StockService::class); + foreach ($materialInputs as $input) { + try { + $stockService->increaseToLot( + stockLotId: $input->stock_lot_id, + qty: (float) $input->qty, + reason: 'work_order_input_cancel', + referenceId: $input->work_order_id + ); + } catch (\Exception $e) { + Log::warning('생산지시 되돌리기: 재고 복원 실패', [ + 'input_id' => $input->id, + 'stock_lot_id' => $input->stock_lot_id, + 'error' => $e->getMessage(), + ]); + } + } + $deletedCounts['material_inputs'] = WorkOrderMaterialInput::whereIn('work_order_id', $workOrderIds)->delete(); + } + + // 2. 문서 삭제 (검사 성적서, 작업일지 등) + $documentIds = Document::where('linkable_type', 'work_order') + ->whereIn('linkable_id', $workOrderIds) + ->pluck('id') + ->toArray(); + + if (count($documentIds) > 0) { + DocumentData::whereIn('document_id', $documentIds)->delete(); + DocumentApproval::whereIn('document_id', $documentIds)->delete(); + $deletedCounts['documents'] = Document::whereIn('id', $documentIds)->forceDelete(); + } + + // 3. 출하 정보에서 작업지시 참조 해제 (출하 자체는 보존) + DB::table('shipments') + ->whereIn('work_order_id', $workOrderIds) + ->update(['work_order_id' => null]); + + // 4. 작업지시 부속 데이터 삭제 + $deletedCounts['step_progress'] = DB::table('work_order_step_progress') + ->whereIn('work_order_id', $workOrderIds) + ->delete(); + + $deletedCounts['assignees'] = DB::table('work_order_assignees') + ->whereIn('work_order_id', $workOrderIds) + ->delete(); + + $deletedCounts['bending_details'] = DB::table('work_order_bending_details') + ->whereIn('work_order_id', $workOrderIds) + ->delete(); + + $deletedCounts['issues'] = DB::table('work_order_issues') + ->whereIn('work_order_id', $workOrderIds) + ->delete(); + + // 5. 작업결과 삭제 $deletedCounts['work_results'] = DB::table('work_results') ->whereIn('work_order_id', $workOrderIds) ->delete(); - // 2. 작업지시 품목 삭제 + // 6. 작업지시 품목 삭제 $deletedCounts['work_order_items'] = DB::table('work_order_items') ->whereIn('work_order_id', $workOrderIds) ->delete(); - // 3. 작업지시 삭제 - $deletedCounts['work_orders'] = WorkOrder::whereIn('id', $workOrderIds) - ->delete(); + // 7. 작업지시 삭제 + $deletedCounts['work_orders'] = WorkOrder::whereIn('id', $workOrderIds)->delete(); } - // 4. 수주 상태를 CONFIRMED로 되돌리기 + // 8. 수주 상태를 CONFIRMED로 되돌리기 $previousStatus = $order->status_code; $order->status_code = Order::STATUS_CONFIRMED; $order->updated_by = $userId;