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 Name | Type | Required | Description |
|---|---|---|---|
| ChargeId | int | Yes | Primary key - unique charge identifier |
| ChargeType | ChargeType | Yes | Type of charge (Income, Expense, Credit) |
| ChargeStatus | ChargeStatus | Yes | Current status (Pending, Open, Posted, Paid, Void) |
| OrganizationId | int? | No | Organization owning this charge (multi-tenancy) |
| AccountingItemId | int | Yes | Accounting item (chart of accounts code) |
| AccountingItem | AccountingItem | No | Navigation property to accounting item |
| ApplyBy | ApplyBy | Yes | Calculation method (Pieces, Weight, Volume, FlatRate, etc.) |
| ApplyToContactId | int | Yes | Customer (Income) or Vendor (Expense) for this charge |
| ApplyToContact | Contact | No | Navigation property to customer/vendor |
| Description | string? | No | Charge description |
| Quantity | decimal | Yes | Quantity (pieces, weight, volume, etc.) |
| Unit | string? | No | Unit of measure (Kg, Lb, Pcs, Container, etc.) |
| Price | decimal | Yes | Unit price |
| Amount | decimal | Yes | Line amount (Quantity × Price, before tax) |
| SalesTaxId | int? | No | Sales tax code for this charge |
| SalesTax | SalesTax | No | Navigation property to sales tax |
| SalesTaxRate | decimal | Yes | Tax rate (e.g., 0.0825 for 8.25%) |
| SalesTaxAmount | decimal | Yes | Tax amount (Amount × SalesTaxRate) |
| TotalAmount | decimal | Yes | Total including tax (Amount + SalesTaxAmount) |
| CurrencyId | int | Yes | Currency for this charge |
| Currency | Currency | No | Navigation property to currency |
| PaidAs | PaidAs | Yes | Prepaid or Collect (freight payment method) |
| IsConsolidated | bool | Yes | Whether this is a consolidated charge |
| ShowInDocuments | bool | Yes | Whether to show on customer-facing documents |
| AllowAutomaticUpdate | bool | Yes | Whether to recalculate when commodity data changes |
| CalculatedOf | CalculatedOfTypes? | No | For ApplyBy=Calculated charges (Income, Expense, Profit, IncomeFreight) |
| RateId | int? | No | Rate used for this charge |
| Rate | Rate | No | Navigation property to rate |
| Note | string? | No | Calculation notes (e.g., "[email protected], MIN CHARGE") |
| CustomValues | Dictionary<string, object> | No | Extensible custom properties dictionary |
| Created | DateTime | Yes | Creation timestamp (inherited from AuditableEntity) |
| CreatedBy | string | Yes | User ID who created the charge (inherited) |
| LastModified | DateTime | Yes | Last modification timestamp (inherited) |
| LastModifiedBy | string | Yes | User ID who last modified (inherited) |
ChargeType Enum
Determines the accounting impact and business purpose:
| Value | Description | Used For |
|---|---|---|
| Income | Revenue charge | Customer billings, freight charges, accessorial fees |
| Expense | Cost charge | Vendor bills, carrier payments, third-party costs |
| Credit | Credit adjustment | Customer refunds, billing corrections, discounts |
ChargeStatus Enum
Represents the charge lifecycle:
| Value | Description | When Used |
|---|---|---|
| Pending | Awaiting approval or service | Initial status for charges needing approval |
| Open | Ready to be posted | Charge is finalized but not yet on an accounting transaction |
| Posted | On accounting transaction | Charge has been added to invoice/bill |
| Paid | Payment received/made | Charge is on a paid accounting transaction |
| Void | Cancelled charge | Charge has been voided/deleted |
ApplyBy Enum
Determines how quantity is calculated from commodities:
| Value | Description | Quantity Calculation |
|---|---|---|
| FlatRate | Fixed charge | Quantity = 1, regardless of shipment size |
| Pieces | Per piece/package | Sum of commodity Pieces |
| Weight | Per weight unit | Sum of commodity weight in Kg or Lb |
| ChargeableWeight | Per chargeable weight | Greater of actual weight or volumetric weight |
| Volume | Per volume unit | Sum of commodity volume (CBM, CFT, etc.) |
| Container | Per container | Count of container-type commodities |
| Calculated | Percentage of other charges | Based on CalculatedOf (Income, Expense, Profit) |
CalculatedOfTypes Enum
For ApplyBy=Calculated charges, determines what to base the calculation on:
| Value | Description | Calculation Base |
|---|---|---|
| Income | Percentage of revenue | Sum of all Income charges × Price |
| Expense | Percentage of costs | Sum of all Expense charges × Price |
| Profit | Percentage of profit | (Income - Expense) × Price |
| IncomeFreight | Percentage of freight revenue | Sum of Income charges with ItemType=Freight × Price |
Relationships (Navigation Properties)
| Relationship | Type | Description |
|---|---|---|
| Orders | ICollection<Order> | Orders associated with this charge |
| OrderCharges | ICollection<OrderCharges> | Junction table for order-charge relationships |
| AccountingTransactions | ICollection<AccountingTransaction> | Accounting transactions including this charge |
| AccountingTransactionCharges | ICollection<AccountingTransactionCharges> | Junction table for transaction-charge relationships |
| AccountingItem | AccountingItem | Chart of accounts code |
| ApplyToContact | Contact | Customer or vendor |
| Currency | Currency | Currency for amounts |
| SalesTax | SalesTax | Sales tax definition |
| Rate | Rate | Rate used for pricing |
| Organization | Organization | Parent 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
AllowAutomaticUpdateflag unlessforceUpdate = true - Skips calculation if ChargeStatus is Paid or Void
- Calls
ApplyTariffInfo()→SetAmounts()
- Respects
Amount Calculation (Private)
SetAmounts()- Calculate Amount, SalesTaxAmount, TotalAmountAmount = 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 ApplyByApplyTariffForCalculated(CalculatedOfTypes?)- Calculate quantity for percentage-based chargesApplyTariffForContainer(TariffOptions)- Calculate quantity for container chargesApplyPriceBounds(TariffOptions)- Enforce minimum/maximum price limitsApplyBaseCharge(TariffOptions)- Add base charge to totalApplyMinimumChargeableWeight(TariffOptions)- Enforce minimum chargeable weightApplyRateWorkflow()- Add rate workflow quote amounts to charge
Commodity Aggregation (Private)
GetCommoditySum(Func<Commodity, decimal?>)- Sum commodity values, filtering by BillToContactIdGetContainerCommoditySum(Func<Commodity, decimal?>)- Sum values from both containers and standalone items
Property Updates
ChangePrice(decimal)- Update unit priceChangeQuantity(decimal)- Update quantity (rounds to 4 decimals)ChangeAmount(decimal)- Manually set amount, recalculate totalChangeChargeStatus(ChargeStatus)- Update statusChangeChargeType(ChargeType)- Change type (Income, Expense, Credit)ChangeApplyBy(ApplyBy)- Change calculation methodChangeApplyToContactId(int)- Change customer/vendorChangeAccountingItemId(int)- Change GL accountChangeCurrencyId(int)- Change currencyChangeSalesTaxId(int?)- Change tax codeChangeSalesTaxRate(decimal)- Update tax rateChangeDescription(string?)- Update descriptionChangeNote(string?)- Update notesChangeUnit(string?)- Update unit of measureChangeIsConsolidated(bool)- Set consolidated flagChangeShowInDocuments(bool)- Set visibility flagChangePaidAs(PaidAs)- Set prepaid/collectChangeAllowAutomaticUpdate(bool)- Enable/disable auto-recalculationChangeRateId(int?)- Set rate referenceChangeCalculatedOf(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 associationsChangeAccountingTransactions(IEnumerable<AccountingTransaction>)- Set transaction collectionChangeOrders(IEnumerable<Order>)- Set order collectionChangeApplyToContact(Contact?)- Set customer/vendor objectChangeSalesTax(SalesTax?)- Set tax objectChangeAccountingItem(AccountingItem?)- Set accounting item objectChangeCurrency(Currency?)- Set currency objectSetRate(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 organizationChangeChargeId(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: truefor charges that should recalculate when commodities change (quotes, dynamic pricing) - Use
allowAutomaticUpdate: falsefor locked charges (accepted quotes, fixed pricing, manual overrides) - Call
Calculate(forceUpdate: true)to recalculate even whenallowAutomaticUpdateis 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
BillToContactIdon commodities for multi-customer shipments - Create separate charge for each customer with matching
ApplyToContactId - System automatically filters commodities by
BillToContactIdduring calculation - Enables accurate per-customer billing in consolidated shipments
6. Sales Tax Integration
- Set
SalesTaxIdfor automatic tax rate lookup - Or set
SalesTaxRatedirectly (e.g., 0.0825 for 8.25%) - Tax calculated automatically in
SetAmounts():SalesTaxAmount = Amount × SalesTaxRate TotalAmountincludes tax:Amount + SalesTaxAmount
7. Tariff Integration
- Link charge to Rate via
RateIdfor automatic pricing Calculate()applies tariff rules fromRate.TarifforAccountingItem.Tariff- Tariff provides: pricing tiers, min/max bounds, base charges, minimum chargeable weight
8. Price Bounds and Minimums
- Define
MinimumandMaximumon 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.DecimalPlacesfor 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: truefor customer-facing charges (freight, fees) - Set
showInDocuments: falsefor 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
Related Topics
- AccountingTransaction Entity - Invoices and bills containing charges
- AccountingTransactionCharge Entity - Junction table for transaction-charge relationships
- OrderCharge Entity - Junction table for order-charge relationships
- AccountingItem Entity - Chart of accounts codes
- SalesTax Entity - Tax definitions and rates
- Rate Entity - Pricing rates and tariffs
- Tariff Entity - Pricing rule definitions
- Contact Entity - Customers and vendors
- Commodity Entity - Freight items used in calculations
- Order Entity - Orders containing charges
- Currency Entity - Currency definitions
- Entity System Overview - Aggregate root patterns and architecture