StabisoDocs

Sales and customers

Price lists per customer and currency

A price list gives particular customers their own prices for a company's products: each list is of one company (entity) and in one currency, and holds prices of its products in volume tiers (a lower price from a quantity on), each from a day. A customer takes at most one list per currency (a Swiss reseller may have a CHF list and a EUR list). A new invoice, credit note, quote or sales order line of a product proposes the customer's price for the line's quantity when there is one, and the list price otherwise; a line that gives no price takes it, and a price the line gives wins (What the system fills in). Nothing here posts. The design is ADR-0070; the controls are in the control matrix (section "Price lists", PL1 to PL5).

Everything is a REST operation first (/v1, tag "price lists" in the generated reference); the MCP tool list_price_lists reads the same operations. Keeping lists is drafting (scope draft), as keeping products is.

Lists

POST  /v1/price-lists                      {entity, code?, name, currency?, prices?}
GET   /v1/price-lists                      ?entity&active&limit
GET   /v1/price-lists/{price_list_id}
PATCH /v1/price-lists/{price_list_id}      name, active

The code is unique in the entity; left out, it is made from the name (Wholesale CHF is WHOLESALE-CHF, WHOLESALE-CHF-2 when that is taken). The entity, the code and the currency never change. A list without a currency is in the company's own. A list is never deleted: active: false stops lines from proposing its prices and it is given to no new customer; the customers that take it keep it, unused, until it is active again or they are given another list. Every change is audited (price_list.create, price_list.update with the previous values). A list answers with every price (by product, tier and the newest first) and the customers that take it.

Prices and tiers

POST /v1/price-lists/{price_list_id}/prices   {product, unit_price, min_quantity?, price_period?, valid_from?}

A price names a product of the list's company (code or id), the net price of one unit, the smallest quantity it holds for (min_quantity, default 1) and its first day (valid_from, default today where the company is). A recurring product's price is per month or year, a one-off product's per unit, as for list prices. A price is never changed: a new price from a later day replaces the tier's price from that day on (409 price_list_price_exists for a second price of the product and tier from the same day).

The price in force for a quantity on a day is the lowest of the tiers the quantity reaches, each at its latest price from on or before the day: a larger quantity never costs more per unit, and a line of less than one unit (half a roll) takes the price of the first tier. With the demo's wholesale list (scanner CHF 229.00 from 1 piece, CHF 209.00 from 10 pieces, both from 1 January 2026), 9 scanners cost 229.00 each and 10 cost 209.00 each.

A customer's lists

GET    /v1/entities/{entity}/customers/{party}/price-lists
PUT    /v1/entities/{entity}/customers/{party}/price-lists/{currency}   {price_list}
DELETE /v1/entities/{entity}/customers/{party}/price-lists/{currency}

PUT gives the customer the list (code or id, an active list of its company in that currency) in place of the one it had in the currency; giving it the list it has changes nothing. DELETE takes the list away; its lines propose the list price again. Both are safe to repeat and audited on the customer (party.price_list, with the previous list). 422 price_list_currency for a list in another currency, 409 price_list_inactive for an inactive one, 409 price_list_assigned_meanwhile when someone else gave the customer its first list in the currency at the same moment, 404 for a vendor or an unknown customer.

What a line proposes

GET /v1/products/{product_id}/price   ?currency&on&party&quantity

With party (a customer of the product's company) the answer carries, beside the list price and SSP in force, customer_price: the customer's price for the quantity (default 1) from the active list it takes in the currency, with the list (price_list, price_list_name) and the tier (min_quantity) it came from; null when it takes none, the list is inactive or has no price of the product for the quantity on the day. The screens' line proposes it and says so in plain words ("Customer price 209.00 CHF from the price list Wholesale CHF for 10 or more, valid from 01.01.2026. List price: 249.00 CHF."). A price left as proposed follows a new quantity, customer, currency or date; a typed price stays. A credit note line that credits an invoice line keeps the price that line was invoiced at: nothing is proposed for it, so crediting 2 of 12 scanners invoiced at 209.00 credits 209.00 each.

Screens

Sales > Price lists lists the lists with their currency, number of prices and customers; New price list creates one; a list's card shows its prices by product and tier (in force, replaced or upcoming), its customers, Add price and Deactivate. The customer card has a Price lists section: the list per currency, Change, Remove and Give a price list.

Not built

Recurring invoice templates and subscriptions do not read price lists (a subscription's prices are its approved terms). Lists across currencies or companies, percentage discounts per list or product group, and the list's name on the PDF are not built.

Stabiso, the Enterprise System of Record · generated from the code and its guides · release 6f03a5e846b3