fix:생산지시 되돌리기 시 누락된 관련 데이터 삭제 보완

- 자재 투입(material_inputs) 재고 복구(increaseToLot) 후 삭제
- 문서(documents/data/approvals) 영구삭제 (검사 성적서, 작업일지)
- 출하(shipments) work_order_id 참조 해제
- step_progress, assignees, bending_details, issues 명시적 삭제 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 04:03:10 +09:00
parent 5eaa65cc9c
commit 090a978991

View File

@@ -2,14 +2,19 @@
namespace App\Services; 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\Items\Item;
use App\Models\Orders\Order; use App\Models\Orders\Order;
use App\Models\Orders\OrderHistory; use App\Models\Orders\OrderHistory;
use App\Models\Orders\OrderNode; use App\Models\Orders\OrderNode;
use App\Models\Production\WorkOrder; use App\Models\Production\WorkOrder;
use App\Models\Production\WorkOrderMaterialInput;
use App\Models\Quote\Quote; use App\Models\Quote\Quote;
use App\Models\Tenants\Sale; use App\Models\Tenants\Sale;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -1289,25 +1294,87 @@ public function revertProductionOrder(int $orderId): array
'work_results' => 0, 'work_results' => 0,
'work_order_items' => 0, 'work_order_items' => 0,
'work_orders' => 0, 'work_orders' => 0,
'material_inputs' => 0,
'documents' => 0,
'step_progress' => 0,
'assignees' => 0,
'bending_details' => 0,
'issues' => 0,
]; ];
if (count($workOrderIds) > 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') $deletedCounts['work_results'] = DB::table('work_results')
->whereIn('work_order_id', $workOrderIds) ->whereIn('work_order_id', $workOrderIds)
->delete(); ->delete();
// 2. 작업지시 품목 삭제 // 6. 작업지시 품목 삭제
$deletedCounts['work_order_items'] = DB::table('work_order_items') $deletedCounts['work_order_items'] = DB::table('work_order_items')
->whereIn('work_order_id', $workOrderIds) ->whereIn('work_order_id', $workOrderIds)
->delete(); ->delete();
// 3. 작업지시 삭제 // 7. 작업지시 삭제
$deletedCounts['work_orders'] = WorkOrder::whereIn('id', $workOrderIds) $deletedCounts['work_orders'] = WorkOrder::whereIn('id', $workOrderIds)->delete();
->delete();
} }
// 4. 수주 상태를 CONFIRMED로 되돌리기 // 8. 수주 상태를 CONFIRMED로 되돌리기
$previousStatus = $order->status_code; $previousStatus = $order->status_code;
$order->status_code = Order::STATUS_CONFIRMED; $order->status_code = Order::STATUS_CONFIRMED;
$order->updated_by = $userId; $order->updated_by = $userId;