fix: 수주 삭제 로직 강화 - 연관 데이터 cascade soft delete

- 삭제 불가 상태 추가 (생산중/생산완료/출하중/출하완료)
- 작업지시/출하 존재 시 삭제 차단 + 에러 메시지
- order_item_components → order_items → order_nodes → order 순차 soft delete
- DB 트랜잭션으로 원자성 보장

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-09 21:31:19 +09:00
parent 61c70b6fd1
commit be572678db
2 changed files with 40 additions and 4 deletions

View File

@@ -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';
});
}
/**

View File

@@ -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' => '확정 상태의 수주만 생산지시를 생성할 수 있습니다.',