Fieldpine Logo Documentation Home  

Pricing Technical Overview

This is a full technical description for IT support staff Refer to /docs/pricing.htm for a more user level description of pricing

How Pricing is Decided

When an item is added to a sale being processed, the steps below are performed. The following is believed to be an accurate description of the process but it has been simplified and some details omitted in order to be described.

  1. An item is selected to be sold. How the product is selected for sale is largely irrelevant.
  2. If the item is weighed (unit of measure is gm, kg etc) the scales are read, or the user asked to input the weight. This is set to the quantity of the item. If packaging weight is defined for the item this is subtracted from the quantity now.
  3. If the item is not unit based or weighed, the teller is prompted for the quantity.
  4. If the product is prepay recharge/topup, the pricing engine passes to prepay code handlers and exits.
  5. Custom Script handlers for "Saleline Pre Add" are executed. This is before the item has been connected to the sale so these handlers cannot yet alter the price.
  6. (A) If the request to add the item has also set a price, that is loaded as the UnitPrice for the item.
  7. If (A) does not apply, and the product is marked "Prompt Price" or "Variable Priced", the teller is prompted to enter the price now.
  8. If the product has specifically being marked "Prompt Quantity", the quantity is captured from the teller.
  9. A precheck is made to see if this product can belong to a Kit. If a kit is possible, the item is forced to a new saleline.
  10. If the product has modifiers, these are prompted now.
  11. If possible, the sale is scanned to see if this item already exists in a form that is suitable to just increase the quantity.
  12. The saleline is created and applied to the sale.
    • If the product is variant based, a variant specific price is loaded if possible
    • If the product is a modifier, the base modifier pricing is applied
    • The base price from products record is loaded
    • If the setting ProductPriceBand is defined, this is applied now. There are two special cases for zero pricing here, one for hire stores and another using department based pricing.
    • Any pricemaps that apply to this sale are checked and loaded.
    • If no pricemap exists and the customer record has a fixed discount percentage, this is applied now. This is deprecated functionality and all new sites should use pricemaps to achieve per customer discounting.
    • The price band defined for the sale is fetched. This can result in a product specific priceband if pricebandmaps are in use.
    • Any pricemaps that apply to this sale are checked and loaded for a second time if conditions have changed
    • If pricing was not specifically set, check to see if a store wide markdown is in effect and apply that discount.
    • If store specific uplifts are present, these are applied.
    • If PriceWholeSale mode is enabled, this is applied and the next steps below are skipped.
    • Any Quantity Discount rules that apply are added now.
    • Financial rounding is applied, in case any price totals are fractions of a currency unit
    • If prices are detected as having changed, the custom event "Saleline, Price Changed" is fired.
  13. If sale wide discounts are present, these are applied to the new saleline
  14. (P1822) If Price smearing is in effect (setting SalePriceSmear=1, default is off) the price is adjusted to the most recent saleline. Price smearing is a function used to ensure that a price set on a product is also applied to any more of those items that might be sold in the same sale.
  15. Sale based machines are run.
  16. PostSaleLinesChange(2);
    • The customers floor limit is checked and enforced if necessary
  17. If the product can belong to a kit, the kit is applied now.
  18. If automatic discounting is present for this customer, these are applied now if possible. Automatic discounting at this point is not widely used and has been superseeded by PriceMaps.
  19. PostAddToSale();
    • Any additional related salelines are added now.
    • If a PosCommand is present for this product, it is executed.
    • If this product can be purchased out of reward points, the teller is prompted to confirm reward points can be used and the price set to zero.
  20. Custom script handlers for "Saleline Add" are executed. These script handlers can now change the price of the item.

A single saleline has two or three prices the customer sees, the totalprice, the unitprice and perhaps the unitprice before discounts. Where totalprice = unitprice * Quantity. These fields are highlighted bright green in the table below.

Internally, these 3 prices are implemented by holding the values in both inclusive and tax exclusive modes. The pricing engine typically uses Tax inclusive mode, but sometimes it needs tax exclusive pricing details. In some circumstances, some customers are tax exempt, so all the totals used need to be the ExTax prices.

The "Ticket price" (or sticker price) is the base price for a store. This is derived by the POS and cannot be altered for a saleline, but this field is only really used as an input reference for pricing. A Delta can be applied to the input price, creating what is internally called the TicketPriceOut price.

Both the UnitPrice and SubTotal (aka Totalprice) fields have an input, delta and output component. Delta pricing can be fixed amounts or percentages.

This table shows the internal Field numbers assigned to each price field on each line. Each of these fields can be read using PosScript or added to receipts etc. The TrN lines hold details of individual tax amounts

TicketPrice UnitPrice SubTotal
In Delta Out InDeltaOut InDeltaOut
IncTax 360 330 325 350 320 365 355 205 (335)
Tr1 361 331 326 351 321 366 356 336
Tr2 362 332 327 352 322 367 357 337
Tr3 363 333 328 353 323 368 358 338
ExTax 364 334 329 354 324 369 359 339

Note, while the Out/In fields shown may appear to be the same, they are held separately, so that price changes and calculations can clearly keep track of intent. For example, the TicketPriceOut (330) might be $8, which implies (325) is also $8; but your pricing rules apply a "Set Unit Price to $6 for this customer". This changes (325) to $6, but leaves (330) at $8

The pricing engine sometimes maintains multiple copies of pricing for a saleline and switches between them as sales progress. For example, consider when the pricing Machine "Buy3Pay2" is operational. (This says that in any group of three products, the customer receives the lowest price in that group for free). A copy of the above table is stored to hold the base information for each product, but a second copy is also held for what the actual pricing to the customer is currently. This second copy is re-evaluated each time the sale changes