From be572678db9e8da590360cef627502021d20e61e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Mon, 9 Feb 2026 21:31:19 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=88=98=EC=A3=BC=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EA=B0=95=ED=99=94=20-=20=EC=97=B0?= =?UTF-8?q?=EA=B4=80=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20cascade=20soft=20dele?= =?UTF-8?q?te?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 삭제 불가 상태 추가 (생산중/생산완료/출하중/출하완료) - 작업지시/출하 존재 시 삭제 차단 + 에러 메시지 - order_item_components → order_items → order_nodes → order 순차 soft delete - DB 트랜잭션으로 원자성 보장 Co-Authored-By: Claude Opus 4.6 --- app/Services/OrderService.php | 42 +++++++++++++++++++++++++++++++---- lang/ko/error.php | 2 ++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php index 565a1b5..151c2f2 100644 --- a/app/Services/OrderService.php +++ b/app/Services/OrderService.php @@ -254,6 +254,7 @@ public function update(int $id, array $data) public function destroy(int $id) { $tenantId = $this->tenantId(); + $userId = $this->apiUserId(); $order = Order::where('tenant_id', $tenantId)->find($id); if (! $order) { @@ -263,16 +264,49 @@ public function destroy(int $id) // 진행 중이거나 완료된 수주는 삭제 불가 if (in_array($order->status_code, [ Order::STATUS_IN_PROGRESS, + Order::STATUS_IN_PRODUCTION, + Order::STATUS_PRODUCED, + Order::STATUS_SHIPPING, + Order::STATUS_SHIPPED, Order::STATUS_COMPLETED, ])) { throw new BadRequestHttpException(__('error.order.cannot_delete_in_progress')); } - $order->deleted_by = $this->apiUserId(); - $order->save(); - $order->delete(); + // 작업지시가 존재하면 삭제 불가 + if ($order->workOrders()->exists()) { + throw new BadRequestHttpException(__('error.order.cannot_delete_has_work_orders')); + } - return 'success'; + // 출하 정보가 존재하면 삭제 불가 + if ($order->shipments()->exists()) { + throw new BadRequestHttpException(__('error.order.cannot_delete_has_shipments')); + } + + return DB::transaction(function () use ($order, $userId) { + // 1. order_item_components soft delete + foreach ($order->items as $item) { + $item->components()->update(['deleted_by' => $userId]); + $item->components()->delete(); + } + + // 2. order_items soft delete + $order->items()->update(['deleted_by' => $userId]); + $order->items()->delete(); + + // 3. order_nodes soft delete + $order->nodes()->update(['deleted_by' => $userId]); + $order->nodes()->delete(); + + // 4. order 마스터 soft delete + $order->deleted_by = $userId; + $order->save(); + $order->delete(); + + // order_histories, order_versions는 감사 기록이므로 보존 + + return 'success'; + }); } /** diff --git a/lang/ko/error.php b/lang/ko/error.php index 7219270..ab2dd98 100644 --- a/lang/ko/error.php +++ b/lang/ko/error.php @@ -400,6 +400,8 @@ 'order' => [ 'cannot_update_completed' => '완료 또는 취소된 수주는 수정할 수 없습니다.', 'cannot_delete_in_progress' => '진행 중이거나 완료된 수주는 삭제할 수 없습니다.', + 'cannot_delete_has_work_orders' => '작업지시가 존재하는 수주는 삭제할 수 없습니다. 작업지시를 먼저 삭제해주세요.', + 'cannot_delete_has_shipments' => '출하 정보가 존재하는 수주는 삭제할 수 없습니다. 출하를 먼저 삭제해주세요.', 'invalid_status_transition' => '유효하지 않은 상태 전환입니다.', 'already_created_from_quote' => '이미 해당 견적에서 수주가 생성되었습니다.', 'must_be_confirmed_for_production' => '확정 상태의 수주만 생산지시를 생성할 수 있습니다.',