Skip to main content

OrderTotals

A display-only financial summary for orders and quotations. Renders subtotal, discounts, shipping costs, transaction costs, VAT breakdowns, and the grand total. Each row can be toggled on or off, and all labels and price formatting are fully customizable.

The component handles presentation only -- it does not perform any API calls, mutations, or side effects.

Usage

All defaults

import OrderTotals from '@/components/propeller/OrderTotals';

<OrderTotals order={order} />

Minimal summary (hide VAT details)

<OrderTotals
order={order}
showVATs={false}
showTotalVat={false}
showTotalExclVat={false}
/>

Custom labels (Dutch)

<OrderTotals
order={quote}
labels={{
subtotal: 'Subtotaal:',
discount: 'Korting:',
subtotalWithDiscount: 'Subtotaal met korting:',
transactionCosts: 'Transactiekosten:',
shippingCosts: 'Verzendkosten:',
totalExclVat: 'Totaal excl. BTW:',
vat: 'BTW',
totalVat: 'Totaal BTW:',
total: 'Totaal:',
}}
/>

Custom price formatting

<OrderTotals
order={order}
formatPrice={(price) => `$ ${price.toFixed(2)}`}
/>

Quote detail page (real-world example)

<OrderTotals
order={quote}
title="Quote summary"
showShippingCosts={false}
labels={{
subtotal: 'Subtotal:',
discount: 'Discount:',
total: 'Quote total:',
}}
/>

Configuration

Data

PropTypeRequiredDefaultDescription
orderOrderYes--The order or quote object to display totals for

Display toggles

All toggles default to true. The grand total row is always visible and cannot be hidden.

PropTypeDefaultDescription
showSubtotalbooleantrueShow the subtotal row
showDiscountbooleantrueShow discount row (only renders when the order actually has a discount)
showShippingCostsbooleantrueShow shipping costs (only renders when shipping costs are present)
showVATsbooleantrueShow individual VAT rate rows
showTotalExclVatbooleantrueShow total excluding VAT
showTotalVatbooleantrueShow total VAT amount

Customization

PropTypeDefaultDescription
titlestring'Order summary'Block title (not currently rendered in the template but available for wrapper use)
labelsRecord<string, string>See table belowOverride any row label
formatPrice(price: number) => string(p) => `€${p.toFixed(2)}` Custom price formatter applied to every monetary value

Labels

KeyDefault valueWhere it appears
subtotalSubtotal:Subtotal row
discountDiscount:Discount row
subtotalWithDiscountSubtotal with discount:Subtotal-after-discount row
transactionCostsTransaction costs:Transaction/payment costs row
shippingCostsShipping costs:Shipping/postage costs row
totalExclVatTotal excl. VAT:Total excluding VAT row
vatVATEach VAT rate row (rendered as {percentage}% VAT:)
totalVatTotal VAT:Summed VAT row
totalTotal:Grand total row

SDK Services

OrderTotals is a pure display component -- it does not call any SDK service. It reads from the Order object that the parent fetches (typically via OrderService).

Order type fields used

FieldTypeDescription
order.total.grossnumberSubtotal and total excluding VAT
order.total.netnumberGrand total including VAT
order.total.discountTypeOrderDiscountTypeDiscount kind: A = absolute amount, P = percentage, N = none
order.total.discountValuenumberThe raw discount value (currency amount for A, percentage number for P)
order.total.taxPercentagesArray<{ percentage: number; total: number }>Per-rate VAT breakdown
order.postageData.grossnumberShipping costs (excl. VAT)
order.paymentData.grossnumberTransaction/payment costs (excl. VAT)

OrderDiscountType enum

Accessed via Enums.OrderDiscountType:

ValueMeaningDisplay format
AAbsolute amount-€{discountValue} (formatted through formatPrice)
PPercentage- {discountValue}%
NNo discountRow is hidden entirely

Behavior

Discount display

  • The discount row only appears when both showDiscount is true and the order has an active discount (discountType is not N and discountValue > 0).
  • When a discount is present, an additional "subtotal with discount" row appears directly below it, showing gross - discountValue.
  • Absolute discounts (A) are formatted through formatPrice with a leading - sign.
  • Percentage discounts (P) display as - {value}% without currency formatting.

VAT breakdown

  • Each entry in order.total.taxPercentages with a non-zero percentage and total renders as its own row (e.g., "21% VAT: ...").
  • The "Total VAT" row sums all qualifying tax entries.
  • Zero-rate or zero-total tax entries are filtered out automatically.

Price formatting

  • The default formatter outputs prices as €{value} with two decimal places (e.g., €12.50).
  • Passing a formatPrice function overrides formatting for every monetary value in the component -- subtotal, discount amounts, shipping, transaction costs, VAT, and totals.
  • Null or undefined prices are treated as 0.

Transaction costs

  • Transaction costs always render when order.paymentData.gross > 0. There is no toggle prop for this row because transaction costs are considered a mandatory line item.

Grand total

  • The grand total row (order.total.net) is always visible and cannot be hidden by any prop. It renders with bold styling and a top border to visually separate it from the other rows.