Pass dicts instead of StockItem/Warehouse ORM objects to the purchase order form template so Jinja's tojson filter can serialize them for the embedded script. Fixes TypeError when creating or editing a PO. - new_purchase_order and edit_purchase_order now convert query results to minimal dicts (id, sku, name, unit for items; id, code, name for warehouses) before render_template. - Add docs/implementation-notes/INVENTORY_PO_FORM_JSON.md describing the requirement and pattern for other forms embedding data in JS.
1.3 KiB
Inventory: Purchase Order Form JSON Data
Overview
The purchase order create/edit form (inventory/purchase_orders/form.html) embeds stock_items and warehouses into a <script> block so the front-end can build dropdowns and add rows. Jinja’s tojson filter is used to serialize these variables.
Requirement
Variables passed to the template for use with | tojson must be JSON-serializable. SQLAlchemy model instances (e.g. StockItem, Warehouse) are not JSON-serializable by default and will raise TypeError: Object of type StockItem is not JSON serializable when rendering.
Solution
In app/routes/inventory.py, the new and edit purchase order handlers convert query results to plain dicts before passing them to the template:
- Stock items:
[{"id", "sku", "name", "unit"} for s in stock_items_q] - Warehouses:
[{"id", "code", "name"} for w in warehouses_q]
The template’s JavaScript only needs these fields, so the route builds minimal dicts and passes them as stock_items and warehouses. No template changes are required.
For Other Forms
Any inventory (or other) form that embeds server data in a script with | tojson should receive lists of dicts (or other JSON-serializable types), not ORM objects. Convert in the route before calling render_template.