389 lines
5.8 KiB
Markdown
389 lines
5.8 KiB
Markdown
# Task P.4.4 - Product Item Engine
|
|
|
|
## Objective
|
|
|
|
Implement the Product Item Engine for the new section-based PDF runtime.
|
|
|
|
The Product Item Engine is responsible only for transforming quotation items into a PDFMe-compatible table model.
|
|
|
|
This task does **not** create or modify PDF templates.
|
|
|
|
This task does **not** insert Product Item pages.
|
|
|
|
This task prepares the runtime for Task P.4.5.
|
|
|
|
---
|
|
|
|
# Prerequisites
|
|
|
|
Completed
|
|
|
|
* P.4 Discovery
|
|
* P.4.1 Runtime Verification
|
|
* P.4.2 Runtime Architecture Design
|
|
* P.4.3 Runtime Refactoring
|
|
* P.4.3.1 Runtime Regression Stabilization
|
|
|
|
Runtime audit must already pass before implementation begins.
|
|
|
|
---
|
|
|
|
# Scope
|
|
|
|
Included
|
|
|
|
* Product Item Engine
|
|
* Product Item Builder
|
|
* Product Item Mapping
|
|
* PDFMe Table Model
|
|
* Pagination Model
|
|
* Runtime Contracts
|
|
* Unit Tests
|
|
|
|
Excluded
|
|
|
|
* PDF template JSON
|
|
* CRM Template UI
|
|
* Template Version
|
|
* Page insertion
|
|
* Product Item page rendering
|
|
* User render options
|
|
|
|
---
|
|
|
|
# Architecture
|
|
|
|
The runtime shall use the existing section-based architecture.
|
|
|
|
```text
|
|
Quotation Document
|
|
|
|
↓
|
|
|
|
Render Context
|
|
|
|
↓
|
|
|
|
Section Composer
|
|
|
|
↓
|
|
|
|
Product Item Engine
|
|
|
|
↓
|
|
|
|
BuiltSection
|
|
|
|
↓
|
|
|
|
Template Assembler
|
|
```
|
|
|
|
The engine must be completely isolated from
|
|
|
|
* Topic Engine
|
|
* Signature Resolver
|
|
* Customer Section
|
|
|
|
---
|
|
|
|
# Responsibilities
|
|
|
|
The Product Item Engine shall
|
|
|
|
* read quotation items
|
|
* normalize data
|
|
* format values
|
|
* build PDFMe table rows
|
|
* calculate row metadata
|
|
* estimate pagination
|
|
* return a BuiltSection
|
|
|
|
The engine must not know
|
|
|
|
* page indexes
|
|
* template layouts
|
|
* template JSON
|
|
* page insertion
|
|
* section ordering
|
|
|
|
---
|
|
|
|
# Input
|
|
|
|
Primary source
|
|
|
|
```text
|
|
documentData.items
|
|
```
|
|
|
|
The engine shall not query the database.
|
|
|
|
It receives all data from RenderContext.
|
|
|
|
---
|
|
|
|
# Output
|
|
|
|
Return
|
|
|
|
```ts
|
|
interface ProductItemSection extends BuiltSection {
|
|
role: SectionRole.ProductItems;
|
|
|
|
rows: ProductItemRow[];
|
|
|
|
pagination: PaginationModel;
|
|
|
|
tableModel: PdfmeTableModel;
|
|
}
|
|
```
|
|
|
|
The output must be renderer-independent.
|
|
|
|
---
|
|
|
|
# Product Item Mapping
|
|
|
|
Support at minimum
|
|
|
|
| Column | Source |
|
|
| ----------- | ----------- |
|
|
| Item | itemNumber |
|
|
| Description | description |
|
|
| Qty | quantity |
|
|
| Unit | unitLabel |
|
|
| Unit Price | unitPrice |
|
|
| Discount | discount |
|
|
| Total | totalPrice |
|
|
|
|
If additional fields exist they should be supported when available.
|
|
|
|
Examples
|
|
|
|
* productCode
|
|
* specification
|
|
* remark
|
|
* model
|
|
* brand
|
|
|
|
Missing optional fields must not fail rendering.
|
|
|
|
---
|
|
|
|
# Value Formatting
|
|
|
|
Use centralized formatters.
|
|
|
|
Never format inside templates.
|
|
|
|
Support
|
|
|
|
* currency
|
|
* decimal quantity
|
|
* percentage
|
|
* empty value normalization
|
|
|
|
Formatting must remain locale-aware.
|
|
|
|
---
|
|
|
|
# PDFMe Table Model
|
|
|
|
Generate a canonical table model independent of template layout.
|
|
|
|
Example
|
|
|
|
```ts
|
|
interface PdfmeTableModel {
|
|
headers;
|
|
rows;
|
|
columnWidths;
|
|
alignments;
|
|
}
|
|
```
|
|
|
|
The template consumes this model later.
|
|
|
|
The engine must not know where the table is rendered.
|
|
|
|
---
|
|
|
|
# Pagination Model
|
|
|
|
Implement pagination metadata.
|
|
|
|
The engine shall estimate
|
|
|
|
* row count
|
|
* page count
|
|
* header repetition
|
|
* orphan row prevention
|
|
* available content height
|
|
|
|
Do not insert pages.
|
|
|
|
Return only metadata.
|
|
|
|
Example
|
|
|
|
```ts
|
|
interface PaginationModel {
|
|
estimatedPages;
|
|
rowsPerPage;
|
|
headerRows;
|
|
footerRows;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
# Empty State
|
|
|
|
When quotation has zero items
|
|
|
|
Return an empty Product Item section.
|
|
|
|
Do not throw an exception.
|
|
|
|
Runtime decides whether the section is rendered.
|
|
|
|
---
|
|
|
|
# Error Handling
|
|
|
|
Generate Runtime Issues for
|
|
|
|
* invalid quantity
|
|
* invalid price
|
|
* missing mandatory description
|
|
* invalid totals
|
|
|
|
Do not stop rendering because of one invalid row.
|
|
|
|
---
|
|
|
|
# Product Item Builder
|
|
|
|
Create a dedicated builder.
|
|
|
|
Responsibilities
|
|
|
|
* invoke Product Item Engine
|
|
* produce BuiltSection
|
|
* register itself in Section Registry
|
|
|
|
The builder must not manipulate templates.
|
|
|
|
---
|
|
|
|
# Unit Tests
|
|
|
|
Cover
|
|
|
|
* 0 items
|
|
* 1 item
|
|
* 10 items
|
|
* 100 items
|
|
* long descriptions
|
|
* missing optional fields
|
|
* currency formatting
|
|
* decimal quantities
|
|
* zero discount
|
|
* non-zero discount
|
|
|
|
---
|
|
|
|
# Integration Tests
|
|
|
|
Verify
|
|
|
|
* Section Composer accepts Product Item Builder
|
|
* BuiltSection returned correctly
|
|
* Runtime diagnostics preserved
|
|
* Existing sections unaffected
|
|
|
|
No template rendering yet.
|
|
|
|
---
|
|
|
|
# Performance Requirements
|
|
|
|
Support
|
|
|
|
* 500 quotation items
|
|
|
|
without significant performance degradation.
|
|
|
|
Avoid unnecessary cloning.
|
|
|
|
Avoid repeated formatting.
|
|
|
|
---
|
|
|
|
# Code Quality
|
|
|
|
* Single Responsibility Principle
|
|
* Strong typing
|
|
* Immutable outputs
|
|
* No duplicated mapping logic
|
|
* Shared formatter usage
|
|
* Shared runtime contracts
|
|
* Builder registration through Section Registry
|
|
|
|
---
|
|
|
|
# Deliverables
|
|
|
|
* Product Item Engine
|
|
* Product Item Builder
|
|
* Product Item Mapping
|
|
* PDFMe Table Model
|
|
* Pagination Model
|
|
* Runtime diagnostics
|
|
* Unit tests
|
|
* Integration tests
|
|
|
|
---
|
|
|
|
# Acceptance Criteria
|
|
|
|
* Product Item Engine is independent from template layout.
|
|
* Engine produces canonical PDFMe table model.
|
|
* Engine does not manipulate templates.
|
|
* Engine does not insert pages.
|
|
* Engine returns pagination metadata only.
|
|
* Existing runtime regression tests remain PASS.
|
|
* Runtime audit continues to pass.
|
|
* Product Item Engine is ready for Task P.4.5.
|
|
|
|
---
|
|
|
|
# Out of Scope
|
|
|
|
## Task P.4.5
|
|
|
|
* New PDF template
|
|
* Product Item page
|
|
* PDFMe table rendering
|
|
* Page insertion
|
|
* Header repetition in rendered PDF
|
|
|
|
## Task P.4.6
|
|
|
|
* CRM Template integration
|
|
* Template version management
|
|
* Preview integration
|
|
|
|
## Task P.4.7
|
|
|
|
* Render Policy UI
|
|
* Optional section configuration
|
|
* User-selectable Product Item visibility
|
|
|
|
---
|
|
|
|
# Final Success Condition
|
|
|
|
At the end of Task P.4.4, the runtime is capable of producing a fully normalized Product Item section and PDFMe table model, ready to be rendered by a future template, while the existing PDF output remains unchanged.
|