Oversized Pallet Computation — Developer Guide
When freight dimensions exceed standard pallet limits, the rate engine automatically switches from **per-pallet pricing** to **per-kg/chargeable-weight pricing**.
Overview
Section titled “Overview”When freight dimensions exceed standard pallet limits, the rate engine automatically switches from per-pallet pricing to per-kg/chargeable-weight pricing. This prevents oversized freight from being undercharged at flat per-pallet rates.
Standard Pallet Dimensions
Section titled “Standard Pallet Dimensions”Source: pallet_master_types table (AU PLAIN) + JATT Scope of Assumptions Item 2.
| Dimension | Limit |
|---|---|
| Length | 120 cm (1200 mm) |
| Width | 120 cm (1200 mm) |
| Height | 120 cm (1200 mm) |
| Weight | 1,000 kg per pallet |
If any single item exceeds any of these limits, the freight is classified as oversized.
Priority Order (How the Engine Decides)
Section titled “Priority Order (How the Engine Decides)”1. Rate entry has EXPLICIT conditions (rate_entry_conditions table) → Condition evaluation takes priority → If conditions fail, skip to next candidate → If conditions pass, use that rate entry's pricing
2. Global oversize rule ENABLED + pallet method + no explicit dimension conditions → Check freight against standard pallet dimensions → If oversized → fall back to per-kg/chargeable-weight rate card → If within limits → use pallet rate normally
3. Global oversize rule DISABLED (ENFORCE_PALLET_OVERSIZE_RULE=false) → No automatic fallback — all freight uses pallet rates regardless of sizeConfiguration
Section titled “Configuration”Environment Variable
Section titled “Environment Variable”# .env / .env.devENFORCE_PALLET_OVERSIZE_RULE=true # default — oversized pallets fall back to per-kgENFORCE_PALLET_OVERSIZE_RULE=false # disable — allow any size at pallet ratesDatabase: pallet_master_types
Section titled “Database: pallet_master_types”The standard dimensions come from this table:
SELECT default_length_mm, default_width_mm, default_height_mmFROM pallet_master_typesWHERE code = 'AU_PLAIN';
-- Returns: 1165mm × 1165mm × 150mm (converted to cm in code, rounded up to 120cm)If the table is empty or missing, the code falls back to hardcoded defaults: 120×120×120cm.
Computation Flow
Section titled “Computation Flow”Step 1: Rate Card Selection
Section titled “Step 1: Rate Card Selection”The engine calls _find_matching_rate_entries() which returns ALL candidate rate entries for a zone pair, ordered by preference:
- Customer-specific rate entries first
- Global rate entries second
- Within each group, entries matching
charging_typeare preferred
Step 2: Conditions Eligibility Filter
Section titled “Step 2: Conditions Eligibility Filter”For each candidate, the engine evaluates conditions from rate_entry_conditions:
packaging_type— allowed packaging typestransport_configuration— allowed vehicle configstime_window_pickup— pickup time restrictionsfreight_dimensions— min/max length, width, height, weight, volume
The first candidate whose conditions all pass is selected.
Step 3: Global Oversize Check
Section titled “Step 3: Global Oversize Check”If the selected rate entry:
- Uses a pallet calculation method (
pallet,per_pallet,quantity) - Has no explicit
freight_dimensionsconditions (explicit conditions already handled in Step 2) - And
ENFORCE_PALLET_OVERSIZE_RULEistrue
Then each item is checked against standard dimensions:
for item in items: if (length_cm > 120 or width_cm > 120 or height_cm > 120 or weight_kg > 1000): # OVERSIZE DETECTED → fall back to per-kgStep 4: Per-KG Fallback
Section titled “Step 4: Per-KG Fallback”If oversize is detected, the engine:
- Skips the pallet rate entry (logs it in
skipped_entries) - Re-searches for rate entries with
charging_type='weight' - Filters out any pallet-method entries from the fallback results
- Uses the first per-kg entry whose conditions pass
- Computes pricing based on chargeable weight
Pricing Comparison Example
Section titled “Pricing Comparison Example”Route: Melbourne → Brisbane | Cargo: 8 Pallets
| Standard Pallet | Oversized Pallet | |
|---|---|---|
| Dimensions | 120×120×120cm | 150×150×200cm |
| Weight each | 100 kg | 500 kg |
| Rate Card | JATT Pallet Rates | JATT Per KG Rates |
| Method | Per pallet (tier) | Per kg (chargeable weight) |
| Tier | 5-12 Pallets @ $269.94 | 751kg+ @ $0.29/kg |
| Chargeable wt/pallet | 180 kg (volumetric) | 1,125 kg (volumetric) |
| Total chargeable | 1,440 kg | 9,000 kg |
| Base rate | $15.00 | $15.00 |
| Item charges | 8 × $269.94 = $2,159.52 | 9,000 × $0.29 = $2,610.00 |
| Subtotal | ~$2,174.52 | ~$2,625.00 |
The ~$450 difference reflects the additional truck space consumed by oversized pallets.
Chargeable Weight Calculation
Section titled “Chargeable Weight Calculation”Per pallet: Volume (m³) = (L × W × H) / 1,000,000 Volumetric weight = Volume × cubic_factor (default 250) Dead weight = actual weight in kg Chargeable weight = max(volumetric_weight, dead_weight)
Total chargeable = sum(chargeable_weight × quantity) for all itemsStandard: (120×120×120) / 1,000,000 × 250 = 0.432 m³ × 250 = 108 kg volumetric. Dead = 100 kg. Chargeable = 108 kg. But actual pallet rate ignores this — charges per pallet.
Oversized: (150×150×200) / 1,000,000 × 250 = 4.5 m³ × 250 = 1,125 kg volumetric. Dead = 500 kg. Chargeable = 1,125 kg × 8 = 9,000 kg total.
Rate Card Data (JATT Reference)
Section titled “Rate Card Data (JATT Reference)”JATT Pallet Rates (per pallet, tiered by quantity)
Section titled “JATT Pallet Rates (per pallet, tiered by quantity)”| Tier | Price/Pallet (Melb→Bris) |
|---|---|
| 1-4 Pallets | $276.40 |
| 5-12 Pallets | $269.94 |
| 13+ Pallets | $263.48 |
Used when all items are within standard dimensions.
JATT Per KG Rates (per chargeable kg, tiered by weight)
Section titled “JATT Per KG Rates (per chargeable kg, tiered by weight)”| Tier | Rate/kg (Melb→Bris) |
|---|---|
| Base rate | $15.00 |
| Minimum charge | $37.50 |
| Up to 500 kg | $0.38/kg |
| 501-751 kg | $0.34/kg |
| 751+ kg | $0.29/kg |
Used as fallback when pallet dimensions are exceeded.
JATT Standard Pallet Assumptions (from Scope of Assumptions)
Section titled “JATT Standard Pallet Assumptions (from Scope of Assumptions)”Item 2: “Standard Pallet Dimensions — 1.2 x 1.2 x 1.2, Weight 1000 Kg”
API Response — What Changes
Section titled “API Response — What Changes”When the oversize rule fires, the compute-rate response includes:
{ "computation": { "rate_card_name": "JATT Per KG Rates", "calculation_steps": [ "Skipped: JATT Pallet Rates (Entry 456) — Freight exceeds global standard pallet dimensions", "OVERSIZE: Item 150x150x200cm/500kg exceeds standard 120x120x120cm/1000kg", "Global rule: pallet rate 'JATT Pallet Rates' skipped — falling back to per-kg/chargeable-weight", "Fell back to: JATT Per KG Rates (ID: 18, method: weight)" ], "skipped_entries": [ { "rate_card_name": "JATT Pallet Rates", "rate_entry_id": 456, "reason": ["Freight exceeds global standard pallet dimensions"] } ], "totals": { "initial_cost": 15.00, "base_charge": 2610.00, "final_total": 2610.00 } }}Code Reference
Section titled “Code Reference”| File | Function/Section | Purpose |
|---|---|---|
api/rate_entries_api.py | compute_rate() ~line 1790 | Global oversize check block |
api/rate_entries_api.py | _find_matching_rate_entries() ~line 2366 | Returns all candidate rate entries |
api/rate_entries_api.py | _evaluate_conditions() ~line 2474 | Condition evaluation (all types) |
api/rate_entries_api.py | _get_au_plain_dimensions() ~line 2829 | Fetch standard pallet dims from DB |
migrations/create_pallet_schema.sql | pallet_master_types table | Standard pallet definitions |
Adding Custom Oversize Rules
Section titled “Adding Custom Oversize Rules”Option A: Per-Rate-Entry Conditions (takes priority over global rule)
Section titled “Option A: Per-Rate-Entry Conditions (takes priority over global rule)”Add a freight_dimensions condition to a specific rate entry via the API:
POST /api/rate-entries/{id}/conditions{ "applies_to": {"type": "freight_dimensions"}, "max_length_cm": 200, "max_width_cm": 200, "max_height_cm": 250, "max_weight_kg": 2000}This rate entry will only match freight within those dimensions. The global rule won’t fire because explicit dimension conditions exist.
Option B: Addons for Surcharges
Section titled “Option B: Addons for Surcharges”Add an “Oversized Item Surcharge” addon via the Unified Addons system:
- Addon Type: Surcharge
- Value Type: Fixed amount (e.g., $85.00)
- Trigger Mode: Manual (operator selects when needed)
- Applies On: Subtotal
This surcharge is applied ON TOP of whichever rate card is used (pallet or per-kg).
Option C: Disable Global Rule Entirely
Section titled “Option C: Disable Global Rule Entirely”ENFORCE_PALLET_OVERSIZE_RULE=falseAll pallets will be charged at pallet rates regardless of dimensions. Use explicit conditions on individual rate entries to control oversize behavior.