How to Implement _origin  in Odoo?
✅ What is _origin ?
In Odoo, every recordset has a special attribute called _origin, which refers to the original database record that a given record was derived from — before any changes or duplication.

This attribute is especially useful when dealing with new/virtual/in-memory records (e.g., created using copy(), new(), or in transient models).

🔍 Use Case

_origin is often used internally by Odoo to:
  • Detect whether a record is newly created or duplicated.
  • Compare with the original record.
  • Track original references during onchange, copy, or create flows.

📌 Realistic Odoo Example

🧾 Use Case: Copying a Sale Order and Reusing Certain Fields from the Original

class SaleOrder(models.Model):

    _inherit = ‘sale.order’

 

    def copy(self, default=None):

        res = super().copy(default)

        

        if self._origin:

            _logger.info(f”Copied from: {self._origin.name}“)

            # Use something from the original

            res.note = f“Copied from order: {self._origin.name}”

        return res

🔁 What’s Happening:

  • self is the temporary, new copy (not yet committed).
  • self._origin is the original sale order being copied.
  • You can access fields from _origin to carry over notes, references, or custom values.
🧠 Where _origin is Used Use
Scenario
Purpose of _origin
record.copy() Reference to the original source record
record.new(data) Keeps track of the original DB record
Transient models (wizards) Often used to compare input vs original
Onchange methods Compare user input with source values

❗️ Important Notes

  • _origin is only relevant in virtual/in-memory contexts.
  • For regular, saved records: record == record._origin
  • record._origin.id gives you the original database ID.

✅ Summary Table

Attribute
_origin
Used In Virtual/unsaved/temporary recordsets
Points To Original database record
Use Case Compare values, fetch original refs
Common In copy(), new(), transient models