Skip to main content

SalesPad for BC - Advanced Pricing - Knowledgebase / Mission Control / Mission Control Documentation - Cavallo Technical Support

SalesPad for BC - Advanced Pricing

Authors list
  • Product Development

SalesPad Advanced Pricing for Business Central gives you the power to fully align your sales document pricing with your business rules, respecting customer contracts and calculating the right prices every time.  Unlike BC’s blanket rule for lowest-price-wins, you can set up priority sequences for which price wins when multiple possibilities exist.  Plus you have complete control to select any eligible price, or manually override in those special situations where the typical rules don’t apply.

Leverage contract pricing to keep track of item quantity and price commitments with certain customers.  Use group pricing to assign prices based on the real-time data on every order, taking into consideration your rules for relevant customers and items.  Calculate pricing with percent or amount adjustments from the unit cost or other fields, specific target margin percentages, or your own custom expressions for more complex scenarios.

Combine Advanced Pricing with Mission Control to automatically reprice sales documents as they move in workflow.  When vendor costs change, workflow repricing ensures your bottom line doesn’t take the hit.  And whether pricing is assigned manually, automatically, or via workflow, every decision is logged to a line-level audit for complete transparency and accountability.

What It Looks Like

Automatic Pricing

When entering sales quotes and orders in Business Central, line item pricing automatically calculates as each line is entered.  If a SalesPad Advanced Pricing price source is eligible for a line, it is assigned instead of any BC pricing rules.  If no SalesPad price sources apply, then base BC pricing is used.

On the Sales Order and Sales Quote screens, each line shows: 

  • SalesPad Price Source — read-only, drillable field showing which source (Contract, Group Pricing, Manual, or blank) supplied the current price. Drilling in (which requires Manager access) opens the price source's card. A line whose Unit Price was typed in manually shows Manual instead of being blank, so it is visibly distinct from a line with no SalesPad price at all. 

  • Prevent Reprice checkbox — visible/editable for Admins, and allows blocking a line from being automatically repriced.

On each line, an action is available in the Processing group:

  • Price Trace — opens the full pricing history for the line: every price change, who made it, why it won, and every alternative that was evaluated for the most recent engine-driven price.

At the document header level, a Reprice action re-evaluates and reapplies the best price for every line on the order/quote, automatically skipping lines that are flagged to Prevent Reprice.

Manual Price Overrides

Typing a new Unit Price directly onto a SalesPad-priced line is always allowed. What happens next depends on the Manual Price Handling setting on the SalesPad Pricing Configuration page:

  • Never (default): the price is accepted; a later Reprice action or line change may still recalculate and change it again automatically.

  • Prompt: if the line already had a computed price from Contract or Group Pricing, the user is asked whether to lock the new price (which will automatically flag that line to Prevent Reprice) or leave it unlocked.

  • Always: the line is locked against repricing automatically, with no prompt.

Either way, the line's Price Source becomes Manual, and its Pricing No. and Price Line No. are cleared as it's no longer tied to a SalesPad price source.  The change is recorded in the Price Trace with reason “Manual”.

Manual Price Source Selection

If more than one price source qualifies for a line, Business Central's standard price-picker page (Get Price Line) lists every qualifying candidate — including every Group Pricing quantity tier, not just the winning one — with extra SalesPad columns (Source, Seq., Match) added alongside the standard price and discount columns. Selecting a different row than the winner automatically applies that price to the line, and the choice is recorded in the Price Trace with reason “Manual Source Selection”. 

Pricing Review

Trigger the Price Trace action for a sales line to see:

  • The final applied price, who applied it, when, and why (Sequence (First Match) / Lowest Price / Highest Price / Manual Override / Manual Source Selection).

  • Every candidate price that the engine considered for that resolution (if the price came from the engine), with the winning candidate flagged.

This is the primary tool for answering "why did this customer get this price?" without manually reverse-engineering contracts and groups.

Bulk Price Source Updates

Use the Mass Update Hub on the SalesPad Pricing Configuration page to change many Contract or Group Pricing records at once, following the same four-step pattern:

  1. Set a filter — build a filter against Contract Headers, Contract Lines, Group Headers, or Group Lines.  The Matching Record Count shows how many records currently qualify.
  2. Set properties to update — enter new values only for the fields you want to change.  The Pending Changes summary lists exactly what will be updated, and untouched fields are left alone.
  3. Preview — review a read-only list of every affected record with changed values highlighted in bold.
  4. Confirm or Cancel — confirming updates only the specified fields.  Cancelling discards the preview with no changes made.

Import and Export via Excel

From the Group Pricing List or Customer Contract List, you can choose to Export to Excel or Import from Excel.

  • Export builds a two-sheet workbook (Headers and Lines) reflecting the current list filter, processed as a background job. A notification appears when it's ready, with Download and Dismiss actions.

  • Import prompts for Merge (update existing and insert new) or Append (insert-only) mode, then accepts an uploaded workbook in the same two-sheet format. Row-level errors don't abort the whole import — you'll get a completion notification with Inserted/Updated/Skipped counts, and any errors will be available for review.

  • Import requires the No. Series for the source type (configured under Numbering in SalesPad Pricing Configuration) to have Manual Nos. enabled. If it doesn't, the import is blocked immediately — before any mode selection or file upload prompt. Enable Manual Nos. on the series first, then retry.

  • Only one import or export job runs per source type (Contract or Group Pricing) per company at a time.  This applies across all users in that company, not just the one who started it, and other companies in the same environment are unaffected. The page shows a live "in progress…" status until it completes.

Setup

User Access

Before users can see or use Smart Printing, an administrator must assign each user a Smart Printing Role in Business Central's User Setup page.  Search for User Setup in Business Central and assign the appropriate role for each user.

Role

What the user can do

None (default)

Nothing — blocked from all pricing pages.

User

Work with prices on sales documents: see the Price Source field, use Reprice.

Manager

Everything above, plus drill into pricing details and view the Price Trace.

Admin

Everything above, plus configure sources, filters, expressions, sequence/priority, mass update, and import/export.

Users who already have Business Central's built-in "D365 SALES DOC, EDIT" permission set automatically receive the pricing permission set as well — no separate assignment is needed for basic order entry access.

Licensing note: Admin-level write access additionally requires a valid Cavallo license (sandbox environments always behave as licensed). Without one, pricing pages open read-only and a notification links to license management.

Enabling Advanced Pricing

Before Contract or Group Pricing can apply to sales documents, the price calculation method must be set to SalesPad Advanced Pricing.  Open Feature Management and Enable Feature Update: “New sales pricing experience” if it is not already enabled.  SalesPad Advanced Pricing is used whenever it is selected as the Price Calculation Method throughout Business Central.

You can set Price Calculation Method at these levels:

  • Sales & Receivables Setup (global default - which may be hidden and require personalizing the layout)

  • Customer Group (group override)

  • Customer (most specific override)

Effective priority is:

  1. Customer

  2. Customer Group

  3. Sales & Receivables Setup

Pricing Configuration

The SalesPad Pricing Configuration page (which requires Admin access) is the hub for all Advanced Pricing configuration.

Price Priority lets you decide whether pricing is applied based on the lowest price, highest price, or your configured sequence.

All of your currently configured price sources are shown in a sequenced list.  When Price Priority is set to Sequence, the topmost pricing in the list that is valid for the given customer, order, and item will be used to set the price for that item.  You can use the Move Up and Move Down buttons to resequence the price sources to reflect your priority order.

Under Pricing Settings, the Price Date Field determines which sales document field is used to determine whether it falls in the specified date range for each price source.  This defaults to Order Date, and can be changed to a different field if desired.  Clear this field to disable date window filtering entirely.

The Numbering section provides configuration options for the No. Series used for new Contracts and new Pricing Groups. The configured number series must have Manual Nos. enabled to allow importing or manually entering a number on the Contract or Pricing Group card. If no number series is configured, manual entry and import are unrestricted.

Reusable Filters has drilldowns to the four filter lists (customer, document, item, sales line), Price Expressions has drilldowns to the price expression list, and Mass Update has drilldowns to the Mass Update Hub. 

Test Pricing opens a list of sales order / quote lines, and selecting one and running “View Qualifying SalesPad Prices” shows every candidate price that SalesPad Advanced Pricing would display for it.  Note that selecting a candidate will apply the pricing to the selected sales line.

Select any price source to make changes to it.

Group Pricing

Open the Pricing Group List — reachable from the SalesPad Pricing Configuration's Group Pricing price source for the full unfiltered list, or from a specific customer’s Group Pricing action on the Customer Card — and create a new Pricing Group. 

In the Group Properties section, you can manually assign the Sequence (lower values are prioritized first), set a helpful Description, and optionally configure a valid date range.  

In the Filter section, you must select a customer scope: Apply To All Customers, a specific Customer No., or a Customer Filter Code.  You can filter valid documents and items further with a Document Filter Code and/or Sales Line Filter Code.

Add Pricing Group Lines, each with:

  • A Match Field — how the line is matched: Item Number, Sales Line Filter, Item Filter, or Item Category — and a corresponding Match Value. In the event of a match on multiple price lines, the priority will be Item Number, Sales Line Filter, Item Filter, then Item Category.

  • A Price Type — Fixed Amount, Percent Adjustment, Amount Adjustment, Markup Percent, Margin Percent, or Expression — and its inputs (Fixed Price, Adjustment %/amount + cost basis, or a Price Expression Code).

  • Optionally set up quantity breaks with Qty Start and Qty End, and discounts with Discount % or Discount Amount.

Set the Status to Active once every Item Number line has a Unit of Measure, at least one scope filter is set on the header, and every Expression line has a Price Expression Code assigned. Fields can no longer be edited once the Status leaves Draft.  The Inactive status is available to retire a group from pricing without deleting it. 

Note about Unit of Measure: lines that use a match type other than Item Number will multiply the group price by the sales line's Qty per Unit of Measure.  The Item Number match type can specify the price for each UofM, and it won't multiply by the line’s Qty per Unit of Measure.

Reusable Filters

Use the four filter lists under Reusable Filters on the SalesPad Pricing Configuration page to define named, reusable criteria instead of one-off scoping.

For each filter, drill into the filter cell to open BC's standard filter builder for the target table.  This is the same filter UI used throughout Business Central, and ranges, wildcards, and OR conditions are all supported.  Use Test [Entity] Filter to preview which records currently match. 

The Active Sources column shows a green LIVE indicator when a filter is currently used by an active pricing group, with a drilldown to see exactly which groups depend on it, which is helpful to review before editing or deleting a filter. 

Use Copy Selected Filters to duplicate one or more filters under new codes instead of rebuilding them from scratch.

Price Expressions

Price Expressions are formulas usable wherever a Group Pricing line's Price Type is set to Expression.

Open Price Expressions from the SalesPad Pricing Configuration page and create a new expression with a Code and Description.

Use the built-in editor (a Monaco-based formula editor) to write the formula, referencing the live document, line, item, and customer data, for example:

Description

Formula

15% markup on unit cost

[Item.Unit Cost] * (1.15)

Quantity × list price

[Line.Quantity] * [Item.Unit Price]

10% of the customer’s credit limit

[Customer.Credit Limit] * 0.1

Reference another expression

[EXPR01]

1 if item description contains "BULK"

[Item.Description].Contains('BULK')

Click Validate Expression to check syntax, and Test Expression to run it against a real sales line and see the resulting price.

Then you can assign the expression to a Group Pricing line's Price Expression Code.

The editor's autocomplete only suggests numeric (Decimal or Integer) fields on each entity, because those are the only kinds of fields usable in an arithmetic formula. FlowFields are calculated automatically when referenced. Supported operators are + - * / with standard precedence and parentheses for grouping, plus the .Contains('text') substring test shown above.  There's no AND/OR conditional logic, so branching logic isn't currently possible in a single expression.

The Price Expression List shows a ● LIVE indicator for expressions that are currently referenced, directly or through another expression, by an active group.  Drill in to see all dependents before changing or deleting an expression.

Contract Pricing

Open the Customer Contract List — reachable from the SalesPad Pricing Configuration's Contract price source for the full unfiltered list, or from a specific customer's Contract Pricing action on the Customer Card — and use New to create a contract.

In the General section, select the Customer Number for this contract and set a Description.

In the Terms section, choose a Contract Type:

  • Grouped — one shared committed quantity pool at the header level, spread across all lines.

  • Detail — each line tracks its own committed quantity independently.

You can also optionally set a Begin Date and End Date to define the period during which the contract is valid.

Add contract lines in the Pricing section.  For each line, set the Item Number and Unit of Measure, Variant (optional), Contract Price, and Discount % or Discount Amount (optional, only use one or the other).  

Change the Status in the General section from Draft to Active to make this contract usable for pricing. Activation is blocked if any line is missing a UofM, or if another active contract already overlaps on the same customer, item, UofM, variant, and date range. Once Active, the contract header and lines lock and can no longer be edited — fields are only editable while the Status is Draft.

Set the Status to Inactive to retire a contract from pricing without deleting it — pricing logic treats Inactive exactly like Draft and excludes it from consideration. Unlike Active, a contract never becomes Inactive automatically; it's a manual step, typically taken before deleting the contract.

Examples

Give a customer a negotiated price for a fixed quantity

Goal: Customer 10000 gets item 1896-S at $42.00 for the next 500 units, tracked as one pool.

  1. Customer Contract List → New. (Reachable via SalesPad Pricing Configuration's Price Sequence, or via this customer's Contract Pricing action on the Customer Card, which opens the same list pre-filtered to customer 10000.)
  2. Contract Type = Grouped, Contract Qty = 500.
  3. Add a Contract Line: Item No. = 1896-S, Unit of Measure Code = PCS, Contract Price = 42.00.
  4. Set Status = Active (blocked if UoM is missing on any line, or if it overlaps another active contract for this customer/item/UoM).
  5. Enter a sales order for customer 10000, item 1896-S — the line prices at $42.00 and Price Source shows Contract. As quantities are ordered, Sold Qty on the contract climbs; once it reaches 500, further lines fall back to standard pricing (or another qualifying source).
Give a 10% markup-on-cost price to a category of items for a set of customers

Goal: All customers matching a "Wholesale" customer filter get Unit Cost + 10% on every item in category HARDWARE.

  1. SalesPad Pricing Configuration → Reusable Filters → Customer Filter → create/confirm a WHOLESALE filter (e.g. Customer Price Group = WHOLESALE).
  2. Pricing Group List → New group: Customer Filter Code = WHOLESALE, Status = Draft.
  3. Add a Pricing Group Line: Match Field = ItemCategory, Match Value = HARDWARE, Price Type = MarkupPercent, Price Source = UnitCost, Adjustment = 10.
  4. Activate the group.
  5. A sales order for a wholesale customer with a hardware-category item now prices at cost + 10%, Price Source = GroupPricing.
Build a formula-driven price with quantity breaks

Goal: Item WIDGET-1 prices at list price minus a scaling discount depending on quantity, using a formula (up to 50% off the Unit Price), instead of a flat percentage.

  1. SalesPad Pricing Configuration → Price Expressions → New: Code WIDGETQTY, formula: MAX([Item.Unit Price] - ([Line.Quantity] * 0.10), [Item.Unit Price] * .5)
  2. Validate Expression, then Test Expression against a real order line to sanity-check the output.
  3. Pricing Group → add two lines both matching ItemNumber = WIDGET-1:
    1. Line A: Qty Start = 1, Qty End = 49, Price Type = FixedAmount (list price, no discount). 
    2. Line B: Qty Start = 50, Price Type = Expression, Price Expression Code = WIDGETQTY.
  4. Activate the group. Orders for 50+ units automatically evaluate the formula; smaller orders use the flat price.
Investigate an unexpected price on an order

Goal: A rep asks why a line priced at $38.50 instead of the expected contract price of $35.00.

  1. Open the sales line → Price Trace action.
  2. Check the latest entry's Reason. If it's Sequence (First Match)/Lowest Price/Highest Price, expand the candidates: was the $35.00 contract even in the list? If not, the contract likely didn't qualify (wrong UoM, expired date window, quantity already exhausted, wrong variant).
  3. If Reason is Manual Override, someone typed the price directly — check Prevent Reprice to see if it's now frozen, and uncheck it directly on the line if it needs to participate in pricing again.
  4. If the contract used to work, check the Customer Contract List — confirm Status = Active and remaining quantity (Contract Qty − Sold Qty) is still positive.
Raise every active group price by a flat amount

Goal: Increase Fixed Price by $2.00 across a specific set of group pricing lines (e.g., all lines in groups whose No. starts with GP-2026).

  1. Mass Update Hub → Group Pricing Lines….
  2. Set filter: Group No. = GP-2026*.
  3. Confirm Matching Records is as expected.
  4. In Properties to Update, enter the new Fixed Price value for the lines that should change (bulk math isn't automatic — the new value is what gets written, so compute/enter the target price per line grouping as needed, or run separate filtered passes per current price tier).
  5. Review the confirmation preview (changed cells shown in bold), then Apply Changes.
Bulk-load contract prices from Excel

Goal: A distributor sends a spreadsheet of 200 negotiated item prices for a customer's new contract.

  1. Create the Contract Header (Customer, Contract Type, Status = Draft) first, so the workbook only needs to supply lines against an existing contract number.
  2. Customer Contract List → Export to Excel (with the list filtered to the new contract) to get a correctly-formatted template with the right column headers.
  3. Fill in the "Lines" sheet with Item No., UoM, Contract Price (and Qty if Detail-type), keeping the exported "Headers" sheet's Contract No. intact.
  4. Customer Contract List → Import from Excel, choose Merge mode, upload the workbook.
  5. Watch the in-progress banner; when complete, review the Inserted/Updated/Skipped counts and check the Error Text for any rejected rows (e.g., invalid Item No.) before activating the contract.

Troubleshooting

Symptom

Likely cause and resolution

A line doesn't get any Cavallo price at all

No contract or group qualifies, so the logic falls back to standard BC pricing automatically. Check the date window, UoM/variant match, customer scope, and quantity remaining.

Price won't recalculate after a change

Prevent Reprice is flagged on the line.  Open the sales document and unflag that checkbox on the line.

Manual price edit didn't prompt to lock

Manual Price Handling is not set to Prompt in SalesPad Pricing Configuration, or the line had no Cavallo source to begin with (the prompt only fires when a computed price already existed).

A pricing/setup page won't open, or opens read-only

Insufficient access level in User Setup, or no valid license for Admin write access.

Import/Export action is greyed out or won't start

Another import/export job is already Pending or Running for that source type. Wait for it to finish, or check the Job Queue Log if it appears stuck.

Import blocked with a “Manual Nos.” error

The No. Series for that source type does not have Manual Nos. enabled. Import requires it so that records can be assigned numbers from the file. In SalesPad Pricing Configuration, under the Numbering section, open the No. Series and enable Manual Nos.

Expression won't validate

Referenced field name doesn't exist on the mapped entity, or a circular [Code] reference.  In the Price Expression card, check the Validate Expression error text.

Contract won't activate

A line is missing Unit of Measure, or it overlaps another active contract for the same customer, item, UofM, variant, and date range.  Check Contract Pricing setup.

Group won't activate

An Item Number line is missing UofM, no scope filter is set on the header, or an Expression line has no Price Expression Code.  Check Group Pricing setup.

Helpful Unhelpful