feat: BOM 계산 debug_steps에 수식 정보 추가
- calculateKyungdongBom 메서드에 formulas 배열 추가 - Step 1: 입력값 (변수, 설명, 값, 단위) - Step 3: 변수계산 (수식, 대입, 결과) - Step 6-7: 품목별 수량/금액 계산 과정 - Step 9: 카테고리별 소계 계산 - Step 10: 최종합계 수식 - 프론트엔드에서 실제 계산 수식 확인 가능 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1059,10 +1059,13 @@ private function addProcessGroupToItems(array $items, array $groupedItems): arra
|
||||
|
||||
/**
|
||||
* 품목 단가 조회
|
||||
*
|
||||
* @param string $itemCode 품목 코드
|
||||
* @param int|null $tenantIdOverride 테넌트 ID (외부 호출 시 사용)
|
||||
*/
|
||||
private function getItemPrice(string $itemCode): float
|
||||
public function getItemPrice(string $itemCode, ?int $tenantIdOverride = null): float
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
$tenantId = $tenantIdOverride ?? $this->tenantId();
|
||||
|
||||
if (! $tenantId) {
|
||||
$this->errors[] = __('error.tenant_id_required');
|
||||
@@ -1580,14 +1583,20 @@ private function calculateKyungdongBom(
|
||||
]);
|
||||
|
||||
// Step 1: 입력값 수집
|
||||
$W0 = (float) ($inputVariables['W0'] ?? 0);
|
||||
$H0 = (float) ($inputVariables['H0'] ?? 0);
|
||||
$QTY = (int) ($inputVariables['QTY'] ?? 1);
|
||||
$bracketInch = $inputVariables['bracket_inch'] ?? '5';
|
||||
$productType = $inputVariables['product_type'] ?? 'screen';
|
||||
|
||||
$this->addDebugStep(1, '입력값수집', [
|
||||
'W0' => $inputVariables['W0'] ?? null,
|
||||
'H0' => $inputVariables['H0'] ?? null,
|
||||
'QTY' => $inputVariables['QTY'] ?? 1,
|
||||
'bracket_inch' => $inputVariables['bracket_inch'] ?? '5',
|
||||
'product_type' => $inputVariables['product_type'] ?? 'screen',
|
||||
'finishing_type' => $inputVariables['finishing_type'] ?? 'SUS',
|
||||
'finished_goods' => $finishedGoodsCode,
|
||||
'formulas' => [
|
||||
['var' => 'W0', 'desc' => '개구부 폭', 'value' => $W0, 'unit' => 'mm'],
|
||||
['var' => 'H0', 'desc' => '개구부 높이', 'value' => $H0, 'unit' => 'mm'],
|
||||
['var' => 'QTY', 'desc' => '수량', 'value' => $QTY, 'unit' => 'EA'],
|
||||
['var' => 'bracket_inch', 'desc' => '브라켓 인치', 'value' => $bracketInch, 'unit' => '인치'],
|
||||
['var' => 'product_type', 'desc' => '제품 타입', 'value' => $productType, 'unit' => ''],
|
||||
],
|
||||
]);
|
||||
|
||||
// Step 2: 완제품 조회
|
||||
@@ -1616,15 +1625,20 @@ private function calculateKyungdongBom(
|
||||
$handler = new KyungdongFormulaHandler;
|
||||
|
||||
// Step 3: 경동 전용 변수 계산
|
||||
$W0 = (float) ($inputVariables['W0'] ?? 0);
|
||||
$H0 = (float) ($inputVariables['H0'] ?? 0);
|
||||
$QTY = (int) ($inputVariables['QTY'] ?? 1);
|
||||
$bracketInch = $inputVariables['bracket_inch'] ?? '5';
|
||||
$productType = $inputVariables['product_type'] ?? 'screen';
|
||||
|
||||
// 중량 계산 (5130 로직)
|
||||
$W1 = $W0 + 140;
|
||||
$H1 = $H0 + 350;
|
||||
$area = ($W0 * ($H0 + 550)) / 1000000;
|
||||
$weight = $area * ($productType === 'steel' ? 25 : 2) + ($W0 / 1000) * 14.17;
|
||||
|
||||
// 중량 계산 (제품타입별)
|
||||
if ($productType === 'steel') {
|
||||
$weight = $area * 25;
|
||||
$weightFormula = "AREA × 25";
|
||||
$weightCalc = "{$area} × 25";
|
||||
} else {
|
||||
$weight = $area * 2 + ($W0 / 1000) * 14.17;
|
||||
$weightFormula = "AREA × 2 + (W0 / 1000) × 14.17";
|
||||
$weightCalc = "{$area} × 2 + ({$W0} / 1000) × 14.17";
|
||||
}
|
||||
|
||||
// 모터 용량 결정
|
||||
$motorCapacity = $handler->calculateMotorCapacity($productType, $weight, $bracketInch);
|
||||
@@ -1636,8 +1650,8 @@ private function calculateKyungdongBom(
|
||||
'W0' => $W0,
|
||||
'H0' => $H0,
|
||||
'QTY' => $QTY,
|
||||
'W1' => $W0 + 140,
|
||||
'H1' => $H0 + 350,
|
||||
'W1' => $W1,
|
||||
'H1' => $H1,
|
||||
'AREA' => round($area, 4),
|
||||
'WEIGHT' => round($weight, 2),
|
||||
'MOTOR_CAPACITY' => $motorCapacity,
|
||||
@@ -1647,13 +1661,56 @@ private function calculateKyungdongBom(
|
||||
]);
|
||||
|
||||
$this->addDebugStep(3, '변수계산', [
|
||||
'W0' => $W0,
|
||||
'H0' => $H0,
|
||||
'area' => round($area, 4),
|
||||
'weight' => round($weight, 2),
|
||||
'motor_capacity' => $motorCapacity,
|
||||
'bracket_size' => $bracketSize,
|
||||
'calculation_type' => '경동기업 전용 공식',
|
||||
'formulas' => [
|
||||
[
|
||||
'var' => 'W1',
|
||||
'desc' => '제작 폭',
|
||||
'formula' => 'W0 + 140',
|
||||
'calculation' => "{$W0} + 140",
|
||||
'result' => $W1,
|
||||
'unit' => 'mm',
|
||||
],
|
||||
[
|
||||
'var' => 'H1',
|
||||
'desc' => '제작 높이',
|
||||
'formula' => 'H0 + 350',
|
||||
'calculation' => "{$H0} + 350",
|
||||
'result' => $H1,
|
||||
'unit' => 'mm',
|
||||
],
|
||||
[
|
||||
'var' => 'AREA',
|
||||
'desc' => '면적',
|
||||
'formula' => '(W0 × (H0 + 550)) / 1,000,000',
|
||||
'calculation' => "({$W0} × ({$H0} + 550)) / 1,000,000",
|
||||
'result' => round($area, 4),
|
||||
'unit' => '㎡',
|
||||
],
|
||||
[
|
||||
'var' => 'WEIGHT',
|
||||
'desc' => '중량',
|
||||
'formula' => $weightFormula,
|
||||
'calculation' => $weightCalc,
|
||||
'result' => round($weight, 2),
|
||||
'unit' => 'kg',
|
||||
],
|
||||
[
|
||||
'var' => 'MOTOR_CAPACITY',
|
||||
'desc' => '모터 용량',
|
||||
'formula' => '중량/브라켓 기준표 조회',
|
||||
'calculation' => "WEIGHT({$weight}) + INCH({$bracketInch}) → 조회",
|
||||
'result' => $motorCapacity,
|
||||
'unit' => '',
|
||||
],
|
||||
[
|
||||
'var' => 'BRACKET_SIZE',
|
||||
'desc' => '브라켓 크기',
|
||||
'formula' => '중량 기준표 조회',
|
||||
'calculation' => "WEIGHT({$weight}) → 조회",
|
||||
'result' => $bracketSize,
|
||||
'unit' => '인치',
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
// Step 4-7: 동적 항목 계산 (KyungdongFormulaHandler 사용)
|
||||
@@ -1662,22 +1719,26 @@ private function calculateKyungdongBom(
|
||||
$this->addDebugStep(4, 'BOM전개', [
|
||||
'total_items' => count($dynamicItems),
|
||||
'item_categories' => array_unique(array_column($dynamicItems, 'category')),
|
||||
'items' => array_map(fn ($item) => [
|
||||
'name' => $item['item_name'],
|
||||
'category' => $item['category'],
|
||||
], $dynamicItems),
|
||||
]);
|
||||
|
||||
// Step 5-7: 단가 계산 (각 항목별)
|
||||
$calculatedItems = [];
|
||||
foreach ($dynamicItems as $item) {
|
||||
$this->addDebugStep(6, '수량계산', [
|
||||
'item_name' => $item['item_name'],
|
||||
'quantity' => $item['quantity'],
|
||||
]);
|
||||
$itemFormulas = [];
|
||||
|
||||
$this->addDebugStep(7, '금액계산', [
|
||||
'item_name' => $item['item_name'],
|
||||
'quantity' => $item['quantity'],
|
||||
foreach ($dynamicItems as $item) {
|
||||
$itemFormulas[] = [
|
||||
'item' => $item['item_name'],
|
||||
'qty_formula' => $item['quantity_formula'] ?? '고정값',
|
||||
'qty_result' => $item['quantity'],
|
||||
'unit_price' => $item['unit_price'],
|
||||
'total_price' => $item['total_price'],
|
||||
]);
|
||||
'price_formula' => '수량 × 단가',
|
||||
'price_calc' => "{$item['quantity']} × {$item['unit_price']}",
|
||||
'total' => $item['total_price'],
|
||||
];
|
||||
|
||||
$calculatedItems[] = [
|
||||
'item_code' => $item['item_code'] ?? '',
|
||||
@@ -1686,13 +1747,23 @@ private function calculateKyungdongBom(
|
||||
'specification' => $item['specification'] ?? '',
|
||||
'unit' => $item['unit'],
|
||||
'quantity' => $item['quantity'],
|
||||
'quantity_formula' => $item['quantity_formula'] ?? '',
|
||||
'unit_price' => $item['unit_price'],
|
||||
'total_price' => $item['total_price'],
|
||||
'category_group' => $item['category'],
|
||||
'process_group' => $item['category'],
|
||||
'calculation_note' => '경동기업 전용 계산',
|
||||
];
|
||||
}
|
||||
|
||||
$this->addDebugStep(6, '수량계산', [
|
||||
'formulas' => $itemFormulas,
|
||||
]);
|
||||
|
||||
$this->addDebugStep(7, '금액계산', [
|
||||
'formulas' => $itemFormulas,
|
||||
]);
|
||||
|
||||
// Step 8: 카테고리별 그룹화
|
||||
$groupedItems = [];
|
||||
foreach ($calculatedItems as $item) {
|
||||
@@ -1718,22 +1789,33 @@ private function calculateKyungdongBom(
|
||||
|
||||
// Step 9: 소계 계산
|
||||
$subtotals = [];
|
||||
$subtotalFormulas = [];
|
||||
foreach ($groupedItems as $category => $group) {
|
||||
$subtotals[$category] = [
|
||||
'name' => $group['name'],
|
||||
'count' => count($group['items']),
|
||||
'subtotal' => $group['subtotal'],
|
||||
];
|
||||
$subtotalFormulas[] = [
|
||||
'category' => $group['name'],
|
||||
'formula' => implode(' + ', array_map(fn ($i) => $i['item_name'], $group['items'])),
|
||||
'result' => $group['subtotal'],
|
||||
];
|
||||
}
|
||||
|
||||
$this->addDebugStep(9, '소계계산', $subtotals);
|
||||
$this->addDebugStep(9, '소계계산', [
|
||||
'formulas' => $subtotalFormulas,
|
||||
'subtotals' => $subtotals,
|
||||
]);
|
||||
|
||||
// Step 10: 최종 합계
|
||||
$grandTotal = array_sum(array_column($calculatedItems, 'total_price'));
|
||||
$subtotalValues = array_column($subtotals, 'subtotal');
|
||||
|
||||
$this->addDebugStep(10, '최종합계', [
|
||||
'item_count' => count($calculatedItems),
|
||||
'grand_total' => $grandTotal,
|
||||
'formula' => implode(' + ', array_column($subtotals, 'name')),
|
||||
'calculation' => implode(' + ', array_map(fn ($v) => number_format($v), $subtotalValues)),
|
||||
'result' => $grandTotal,
|
||||
'formatted' => number_format($grandTotal).'원',
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user