feat: 견적확정 밸리데이션, 작업지시 통계 공정별 카운트, 입고/재고 개선

- 견적확정 시 업체명/현장명/담당자/연락처 필수 검증 추가 (QuoteService)
- 작업지시 stats API에 by_process 공정별 카운트 반환 추가
- 작업지시 목록/상세 쿼리에 수주 개소(rootNodes) 연관 로딩
- 작업지시 품목에 sourceOrderItem.node 관계 추가
- 입고관리 완료건 수정 허용 및 재고 차이 조정
- work_order_step_progress 테이블 마이그레이션
- receivings 테이블 options 컬럼 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-07 03:27:07 +09:00
parent 6b3e5c3e87
commit 487e651845
22 changed files with 1422 additions and 72 deletions

View File

@@ -1,6 +1,6 @@
# 논리적 데이터베이스 관계 문서
> **자동 생성**: 2026-02-05 15:42:10
> **자동 생성**: 2026-02-07 01:10:55
> **소스**: Eloquent 모델 관계 분석
## 📊 모델별 관계 현황
@@ -308,6 +308,36 @@ ### folders
**모델**: `App\Models\Folder`
### interview_answers
**모델**: `App\Models\Interview\InterviewAnswer`
- **session()**: belongsTo → `interview_sessions`
- **question()**: belongsTo → `interview_questions`
- **template()**: belongsTo → `interview_templates`
### interview_categorys
**모델**: `App\Models\Interview\InterviewCategory`
- **templates()**: hasMany → `interview_templates`
- **sessions()**: hasMany → `interview_sessions`
### interview_questions
**모델**: `App\Models\Interview\InterviewQuestion`
- **template()**: belongsTo → `interview_templates`
### interview_sessions
**모델**: `App\Models\Interview\InterviewSession`
- **category()**: belongsTo → `interview_categories`
- **answers()**: hasMany → `interview_answers`
### interview_templates
**모델**: `App\Models\Interview\InterviewTemplate`
- **category()**: belongsTo → `interview_categories`
- **questions()**: hasMany → `interview_questions`
### custom_tabs
**모델**: `App\Models\ItemMaster\CustomTab`
@@ -469,6 +499,8 @@ ### orders
- **item()**: belongsTo → `items`
- **sale()**: belongsTo → `sales`
- **items()**: hasMany → `order_items`
- **nodes()**: hasMany → `order_nodes`
- **rootNodes()**: hasMany → `order_nodes`
- **histories()**: hasMany → `order_histories`
- **versions()**: hasMany → `order_versions`
- **workOrders()**: hasMany → `work_orders`
@@ -484,6 +516,7 @@ ### order_items
**모델**: `App\Models\Orders\OrderItem`
- **order()**: belongsTo → `orders`
- **node()**: belongsTo → `order_nodes`
- **item()**: belongsTo → `items`
- **quote()**: belongsTo → `quotes`
- **quoteItem()**: belongsTo → `quote_items`
@@ -494,6 +527,14 @@ ### order_item_components
- **orderItem()**: belongsTo → `order_items`
### order_nodes
**모델**: `App\Models\Orders\OrderNode`
- **parent()**: belongsTo → `order_nodes`
- **order()**: belongsTo → `orders`
- **children()**: hasMany → `order_nodes`
- **items()**: hasMany → `order_items`
### order_versions
**모델**: `App\Models\Orders\OrderVersion`
@@ -567,6 +608,7 @@ ### work_orders
- **primaryAssignee()**: hasMany → `work_order_assignees`
- **items()**: hasMany → `work_order_items`
- **issues()**: hasMany → `work_order_issues`
- **stepProgress()**: hasMany → `work_order_step_progress`
- **shipments()**: hasMany → `shipments`
- **bendingDetail()**: hasOne → `work_order_bending_details`
@@ -594,6 +636,14 @@ ### work_order_items
- **workOrder()**: belongsTo → `work_orders`
- **item()**: belongsTo → `items`
### work_order_step_progress
**모델**: `App\Models\Production\WorkOrderStepProgress`
- **workOrder()**: belongsTo → `work_orders`
- **processStep()**: belongsTo → `process_steps`
- **workOrderItem()**: belongsTo → `work_order_items`
- **completedByUser()**: belongsTo → `users`
### work_results
**모델**: `App\Models\Production\WorkResult`