7.2 KiB
Task H.5.2: PDFME Price Table Input Normalization
Goal
แก้ปัญหา PDFME ไม่แสดงข้อความในตารางราคา
Current template field:
{
"name": "quotation_price_data",
"type": "table",
"content": "[[\"Price (Exclude VAT)\",\"{quotation_price}\",\" \",\"{currency}\"]]"
}
Expected output:
Price (Exclude VAT) ฿500,000.00 THB
Root cause:
PDFME table field นี้ควรได้รับ input ตาม schema name:
quotation_price_data
ในรูปแบบ:
[
["Price (Exclude VAT)", "฿500,000.00", " ", "THB"]
]
ไม่ควร rely กับการ map cell ย่อย {quotation_price} และ {currency} ภายใน table content
Must Read
docs/implementation/task-h5-pdf-mapping-audit-visual-parity.md
docs/business/pdf-mapping-registry.md
docs/business/pdf-placeholder-registry.md
docs/implementation/task-h51-pdf-integrity-audit.md
src/features/crm/quotations/document/server/pdfme-transforms.ts
src/features/crm/quotations/document/server/service.ts
src/features/foundation/document-template/server/service.ts
src/features/foundation/pdf-generator/server/service.ts
src/db/seeds/foundation.seed.ts
scripts/audit-pdf-runtime-payload.ts
scripts/audit-payload-parity.ts
scripts/generate-pdf-integrity-report.ts
Scope H5.2.1: Add PDFME Price Table Field
Update quotation document builder:
src/features/crm/quotations/document/server/service.ts
Add to documentData.pdfme:
quotation_price_data: string[][];
Expected shape:
[
[
"Price (Exclude VAT)",
formatPdfCurrency(quotation.subtotal, quotation.currency),
" ",
quotation.currency || "THB"
]
]
Rules:
- first column must be
"Price (Exclude VAT)" - second column must be formatted currency string such as
฿500,000.00 - third column is
" "to match template spacing - fourth column must be currency code such as
THB - never return
undefined - if price is missing, use
"-" - if currency is missing, fallback to
"THB"
Scope H5.2.2: Keep Scalar Fields For Compatibility
Keep existing fields:
pdfme.quotation_price
pdfme.currency
But table rendering must use:
pdfme.quotation_price_data
Do not remove existing fields because other templates or audits may still reference them.
Scope H5.2.3: Template Mapping Seed Update
Update:
src/db/seeds/foundation.seed.ts
Ensure mapping exists:
quotation_price_data -> pdfme.quotation_price_data
With:
dataType = table
defaultValue = [["Price (Exclude VAT)", "-", " ", "THB"]]
sortOrder appropriate
Retain mappings if used elsewhere:
quotation_price -> pdfme.quotation_price
currency -> pdfme.currency
But do not depend on them for quotation_price_data.
Rules:
- idempotent seed
- update existing incorrect mapping
- no duplicate mapping
- no hardcoded organizationId
- apply to active ALLA / ONVALLA template versions
Scope H5.2.4: Template Mapping Resolver
Update:
src/features/foundation/document-template/server/service.ts
Ensure mapDocumentDataToTemplateInput() preserves table input when source value is already:
string[][]
For mapping:
placeholderKey = quotation_price_data
dataType = table
sourcePath = pdfme.quotation_price_data
Expected template input:
{
quotation_price_data: [
["Price (Exclude VAT)", "฿500,000.00", " ", "THB"]
]
}
Do not stringify this table.
Do not flatten it.
Do not attempt nested placeholder interpolation for this field.
Scope H5.2.5: Template Placeholder Audit Update
Update:
scripts/audit-pdf-template-inventory.ts
scripts/audit-pdf-mapping-coverage.ts
scripts/audit-pdf-runtime-payload.ts
scripts/audit-payload-parity.ts
scripts/generate-pdf-integrity-report.ts
Audit must recognize:
quotation_price_data
as the table field to verify.
Expected checks:
quotation_price_data exists in template schema
quotation_price_data mapping exists
quotation_price_data sourcePath = pdfme.quotation_price_data
quotation_price_data resolved type = string[][]
quotation_price_data row count >= 1
quotation_price_data[0][1] contains formatted currency
quotation_price_data[0][3] contains currency code
Scope H5.2.6: Approved Snapshot Parity Fix
Approved snapshot must store:
templateInput.quotation_price_data
And it must match current runtime payload unless quotation data changed after approval.
For fixture QT-H5-AUDIT, after regenerating approved PDF:
Expected:
Approved Snapshot Parity = PASS
inconsistentKeys = []
Rules:
- if approved snapshot exists with old data, regenerate artifact only in fixture/dev environment
- do not silently overwrite locked production artifacts
- production regeneration must require explicit void/regenerate flow later
Scope H5.2.7: PDFME Input Compatibility
Because current template content still has nested tokens:
{quotation_price}
{currency}
inside:
quotation_price_data
Runtime should still prioritize input key:
quotation_price_data
over nested tokens.
Optional safe improvement:
If needed, update the active template schema content from:
"[[\"Price (Exclude VAT)\",\"{quotation_price}\",\" \",\"{currency}\"]]"
to:
"[[\"Price (Exclude VAT)\",\"-\",\" \",\"THB\"]]"
But only if PDFME requires removing nested placeholders for table input to render correctly.
Do not make layout changes.
Scope H5.2.8: Verification
Run:
npm run audit:pdf
Expected:
Template Version Integrity: PASS
Placeholder Integrity: PASS
Payload Parity: PASS
Topic Runtime: PASS
Approved Snapshot Parity: PASS
Overall Status: PASS
Also verify actual preview / PDF visually shows:
Price (Exclude VAT) ฿500,000.00 THB
Scope H5.2.9: Documentation
Update:
docs/business/pdf-mapping-registry.md
docs/business/pdf-placeholder-registry.md
docs/implementation/task-h51-pdf-integrity-audit.md
docs/implementation/technical-debt.md
Document:
quotation_price_data is the canonical PDFME table field for price display.
quotation_price and currency remain scalar compatibility fields.
Do not use nested table placeholders for canonical price table rendering.
Explicit Non-Scope
Do NOT implement:
signature image
draw signature
new PDF template design
visual designer
approved artifact void/regenerate UI
report center
currency exchange calculation
multi-currency tax logic
Output
After completion, summarize:
- Files Modified
- PDFME Price Table Field Added
- Mapping Seed Updated
- Resolver Behavior Confirmed
- Audit Updated
- Approved Snapshot Parity Result
- Remaining Risks
Definition of Done
Task H.5.2 passes when:
pdfme.quotation_price_dataexistsquotation_price_datamaps topdfme.quotation_price_dataquotation_price_dataisstring[][]- PDF renders
Price (Exclude VAT) ฿500,000.00 THB - scalar
quotation_priceandcurrencyremain available - approved snapshot stores
templateInput.quotation_price_data npm run audit:pdfreturns Overall Status PASSinconsistentKeysis empty