diff options
Diffstat (limited to 'lib/general-contracts/utils.ts')
| -rw-r--r-- | lib/general-contracts/utils.ts | 73 |
1 files changed, 69 insertions, 4 deletions
diff --git a/lib/general-contracts/utils.ts b/lib/general-contracts/utils.ts index ec15a3a1..1262dc4d 100644 --- a/lib/general-contracts/utils.ts +++ b/lib/general-contracts/utils.ts @@ -1,5 +1,8 @@ import { format } from "date-fns" +const DEFAULT_SHI_ADDRESS = "경기도 성남시 분당구 판교로 227번길 23" +const DEFAULT_SHI_CEO_NAME = "최성안" + /** * ContractSummary 인터페이스 (UI 컴포넌트와 맞춤) */ @@ -20,6 +23,9 @@ export function mapContractDataToTemplateVariables(contractSummary: ContractSumm const { basicInfo, items, storageInfo } = contractSummary const firstItem = items && items.length > 0 ? items[0] : {} + const shiAddress = basicInfo.shiAddress || DEFAULT_SHI_ADDRESS + const shiCeoName = basicInfo.shiCeoName || DEFAULT_SHI_CEO_NAME + // 날짜 포맷팅 헬퍼 (YYYY-MM-DD) const formatDate = (date: any) => { if (!date) return '' @@ -164,6 +170,51 @@ export function mapContractDataToTemplateVariables(contractSummary: ContractSumm ).join('\n') : '' + // PDFTron 템플릿 루프용 데이터 ({{#storageList}} ... {{/storageList}} 사용) + const storageList = storageItems.map(item => ({ + project: (item.projectName || item.projectCode || '').toString().trim(), + poNumber: (item.poNumber || '').toString().trim(), + hullNumber: (item.hullNumber || '').toString().trim(), + remainingAmount: formatCurrency(item.remainingAmount), + })) + + // 일반 견적 품목 루프용 데이터 ({{#itemsList}} ... {{/itemsList}} 사용) + const itemsList = (items || []).map((item, idx) => { + const quantityRaw = item.quantity ?? item.qty ?? '' + const unitPriceRaw = item.contractUnitPrice ?? item.unitPrice ?? '' + const amountRaw = + item.contractAmount ?? + (Number(quantityRaw) * Number(unitPriceRaw)) + + const quantityNum = Number(quantityRaw) + const hasQuantity = !isNaN(quantityNum) + const unitPriceNum = Number(unitPriceRaw) + const hasUnitPrice = !isNaN(unitPriceNum) + const hasAmountCalc = !isNaN(amountRaw as number) + + const amount = hasAmountCalc ? formatCurrency(amountRaw) : '' + + return { + no: idx + 1, // NO + hullNumber: (item.projectCode || basicInfo.projectCode || '').toString().trim(), // 호선번호 + shipType: (item.projectName || basicInfo.projectName || '').toString().trim(), // 선종/선형 + exportCountry: (basicInfo.vendorCountry || basicInfo.country || '').toString().trim(), // 수출국 + itemName: (item.itemInfo || item.description || item.itemCode || '').toString().trim(), // 품목 + unit: (item.quantityUnit || '').toString().trim(), // 단위 + unitPrice: hasUnitPrice ? formatCurrency(unitPriceNum) : formatCurrency(unitPriceRaw), // 단가 + amount, // 금액 + remark: (item.remark || item.remarks || item.note || '').toString().trim(), // 비고 + // 보존용 기존 필드 + itemCode: (item.itemCode || item.itemInfo || '').toString().trim(), + quantity: hasQuantity ? quantityNum : (quantityRaw ?? ''), + } + }) + + // 루프 미지원 템플릿을 위한 품목 텍스트 fallback + const itemsTableText = itemsList.length > 0 + ? itemsList.map(i => `${i.no}. ${i.hullNumber || '-'} / ${i.shipType || '-'} / ${i.exportCountry || '-'} / ${i.itemName || '-'} / 단위:${i.unit || '-'} / 단가:${i.unitPrice || '-'} / 금액:${i.amount || '-'} / 비고:${i.remark || '-'}`).join('\n') + : '' + // ═══════════════════════════════════════════════════════════════ // 변수 매핑 시작 @@ -206,8 +257,8 @@ export function mapContractDataToTemplateVariables(contractSummary: ContractSumm // ---------------------------------- // 당사(SHI) 정보 (고정값/설정값) // ---------------------------------- - shiAddress: "경기도 성남시 분당구 판교로 227번길 23", // {{SHI_Address}}, {{위탁자 주소}} - shiCeoName: "최성안", // {{SHI_CEO_Name}}, {{대표이사}} + shiAddress: shiAddress, // {{SHI_Address}}, {{위탁자 주소}} + shiCeoName: shiCeoName, // {{SHI_CEO_Name}}, {{대표이사}} // ---------------------------------- // 품목 정보 @@ -290,7 +341,13 @@ export function mapContractDataToTemplateVariables(contractSummary: ContractSumm // ---------------------------------- storageTableText: storageTableText, // {{storageTableText}} (fallback) // PDFTron에서 배열을 받아 테이블 루프를 돌릴 수 있다면 아래 키를 사용 - storageList: storageItems, + storageList, + + // ---------------------------------- + // 일반 견적 품목 루프 (템플릿 표에 {{#itemsList}} 사용) + // ---------------------------------- + itemsList, + itemsTableText, } // 3. 모든 키를 순회하며 undefined나 null을 빈 문자열로 변환 (안전장치) @@ -300,5 +357,13 @@ export function mapContractDataToTemplateVariables(contractSummary: ContractSumm } }) - return variables + // 4. PDF 템플릿에서 추출한 {{ }} 변수명이 공백을 포함할 수 있어 trim 처리 후 매핑 + const normalizedVariables: Record<string, any> = {} + Object.entries(variables).forEach(([key, value]) => { + const trimmedKey = key.trim() + const trimmedValue = typeof value === 'string' ? value.trim() : value + normalizedVariables[trimmedKey] = trimmedValue + }) + + return normalizedVariables } |
