Supplier price-list import and matching

3 min read

Status Current
Last verified 2026-10-07 (matches Git at import; content not re-reviewed)
Source Git
Source file docs/SUPPLIER_PRICE_LIST_IMPORT.md — view on GitHub
Article language original from Git
Git repository git@github.com:advertech/signage-estimator.git (server: /root/signage-estimator)
Git commit d22587c1f7e3add9efd54c7ffc0be0a01b296fa3 (master)
File last changed cef2f3af2e89 on 2026-09-27
Last imported 2026-10-07T09:14:19+02:00
Note Source of truth: Git. Edit the file in the repository and re-run /root/wiki-sign-expert/import_git_docs.py; edits made here will be overwritten by the next import.

Supplier catalogs are global supplier data, not a projection of a product
technology. Every parsed source row is retained in supplier_products (the
domain-facing alias is SupplierPriceItem) with its raw row, source section,
source page, supplier dimensions, unit prices, and match state. An item can
remain unmatched or be ignored indefinitely; neither state removes it from the
catalog.

SupplierPriceList is revised per supplier. New uploads are DRAFT; publishing
sets published_at, freezes the offer rows, archives the previous published
revision, and makes confirmed offers available to new calculations. Calculation
price snapshots continue to retain their source supplier item, revision, price,
and dimensions. Publishing a later revision does not update an existing
snapshot. CSV and XLSX imports retain their raw columns. PDF extraction is
deliberately marked uncertain and remains a human-review workflow; it preserves
page and section labels where present. It cannot guarantee table structure for
arbitrary supplier PDFs.

Canonical Material records hold normalized identity (including family,
subfamily, manufacturer, product code, and grade). MaterialMapping links a
supplier offer to a canonical material. A confirmed supplier alias stores a
stable supplier SKU/section identity so a later revision can reuse the mapping.
Only an exact remembered alias is automatically confirmed. Structured
category/thickness matches are suggestions and require review; high-confidence
suggestions can be explicitly bulk-confirmed. No import replaces a canonical
material.

Technologies continue to select canonical material IDs (and may filter by
canonical family/subfamily). They do not reference supplier items. Supplier
offers are looked up through confirmed mappings after a canonical material is
selected. This keeps products such as mirror acrylic, rods, tubes, and adhesives
available even when no current technology uses them.

API workflow #

  1. POST /api/suppliers/{supplier_id}/price-lists with file creates a draft.
  2. GET /api/price-lists/{id}/products reviews every retained supplier item.
  3. Link through POST /api/supplier-products/{id}/mapping, create a canonical
    material from a reviewed item, or mark an item ignored.
  4. POST /api/price-lists/{id}/publish publishes the immutable revision. The
    older /activate path remains as a compatibility alias.
  5. Confirmed offers appear under /api/materials/{id}/offers and can be selected
    for future calculations. Existing snapshots remain frozen.

The parser runs in the existing restricted subprocess and retains existing file,
row, cell, decompression, and PDF page limits. The IGEPA-shaped regression PDF
is generated in backend/tests/test_supplier_price_lists.py; the original IGEPA
PDF was not present in this repository/runtime, so supplier-specific layout
accuracy against that exact document remains to be validated when the source is
available.

Updated on 07.10.2026
Table Of Contents