| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Sales (sale_management) • Invoicing (account) • Purchase (purchase) |
| Community Apps Dependencies | Show |
| Lines of code | 9576 |
| Technical Name |
eh_log_disputes_variations |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Sales (sale_management) • Invoicing (account) • Purchase (purchase) |
| Community Apps Dependencies | Show |
| Lines of code | 9576 |
| Technical Name |
eh_log_disputes_variations |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
Disputes and Variations
Cargo claims and post-confirmation scope changes, filed against any operational record, with an append-only audit trail and a clean apply-back to the sale order.
Why this module
Disputes and Variations
File against what actually went wrong
A dispute or variation attaches to a sale order, freight job, transport trip, last-mile delivery, warehouse receipt or pick, ship disbursement account, or container. The source model is checked against an allow-list and the target record must exist, so a typo cannot create a dangling pointer.
Append-only history, locked at the field level
Every dispute transition appends an event row. Events cannot be deleted, and key fields (dispute, type, timestamp, from and to state, company) are immutable after creation. State changes go only through action methods, never a raw write, so the record reads the same to an auditor as it did the day it closed.
Variations write back to the sale order
A variation captures priced lines that net to a delta, moves through submit, approve and apply, then posts those lines onto the resolved sale order so the customer invoice picks up the revised charges. Applied lines are recorded against the variation for a later reversal, and lines lock once the variation is approved.
Day in the life
A coordinator turns a damaged-cargo email into a closed, documented claim.
A consignee reports water damage on a container. The coordinator opens a dispute from the freight job itself, picks the Cargo Damage category (which carries a thirty-day SLA and a survey requirement), and records the claimed amount. The SLA target is computed from the open date; the daily cron will flag the case if it drifts past the window. Investigation starts, a surveyor report is attached, and an offer is tendered. The system refuses an offer above the claimed amount. The customer accepts, the claim is settled at the offered figure, and a settlement letter prints from the record. Every step, from open to close, is sitting in the append-only event log and on the dispute notice PDF, with nothing editable after the fact. Meanwhile a separate re-routing request on a different job becomes a variation: two priced lines, an approval, and an apply step that drops the revised charges straight onto the sale order.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
The polymorphic link is validated twice: the source model must be in the eight-model allow-list, and the target record must actually exist. A dispute cannot point at a model the suite does not track or at a record that was never created.
An offered amount greater than the claimed amount is rejected by constraint. You cannot tender a settlement that exceeds what the customer asked for, which keeps the negotiation gap honest and the exposure tile correct.
The dispute and variation state machines only permit the transitions defined in their allow-lists. Trying to settle a dispute that was never accepted, or apply a variation that was never approved, raises a state-conflict error instead of silently corrupting the record.
Dispute events are append-only. They cannot be created outside the dispute's own action methods, their core fields are immutable after creation, and they cannot be deleted. The history is the history.
Variation lines are mutable while the variation is draft or submitted and lock the moment it is approved. A reduction line carries a negative unit price by design, so a variation can both add and remove charges in one document.
Apply resolves the sale order from the polymorphic source: a sale-order source is itself, a freight job or other source resolves to its linked sale order. If no sale order can be resolved, apply refuses rather than writing charges into thin air.
The eight shipped dispute categories cannot be renamed or deleted, only archived. Your own added categories stay fully editable, so reporting built on the seeded codes does not break under you.
What is inside
Built to do the job, end to end.
- Disputes desk. A dispute model with a ten-state machine (opened, investigating, offered, accepted, settled, rejected, escalated, written off, closed, cancelled), claimed, offered and settled amounts, a computed open-exposure figure, a survey-attached check, and an append-only event log.
- Variations desk. A variation model with a seven-state workflow (draft, submitted, approved, applied, rejected, closed, cancelled), priced lines that net to a delta, negative lines for reductions, and an apply step that posts lines onto the resolved sale order and records them for reversal.
- Seeded categories and SLA. Eight dispute categories ship as data (cargo damage, loss, short shipment, pricing, demurrage and detention, documentation, customs penalty, other), each with a default SLA-day window and a survey-required flag. A daily cron schedules a warning activity on any overdue, non-terminal dispute.
- Three PDF documents. A dispute notice (financials plus the full event log), a settlement letter, and a variation order with a priced line table and a signature block, all rendered through the suite's shared report layout.
- Operational integration. Sale orders and freight jobs gain dispute and variation count fields with drill-down actions, so claims and change orders are visible and openable from the records they belong to.
- Bulk handling and isolation. Mass-settle and mass-write-off wizards process selections and report what moved versus what was skipped. Global record rules isolate disputes, events and variations per company, and access is governed by the suite's existing logistics groups.
Honest about the edges
What this does not do, so nothing surprises you.
- This is a claims and change-control desk, not a customs or compliance engine. Customs penalty is a dispute category only. There is no HS-code validation, no customs declaration fields, no duty calculation, and no EDI messaging.
- The Variation Approval Limit setting is present in configuration but is not yet enforced in the approval logic. Approval is driven by the suite's standard groups and the state machine, not by an automatic amount threshold.
- Variation apply posts lines onto the sale order. Reversal data (the applied lines) is recorded for a future cancellation, but a one-click automatic reversal of an applied variation is not shipped.
- Disputes record claimed, offered and settled amounts but do not post accounting entries. Financial impact lives on the dispute and its documents; it does not create journal entries or credit notes by itself.
- The module depends on the ERP Heritage logistics base, quotation and freight modules. It extends that suite and is not a standalone install on a bare Odoo database.
- Demurrage and detention are handled as a dispute category and free-text context, not as a calculated free-time or per-day charge engine.
Odoo 19 freight forwarder disputes, cargo damage claim management, demurrage dispute Odoo, short shipment claim, customs penalty dispute, logistics change order, variation order Odoo, scope change sale order, 3PL claims management, settlement letter PDF, dispute notice document, append-only audit trail, multi-company logistics, Odoo 19 Community logistics suite, freight job dispute tracking
Please log in to comment on this module