Delivery status and dates

Odoo’s standard Sales app already tracks whether a confirmed order is Not Delivered, Started, Partially Delivered or Fully Delivered, based purely on the state of its linked delivery orders. In day-to-day operations this is not quite enough: warehouse and sales teams also need to know how much of an order has physically gone out, when the last shipment left, and what to do with a delivery that will never exactly match the ordered quantity (bulk or liquid goods) or that was cancelled outright. Separately, on Hungarian companies the accounting rules require an invoice’s posting date and its delivery (fulfillment) date to match exactly, which the standard stock/invoicing integration can silently break on corrective invoices. This page documents the two eYssen modules that close these gaps.

Delivery status on the sales order

Sales order form showing the Delivery Status, Delivery % and Last Delivery Date fields

On a confirmed order, the Delivery group of the Other Info tab shows three complementary indicators, right after the standard Delivery Status field:

  • Delivery % — the percentage of the ordered quantity that has actually been delivered, computed from qty_delivered versus product_uom_qty across all order lines whose product is not a service. It is only shown while the order is confirmed.

  • Last Delivery Date — the completion date/time of the most recent done, outgoing delivery linked to the order (picking_ids filtered on state == 'done' and picking_type_code == 'outgoing'). It only reflects deliveries that already left the warehouse — not the first delivery (that is the standard effective_date field, still shown separately).

Both fields are stored and recompute automatically whenever the order lines or its transfers change, so they can be used directly in filters, groupings and the reporting dashboard described below.

Cancelled deliveries

The standard Delivery Status field only distinguishes Not Delivered, Started, Partially Delivered and Fully Delivered — a fully cancelled order still shows as Not Delivered. This module adds a fifth value, Cancelled: whenever an order has at least one delivery and every one of its transfers is in the Cancelled state, the order’s delivery status is shown as Cancelled instead.

Note

The field’s built-in help text (“Blue: Not Delivered/Started, Orange: Partially Delivered, Green: Fully Delivered”) is Odoo’s own and is not extended for the new state. In the list and Kanban views added by this module, Cancelled is shown with a red (danger) color to keep it visually distinct from the other three.

Manual “Fully Delivered” override

Confirmed order header with the "Fully Delivered" override button

For bulk or liquid goods, the delivered quantity almost never matches the ordered quantity to the last decimal, so the computed status stays Partially Delivered forever even though the delivery is, for all practical purposes, complete. The Fully Delivered header button lets a user override this manually on a confirmed order:

  1. Click Fully Delivered in the order’s header. This sets the technical Forced Fully Delivered flag (force_full_delivery) and immediately recomputes the delivery status to Fully Delivered, regardless of the actual delivered quantities. A chatter message records that the status was manually forced.

  2. The button is only available on confirmed orders whose current status is not already Fully Delivered or Cancelled, and disappears once the override is active.

  3. A Reset Delivery Status button then appears in its place. Clicking it clears the override and lets the status recompute from the real delivered quantities again, also logging a chatter message.

Order header after the override, showing the Reset Delivery Status button

Important

The override never touches stock: no picking, move or backorder is created, cancelled or validated by either button. It only changes what the Delivery Status field reports. A Cancelled order always takes priority over the override — if every delivery on the order is cancelled, the status shows Cancelled even while Forced Fully Delivered is set.

Delivery status in list and search views

Orders list view with color-coded Delivery Status badges and optional columns

The Delivery Status column is enabled by default (colored badge: green for Fully Delivered, orange for Partially Delivered, blue for Not Delivered/Started, red for Cancelled) on both the Sales ‣ Orders list and the Quotations list. Delivery % and Last Delivery Date are added to both lists as optional (hidden by default) columns, toggled from the column-picker.

Search panel Filters showing the five delivery-status filters and the Group By option

The order search panel gains one filter per delivery status — Not Delivered, Delivery Started, Partially Delivered, Fully Delivered and Delivery Cancelled — plus a Last Delivery Date date filter and a Group By: Delivery Status option.

Delivery-status dashboard

Delivery Status reporting list view

A dedicated reporting menu, Sales ‣ Reporting ‣ Delivery Status, gives a cross-order view limited to confirmed orders (state = 'sale'). Its list view combines the order reference, customer, order date, Commitment Date, Expected date (expected_date), First Delivery (the standard effective_date), Last Delivery (last_delivery_date), the Delivery Status badge, the Delivery % progress bar, the order total and the salesperson.

Delivery Status reporting pivot view

The same action also offers Pivot and Graph views: the pivot breaks down Delivery % and the order total by delivery status (columns) and order month (rows); the graph shows total order value per delivery status as a bar chart.

Actual customer receipt date

Beyond the sales order, this module also adds an Actual Customer Receipt Date (delivered_date) field on the delivery (stock.picking) itself. It is a technical, read-only field, not exposed on any view by this module — it exists to record the moment the consumer actually took delivery of the goods (as reported by carrier tracking), which can be noticeably later than date_done (when the warehouse validated the transfer and handed it to the carrier).

The field is populated through the idempotent _set_delivered() hook, which:

  • only applies to outgoing transfers whose destination location is a customer location;

  • silently ignores an empty/falsy timestamp; and

  • never overwrites an existing value — the first confirmed receipt is authoritative, later calls with a different timestamp are no-ops.

Note

eyssen_sale_delivery_status only defines the field and this hook; it is the carrier-tracking integrations (e.g. GLS, Foxpost, MPL delivery methods) that call _set_delivered() once they detect an actual-delivery tracking event, and other eYssen modules (such as the RMA return-window logic) that read the resulting date. Consult those modules’ own documentation for details.

Hungarian invoice fulfillment-date consistency

Hungarian customer invoice showing the Delivery Date field aligned with the Date field

Odoo’s core accounting keeps a Delivery Date field (delivery_date) on every invoice. When the Inventory app is installed, sale_stock automatically syncs that field to the linked sale order’s Effective Date (the completion date of its first delivery) every time the invoice is recomputed. Separately, eyssen_l10n_hu enforces a Hungarian NAV requirement on posting: for a Hungarian company, an invoice’s accounting Date and its Delivery Date must be identical, or Post refuses with “The Accounting Date is not the same as the Fulfillment Date!”. To satisfy this, corrective invoices and credit notes are made to inherit both dates directly from the original invoice they correct or reverse.

The problem this module solves is a compute-ordering one: because sale_stock’s own Delivery Date recompute always tries to re-stamp the field from the sale order’s effective date, that logic can run after eyssen_l10n_hu’s “inherit from the original invoice” logic depending on the exact combination of installed apps — silently pulling a corrective invoice’s delivery date away from the original invoice’s date again, and breaking the accounting-date / delivery-date match at Post time.

eyssen_l10n_hu_sale_stock_delivery_date is a small, dependency-only module (it adds no views, menus or new fields) that depends on both sale_stock and eyssen_l10n_hu. Depending on both guarantees its account.move._compute_delivery_date() override runs after sale_stock’s, so the corrective-invoice logic always has the final say:

  • moves that are already Posted are left untouched (recomputing delivery_date on a posted, already-hashed entry must never happen);

  • on any other move, if it has a Corrected Invoice or is a reversal (reversed_entry_id), both Delivery Date and Date are forced to the original invoice’s delivery date, undoing any stock-driven re-sync; and

  • as a general safety net, if Delivery Date and Date still disagree afterward, Date is aligned to Delivery Date (or vice-versa if Delivery Date is empty).

Important

This logic is intentionally duplicated, line for line, between eyssen_l10n_hu and eyssen_l10n_hu_sale_stock_delivery_date — the module’s own code comments say so explicitly. If this behavior is ever changed, both modules must be updated together, or a Hungarian company with both sale_stock and eyssen_l10n_hu installed but this module missing can end up with the exact desync it was written to prevent.

Configuration

Both modules are ordinary Odoo apps, installed from Apps; neither has a Settings toggle.

  • Sale Delivery Status (eyssen_sale_delivery_status) depends on sale_management, stock and sale_stock. Installing it is enough to get the extra fields, list/search additions and the reporting menu — there is nothing further to configure.

  • eYssen Sale Stock Delivery Date (eyssen_l10n_hu_sale_stock_delivery_date) depends on sale_stock and eyssen_l10n_hu, and is not auto-installed and not required by any other eYssen module. Install it explicitly on any Hungarian company (eyssen_l10n_hu installed) that also uses stock-driven sales invoicing (sale_stock) — otherwise corrective invoices on that database remain exposed to the fulfillment-date desync described above.

Tip

The Fully Delivered and Reset Delivery Status buttons and the delivery fields on the order form require no security group beyond ordinary access to Sales orders — there is no dedicated permission for this feature.

Usage

  1. Confirm a sales order with a delivery route as usual. As transfers are validated, the standard Delivery Status, plus this module’s Delivery % and Last Delivery Date, update automatically on the order’s Other Info tab.

  2. If every delivery on the order ends up cancelled, the status switches to Cancelled instead of staying at Not Delivered.

  3. For bulk/liquid goods that will never reach exactly 100%, click Fully Delivered in the header once the shipment is effectively complete; click Reset Delivery Status later if the override needs to be undone.

  4. Use the Filters and Group By: Delivery Status options on Sales ‣ Orders, or the dedicated Sales ‣ Reporting ‣ Delivery Status dashboard, to review delivery progress across orders.

  5. On Hungarian companies with both modules installed, correcting or reversing an invoice keeps its Delivery Date and Date aligned with the original invoice automatically — no manual date entry is needed on the corrective invoice itself.

Scope and modules

  • eyssen_sale_delivery_status — adds the Delivery %, Last Delivery Date and Cancelled delivery status to sale orders, the manual Fully Delivered override, the delivery-status search filters and list columns, the Sales ‣ Reporting ‣ Delivery Status dashboard, and the Actual Customer Receipt Date field on deliveries.

  • eyssen_l10n_hu_sale_stock_delivery_date — keeps a Hungarian corrective/reversal invoice’s Delivery Date (fulfillment date) aligned with its original invoice, independent of the sale order’s stock-driven effective date, so the NAV accounting-date/delivery-date rule enforced by eyssen_l10n_hu keeps holding at Post time.