Charges
Charges play an integral role in determining the expenses and income associated with orders. They are added to an order and subsequently posted to an invoice through the reconciliation process.
The Lifecycle of a Charge:
-
Creation:
- A charge is initially appended to an order
-
In Progress: Open or Pending
- "Open" status, signifying that it hasn't been invoiced yet.
- "Pending" status indicates it isn't ready for invoicing, perhaps because certain criteria haven't been met. For instance, the charge might be added, but the billed weight may not be available.
-
Invoicing: Posted
- Post-reconciliation, charges are transferred to the invoice.
- At this stage, the charge's status transitions to "Posted".
-
Payment: Paid
- Once the associated invoice is settled, the charge status updates to "Paid".
- Importantly, once marked as "Paid", a charge can neither be altered nor deleted.
Charge Details
- Charge can be 2 main types: Freight and General.
- Freight charges are used for freight-related items or services that are direct freight, e.g., Ocean Freight, Air Freight, Ground Freight, etc.
- General charges are used for items or services that don't fit under Freight or the other listed categories.
Freight Charges
Freight Charge is a charge that is related to the freight service. It can be either a cost or income. It uses rates to calculate the amount and order commodity to calculate the quantity. In addition, rate and quantity can be entered manually in the charge if needed.
Allow Automatic Update
If this option is enabled, the charge will be automatically updated when the order is updated. For example, if the order commodity is changed, the charge quantity will be updated accordingly.
General Charges
General Charge is a charge that is not related to the freight service. General charge rate can be copied from Accounting Items or it can be entered manually in the charge.
Fields:
- Accounting Item: Accounting item that is used to calculate the amount of the charge and to determine the account to which the charge will be posted.
- Tax Code: Tax code that is used to calculate the tax amount of the charge.
- Currency: Currency of the charge.
- Description: Description of the charge.
- Bill to Account: Customer Account to which the charge will be billed.
- Paid As: Determines how the charge will be paid. It can be either "Prepaid" or "Collect".
- Rate: Rate of the charge. _ (Freight Charge Only) _
- Apply By: Determines how the quantity will be calculated. Possible values: Pieces, Weight, Volume, Container, Calculated (%) _ (Freight Charge Only) _
- Is Consolidated: Determines whether the charge is consolidated or not.
- Show on Document: Determines whether the charge will be shown on the invoice or not.
- Allow Automatic Update: Determines whether the charge will be automatically updated when the order is updated. _ (Freight Charge Only) _
- Quantity: Quantity of the charge.
- Unit: Unit of the charge. Example: kg, m3, etc.
- Price: Price of the charge.
- Amount: Calculated amount of the charge. It is calculated as Quantity * Price.
- Notes: Notes of the charge. Notes are shown on the invoice.
Charge Calculation
How Quantity is Calculated
When Allow Automatic Update is enabled, the system automatically calculates the charge quantity based on the Apply By setting and order commodities.
Apply By Types
The Apply By field determines how the charge quantity is calculated from order commodities.
Flat Rate
- Quantity: Always 1
- Use Case: Fixed fees that don't depend on shipment size (documentation fees, handling charges, flat delivery fees)
- Calculation:
Quantity = 1 - Note: Price determines the total charge amount
Pieces
- Quantity: Total number of pieces from matching commodities
- Use Case: Per-piece handling, carton charges, piece-based storage fees
- Calculation:
- For containers: Sum of child commodity pieces (filtered by container and child
BillToContactId) - For standalone: Sum of commodity pieces (filtered by
BillToContactId)
- For containers: Sum of child commodity pieces (filtered by container and child
- Example:
Container (null) with:- 10 pieces (Customer A)- 5 pieces (Customer B)Customer A charge: 10 piecesCustomer B charge: 5 pieces
Weight
- Quantity: Total weight in kg or lb from matching commodities
- Use Case: Freight charges based on actual weight, weight-based storage
- Calculation:
- For containers: Sum of child commodity weight (filtered by container and child
BillToContactId) - For standalone: Sum of commodity weight (filtered by
BillToContactId) - Weight is converted to the rate's unit (kg or lb) before summing
- For containers: Sum of child commodity weight (filtered by container and child
- Example:
Container (null) with:- 100kg (Customer A)- 50kg (Customer B)- 5kg shared packing (null)Customer A charge: 100kg + 5kg = 105kgCustomer B charge: 50kg + 5kg = 55kg
Volume
- Quantity: Total volumetric weight from matching commodities
- Use Case: Volume-based freight (especially air freight), cubic meter charges
- Calculation:
- For containers: Sum of child commodity volume weight (filtered by container and child
BillToContactId) - For standalone: Sum of commodity volume weight (filtered by
BillToContactId) - Volume weight = (Length × Width × Height) / divisor
- Divisor typically 5000 for kg, 166 for lb (configurable)
- For containers: Sum of child commodity volume weight (filtered by container and child
- Example:
Container (null) with:- 2.5 m³ (Customer A)- 1.8 m³ (Customer B)Customer A charge: 2.5 m³Customer B charge: 1.8 m³
Chargeable Weight
- Quantity: Higher of actual weight or volumetric weight for each commodity, then summed
- Use Case: Standard freight pricing (ocean, air, ground) where both weight and volume matter
- Calculation:
- For each commodity:
max(actual weight, volumetric weight) - Then sum all chargeable weights (filtered by container and child
BillToContactId) - This ensures shipments pay for whichever dimension (weight or volume) is greater
- For each commodity:
- Example:
Container (null) with:- Item A: actual 100kg, volumetric 120kg → chargeable 120kg (Customer A)- Item B: actual 80kg, volumetric 60kg → chargeable 80kg (Customer A)Customer A charge: 120kg + 80kg = 200kg
- Why It Matters: Light but bulky items pay for space they occupy; heavy compact items pay for weight
Container
- Quantity: Count of containers by type
- Use Case: Container-specific charges (terminal handling, container rental, per-container fees)
- Calculation:
- Counts distinct containers matching the charge's container type filter
- Each container counts as 1 unit regardless of contents
- Filters by container's
BillToContactId
- Example:
Order with:- 2× 20ft containers (Customer A)- 1× 40ft container (Customer B)20ft Container Charge for Customer A: 2 containers40ft Container Charge for Customer B: 1 container
- Note: This is the ONLY Apply By type that counts container commodities themselves rather than children
Calculated
- Quantity: Percentage-based calculation from other charges
- Use Case: Commission fees, percentage-based markups, profit shares
- Calculation Types:
- Income: Percentage of total income charges on the order
- Expense: Percentage of total expense charges on the order
- Profit: Percentage of difference between income and expense
- Example:
Order with:- Freight charge: $1000 (income)- Handling: $200 (income)- Cost: $800 (expense)Commission (5% of Income): $1200 × 0.05 = $60Profit Share (10% of Profit): ($1200 - $800) × 0.10 = $40
Split Billing with BillToContactId
The system supports split billing where different commodities in the same order can be billed to different customers using the BillToContactId field on commodities.
How BillToContactId Works
- BillToContactId = null: Commodity is included in ALL charges (universal billing)
- BillToContactId = Customer A: Commodity is ONLY included in charges where
ApplyToContactId = Customer A
Example: Multi-Customer LCL Shipment
Order with 3 commodities:
├── Commodity A (30kg, BillToContactId = null) → Charged to ALL customers
├── Commodity B (50kg, BillToContactId = Customer 1) → Only Customer 1
└── Commodity C (70kg, BillToContactId = Customer 2) → Only Customer 2
Freight Charge 1 (ApplyToContactId = Customer 1, ApplyBy = Weight):
Quantity = 30kg (Commodity A) + 50kg (Commodity B) = 80kg
Freight Charge 2 (ApplyToContactId = Customer 2, ApplyBy = Weight):
Quantity = 30kg (Commodity A) + 70kg (Commodity C) = 100kg
Use Case: Co-loading where multiple customers share container space, each paying for their specific items plus shared materials.
Container Commodity Handling
When commodities are marked as containers (using Package Category with IsContainer = true), the system handles them specially:
Container vs. Standalone Commodities
The system processes commodities using two paths:
-
Container Path: For commodities where
PackageCategory.IsContainer = true- System drills down into child commodities (items inside the container)
- Uses child commodity properties (pieces, weight, volume)
- Filters based on both container and child
BillToContactId:- If container has
BillToContactIdset, only charges matching that customer include this container's children - Within that container, children are further filtered by their own
BillToContactId
- If container has
- Container's own properties (weight, pieces) are not counted - only children
-
Standalone Path: For regular commodities
- Uses commodity's own properties directly
- Filters by commodity's
BillToContactId
Example 1: Container with No BillToContactId (Shared Container)
Order:
└── Container Pallet (IsContainer = true, BillToContactId = null)
├── Child Item A (10 pieces, 20kg, BillToContactId = null)
├── Child Item B (5 pieces, 15kg, BillToContactId = Customer 1)
└── Child Item C (8 pieces, 25kg, BillToContactId = Customer 2)
Freight Charge (ApplyToContactId = Customer 1, ApplyBy = Pieces):
Container matches (null = any customer) → Check children:
Quantity = 10 pieces (Item A, null) + 5 pieces (Item B, Customer 1) = 15 pieces
Freight Charge (ApplyToContactId = Customer 2, ApplyBy = Weight):
Container matches (null = any customer) → Check children:
Quantity = 20kg (Item A, null) + 25kg (Item C, Customer 2) = 45kg
Use Case: LCL shipment where multiple customers share one container.
Example 2: Container Assigned to Specific Customer
Order:
├── Container A (IsContainer = true, BillToContactId = Customer 1)
│ ├── Child Item A1 (10 pieces, 20kg, BillToContactId = null)
│ └── Child Item A2 (5 pieces, 15kg, BillToContactId = Customer 1)
└── Container B (IsContainer = true, BillToContactId = Customer 2)
├── Child Item B1 (8 pieces, 25kg, BillToContactId = null)
└── Child Item B2 (3 pieces, 12kg, BillToContactId = Customer 2)
Freight Charge (ApplyToContactId = Customer 1, ApplyBy = Pieces):
Container A matches (Customer 1) → Check children:
10 pieces (A1, null) + 5 pieces (A2, Customer 1) = 15 pieces
Container B does NOT match (Customer 2) → Skip entire container
Total Quantity = 15 pieces
Freight Charge (ApplyToContactId = Customer 2, ApplyBy = Weight):
Container A does NOT match (Customer 1) → Skip entire container
Container B matches (Customer 2) → Check children:
25kg (B1, null) + 12kg (B2, Customer 2) = 37kg
Total Quantity = 37kg
Use Case: Full container loads (FCL) where each container belongs to one customer.
Example 3: Container with Mixed Child Ownership
Order:
└── Container (IsContainer = true, BillToContactId = Customer 1)
├── Child Item A (10 pieces, BillToContactId = null)
├── Child Item B (5 pieces, BillToContactId = Customer 1)
└── Child Item C (8 pieces, BillToContactId = Customer 2)
Freight Charge (ApplyToContactId = Customer 1, ApplyBy = Pieces):
Container matches (Customer 1) → Check children:
10 pieces (Item A, null) + 5 pieces (Item B, Customer 1) = 15 pieces
Item C is EXCLUDED (Customer 2 ≠ Customer 1)
Total Quantity = 15 pieces
Freight Charge (ApplyToContactId = Customer 2, ApplyBy = Pieces):
Container does NOT match (Customer 1 ≠ Customer 2) → Skip entire container
Total Quantity = 0 pieces
Important: Even though Child Item C has BillToContactId = Customer 2, it is NOT included in Customer 2's charge because the container itself belongs to Customer 1.
Important Notes:
- ✅ Container's
BillToContactIdcontrols which charges can access the container - ✅ Child
BillToContactIdprovides additional filtering within accessible containers - ✅ Container's pieces/weight are not counted - only child items are summed
- ✅
BillToContactId = nullmeans "any customer" at both container and child level