Enable Dark Mode!
how-monkey-patching-works-in-odoo-19.jpg
By: Amrutha AM

How Monkey Patching Works in Odoo 19

Technical Odoo 19 Odoo Enterprises Odoo Community

Odoo is an open-source ERP and business application platform that offers a flexible framework for customization and extension.

 In this blog, we'll explore monkey patching, a powerful technique that allows developers to customize and extend Odoo's functionality at runtime.

What is meant by monkey patching?

Monkey patching is a technique that allows you to modify or extend the functionality of a method or class at runtime, without changing the original source code. In Odoo, it means you can replace the default behavior with your own custom logic. Once patched, every time that method is called, Odoo will execute your version instead of the original.

Monkey patching in Odoo is usually applied in a structured and controlled way.

# Original class
class MyClass:
    def original_method(self):
        print("This is the original method")
# Monkey patching the class with a new method
def new_method(self):
    print("This is the new method")
MyClass.original_method = new_method

By assigning new_method to MyClass.original_method, the original implementation is overridden. As a result, every time the original method is called, the new method is executed instead. This approach enables changes in behavior without modifying the original source code.

Example: Splitting Deliveries in Sales Orders

Imagine a sales order with multiple products. By default, Odoo creates a single delivery order for all items. However, in some cases, you may want to ship each product separately. To enable this, a field can be added to each sales order line to specify the delivery date for individual products, allowing more precise control over scheduling and logistics.

Inheriting the Sale Order Model

To enable separate deliveries based on delivery dates, a new field must be added to the sale.order.line to capture the specific delivery date for each item.

class SaleOrderLine(models.Model):
    _inherit = 'sale.order.line'
    delivery_date = fields.Date("Delivery Date")

Include the field in the views

<odoo>
   <record id="view_order_form" model="ir.ui.view">
       <field name="name">sale.order.inherit.monkey.patching</field>
       <field name="inherit_id" ref="sale.view_order_form"/>
       <field name="model">sale.order</field>
       <field name="arch" type="xml">
           <xpath expr="//field[@name='order_line']/list/field[@name='price_unit']"
                  position="before">
               <field name="delivery_date"/>
           </xpath>
       </field>
   </record>
</odoo>

Updating the _prepare_procurement_values method

Monkey patching is applied to the _prepare_procurement_values method in the sale.order.line model.

def prepare_procurement_values(self, group_id=False):
    Order_id = self.order_id
    deadline_date = self.delivery_date or (
            Order_id.date_order +
            timedelta(days=self.customer_lead or 0.0)
    )
    planned_date = deadline_date - timedelta(
        days=self.order_id.company_id.security_lead)
    values = {
        'group_id': group_id,
        'sale_line_id': self.id,
        'date_planned': planned_date,
        'date_deadline': deadline_date,
        'route_ids': self.route_ids,
        'warehouse_id': Order_id.warehouse_id or False,
        'product_description_variants': self.with_context(
            lang=Order_id.partner_id.lang).
        _get_sale_order_line_multiline_description_variants(),
        'company_id': Order_id.company_id,
        'sequence': self.sequence,
    }
    return values

After defining the new method, it is assigned to the SaleOrderLine class by replacing the original method, so Odoo will use the customized version instead:

SaleOrderLineOriginal._prepare_procurement_values = prepare_procurement_values

Inherit Stock Move Model

For this example, we need to apply monkey patching to two methods: _assign_picking and _key_assign_picking, so that the logic for splitting deliveries and aligning them with individual order lines is correctly applied throughout the sales and stock workflow. The _key_assign_picking method ensures that each sale order line gets a unique picking if the order contains multiple products.

Updating the _key_assign_picking method

def _key_assign_picking(self):
    """Each sale order line gets a unique picking if the order has multiple products"""
    self.ensure_one()
    if self.sale_line_id and self.sale_line_id.order_id.order_line:
        order_lines = self.sale_line_id.order_id.order_line
        if len(order_lines) > 1:
            return (self.sale_line_id.id,)
    return (self.picking_type_id.id, self.location_id.id, self.location_dest_id.id)

Modifying the _assign_picking method

def _assign_picking(self):
    StockPicking = self.env['stock.picking']
    # Sort moves by key to ensure proper grouping
    sorted_moves = sorted(self, key=lambda m: m._key_assign_picking())
    grouped_moves = groupby(sorted_moves, key=lambda m: m._key_assign_picking())
    for group, moves in grouped_moves:
        moves = self.env["stock.move"].concat(*moves)
        moves = moves.filtered(lambda m: float_compare(
            m.product_uom_qty, 0.0, precision_rounding=m.product_uom.rounding
        ) > 0)
        if not moves:
            continue
        pick_values = moves._get_new_picking_values()
        picking = StockPicking.create(pick_values)
        moves.write({'picking_id': picking.id})
        for move in moves:
            move._assign_picking_post_process(new=True)
    return True

In conclusion, the newly created functions are applied to the _assign_picking and _key_assign_picking methods of the StockMove class like

StockMoveOriginal._assign_picking = _assign_picking
StockMoveOriginal._key_assign_picking = _key_assign_picking

Monkey patching in Odoo provides a powerful way to customize default behavior without modifying the core code. This approach demonstrates how runtime modifications can enhance Odoo’s flexibility and meet specific business requirements.

To read more about What is Monkey Patching & How It Can Be Applied in Odoo 18, refer to our blog What is Monkey Patching & How It Can Be Applied in Odoo 18.


If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message