Automatically calculate deal value from products and line items
Automatically calculate deal value from products and line items.
Available on pro and enterprise plans.
Admins can create custom objects. Admins and members with full access to an object can create attributes.
Calculating Deal value from the products or services on each deal gives every rep the same structure to work in, and gives your reports and forecasts consistent numbers. This article shows you how to set up two custom objects, three formulas, and three workflows that calculate Deal value for you. When a rep adds line items to a deal, Attio totals them and updates the Deal value. Each product's price is locked in on the line item when it's created, so changing a product's price later never rewrites past deals. Deals without line items keep the value reps type in.
If you haven't created custom objects or workflows before, read create and manage custom objects and create a workflow first. This article focuses on what to build and why.
Decide whether you need products and line items
This setup is worth it when your team sells more than one product or variable quantities of a product on the same deal. A deal for 40 seats of a license plus an implementation fee is a good example.
If every deal is for one product at one price, you don't need to add complexity through this setup. A typed Deal value or a single formula attribute on Deals is enough.
The tradeoff is setup time, but once it's built, Deal value maintains itself.
Understand how products, line items, and deals fit together
The setup uses three objects. Deals is a standard object that Attio provides, and Products and Line items are custom objects you create.
Products is your price list, with one record per thing you sell (like a platform license) and its current list price.
Line items track what's sold on a specific deal: which product, how many, and at what discount. Each line item belongs to one deal.
Deals is the standard object for tracking your sales pipeline. One deal can have many line items.
This article follows one example throughout. Lumora is a SaaS analytics company that sells three products:
Platform license: $600 per seat per year
Implementation package: $5,000
Premium support: $2,400 per year
Lumora's deal with its customer Ridgeway is for 40 Platform licenses at 10% off, plus the Implementation package.
Each row is a line item, and the deal's value is the sum of its line items. Here's what that looks like:
Platform license 40 seats × $600, 10% off $21,600
Implementation package 1 × $5,000 $5,000
--------
Deal value $26,600Set up the Products and Line items objects
These two custom objects hold your products and what each deal sells (Line items). Create a custom object called Products with these attributes:
Product name: A text attribute for the product's name.
List price: A currency attribute with the current price.
You can add more attributes if you need them.
Then create a custom object called Line items with these attributes:
Product: A record reference to Products that allows only one value. Turn on Required so every line item gets a price.
Deal: A relationship to Deals. Set it up so many line items can belong to one deal, and each line item belongs to one deal. This also adds a Line items attribute to Deals.
Quantity: A number attribute. Turn on Required so a line item can't be saved without a quantity.
Locked price: A currency attribute. The workflow in the section on copying the product's price onto each new line item fills it in with the product's List price.
Discount %: A number attribute for the rep's discount, entered as a whole number such as 10.
Learn how to create attributes and how relationship attributes work.
Once those attributes exist, add a formula attribute called Name that labels each line item with its product and quantity, such as "Platform license x 40". Create it with the AI composer in the formula editor, using this prompt:
Output text. Take the Product name attribute from the linked Product, add the text " x ", then add the Quantity attribute converted to text with text(). Example output: "Platform license x 40".
Creating formulas with the AI composer in this way doesn't use any credits.
Then set Name in the Record text dropdown menu for the Line items object. Reps won't need to enter a name, and it updates when the quantity changes. Learn how to manage record labels.
Treat the Locked price attribute as read-only. When a rep negotiates a better price, they should use the Discount % attribute to reflect that. That keeps the original list price on record, so you can see how much discounting is happening.
Create a product record
Create a product record now so you have something to test with later in this article.
In the sidebar, open the Products object.
If you haven’t created a view yet, you’ll be prompted to do so.
Click the New Product button.
Enter the Product name and List price.
Click Create record.
Your product appears in the Products object, ready to add to a deal.
Show line items on the deal record page
Add a Line items tab to deal records so reps can see and edit each deal's line items in one place. Admins and members with full access to the Deals object can configure record pages.
Open any deal record.
Click the ⋮ icon in the upper-right corner.
Select Configure page.
Click + Add tab.
Select Line items.
Select the attributes to show: Product, Quantity, Locked price, Discount %, and Line total.
Optionally, drag the Line items tab to where you want it.
Click Save changes.
Every deal record now has a Line items tab that lists its line items in a table. Reps can edit line items directly in the table, and sort or filter them. You'll use this tab to test the workflows and formulas in the next sections.
Copy the product's price onto each new line item
This first workflow locks in the product's price on the line item the moment a line item is created, so changing a product's List price later doesn't change the deals it's already on. A workflow is an automation that runs a series of steps for you. It starts from a trigger, the event that sets it off, followed by action blocks that do the work.
If you sell the same product at different prices by region or tier, create one product per price point. Each product then has a single price that doesn't need to change.
Create a workflow with the Attribute value changed trigger on Line items, watching the Product attribute.
Add an Update record block that updates the triggering line item.
Set Locked price to the List price of the line item's product.
You can also use Ask Attio to build this workflow for you by pasting in the prompt below (make any edits to attribute names if needed). Building it this way uses seat credits.
Build a new workflow called "Set locked price when product changes". Trigger: "Attribute value changed" on Line items, watching the Product attribute. Step: an "Update record" block that updates the triggering Line item, setting "Locked price" to the List price of the Product linked to that Line item.
The trigger fires when a value is set or changed for the Product attribute on a line item record. So if a rep picks the wrong product and fixes it, the line item picks up the correct product's price. Changing the value of a List price attribute on a product doesn't trigger this workflow, which is what keeps existing line items locked. See the workflows block library for how each block works.
To test the workflow, open a test deal, click New Line item on its Line items tab, and select a product. Locked price should fill in with that product's List price. For Lumora, a Platform license line shows $600.
Calculate line totals and the deal total
The Line total and Line items total formulas handle the math. Because formulas recalculate when any value they reference changes, editing a line item's quantity or discount updates its Line total and the deal's Line items total automatically, without extra workflows or credits.
Create both formulas with the AI composer, as you did for Name.
On the Line items object, create a formula attribute called Line total and use this prompt:
Multiply the Quantity attribute by the Locked price attribute, then reduce the result by the Discount % attribute as a percentage (10 means 10% off). If Discount % is empty, treat it as 0. Use each attribute's current value, not a historical value.
The result should look like this:
{Quantity} * {Locked price} * (1 - ifNull({Discount %}, 0) / 100) Formulas return nothing if any input is empty, so ifNull stops a line item with no discount from dropping out of the deal's sum.
On the Deals object, create a formula attribute called Line items total, with Currency output, and use this prompt:
Add up the Line total attribute across all of this deal's Line items. If the deal has no line items, return 0.
The result should look like this:
if(count({Line items › Line total}) == 0, currency(0), sum({Line items › Line total})) The if and count part returns $0 instead of a calculation error for deals with no line items. For formula syntax, see formula attributes.
To test the formulas, add a second line item to your test deal and leave its discount empty. Each line should show a Line total, and Line items total should equal their sum. For Lumora's Ridgeway deal, that's $21,600 + $5,000 = $26,600.
Keep Deal value in sync with the line items
Deal value feeds your reports and forecasts, so it needs to stay in sync with line items.
Once a deal has line items, the line items decide its Deal value. Deals without line items keep whatever value reps type in.
Create the second workflow:
Use the Attribute value changed trigger on Deals, watching Line items total.
Add a Filter block that only continues when the deal's Deal stage isn't a won or lost stage.
Add a second Filter block that continues when the deal's Line items attribute isn't empty, or when the trigger's Previous value is greater than 0.
Add an Update record block that sets Deal value to Line items total.
You can also use Ask Attio to build this workflow for you by pasting in the prompt below (make any edits to attribute names if needed). Building it this way uses seat credits.
Build a new workflow that updates a Deal's value whenever its line items total changes, but only while the deal is still open. Trigger: - Use the "Attribute value changed" trigger on the Deals object, watching the "Line items total" attribute. Steps, in order: 1. Filter: only continue if the triggering Deal's "Deal stage" is not "Closed Won" and not "Closed Lost". 2. Filter: only continue if the triggering Deal's "Line items" attribute is not empty, OR the trigger's previous value of "Line items total" is greater than 0. 3. Update record: on the triggering Deal, set "Deal value" to its current "Line items total". Connect the blocks in a single line: trigger -> filter 1 -> filter 2 -> update record. If you can't find any of these attributes or the "Closed Won" / "Closed Lost" stages, ask me which ones to use instead of guessing.
The second filter stops a new deal's $0 Line items total from overwriting a typed Deal value. It only continues when the deal has line items or has just lost its last one. The stage filter keeps closed deals at the value they closed at.
The trigger watches Line items total, not the Line items attribute, because a trigger on Line items only fires when line items are added or removed, not when a rep edits a line.
Don't use Deal value in the Line total or Line items total formulas. Otherwise, this workflow's update to Deal value can trigger it again in a loop that uses workspace credits.
Your test deal's Deal value should now match its Line items total. For Lumora, Ridgeway shows $26,600. If you remove all of a deal's line items, its Deal value goes to $0.
Stop reps from typing over Deal value
You can't stop the Deal value from being edited, so a third workflow sets it back to Line items total when a rep edits it. Without it, a typed value can become a closed deal's final value.
Create the third workflow:
Use the Attribute value changed trigger on Deals, watching Deal value.
Add a Filter block that only continues when the deal's Deal stage isn't a won or lost stage.
Add a second Filter block that only continues when the deal's Line items attribute isn't empty.
Add a third Filter block that only continues when Deal value doesn't equal Line items total.
Add an Update record block that sets Deal value to Line items total.
You can also use Ask Attio to build this workflow for you by pasting in the prompt below (make any edits to attribute names if needed). Building it this way uses seat credits.
Build a workflow called "Reset Deal value to line items total". Trigger: "Attribute value changed" on the Deals object, watching "Deal value". Blocks, connected in a single line (trigger -> 1 -> 2 -> 3 -> 4): 1. Filter: "Deal stage" is not "Closed Won" AND not "Closed Lost", in one Filter block. 2. Filter: "Line items" is not empty. 3. Filter: "Deal value" does not equal "Line items total". 4. Update record: on the triggering Deal, set "Deal value" to "Line items total". Notes: - Read every Deal attribute from the trigger's record, not from a lookup step. - "Line items total" is a read-only currency attribute, so type the value in the Update record block as number-or-currency. - If any attribute or the Closed Won / Closed Lost stages are missing, ask me which to use instead of guessing.
The third filter stops the workflow from triggering itself. Its own update to Deal value fires the trigger again, but the values now match, so the run stops there. The first two filters leave closed deals and deals without line items alone. To change the value of a deal that has line items, edit its line items instead, and use Discount % for discounts.
Add line items to a deal
Reps create one line item per product or service that they're selling in that deal. A deal for licenses and an implementation package has two line items. Create line items from the deal's Line items tab, so each one is linked to the deal automatically.
Open the deal and select the Line items tab.
Click New Line item. If the deal already has line items, click Add line item.
Select a Product, enter a Quantity, and optionally enter a Discount %.
Repeat these steps for each product on the deal. Name and Deal fill in automatically. Leave Locked price empty because the workflow fills it in with the product's List price after you select a product. To offer a lower price, enter a Discount % instead. Line total and Deal value then update automatically.
Check that prices stay locked and Deal value syncs
Run three quick checks on your test deal:
Change List price on a test product. Line items that already use it keep their Locked price, and Deal value doesn't change. If Lumora raised Platform license to $700, Ridgeway's line would keep $600.
Move a deal to a won or lost stage, then edit one of its line items. Line items total should update, but Deal value shouldn’t.
Type a different value into Deal value on an open deal with line items. It should change back to Line items total.
Use Deal value in reports and forecasts
With Deal value calculated from line items, every report, view, and forecast that uses it is built on consistent numbers. The natural next step is to weight Deal value by stage probability. Learn how in setting up a weighted pipeline.
Frequently asked questions
Line items created before the first workflow existed won't have a Locked price. To fill it in, clear the line item's Product, then select the product again. This triggers the workflow, which copies the product's current List price. If the product's price has changed since the deal was made, check that Locked price matches what was sold.
Yes, and Line items total updates, but Deal value doesn't. That keeps closed deals at the value they closed at. If the change should count, update Deal value by hand.
No, anyone with access to edit line items can change them. If a rep types over Deal value on an open deal with line items, the third workflow changes it back. See the section on stopping reps from typing over Deal value.
Each currency attribute uses one currency, set in its attribute settings, so every line item and deal in this setup shares the same currency. Formulas don't convert between currencies, so set List price, Locked price, Line items total, and Deal value to the same one. Otherwise, the number carries over unchanged. For example, a €5,000 Locked price becomes $5,000 in a Line items total set to US dollars.
Deal value updates every time a line item changes. Workflows or alerts that trigger on Deal value changes run each time, and they can run on a value partway through a rep's edits. Consider triggering them on a stage change instead, or adding a condition such as a minimum value.