fix: 조인트바 자동 계산 추가 (레거시 5130 공식 적용)

- KyungdongFormulaHandler: joint_bar_qty 미전달 시 자동 계산
  공식: (2 + floor((제작가로 - 500) / 1000)) × 셔터수량
- OrderService.extractSlatInfoFromBom(): 동일 폴백 추가
- OrderService.createWorkOrders(): slat_info.joint_bar 0일 때 width 기반 계산
- CURRENT_WORKS.md 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 22:35:43 +09:00
parent 1429f22f11
commit 2fedc3a712
3 changed files with 73 additions and 1 deletions

View File

@@ -1,3 +1,46 @@
## 2026-02-19 (수) - 슬랫 조인트바 자동 계산 및 데이터 파이프라인 완성
### 작업 목표
- 조인트바 수량이 BOM에 생성되지 않는 문제 수정
- 견적→수주→작업지시 전체 데이터 파이프라인에 조인트바/방화유리 연동
### 근본 원인
- `joint_bar_qty`가 프론트에서 전달되지 않아 항상 0 → 조인트바 BOM 미생성
- 레거시 5130은 자동 계산: `(2 + floor((제작가로 - 500) / 1000)) × 셔터수량`
### 수정된 파일
| 파일명 | 설명 |
|--------|------|
| `app/Services/Quote/Handlers/KyungdongFormulaHandler.php` | joint_bar_qty 미전달 시 레거시 공식 자동 계산 추가 |
| `app/Services/OrderService.php` | extractSlatInfoFromBom() 및 createWorkOrders()에 동일 폴백 추가 |
### 데이터 백필
- 기존 72건 work_order_items의 slat_info 업데이트 (joint_bar: 0→4, glass_qty: 0→1)
### 상태: ✅ 완료
- ✅ KyungdongFormulaHandler 자동 계산 추가
- ✅ OrderService 3단계 폴백 (nodeOptions → bom_result → width 기반 계산)
- ✅ 기존 데이터 백필 완료
- ✅ 견적 화면에서 조인트바 BOM 항목 표시 확인
- ⬜ 전체 파이프라인 E2E 검증 (견적→수주→작업지시→작업자화면)
---
## 2026-02-19 (수) - 작업일지 담당자 정보 및 슬랫 데이터 파이프라인 구축
### 커밋 내역
- `316d412` fix: 슬랫 작업일지 데이터 파이프라인 구축
- `1ddef5a` fix: 경동 BOM 계산 수정 및 품목-공정 매핑
- `0c58c52` fix: 견적→수주 변환 시 담당자 정보 누락 수정
### 수정된 파일
| 파일명 | 설명 |
|--------|------|
| `app/Services/OrderService.php` | extractSlatInfoFromBom() 신규, createFromQuote/syncFromQuote에 slat_info 추가, createWorkOrders 폴백 |
| `app/Services/Quote/Handlers/KyungdongFormulaHandler.php` | 조인트바 조건: slat → slat+steel 확장 |
---
## 2026-01-30 (목) - 5130↔SAM 견적 교차 검증 완료 + 마이그레이션 검증
### 작업 목표

View File

@@ -1162,10 +1162,17 @@ public function createProductionOrder(int $orderId, array $data)
$slatInfo = $this->extractSlatInfoFromBom($nodeOptions['bom_result']);
}
// slat_info의 joint_bar가 0이면 레거시 공식으로 자동 계산
$woWidth = $nodeOptions['width'] ?? $nodeOptions['open_width'] ?? null;
if ($slatInfo && ($slatInfo['joint_bar'] ?? 0) <= 0 && $woWidth > 0) {
$qty = (int) $orderItem->quantity;
$slatInfo['joint_bar'] = (2 + (int) floor(((float) $woWidth - 500) / 1000)) * $qty;
}
$woItemOptions = array_filter([
'floor' => $orderItem->floor_code,
'code' => $orderItem->symbol_code,
'width' => $nodeOptions['width'] ?? $nodeOptions['open_width'] ?? null,
'width' => $woWidth,
'height' => $nodeOptions['height'] ?? $nodeOptions['open_height'] ?? null,
'cutting_info' => $nodeOptions['cutting_info'] ?? null,
'slat_info' => $slatInfo,
@@ -1238,6 +1245,16 @@ private function extractSlatInfoFromBom(?array $bomResult, array $locItem = []):
}
}
// 프론트 미전달 시 레거시 5130 자동 계산 (Slat_updateCo76)
// col76 = (2 + floor((제작가로 - 500) / 1000)) * 셔터수량
if ($jointBarQty <= 0) {
$width = (float) ($bomVars['W0'] ?? $locItem['width'] ?? 0);
$quantity = (int) ($bomVars['QTY'] ?? $locItem['quantity'] ?? 1);
if ($width > 0) {
$jointBarQty = (2 + (int) floor(($width - 500) / 1000)) * $quantity;
}
}
// 방화유리 수량: 프론트 입력값 우선, 없으면 개소 수량(QTY)
$glassQty = (int) ($locItem['glass_qty'] ?? $bomVars['glass_qty'] ?? $locItem['quantity'] ?? 0);

View File

@@ -925,6 +925,18 @@ public function calculatePartItems(array $params): array
// 5130 레거시: 철재(KQTS01)도 슬랫 공정에서 조인트바 사용
if (in_array($productType, ['slat', 'steel'])) {
$jointBarQty = (int) ($params['joint_bar_qty'] ?? 0);
// 프론트에서 미전달 시 레거시 5130 자동 계산 공식 적용
// 5130/estimate/common/common_addrowJS.php Slat_updateCo76():
// col76 = (2 + floor((제작가로 - 500) / 1000)) * 셔터수량
if ($jointBarQty <= 0) {
$width = (float) ($params['W0'] ?? 0);
$quantity = (int) ($params['QTY'] ?? 1);
if ($width > 0) {
$jointBarQty = (2 + (int) floor(($width - 500) / 1000)) * $quantity;
}
}
if ($jointBarQty > 0) {
$jointBarPrice = $this->getRawMaterialPrice('조인트바');
if ($jointBarPrice > 0) {