// lib/api/quote.ts // 견적 자동산출 API 클라이언트 import { ApiClient } from './client'; import { AUTH_CONFIG } from './auth/auth-config'; // =================================== // 타입 정의 // =================================== /** * 산출된 변수 정보 */ interface CalculationVariable { name: string; value: number; category: string; type: string; } /** * 산출된 품목 정보 */ interface CalculationItem { item_code: string; item_name: string; specification?: string; unit?: string; quantity: number; unit_price: number; total_price: number; formula_variable: string; formula_category?: string; } /** * 비용 합계 */ interface CalculationCosts { material_cost: number; labor_cost: number; install_cost: number; subtotal: number; } /** * 견적 산출 결과 */ export interface CalculationResult { inputs: Record; outputs: Record; items: CalculationItem[]; costs: CalculationCosts; errors: string[]; } /** * 견적 산출 요청 */ export interface CalculateRequest { inputs: { W0: number; // 오픈사이즈 가로 (mm) H0: number; // 오픈사이즈 세로 (mm) QTY?: number; // 수량 INSTALL_TYPE?: string; // 설치 유형 (wall, ceiling, floor) CONTROL_TYPE?: string; // 제어 방식 (switch, remote, smart) MOTOR_TYPE?: string; // 모터 유형 (standard, heavy) CHAIN_SIDE?: string; // 체인 위치 (left, right) }; product_category: 'screen' | 'steel'; } /** * 입력 스키마 필드 정의 */ interface InputSchemaField { label: string; type: 'number' | 'integer' | 'select' | 'text'; unit?: string; required?: boolean; min?: number; max?: number; step?: number; default?: string | number; options?: Array<{ value: string; label: string }>; description?: string; } /** * BOM 계산 요청 (단건) */ export interface CalculateBomRequest { finished_goods_code: string; // 완제품 코드 input_variables: { W0: number; // 오픈사이즈 가로 (mm) H0: number; // 오픈사이즈 세로 (mm) QTY?: number; // 수량 GT?: string; // 가이드레일 설치 유형 (벽면형/측면형) MP?: string; // 모터 전원 (220V/380V) CT?: string; // 연동제어기 (단독/연동) WS?: number; // 마구리 날개치수 INSP?: number; // 검사비 }; } /** * BOM 계산 요청 (다건) */ export interface CalculateBomBulkRequest { items: CalculateBomRequest[]; } /** * BOM 계산 결과 항목 */ interface BomResultItem { item_code: string; item_name: string; specification?: string; unit?: string; quantity: number; unit_price: number; total_price: number; process_group?: string; } /** * BOM 계산 결과 */ export interface BomCalculationResult { finished_goods: { code: string; name: string; item_category?: string; }; items: BomResultItem[]; subtotals: Record; grand_total: number; debug_steps?: Array<{ step: number; label: string; description: string; data?: Record; }>; } /** * API 응답 공통 형식 */ interface ApiResponse { success: boolean; message: string; data: T; } // =================================== // Quote API 클라이언트 // =================================== /** * 견적 자동산출 API 클라이언트 * * @example * ```typescript * // 자동 산출 * const result = await quoteApi.calculate({ * inputs: { W0: 3000, H0: 2500 }, * product_category: 'screen' * }); * * // 입력 스키마 조회 * const schema = await quoteApi.getCalculationSchema('screen'); * ``` */ class QuoteApiClient extends ApiClient { constructor() { super({ mode: 'bearer', apiKey: process.env.NEXT_PUBLIC_API_KEY, getToken: () => { if (typeof window !== 'undefined') { return localStorage.getItem('auth_token'); } return null; }, }); } /** * 자동 견적 산출 * * @param request - 산출 요청 파라미터 * @returns 산출 결과 (변수, 품목, 비용) */ async calculate(request: CalculateRequest): Promise> { return this.post>('/api/v1/quotes/calculate', request); } /** * 견적 미리보기 (저장 없이 계산만) * * @param request - 산출 요청 파라미터 * @returns 미리보기 결과 */ async preview(request: CalculateRequest): Promise> { return this.post>('/api/v1/quotes/preview', request); } /** * 입력 스키마 조회 (동적 폼 생성용) * * @param productCategory - 제품 카테고리 (screen, steel) * @returns 입력 필드 스키마 */ async getCalculationSchema( productCategory?: 'screen' | 'steel' ): Promise>> { const query = productCategory ? `?product_category=${productCategory}` : ''; return this.get>>(`/api/v1/quotes/calculation-schema${query}`); } /** * BOM 기반 자동 견적 산출 (단건) * * @param request - BOM 산출 요청 파라미터 * @returns BOM 계산 결과 */ async calculateBom(request: CalculateBomRequest): Promise> { return this.post>('/api/v1/quotes/calculate/bom', request); } /** * BOM 기반 자동 견적 산출 (다건) * * @param request - 다건 BOM 산출 요청 파라미터 * @returns BOM 계산 결과 배열 */ async calculateBomBulk(request: CalculateBomBulkRequest): Promise> { return this.post>('/api/v1/quotes/calculate/bom/bulk', request); } } // 싱글톤 인스턴스 내보내기 export const quoteApi = new QuoteApiClient(); // 타입 내보내기 export type { CalculationVariable, CalculationItem, CalculationCosts, InputSchemaField, ApiResponse };