Skip to content

Delivery Manifests & Fulfillment

This guide covers the full workflow for picking, packing, and completing customer deliveries using delivery manifests in the Device Inventory module.


Overview

Delivery manifests track device-level picking and shipping for sales orders. Each manifest contains one line per allocated device (IMEI), and the manifest drives the full fulfillment chain: picking, optional packing, COGS accounting, customer invoicing, and settlement report generation.

Manifests are auto-created when a device-enabled SO is confirmed. Operators interact with them through barcode scanning or manual line updates, and marking a manifest complete triggers all downstream accounting and settlement steps automatically.

Delivery Manifests List


Auto-Creation on SO Confirmation

When a sales order with device allocations is confirmed (action_confirm() is called), the system automatically creates a delivery manifest of type 'delivery':

  • One device.manifest record is created and linked to the SO via sale_order_id.
  • One device.manifest.line record is created for each sale.order.line.device allocation, pre-filled with the device IMEI, product, and specs.
  • Manifest state starts at draft.

After confirmation the SO status changes to Sales Order and the delivery manifest is immediately ready for picking.


Step 1: Pick Devices

Path: Open the delivery manifest from the SO smart button, or navigate to Inventory → Device Inventory → Sales → Delivery Manifests.

Manifest Form

Barcode Scanning

Each scan calls _quick_pick(lot) on the matching manifest line. The method validates:

  • The scanned IMEI exists in the system as a stock.lot record.
  • The device matches the IMEI expected on the manifest line.
  • The device status is available or reserved — devices that were already picked cannot be re-scanned.
  • Owner/consignment authorization is confirmed (the device's owning company must match the consignment agreement on the SO).

On a successful scan: - Manifest line status'received' - stock_lot_id is linked on the manifest line - received_count increments and progress_percent updates

Manual Picking

Manifest lines can also be matched manually by selecting the device from the stock_lot_id field on each line and saving. This has the same effect as a barcode scan.


Step 2: Pack Devices (Optional)

Path: Inventory → Device Inventory → Warehouse Operations → Packing Boxes

Packing boxes group physical devices into shipping containers before dispatch.

  • Create a packing box and scan or assign devices into it.
  • Box states: draftpackingreadyshipped
  • The box tracks device count, weight, and dimensions.
  • Shipping labels with barcodes can be printed from the box form.
  • The manifest's packing_box_ids smart button shows the count of boxes associated with the order.

Packing is optional. Manifests can be marked complete without creating packing boxes.


Step 3: Mark Manifest Complete

Click Mark Complete on the manifest form when all devices have been picked.

action_mark_complete() runs the following sequence:

1. Validate Delivery Quantities

_validate_delivery_quantities() is called first. It compares the number of picked devices against the quantities on the SO lines and raises a UserError if picking exceeds what was ordered. This prevents over-delivery.

2. Process Customer Delivery

_process_customer_delivery() is the main processing method. It executes in order:

a. Mark devices as sold

Each picked device has action_mark_sold() called on it. This transitions the device's device_status from reservedsold and records the sale date and sale order reference on the stock.lot record.

b. Create COGS GL entry

_create_cogs_accounting_entry() posts the cost-of-goods-sold journal entry (see Accounting section below). The resulting account.move is stored on cogs_move_id.

c. Create settlement reports (consignment only)

If the SO contains consignment devices (devices owned by Axis Mobile), _create_settlement_reports() is called. It creates two paired consignment.settlement.report records: one owner report (Axis Mobile's view) and one consignee report (Reyder's view). This method uses .sudo() internally to cross the company boundary when writing the owner-side report. Both reports are auto-confirmed. See Settlement Reports for full details.

d. Create customer invoice

_create_customer_invoice() calls Odoo's standard sale_order._create_invoices() method to generate an out_invoice with one line per SO product. The invoice is auto-posted. The resulting account.move is stored on customer_invoice_id.

3. Set State to Done

After successful processing, manifest state'done'.


Accounting on Delivery Complete

COGS Entry

Debit   Device COGS Account (expense)           $X,XXX.XX
  Credit  Device Valuation Account (asset)         $X,XXX.XX
  • Amount: Sum of purchase_cost for all picked devices
  • Journal: Device Stock Journal
  • Auto-posted: Yes
  • Stored on: device.manifest.cogs_move_id
  • Skipped (idempotent) if cogs_move_id is already set

Customer Invoice

  • Uses standard Odoo sale_order._create_invoices()
  • Creates out_invoice (customer invoice) with one line per SO product
  • Price = sale price from the SO line
  • Accounts = standard Odoo product revenue account + AR
  • Auto-posted: Yes
  • Stored on: device.manifest.customer_invoice_id

Settlement Reports (consignment devices)

Two reports are created automatically: - Owner report (Axis Mobile): shows IMEI, model, storage, grade, commission rate, and owner amount. Customer name, SO number, and sale price are intentionally omitted. - Consignee report (Reyder): full details including customer, SO, and sale price.

Both reports are auto-confirmed, which triggers creation of a vendor bill for the owner amount. See Settlement Reports for report structure and data separation details.


Inter-Company Delivery

For inter-company transfers, delivery manifests operate slightly differently:

  • When the manifest is marked complete, _create_buyer_receiving_manifest() is called to auto-create a mirror receiving manifest in the buyer's (destination) company.
  • The COGS GL entry is created in the seller's company books.
  • The customer invoice is created as an inter-company out_invoice in the seller's company. Odoo's inter-company invoice mirroring then auto-creates a draft in_invoice (vendor bill) in the buyer's company.

Smart Buttons on Manifest

Button Description
Received Devices Count of devices with status = 'received' on this manifest
Packing Boxes Count of packing.box records linked to this manifest's SO
Journal Entries GL entries created (COGS move and any related entries)
Sale Order Link back to the originating sale.order
Purchase Order Link to the originating purchase.order (if applicable)

Key Fields Reference

Field Description
manifest_type 'delivery' for outbound customer shipments; 'receiving' for inbound
sale_order_id Link to the originating sale order
state draftin_progressdone
cogs_move_id Link to the COGS journal entry (account.move) created on completion
customer_invoice_id Link to the customer invoice (account.move) created on completion
account_move_id Link to the inventory receipt GL entry (used on receiving manifests)
expected_count Number of devices expected based on SO allocation
received_count Number of manifest lines with status = 'received'
progress_percent received_count / expected_count × 100 — picking progress indicator


Last updated: 2026-03-04 | Module version: 19.0.2.14.0