refactor: 견적 산출 서비스 DB 기반으로 재작성

- Quote 수식 모델 추가 (mng 패턴 적용)
  - QuoteFormula: 수식 정의 (input/calculation/range/mapping)
  - QuoteFormulaCategory: 카테고리 정의
  - QuoteFormulaItem: 품목 출력 정의
  - QuoteFormulaRange: 범위별 값 정의
  - QuoteFormulaMapping: 매핑 값 정의

- FormulaEvaluatorService 확장
  - executeAll(): 카테고리별 수식 실행
  - evaluateRangeFormula/evaluateMappingFormula: QuoteFormula 기반 평가
  - getItemPrice(): prices 테이블 연동

- QuoteCalculationService DB 기반으로 재작성
  - 하드코딩된 품목 코드/로직 제거
  - quote_formulas 테이블 기반 동적 계산
  - getInputSchema(): DB 기반 입력 스키마 생성

- Price 모델 수정
  - items 테이블 연동 (products/materials 대체)
  - ITEM_TYPE 상수 업데이트 (FG/PT/RM/SM/CS)
This commit is contained in:
2025-12-19 16:49:26 +09:00
parent 21d4d0d1b1
commit 0d49e4cc75
8 changed files with 838 additions and 361 deletions

View File

@@ -29,10 +29,16 @@ class Price extends Model
public const STATUS_FINALIZED = 'finalized';
// 품목 유형
public const ITEM_TYPE_PRODUCT = 'PRODUCT';
// 품목 유형 (items.item_type)
public const ITEM_TYPE_FG = 'FG'; // Finished Goods (완제품)
public const ITEM_TYPE_MATERIAL = 'MATERIAL';
public const ITEM_TYPE_PT = 'PT'; // Part (부품)
public const ITEM_TYPE_RM = 'RM'; // Raw Material (원자재)
public const ITEM_TYPE_SM = 'SM'; // Semi-finished (반제품)
public const ITEM_TYPE_CS = 'CS'; // Consumables/Supplies (소모품)
protected $fillable = [
'tenant_id',
@@ -289,7 +295,6 @@ public static function getCurrentPrice(
/**
* 품목 코드로 현재 유효 판매단가 조회
* (quote_formula_items.item_code와 연동용)
*
* @param int $tenantId 테넌트 ID
* @param string $itemCode 품목 코드
@@ -297,32 +302,19 @@ public static function getCurrentPrice(
*/
public static function getSalesPriceByItemCode(int $tenantId, string $itemCode): float
{
// products 테이블에서 품목 코드로 검색
$product = \Illuminate\Support\Facades\DB::table('products')
// items 테이블에서 품목 코드로 검색
$item = \Illuminate\Support\Facades\DB::table('items')
->where('tenant_id', $tenantId)
->where('code', $itemCode)
->whereNull('deleted_at')
->first();
if ($product) {
$price = static::getCurrentPrice($tenantId, self::ITEM_TYPE_PRODUCT, $product->id);
return (float) ($price?->sales_price ?? 0);
if (! $item) {
return 0;
}
// materials 테이블에서도 검색
$material = \Illuminate\Support\Facades\DB::table('materials')
->where('tenant_id', $tenantId)
->where('code', $itemCode)
->whereNull('deleted_at')
->first();
$price = static::getCurrentPrice($tenantId, $item->item_type, $item->id);
if ($material) {
$price = static::getCurrentPrice($tenantId, self::ITEM_TYPE_MATERIAL, $material->id);
return (float) ($price?->sales_price ?? 0);
}
return 0;
return (float) ($price?->sales_price ?? 0);
}
}