- simulator-calculation-logic-mapping.md: design.sam.kr 계산 로직 상세 분석 - 변수 계산 규칙 (W0,H0 → W1,H1,M) - 수식 평가 함수 및 지원 함수 목록 - BOM 10단계 계산 과정 - 단가 계산 방식 (pricing → itemMaster → 면적단가) - simulator-planning-page-sync-plan.md: mng 시뮬레이터 동기화 계획 - index_plans.md: 새 문서 인덱스 추가
8.7 KiB
8.7 KiB
견적 시뮬레이터 계산 로직 매핑
작성일: 2025-12-23 목표: design.sam.kr 계산 로직 → mng 시뮬레이터 동기화
1. Design 계산 로직 분석
1.1 핵심 계산 변수 (AutoCalculationSimulator.tsx:429-444)
const calculationVariables = {
W0: quote.w0, // 오픈사이즈 폭 (입력)
H0: quote.h0, // 오픈사이즈 높이 (입력)
W1: quote.category === '스크린' ? W0 + 140 : W0 + 110, // 제작폭
H1: H0 + 350, // 제작높이
W: W1, // W = W1 (매핑)
H: H1, // H = H1 (매핑)
M: (W1 * H1) / 1000000, // 면적 (㎡)
K: 0 // 중량 (미구현)
};
1.2 수식 평가 함수 (formulaEvaluator.ts)
지원 함수:
| 함수 | 설명 | 예시 |
|---|---|---|
SUM(a, b, ...) |
합계 | SUM(W0, H0, 100) |
AVERAGE(a, b, ...) |
평균 | AVERAGE(W0, H0) |
MAX(a, b, ...) |
최대값 | MAX(W0, 1000) |
MIN(a, b, ...) |
최소값 | MIN(H0, 3000) |
ROUND(value, decimals) |
반올림 | ROUND(M, 2) |
CEIL(value) |
올림 | CEIL(H1 / 1000) |
FLOOR(value) |
내림 | FLOOR(W1 / 500) |
ABS(value) |
절대값 | ABS(W0 - 2000) |
IF(cond, true, false) |
조건문 | IF(W0 > 3000, 2, 1) |
SQRT(value) |
제곱근 | SQRT(M) |
POWER(base, exp) |
거듭제곱 | POWER(W1, 2) |
평가 과정:
// 1. 변수 치환
let expr = formula;
Object.keys(vars).forEach(key => {
const regex = new RegExp(`\\b${key}\\b`, 'g');
expr = expr.replace(regex, vars[key].toString());
});
// 2. 함수 처리 (CEIL, FLOOR, ROUND 등)
expr = processFunctions(expr);
// 3. 최종 계산
return new Function(`return (${expr})`)();
1.3 BOM 계산 과정 (bomCalculatorWithDebug.ts)
10단계 계산 과정:
| 단계 | 설명 | 예시 |
|---|---|---|
| Step 1 | 수량 공식 확인 | H/1000 |
| Step 2 | 변수 값 확인 | {W0:2000, H0:2500, W1:2140, H1:2850, M:6.099} |
| Step 3 | 수량 계산 과정 | H/1000 = 2850/1000 = 2.85 |
| Step 4 | 계산된 수량 | 2.85 |
| Step 5 | 단가 소스 | 단가관리 (15,000원) |
| Step 6 | 기본 단가 | 15,000 |
| Step 7 | 카테고리 승수 | 면적단가 (15,000원/㎡ × 6.099㎡) |
| Step 8 | 최종 단가 | 91,485 |
| Step 9 | 금액 계산 | 2.85 × 91,485 = 260,732 |
| Step 10 | 최종 금액 | 260,732 |
1.4 단가 계산 방식
// 1순위: pricing 테이블에서 조회
const itemPricing = pricings.find(p => p.itemCode === bomEntry.childItemCode);
if (itemPricing && itemPricing.salesPrice) {
unitPrice = itemPricing.salesPrice;
}
// 2순위: 품목마스터에서 조회
else if (childItem.salesPrice) {
unitPrice = childItem.salesPrice;
}
// 면적 기반 품목 판단 (원단, 패널, 도장, 표면처리)
const areaBasedCategories = ['원단', '패널', '도장', '표면처리'];
if (isAreaBased && M > 0) {
finalUnitPrice = unitPrice * M; // 면적 단가
}
2. MNG 현재 구현 상태
2.1 FormulaEvaluatorService.php
✅ 구현됨:
evaluate()- 수식 평가validateFormula()- 수식 검증executeAll()- 전체 수식 실행getItemPrice()- 단가 조회 (Price 모델 연동)getBomTree()- BOM 트리 조회enrichItemsWithDetails()- 품목 상세 정보 추가
지원 함수:
- SUM, ROUND, CEIL, FLOOR, ABS, MIN, MAX, IF, AND, OR, NOT
❌ 미구현:
- 제품 카테고리별 변수 계산 규칙 (W1, H1, M)
- 면적/중량 기반 단가 계산
- 공정별 분류
2.2 simulator.blade.php
✅ 구현됨:
- 입력 변수 폼 (W0, H0, PC, GT, MP, CT 등)
- API 호출 (
/api/admin/quote-formulas/formulas/simulate) - 계산된 변수 표시
- 품목 목록 표시 (BOM 트리 포함)
❌ 미구현:
- 공정별 그룹화 표시
- 단가/금액 계산 결과 표시
- 총합계 표시
3. 매핑 계획
3.1 변수 계산 규칙 추가
quote_formulas 테이블에 추가할 수식:
-- 제작폭 (W1) - 스크린
INSERT INTO quote_formulas (category_id, variable, name, type, formula, output_type, sort_order)
VALUES (1, 'W1', '제작폭', 'calculation', 'IF(PC == "screen", W0 + 140, W0 + 110)', 'variable', 10);
-- 제작높이 (H1)
INSERT INTO quote_formulas (category_id, variable, name, type, formula, output_type, sort_order)
VALUES (1, 'H1', '제작높이', 'calculation', 'H0 + 350', 'variable', 20);
-- 면적 (M)
INSERT INTO quote_formulas (category_id, variable, name, type, formula, output_type, sort_order)
VALUES (1, 'M', '면적', 'calculation', '(W1 * H1) / 1000000', 'variable', 30);
-- W, H 매핑
INSERT INTO quote_formulas (category_id, variable, name, type, formula, output_type, sort_order)
VALUES (1, 'W', '제작폭', 'calculation', 'W1', 'variable', 40);
INSERT INTO quote_formulas (category_id, variable, name, type, formula, output_type, sort_order)
VALUES (1, 'H', '제작높이', 'calculation', 'H1', 'variable', 50);
3.2 FormulaEvaluatorService 확장
// 추가할 메서드
/**
* 카테고리별 단가 계산
*/
private function calculateCategoryPrice(
array $item,
float $basePrice,
array $variables
): array {
$areaBasedCategories = ['원단', '패널', '도장', '표면처리'];
$itemCategory = $item['item_category'] ?? '';
if (in_array($itemCategory, $areaBasedCategories) && isset($variables['M'])) {
return [
'final_price' => $basePrice * $variables['M'],
'calculation_note' => "면적단가 ({$basePrice}원/㎡ × {$variables['M']}㎡)"
];
}
return [
'final_price' => $basePrice,
'calculation_note' => '수량단가'
];
}
/**
* 공정별 품목 그룹화
*/
private function groupItemsByProcess(array $items): array
{
$processOrder = ['screen' => '스크린 공정', 'bending' => '절곡 공정', 'electric' => '전기 공정'];
$grouped = [];
foreach ($processOrder as $code => $label) {
$grouped[$code] = [
'label' => $label,
'items' => [],
'subtotal' => 0
];
}
foreach ($items as $item) {
$process = $item['process_type'] ?? 'etc';
if (isset($grouped[$process])) {
$grouped[$process]['items'][] = $item;
$grouped[$process]['subtotal'] += $item['total_price'] ?? 0;
}
}
return $grouped;
}
3.3 items 테이블 확장
-- 공정 유형 필드 추가
ALTER TABLE items ADD COLUMN process_type VARCHAR(20) DEFAULT NULL
COMMENT '공정유형: screen(스크린), bending(절곡), electric(전기)';
-- 인덱스 추가
CREATE INDEX idx_items_process_type ON items(process_type);
4. 구현 순서
Phase 1: DB 스키마 및 데이터 (1일)
- ✅ items 테이블에
process_type필드 추가 - ✅ 기존 품목에 공정 유형 매핑
- ✅ quote_formulas에 기본 변수 계산 수식 추가
Phase 2: 백엔드 로직 (2일)
- ✅ FormulaEvaluatorService에 카테고리별 단가 계산 추가
- ✅ 공정별 그룹화 메서드 추가
- ✅ executeAll() 반환 구조 확장
Phase 3: 프론트엔드 (1일)
- ✅ simulator.blade.php에 공정별 결과 표시
- ✅ 단가/금액 표시 추가
- ✅ 총합계 표시
Phase 4: 검증 (1일)
- ✅ design.sam.kr과 결과 비교
- ✅ 금액 차이 분석 및 조정
5. 핵심 파일 참조
Design (참조용)
/SAM/design/src/components/
├── AutoCalculationSimulator.tsx # 메인 시뮬레이터 (1068줄)
├── utils/
│ ├── formulaEvaluator.ts # 수식 평가 (312줄)
│ └── bomCalculatorWithDebug.ts # BOM 계산 (232줄)
└── contexts/
└── DataContext.tsx # 마스터 데이터 (9859줄)
MNG (수정 대상)
/SAM/mng/
├── app/Services/Quote/
│ └── FormulaEvaluatorService.php # 핵심 서비스 (575줄)
├── resources/views/quote-formulas/
│ └── simulator.blade.php # 시뮬레이터 UI (867줄)
└── app/Models/
├── Price.php # 단가 모델 (135줄)
└── Item.php # 품목 모델
6. 테스트 케이스
| 입력 | Design 결과 | MNG 목표 |
|---|---|---|
| W0=2000, H0=2500, PC=스크린 | W1=2140, H1=2850, M=6.099 | 동일 |
| 스크린 원단 | 수량공식: W*H/1000000 = 6.099㎡ | 동일 |
| 가이드레일 | 수량공식: H/1000 = 2.85m | 동일 |
이 문서는 design.sam.kr 분석 결과를 바탕으로 mng 시뮬레이터 구현 계획을 정리합니다.