fix(WEB): 작업지시 품목 수주 연동 및 발주처 표시 수정

- 작업지시 생성 시 수주 품목 자동 복사 기능 추가
- 품목 추적용 source_order_item_id 컬럼 추가
- 발주처 표시를 위해 salesOrder 로딩에 client_id 추가
- 담당자 수정 시 assignee_ids 배열 처리 추가

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-01-16 15:30:50 +09:00
parent a0593a3c12
commit 8bac207274
3 changed files with 104 additions and 8 deletions

View File

@@ -19,6 +19,7 @@ class WorkOrderItem extends Model
protected $fillable = [
'tenant_id',
'work_order_id',
'source_order_item_id', // 원본 수주 품목 추적용
'item_id',
'item_name',
'specification',

View File

@@ -40,7 +40,14 @@ public function index(array $params)
$query = WorkOrder::query()
->where('tenant_id', $tenantId)
->with(['assignee:id,name', 'assignees.user:id,name', 'team:id,name', 'salesOrder:id,order_no', 'process:id,process_name,process_code']);
->with([
'assignee:id,name',
'assignees.user:id,name',
'team:id,name',
'salesOrder:id,order_no,client_id,client_name',
'salesOrder.client:id,name',
'process:id,process_name,process_code',
]);
// 검색어
if ($q !== '') {
@@ -133,7 +140,7 @@ public function show(int $id)
'assignee:id,name',
'assignees.user:id,name',
'team:id,name',
'salesOrder:id,order_no,site_name',
'salesOrder:id,order_no,site_name,client_id',
'salesOrder.client:id,name',
'process:id,process_name,process_code,work_steps',
'items',
@@ -171,6 +178,7 @@ public function store(array $data)
$items = $data['items'] ?? [];
$bendingDetail = $data['bending_detail'] ?? null;
$salesOrderId = $data['sales_order_id'] ?? null;
unset($data['items'], $data['bending_detail']);
$workOrder = WorkOrder::create($data);
@@ -178,11 +186,30 @@ public function store(array $data)
// process 관계 로드 (isBending 체크용)
$workOrder->load('process:id,process_name,process_code');
// 품목 저장
foreach ($items as $index => $item) {
$item['tenant_id'] = $tenantId;
$item['sort_order'] = $index;
$workOrder->items()->create($item);
// 품목 저장: 직접 전달된 품목이 없고 수주 ID가 있으면 수주에서 복사
if (empty($items) && $salesOrderId) {
$salesOrder = \App\Models\Orders\Order::with('items')->find($salesOrderId);
if ($salesOrder && $salesOrder->items->isNotEmpty()) {
foreach ($salesOrder->items as $index => $orderItem) {
$workOrder->items()->create([
'tenant_id' => $tenantId,
'source_order_item_id' => $orderItem->id, // 원본 수주 품목 추적용
'item_id' => $orderItem->item_id,
'item_name' => $orderItem->item_name,
'specification' => $orderItem->specification,
'quantity' => $orderItem->quantity,
'unit' => $orderItem->unit,
'sort_order' => $index,
]);
}
}
} else {
// 직접 전달된 품목 저장
foreach ($items as $index => $item) {
$item['tenant_id'] = $tenantId;
$item['sort_order'] = $index;
$workOrder->items()->create($item);
}
}
// 벤딩 상세 저장 (벤딩 공정인 경우)
@@ -227,7 +254,8 @@ public function update(int $id, array $data)
$items = $data['items'] ?? null;
$bendingDetail = $data['bending_detail'] ?? null;
unset($data['items'], $data['bending_detail'], $data['work_order_no']); // 번호 변경 불가
$assigneeIds = $data['assignee_ids'] ?? null;
unset($data['items'], $data['bending_detail'], $data['assignee_ids'], $data['work_order_no']); // 번호 변경 불가
// 품목 수정 시 기존 품목 기록
$oldItems = null;
@@ -235,8 +263,46 @@ public function update(int $id, array $data)
$oldItems = $workOrder->items()->get()->toArray();
}
// 담당자 수정 시 기존 담당자 기록
$oldAssignees = null;
if ($assigneeIds !== null) {
$oldAssignees = $workOrder->assignees()->pluck('user_id')->toArray();
}
$workOrder->update($data);
// 담당자 처리 (assignee_ids 배열)
if ($assigneeIds !== null) {
$assigneeIds = array_unique(array_filter($assigneeIds));
// 기존 담당자 삭제 후 새로 추가
$workOrder->assignees()->delete();
foreach ($assigneeIds as $index => $assigneeId) {
WorkOrderAssignee::create([
'tenant_id' => $workOrder->tenant_id,
'work_order_id' => $workOrder->id,
'user_id' => $assigneeId,
'is_primary' => $index === 0, // 첫 번째가 주 담당자
]);
}
// 주 담당자는 work_orders 테이블에도 설정 (하위 호환)
$primaryAssigneeId = $assigneeIds[0] ?? null;
$workOrder->assignee_id = $primaryAssigneeId;
$workOrder->save();
// 담당자 수정 감사 로그
$this->auditLogger->log(
$workOrder->tenant_id,
self::AUDIT_TARGET,
$workOrder->id,
'assignees_updated',
['assignee_ids' => $oldAssignees],
['assignee_ids' => $assigneeIds]
);
}
// 품목 부분 수정 (ID 기반 upsert/delete)
if ($items !== null) {
$existingIds = $workOrder->items()->pluck('id')->toArray();