Skip to main content

Charge

Introduction

The Charge entity represents individual line items for revenue (Income), costs (Expense), or credits (Credit) in the TMS. Charges are the building blocks of financial transactions, appearing on orders and being grouped into invoices and bills through the AccountingTransaction entity.

Charge provides sophisticated automatic calculation intelligence that applies complex pricing rules from tariffs and rates. The Calculate() method can automatically compute quantities based on commodity dimensions (pieces, weight, volume, chargeable weight), apply minimum/maximum price bounds, add base charges, calculate sales tax, and apply rate workflow adjustments. Charges support multi-customer scenarios where a single shipment contains freight for multiple customers, filtering commodities by BillToContactId.

The entity includes an AllowAutomaticUpdate flag to control whether charges recalculate when underlying commodity data changes, enabling both dynamic pricing (automatically updates) and fixed pricing (locked after quote acceptance).

Entity Structure

Properties

Property NameTypeRequiredDescription
ChargeIdintYesPrimary key - unique charge identifier
ChargeTypeChargeTypeYesType of charge (Income, Expense, Credit)
ChargeStatusChargeStatusYesCurrent status (Pending, Open, Posted, Paid, Void)
OrganizationIdint?NoOrganization owning this charge (multi-tenancy)
AccountingItemIdintYesAccounting item (chart of accounts code)
AccountingItemAccountingItemNoNavigation property to accounting item
ApplyByApplyByYesCalculation method (Pieces, Weight, Volume, FlatRate, etc.)
ApplyToContactIdintYesCustomer (Income) or Vendor (Expense) for this charge
ApplyToContactContactNoNavigation property to customer/vendor
Descriptionstring?NoCharge description
QuantitydecimalYesQuantity (pieces, weight, volume, etc.)
Unitstring?NoUnit of measure (Kg, Lb, Pcs, Container, etc.)
PricedecimalYesUnit price
AmountdecimalYesLine amount (Quantity × Price, before tax)
SalesTaxIdint?NoSales tax code for this charge
SalesTaxSalesTaxNoNavigation property to sales tax
SalesTaxRatedecimalYesTax rate (e.g., 0.0825 for 8.25%)
SalesTaxAmountdecimalYesTax amount (Amount × SalesTaxRate)
TotalAmountdecimalYesTotal including tax (Amount + SalesTaxAmount)
CurrencyIdintYesCurrency for this charge
CurrencyCurrencyNoNavigation property to currency
PaidAsPaidAsYesPrepaid or Collect (freight payment method)
IsConsolidatedboolYesWhether this is a consolidated charge
ShowInDocumentsboolYesWhether to show on customer-facing documents
AllowAutomaticUpdateboolYesWhether to recalculate when commodity data changes
CalculatedOfCalculatedOfTypes?NoFor ApplyBy=Calculated charges (Income, Expense, Profit, IncomeFreight)
RateIdint?NoRate used for this charge
RateRateNoNavigation property to rate
Notestring?NoCalculation notes (e.g., "[email protected], MIN CHARGE")
CustomValuesDictionary<string, object>NoExtensible custom properties dictionary
CreatedDateTimeYesCreation timestamp (inherited from AuditableEntity)
CreatedBystringYesUser ID who created the charge (inherited)
LastModifiedDateTimeYesLast modification timestamp (inherited)
LastModifiedBystringYesUser ID who last modified (inherited)

ChargeType Enum

Determines the accounting impact and business purpose:

ValueDescriptionUsed For
IncomeRevenue chargeCustomer billings, freight charges, accessorial fees
ExpenseCost chargeVendor bills, carrier payments, third-party costs
CreditCredit adjustmentCustomer refunds, billing corrections, discounts

ChargeStatus Enum

Represents the charge lifecycle:

ValueDescriptionWhen Used
PendingAwaiting approval or serviceInitial status for charges needing approval
OpenReady to be postedCharge is finalized but not yet on an accounting transaction
PostedOn accounting transactionCharge has been added to invoice/bill
PaidPayment received/madeCharge is on a paid accounting transaction
VoidCancelled chargeCharge has been voided/deleted

ApplyBy Enum

Determines how quantity is calculated from commodities:

ValueDescriptionQuantity Calculation
FlatRateFixed chargeQuantity = 1, regardless of shipment size
PiecesPer piece/packageSum of commodity Pieces
WeightPer weight unitSum of commodity weight in Kg or Lb
ChargeableWeightPer chargeable weightGreater of actual weight or volumetric weight
VolumePer volume unitSum of commodity volume (CBM, CFT, etc.)
ContainerPer containerCount of container-type commodities
CalculatedPercentage of other chargesBased on CalculatedOf (Income, Expense, Profit)

CalculatedOfTypes Enum

For ApplyBy=Calculated charges, determines what to base the calculation on:

ValueDescriptionCalculation Base
IncomePercentage of revenueSum of all Income charges × Price
ExpensePercentage of costsSum of all Expense charges × Price
ProfitPercentage of profit(Income - Expense) × Price
IncomeFreightPercentage of freight revenueSum of Income charges with ItemType=Freight × Price

Relationships (Navigation Properties)

RelationshipTypeDescription
OrdersICollection<Order>Orders associated with this charge
OrderChargesICollection<OrderCharges>Junction table for order-charge relationships
AccountingTransactionsICollection<AccountingTransaction>Accounting transactions including this charge
AccountingTransactionChargesICollection<AccountingTransactionCharges>Junction table for transaction-charge relationships
AccountingItemAccountingItemChart of accounts code
ApplyToContactContactCustomer or vendor
CurrencyCurrencyCurrency for amounts
SalesTaxSalesTaxSales tax definition
RateRateRate used for pricing
OrganizationOrganizationParent organization

YAML Configuration

Creating a Simple Freight Charge

# Create manual freight charge (no automatic calculation)
- task: Charge/Create@1
name: createFreightCharge
inputs:
organizationId: ${organizationId}
charge:
chargeType: Income
chargeStatus: Open
accountingItemId: ${freightAccountingItemId}
applyBy: Weight
applyToContactId: ${customerId}
description: "Air freight charges"
quantity: 150.5
unit: "Kg"
price: 12.50
salesTaxId: ${salesTaxId}
salesTaxRate: 0.0825
currencyId: ${usdCurrencyId}
paidAs: Prepaid
isConsolidated: false
showInDocuments: true
allowAutomaticUpdate: false
outputs:
- charge: freightCharge
# Amount = 150.5 × 12.50 = 1881.25
# SalesTaxAmount = 1881.25 × 0.0825 = 155.20
# TotalAmount = 1881.25 + 155.20 = 2036.45

Creating a Charge with Automatic Calculation

# Create charge that auto-calculates from commodity weight
- type: createEntity
entityName: Charge
properties:
organizationId: ${organizationId}
chargeType: Income
chargeStatus: Open
accountingItemId: ${freightAccountingItemId}
applyBy: ChargeableWeight
applyToContactId: ${customerId}
description: "Ocean freight - Chargeable weight"
price: 8.75 # Rate per Kg
salesTaxRate: 0.00
currencyId: ${usdCurrencyId}
paidAs: Prepaid
showInDocuments: true
allowAutomaticUpdate: true # Will recalculate when commodities change
rateId: ${oceanRateId}
resultVariable: oceanFreightCharge

# Add charge to order
- type: executeMethod
entityName: Charge
method: AddToOrder
filter:
chargeId: ${oceanFreightCharge.chargeId}
parameters:
orderId: ${orderId}

# Trigger calculation
- type: executeMethod
entityName: Charge
method: Calculate
filter:
chargeId: ${oceanFreightCharge.chargeId}
parameters:
forceUpdate: true
# System calculates chargeable weight from commodities on the order
# Quantity set to max(actual weight, volumetric weight)
# Note updated to show calculation: "[email protected]"

Creating Expense Charges for Carrier Costs

# Create carrier cost charge
- type: createEntity
entityName: Charge
properties:
organizationId: ${organizationId}
chargeType: Expense
chargeStatus: Posted
accountingItemId: ${carrierCostAccountingItemId}
applyBy: FlatRate
applyToContactId: ${carrierId}
description: "Line haul - ABC Freight"
quantity: 1
price: 1200.00
salesTaxRate: 0.00
currencyId: ${usdCurrencyId}
paidAs: Collect
showInDocuments: false
allowAutomaticUpdate: false
resultVariable: carrierCharge

Creating Calculated Charges (Percentage-Based)

# Create fuel surcharge as 15% of freight charges
- type: createEntity
entityName: Charge
properties:
organizationId: ${organizationId}
chargeType: Income
chargeStatus: Open
accountingItemId: ${fuelSurchargeAccountingItemId}
applyBy: Calculated
calculatedOf: IncomeFreight # Calculate as % of freight income
applyToContactId: ${customerId}
description: "Fuel surcharge (15%)"
price: 0.15 # 15% rate
salesTaxRate: 0.0825
currencyId: ${usdCurrencyId}
paidAs: Prepaid
showInDocuments: true
allowAutomaticUpdate: true
resultVariable: fuelSurcharge

# When Calculate() is called, system will:
# 1. Sum all Income charges where ItemType = Freight
# 2. Set Quantity = that sum
# 3. Calculate Amount = Quantity × 0.15

Multi-Customer Consolidation with BillToContactId Filtering

# Scenario: Single container with freight for 3 different customers
# Create charge for Customer A (filters commodities by BillToContactId)
- type: createEntity
entityName: Charge
properties:
organizationId: ${organizationId}
chargeType: Income
chargeStatus: Open
accountingItemId: ${freightAccountingItemId}
applyBy: Weight
applyToContactId: ${customerAId}
description: "Ocean freight - Customer A portion"
price: 10.00
currencyId: ${usdCurrencyId}
allowAutomaticUpdate: true
resultVariable: customerACharge

# When Calculate() runs, it only sums commodities where:
# commodity.BillToContactId == null OR commodity.BillToContactId == customerAId
# This enables accurate per-customer billing in consolidated shipments

Charges with Tariff Min/Max Bounds

# Create charge with tariff that has minimum charge of $50
- type: createEntity
entityName: Charge
properties:
organizationId: ${organizationId}
chargeType: Income
chargeStatus: Open
accountingItemId: ${handlingAccountingItemId}
applyBy: Pieces
applyToContactId: ${customerId}
price: 5.00 # $5 per piece
currencyId: ${usdCurrencyId}
rateId: ${handlingRateId} # Rate has minimum = 50.00
allowAutomaticUpdate: true
resultVariable: handlingCharge

# Scenario 1: 3 pieces
# Calculate() computes: 3 × $5 = $15
# Applies minimum: $50
# Result: Quantity = 1, Price = $50, Unit = "MIN", Note = "[email protected], MIN CHARGE"

# Scenario 2: 20 pieces
# Calculate() computes: 20 × $5 = $100
# Minimum not triggered: $100 > $50
# Result: Quantity = 20, Price = $5, Unit = "Pcs", Note = "[email protected]"

Updating Charge Properties

# Update charge price and recalculate
- type: executeMethod
entityName: Charge
method: ChangePrice
filter:
chargeId: ${chargeId}
parameters:
price: 15.00

- type: executeMethod
entityName: Charge
method: Calculate
filter:
chargeId: ${chargeId}

# Change charge status
- type: executeMethod
entityName: Charge
method: ChangeChargeStatus
filter:
chargeId: ${chargeId}
parameters:
chargeStatus: Posted

# Void a charge (soft delete)
- type: executeMethod
entityName: Charge
method: Delete
filter:
chargeId: ${chargeId}
# Sets ChargeStatus = Void, publishes DeletedChargeEvent

Querying Charges with Relationships

# Query charge with complete data
- type: queryEntity
entityName: Charge
filter:
chargeId: ${chargeId}
include:
- AccountingItem
- ApplyToContact
- Currency
- SalesTax
- Rate.Tariff
- Orders.OrderCommodities.Commodity
- AccountingTransactions
resultVariable: fullCharge

Key Methods

Automatic Calculation

  • Calculate(bool forceUpdate = false) - Core method: Apply tariff rules, calculate quantity from commodities, set amounts
    • Respects AllowAutomaticUpdate flag unless forceUpdate = true
    • Skips calculation if ChargeStatus is Paid or Void
    • Calls ApplyTariffInfo()SetAmounts()

Amount Calculation (Private)

  • SetAmounts() - Calculate Amount, SalesTaxAmount, TotalAmount
    • Amount = Round(Quantity × Price)
    • SalesTaxAmount = Round(SalesTaxRate × Amount)
    • TotalAmount = Round(Amount + SalesTaxAmount)
    • Sets default Note if empty: "{Quantity}@{Price}"

Tariff Application (Private)

  • ApplyTariffInfo() - Apply complex tariff pricing rules based on ApplyBy
  • ApplyTariffForCalculated(CalculatedOfTypes?) - Calculate quantity for percentage-based charges
  • ApplyTariffForContainer(TariffOptions) - Calculate quantity for container charges
  • ApplyPriceBounds(TariffOptions) - Enforce minimum/maximum price limits
  • ApplyBaseCharge(TariffOptions) - Add base charge to total
  • ApplyMinimumChargeableWeight(TariffOptions) - Enforce minimum chargeable weight
  • ApplyRateWorkflow() - Add rate workflow quote amounts to charge

Commodity Aggregation (Private)

  • GetCommoditySum(Func<Commodity, decimal?>) - Sum commodity values, filtering by BillToContactId
  • GetContainerCommoditySum(Func<Commodity, decimal?>) - Sum values from both containers and standalone items

Property Updates

  • ChangePrice(decimal) - Update unit price
  • ChangeQuantity(decimal) - Update quantity (rounds to 4 decimals)
  • ChangeAmount(decimal) - Manually set amount, recalculate total
  • ChangeChargeStatus(ChargeStatus) - Update status
  • ChangeChargeType(ChargeType) - Change type (Income, Expense, Credit)
  • ChangeApplyBy(ApplyBy) - Change calculation method
  • ChangeApplyToContactId(int) - Change customer/vendor
  • ChangeAccountingItemId(int) - Change GL account
  • ChangeCurrencyId(int) - Change currency
  • ChangeSalesTaxId(int?) - Change tax code
  • ChangeSalesTaxRate(decimal) - Update tax rate
  • ChangeDescription(string?) - Update description
  • ChangeNote(string?) - Update notes
  • ChangeUnit(string?) - Update unit of measure
  • ChangeIsConsolidated(bool) - Set consolidated flag
  • ChangeShowInDocuments(bool) - Set visibility flag
  • ChangePaidAs(PaidAs) - Set prepaid/collect
  • ChangeAllowAutomaticUpdate(bool) - Enable/disable auto-recalculation
  • ChangeRateId(int?) - Set rate reference
  • ChangeCalculatedOf(CalculatedOfTypes?) - Set calculation base for Calculated charges

Relationship Management

  • AddToOrder(int?) - Associate charge with order (creates OrderCharges junction entry, prevents duplicates)
  • ChangeAccountingTransactionCharges(IEnumerable<AccountingTransactionCharges>) - Set transaction associations
  • ChangeAccountingTransactions(IEnumerable<AccountingTransaction>) - Set transaction collection
  • ChangeOrders(IEnumerable<Order>) - Set order collection
  • ChangeApplyToContact(Contact?) - Set customer/vendor object
  • ChangeSalesTax(SalesTax?) - Set tax object
  • ChangeAccountingItem(AccountingItem?) - Set accounting item object
  • ChangeCurrency(Currency?) - Set currency object
  • SetRate(Rate?) - Set rate object (internal use)

Deletion

  • Delete() - Soft delete charge
    • Throws exception if ChargeStatus = Paid
    • Sets ChargeStatus = Void
    • Publishes DeletedChargeEvent
    • Removes charge from all associated orders

Extensibility

  • ChangeCustomValues(Dictionary<string, object>?) - Update custom properties (merges with existing)
  • ChangeOrganizationId(int) - Change organization
  • ChangeChargeId(int) - Update charge ID (internal use)

Automatic Calculation Intelligence

The Calculate() Method Workflow

1. Check preconditions:
- If ChargeStatus is Paid or Void → skip calculation
- If AllowAutomaticUpdate is false AND forceUpdate is false → skip calculation

2. ApplyTariffInfo() - Apply tariff pricing rules:

Based on ApplyBy:

a. FlatRate → Quantity = 1

b. Pieces → Quantity = Sum of commodity.Pieces (filtered by BillToContactId)

c. Weight → Quantity = Sum of commodity weight in tariff units (Kg or Lb)

d. ChargeableWeight → Quantity = Max(actual weight, volumetric weight)
- Volumetric weight = volume ÷ volumetric divisor (5000 for Kg, 166 for Lb)

e. Volume → Quantity = Sum of commodity volume in tariff units

f. Calculated → Quantity = Sum of charges based on CalculatedOf:
- Income: Sum all Income charges
- Expense: Sum all Expense charges
- Profit: (Total Income - Total Expense)
- IncomeFreight: Sum Income charges where ItemType = Freight

g. Container → Quantity/Price from tariff.GetRate() for each container type

Get Price from tariff.GetRate(Quantity) - supports tiered pricing

Apply modifiers:
- ApplyMinimumChargeableWeight() - enforce minimum weight
- ApplyPriceBounds() - enforce min/max charge limits
- ApplyBaseCharge() - add base charge to total
- ApplyRateWorkflow() - add rate quote amounts

3. SetAmounts() - Calculate monetary values:
- Amount = Round(Quantity × Price)
- SalesTaxAmount = Round(SalesTaxRate × Amount)
- TotalAmount = Round(Amount + SalesTaxAmount)
- Set Note if empty

BillToContactId Filtering Logic

For multi-customer consolidations, the charge calculation filters commodities:

Include commodity if:
commodity.BillToContactId == null (unassigned freight)
OR
commodity.BillToContactId == charge.ApplyToContactId (assigned to this customer)

This enables scenarios like:

  • Single container with 3 customers' freight
  • Each customer gets separate charge
  • Each charge only counts their commodities
  • Accurate per-customer billing in consolidations

Price Bounds Example

Tariff configuration:
Minimum: $50.00
Maximum: $200.00

Scenario A: Small shipment
Calculated: 3 pieces × $5 = $15
Applies minimum: $50
Result: Quantity = 1, Price = $50, Unit = "MIN", Note = "[email protected], MIN CHARGE"

Scenario B: Normal shipment
Calculated: 20 pieces × $5 = $100
Within bounds: $50 < $100 < $200
Result: Quantity = 20, Price = $5, Unit = "Pcs", Note = "[email protected]"

Scenario C: Large shipment
Calculated: 50 pieces × $5 = $250
Applies maximum: $200
Result: Quantity = 1, Price = $200, Unit = "MAX", Note = "[email protected], MAX CHARGE"

Domain Events

DeletedChargeEvent

Published when Delete() is called. Allows charge deletion logic to be handled asynchronously (e.g., updating order totals, triggering notifications).

Event Properties:

  • Charge - The charge being deleted

Use Cases

1. Automatic Freight Charge Calculation

# Create order with commodities
- type: createEntity
entityName: Order
# ... order properties
resultVariable: order

- type: createEntity
entityName: Commodity
properties:
# 10 pallets, 150 Kg each, 1.5 CBM each
pieces: 10
weight: 150
weightUnit: Kg
volumeTotal: 15.0
volumeUnit: Cbm
resultVariable: pallet

# Add commodity to order
- type: executeMethod
entityName: Order
method: ChangeOrderCommodities
# ... add commodity

# Create auto-calculating charge
- type: createEntity
entityName: Charge
properties:
chargeType: Income
applyBy: ChargeableWeight
applyToContactId: ${customerId}
price: 8.50 # Per Kg
rateId: ${oceanRateId}
allowAutomaticUpdate: true
resultVariable: freightCharge

# Add to order
- type: executeMethod
entityName: Charge
method: AddToOrder
filter:
chargeId: ${freightCharge.chargeId}
parameters:
orderId: ${order.orderId}

# Calculate
- type: executeMethod
entityName: Charge
method: Calculate
filter:
chargeId: ${freightCharge.chargeId}
parameters:
forceUpdate: true

# Result:
# Actual weight: 10 × 150 Kg = 1500 Kg
# Volumetric weight: 15 CBM × 1000 / 5 = 3000 Vkg
# Chargeable weight: Max(1500, 3000) = 3000 Vkg
# Amount: 3000 × $8.50 = $25,500
# Note: "[email protected]"

2. Multi-Customer Consolidation Billing

# Container with 3 customers' freight
# Set BillToContactId on commodities
- type: createEntity
entityName: Commodity
properties:
pieces: 5
weight: 100
billToContactId: ${customerAId}
resultVariable: customerACommodity

- type: createEntity
entityName: Commodity
properties:
pieces: 8
weight: 150
billToContactId: ${customerBId}
resultVariable: customerBCommodity

- type: createEntity
entityName: Commodity
properties:
pieces: 3
weight: 50
billToContactId: ${customerCId}
resultVariable: customerCCommodity

# Create separate charge for each customer
- type: createEntity
entityName: Charge
properties:
chargeType: Income
applyBy: Weight
applyToContactId: ${customerAId}
price: 10.00
allowAutomaticUpdate: true
resultVariable: customerACharge
# Calculate() sums only customerACommodity: 100 Kg × $10 = $1000

- type: createEntity
entityName: Charge
properties:
chargeType: Income
applyBy: Weight
applyToContactId: ${customerBId}
price: 10.00
allowAutomaticUpdate: true
resultVariable: customerBCharge
# Calculate() sums only customerBCommodity: 150 Kg × $10 = $1500

- type: createEntity
entityName: Charge
properties:
chargeType: Income
applyBy: Weight
applyToContactId: ${customerCId}
price: 10.00
allowAutomaticUpdate: true
resultVariable: customerCCharge
# Calculate() sums only customerCCommodity: 50 Kg × $10 = $500

3. Fuel Surcharge as Percentage of Freight

# Create freight charge
- type: createEntity
entityName: Charge
properties:
chargeType: Income
accountingItemId: ${freightItemId} # ItemType = Freight
applyBy: Weight
applyToContactId: ${customerId}
quantity: 500
price: 12.00
resultVariable: freightCharge
# Total: 500 × $12 = $6000

# Create fuel surcharge as 15% of freight
- type: createEntity
entityName: Charge
properties:
chargeType: Income
accountingItemId: ${fuelSurchargeItemId}
applyBy: Calculated
calculatedOf: IncomeFreight # Sum freight charges only
applyToContactId: ${customerId}
price: 0.15 # 15%
allowAutomaticUpdate: true
resultVariable: fuelSurcharge

# Calculate
- type: executeMethod
entityName: Charge
method: Calculate
filter:
chargeId: ${fuelSurcharge.chargeId}
# Quantity set to $6000 (sum of freight charges)
# Amount = $6000 × 0.15 = $900

Best Practices

1. Automatic vs Manual Calculation

  • Use allowAutomaticUpdate: true for charges that should recalculate when commodities change (quotes, dynamic pricing)
  • Use allowAutomaticUpdate: false for locked charges (accepted quotes, fixed pricing, manual overrides)
  • Call Calculate(forceUpdate: true) to recalculate even when allowAutomaticUpdate is false

2. ChargeType Usage

  • Income charges increase revenue (customer billings) - appear on Invoices
  • Expense charges increase costs (vendor bills) - appear on Bills
  • Credit charges reduce customer balance (refunds, adjustments) - appear on Credit Memos

3. ChargeStatus Lifecycle

  • Pending → charges awaiting approval
  • Open → approved charges not yet on invoice/bill
  • Posted → charges added to AccountingTransaction
  • Paid → charges on paid AccountingTransaction (cascaded from transaction)
  • Void → deleted/cancelled charges (use Delete() method)

4. ApplyBy Selection

  • FlatRate - Fixed charges (documentation fee, handling fee)
  • Pieces - Per-package charges (handling, labeling)
  • Weight - Weight-based (air freight, LTL)
  • ChargeableWeight - Greater of actual/volumetric (air freight standard)
  • Volume - Volume-based (ocean freight, warehousing)
  • Container - Per-container (FCL, container handling)
  • Calculated - Percentage-based (fuel surcharge, insurance, margin)

5. Multi-Customer Consolidations

  • Set BillToContactId on commodities for multi-customer shipments
  • Create separate charge for each customer with matching ApplyToContactId
  • System automatically filters commodities by BillToContactId during calculation
  • Enables accurate per-customer billing in consolidated shipments

6. Sales Tax Integration

  • Set SalesTaxId for automatic tax rate lookup
  • Or set SalesTaxRate directly (e.g., 0.0825 for 8.25%)
  • Tax calculated automatically in SetAmounts(): SalesTaxAmount = Amount × SalesTaxRate
  • TotalAmount includes tax: Amount + SalesTaxAmount

7. Tariff Integration

  • Link charge to Rate via RateId for automatic pricing
  • Calculate() applies tariff rules from Rate.Tariff or AccountingItem.Tariff
  • Tariff provides: pricing tiers, min/max bounds, base charges, minimum chargeable weight

8. Price Bounds and Minimums

  • Define Minimum and Maximum on Tariff for automatic enforcement
  • System applies bounds in ApplyPriceBounds() during calculation
  • Charge note indicates when bounds applied: "MIN CHARGE", "MAX CHARGE"

9. Currency Rounding

  • All amounts rounded to currency decimal places (default: 2)
  • Use Currency.DecimalPlaces for currency-specific rounding (e.g., JPY = 0, KWD = 3)
  • Rounding applied in Round() helper method

10. Custom Values for Rate Workflow

  • Store rate quotes in customValues.rateWorkflowResponse
  • ApplyRateWorkflow() automatically adds rate quote amounts during calculation
  • Enables integration with external rating APIs

11. ShowInDocuments Flag

  • Set showInDocuments: true for customer-facing charges (freight, fees)
  • Set showInDocuments: false for internal charges (cost allocations, markups)
  • Controls visibility on invoices and BOLs

12. Deleting Charges

  • Use Delete() method instead of direct deletion
  • Throws exception if charge is Paid (prevents deleting paid charges)
  • Sets status to Void, publishes event, removes from orders
  • Preserves audit trail while marking charge inactive