Skip to content

[14.0][16.0][stock_move_backdating] _create_backorder returns None instead of empty Recordset causing crashes #2266

@mktsrl

Description

@mktsrl

Module

stock_move_backdating

Describe the bug

The method _create_backorder in models/stock_picking.py overrides the standard behavior. However, when the condition regarding date_backdating is met, the method ends without an explicit return statement. In Python, this results in returning None.
This behavior breaks compatibility with other modules (e.g., l10n_it_delivery_note) that extend _create_backorder and expect the standard Odoo return type (a stock.picking Recordset), causing TypeError: 'NoneType' object is not iterable downstream.

def _create_backorder(self):
    # When a move needs backdating,
    # we are processing the moves of a picking one by one,
    # so we don't have to create a backorder if a move is missing
    if "date_backdating" not in self.env.context:
        return super()._create_backorder()

To Reproduce

Affected versions: 14.0 (and potentially 16.0)

Steps to reproduce the behavior:

  1. Install stock_move_backdating (and any module that iterates over the result of _create_backorder, such as l10n_it_delivery_note, to witness the crash).
  2. Create a Stock Picking (e.g., Receipt).
  3. Validate it (Done).
  4. Unlock the picking.
  5. Edit the operations, forcing a Effective Date in the past (this triggers the date_backdating context logic).
  6. Click Validate.

Result:
The method returns None. If another module tries to iterate over the result (e.g., for backorder in backorders:), it crashes with: TypeError: 'NoneType' object is not iterable.

Expected behavior
The method should return an empty Recordset self.env['stock.picking'] instead of None when skipping the super call, to maintain consistency with the Odoo API and prevent regressions in other modules.

Additional context
The issue stems from the fact that stock_move_backdating prevents the creation of a backorder when backdating is active in the context.
I haven't deeply investigated how/where the date_backdating context is injected, but the override in this module is definitely the source of the None return value

Suggested Fix:
Return an empty recordset explicitly.

def _create_backorder(self):
    if "date_backdating" not in self.env.context:
        return super()._create_backorder()
    return self.env['stock.picking']  # Return empty recordset instead of None

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions