# Phase 3 구현 상세 > **구현일:** 2025-12-19 > **상태:** ✅ 완료 --- ## 1. Price 모델 구현 ### 파일 위치 `mng/app/Models/Price.php` ### 주요 기능 #### 상수 정의 ```php // 상태 const STATUS_DRAFT = 'draft'; const STATUS_ACTIVE = 'active'; const STATUS_INACTIVE = 'inactive'; const STATUS_FINALIZED = 'finalized'; // 품목 유형 const ITEM_TYPE_PRODUCT = 'PRODUCT'; const ITEM_TYPE_MATERIAL = 'MATERIAL'; // 반올림 규칙 const ROUNDING_ROUND = 'round'; const ROUNDING_CEIL = 'ceil'; const ROUNDING_FLOOR = 'floor'; ``` #### getCurrentPrice() 메서드 ```php /** * 특정 품목의 현재 유효 단가 조회 * * @param int $tenantId 테넌트 ID * @param string $itemTypeCode 품목 유형 (PRODUCT/MATERIAL) * @param int $itemId 품목 ID * @param int|null $clientGroupId 고객 그룹 ID (NULL = 기본가) * @return Price|null */ public static function getCurrentPrice( int $tenantId, string $itemTypeCode, int $itemId, ?int $clientGroupId = null ): ?self ``` **조회 조건:** 1. tenant_id 일치 2. item_type_code 일치 (PRODUCT/MATERIAL) 3. item_id 일치 4. client_group_id 일치 또는 NULL (기본가) 5. status = 'active' 6. effective_from <= 현재일 7. effective_to >= 현재일 또는 NULL **우선순위:** - 고객그룹 지정된 가격 > 기본가 - 최신 effective_from 우선 #### getSalesPriceByItemCode() 메서드 ```php /** * 품목 코드로 현재 유효 판매단가 조회 * (quote_formula_items.item_code와 연동용) * * @param int $tenantId 테넌트 ID * @param string $itemCode 품목 코드 * @return float 판매단가 (없으면 0) */ public static function getSalesPriceByItemCode(int $tenantId, string $itemCode): float ``` **조회 순서:** 1. products 테이블에서 code로 검색 2. 발견되면 → Price::getCurrentPrice() 호출 3. 미발견시 → materials 테이블에서 검색 4. 발견되면 → Price::getCurrentPrice() 호출 5. 미발견시 → 0 반환 --- ## 2. getItemPrice() 연동 ### 파일 위치 `mng/app/Services/Quote/FormulaEvaluatorService.php:324-335` ### 변경 전 (TODO 상태) ```php private function getItemPrice(string $itemCode): float { // TODO: 품목 마스터에서 단가 조회 return 0; } ``` ### 변경 후 (구현 완료) ```php private function getItemPrice(string $itemCode): float { $tenantId = session('selected_tenant_id'); if (!$tenantId) { $this->errors[] = "테넌트 ID가 설정되지 않았습니다."; return 0; } return \App\Models\Price::getSalesPriceByItemCode($tenantId, $itemCode); } ``` ### 동작 흐름 ``` quote_formula_items.item_code ↓ FormulaEvaluatorService::getItemPrice() ↓ Price::getSalesPriceByItemCode() ├── products 테이블 검색 (code 컬럼) └── materials 테이블 검색 (code 컬럼) ↓ Price::getCurrentPrice() ↓ prices.sales_price 반환 ``` --- ## 3. Seeder 현황 ### 기존 Seeder 파일 | 파일 | 설명 | 데이터 수 | |------|------|----------| | `QuoteFormulaCategorySeeder.php` | 카테고리 | 11개 | | `QuoteFormulaSeeder.php` | 수식 | ~30개 | | `QuoteFormulaItemSeeder.php` | 품목 출력 | 미정 | | `QuoteFormulaMappingSeeder.php` | 매핑 | 미정 | ### 카테고리 목록 (11개) | 코드 | 이름 | 순서 | |------|------|------| | OPEN_SIZE | 오픈사이즈 | 1 | | MAKE_SIZE | 제작사이즈 | 2 | | AREA | 면적 | 3 | | WEIGHT | 중량 | 4 | | GUIDE_RAIL | 가이드레일 | 5 | | CASE | 케이스 | 6 | | MOTOR | 모터 | 7 | | CONTROLLER | 제어기 | 8 | | EDGE_WING | 마구리 | 9 | | INSPECTION | 검사 | 10 | | PRICE_FORMULA | 단가수식 | 11 | ### 실행 명령어 ```bash # api 디렉토리에서 실행 cd /Users/hskwon/Works/@KD_SAM/SAM/api # 순차 실행 (의존성 순서) php artisan db:seed --class=QuoteFormulaCategorySeeder php artisan db:seed --class=QuoteFormulaSeeder php artisan db:seed --class=QuoteFormulaItemSeeder php artisan db:seed --class=QuoteFormulaMappingSeeder # 또는 한번에 php artisan db:seed --class=QuoteFormulaCategorySeeder && \ php artisan db:seed --class=QuoteFormulaSeeder ``` --- ## 4. 테스트 방법 ### 1) 단가 조회 테스트 ```bash cd /Users/hskwon/Works/@KD_SAM/SAM/api php artisan tinker # 테스트 >>> \App\Models\Price::where('tenant_id', 1)->first() >>> DB::table('products')->where('tenant_id', 1)->first() ``` ### 2) 수식 실행 테스트 ```bash cd /Users/hskwon/Works/@KD_SAM/SAM/mng # mng UI에서 시뮬레이터 접속 # URL: /quote-formulas/simulator ``` --- ## 5. 변경 파일 목록 ### 신규 생성 | 파일 | 설명 | |------|------| | `mng/app/Models/Price.php` | 가격 모델 | | `docs/projects/quotation/phase-3-implementation/README.md` | Phase 3 README | | `docs/projects/quotation/phase-3-implementation/implementation.md` | 구현 상세 | | `docs/projects/quotation/phase-3-implementation/table-mapping.md` | 테이블 매핑 | ### 수정 | 파일 | 변경 내용 | |------|----------| | `mng/app/Services/Quote/FormulaEvaluatorService.php` | getItemPrice() 구현 | | `docs/projects/quotation/PROGRESS.md` | Phase 3 상태 업데이트 | --- ## 참조 - [README.md](./README.md) - [table-mapping.md](./table-mapping.md) - [Phase 1: js-formulas.md](../phase-1-5130-analysis/js-formulas.md) - [Phase 2: issues.md](../phase-2-mng-analysis/issues.md)