Skip to content

fix(workflows): the BOM roll-up priced components from the wrong articles - #71

Merged
sauterbe merged 1 commit into
mainfrom
fix/purchase-price-filter-never-filtered
Aug 7, 2026
Merged

fix(workflows): the BOM roll-up priced components from the wrong articles#71
sauterbe merged 1 commit into
mainfrom
fix/purchase-price-filter-never-filtered

Conversation

@sauterbe

@sauterbe sauterbe commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

A regression I shipped in #69, found while chasing a silently-ignored status filter.

Migrating the template off the raw API replaced a path-scoped call — /products/{id}/purchasePrices, correct by construction — with PurchasePrice.list filtered by product. In the flat shape query: {product: <id>}, which is what the skill documentation teaches, that filter does nothing: a core reads a filter only as filter[i][key|op|value], and Xentral answers 200 with the unfiltered collection for a query param it does not know.

So the leaf branch took its "standard supplier base tier" from a pool of arbitrary articles and wrote that as the component's purchase price. No error, no empty result — a confidently wrong number.

Measured on mvp

call result
flat product=prd_8 50 rows across 11 different products — exactly 1 actually prd_8
bracketed product=prd_8 1 row, prd_8
bracketed product=prd_62004 0 rows — that article has no purchase price

Why my own tests missed it

The fixture scenarios hand the node an already-filtered list. They pin the arithmetic, not whether the filter reaches the wire. That is precisely the gap I have been flagging in other people's work, and it caught me.

Not dependent on the platform fix

The bracketed shape works today. agent-os fix/flat-list-filters-never-filtered additionally makes the flat shape filter properly, but this fix does not wait for it — and stays correct after it lands.

validate_graph and the render are clean; the rendered call is now:

business_entity_op("PurchasePrice", "list", {"query": {
    "filter[0][key]": "product", "filter[0][op]": "equals",
    "filter[0][value]": _ref(context, "n_pid", ""),
    "page[number]": 1, "page[size]": 50}})

Seven more templates are affected, differently

They use the same flat shape, but most also name keys that do not exist as filters at all (maxAgeDays, belowMinStock, invoiced, minOverdueDays, creditNoteCreated), or a value outside the field's options, or — in return_to_credit_note — an entity (SalesReturn) that the core does not have. Those need a redesign per template, not a shape swap, so they are deliberately not in here. Detailed per-template map in the discussion.

…cles

Regression I shipped in #69. Migrating the template off the raw API replaced a
path-scoped call — `/products/{id}/purchasePrices`, correct by construction —
with `PurchasePrice.list` filtered by `product`. In the flat shape
`query: {product: <id>}`, which is what the skill documentation teaches, that
filter does nothing: a core reads a filter only as `filter[i][key|op|value]`, and
Xentral answers 200 with the UNFILTERED collection for a query param it does not
know.

So the leaf branch took its "standard supplier base tier" from a pool of
arbitrary articles and wrote that as the component's purchase price. No error, no
empty result — a confidently wrong number.

Measured on mvp, same call, both shapes:

    flat      product=prd_8  -> 50 rows across 11 different products
                               (exactly 1 of them actually prd_8)
    bracketed product=prd_8  -> 1 row, prd_8
    bracketed product=prd_62004 -> 0 rows (that article has no purchase price)

My fixture tests did not catch it because they hand the node an already-filtered
list — they pin the arithmetic, not whether the filter reaches the wire. That is
the same gap I have been flagging in other people's work.

The bracketed shape works today and stays correct after agent-os
`fix/flat-list-filters-never-filtered`, which makes the flat shape filter too;
this does not depend on that landing.
@sauterbe
sauterbe merged commit ce089eb into main Aug 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant