# Task H.5.2: PDFME Price Table Input Normalization

## Goal

แก้ปัญหา PDFME ไม่แสดงข้อความในตารางราคา

Current template field:

```json
{
  "name": "quotation_price_data",
  "type": "table",
  "content": "[[\"Price (Exclude VAT)\",\"{quotation_price}\",\" \",\"{currency}\"]]"
}
```

Expected output:

```txt
Price (Exclude VAT)    ฿500,000.00        THB
```

Root cause:

PDFME table field นี้ควรได้รับ input ตาม schema name:

```txt
quotation_price_data
```

ในรูปแบบ:

```ts
[
  ["Price (Exclude VAT)", "฿500,000.00", " ", "THB"]
]
```

ไม่ควร rely กับการ map cell ย่อย `{quotation_price}` และ `{currency}` ภายใน table content

---

# Must Read

```txt
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:

```txt
src/features/crm/quotations/document/server/service.ts
```

Add to `documentData.pdfme`:

```ts
quotation_price_data: string[][];
```

Expected shape:

```ts
[
  [
    "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:

```ts
pdfme.quotation_price
pdfme.currency
```

But table rendering must use:

```txt
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:

```txt
src/db/seeds/foundation.seed.ts
```

Ensure mapping exists:

```txt
quotation_price_data -> pdfme.quotation_price_data
```

With:

```txt
dataType = table
defaultValue = [["Price (Exclude VAT)", "-", " ", "THB"]]
sortOrder appropriate
```

Retain mappings if used elsewhere:

```txt
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:

```txt
src/features/foundation/document-template/server/service.ts
```

Ensure `mapDocumentDataToTemplateInput()` preserves table input when source value is already:

```ts
string[][]
```

For mapping:

```txt
placeholderKey = quotation_price_data
dataType = table
sourcePath = pdfme.quotation_price_data
```

Expected template input:

```ts
{
  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:

```txt
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:

```txt
quotation_price_data
```

as the table field to verify.

Expected checks:

```txt
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:

```ts
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:

```txt
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:

```txt
{quotation_price}
{currency}
```

inside:

```txt
quotation_price_data
```

Runtime should still prioritize input key:

```txt
quotation_price_data
```

over nested tokens.

Optional safe improvement:

If needed, update the active template schema content from:

```json
"[[\"Price (Exclude VAT)\",\"{quotation_price}\",\" \",\"{currency}\"]]"
```

to:

```json
"[[\"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:

```txt
npm run audit:pdf
```

Expected:

```txt
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:

```txt
Price (Exclude VAT)    ฿500,000.00        THB
```

---

# Scope H5.2.9: Documentation

Update:

```txt
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:

```txt
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:

```txt
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:

1. Files Modified
2. PDFME Price Table Field Added
3. Mapping Seed Updated
4. Resolver Behavior Confirmed
5. Audit Updated
6. Approved Snapshot Parity Result
7. Remaining Risks

---

# Definition of Done

Task H.5.2 passes when:

* `pdfme.quotation_price_data` exists
* `quotation_price_data` maps to `pdfme.quotation_price_data`
* `quotation_price_data` is `string[][]`
* PDF renders `Price (Exclude VAT) ฿500,000.00 THB`
* scalar `quotation_price` and `currency` remain available
* approved snapshot stores `templateInput.quotation_price_data`
* `npm run audit:pdf` returns Overall Status PASS
* `inconsistentKeys` is empty
