74ebc34fea162b680081164867348d4085943c1c
Use Case ======== In the coupon module, a call to a write, a create or an unlink on a sales order line may trigger a write, a create or an unlink on another line. Example: I have a promotional offer "If you buy for more than 100 euros, you got a 10 percent discount on the sales order. On my sales order, I buy 2 imac at 999 euros. At that moment my total amount is over 1000 euros and I got another line, the discount. I write on the sales order line that I only buy one imac, a unlink is trigger on the reward line to remove it from the sales order. Current Solution ================ At the beginning, I was overwriting the write, the create and the unlink methods on the sales order line to perform the correct actions according to the promotional offers that were still applicable, not applicable anymore of newly applicable. This solution was followed by side effects on the computed fields. For example, a write on the SO line that was triggering an unlink on another line was triggering a computed field that depended on the sales order line. In that case, the environment I received on the compute method was the environment before the line unlink. As the compute method was looping on the sales order line, it was taking values on a line that wasn't existing anymore and that way it was triggering an 'This record doesn't exist or has been deleted' error. After a discussion with @rco-odoo, we realized that the only way to achieve this was to override the write method on a sales order to avoid quadratic computation loop when creating/editing/deleting sale order lines. As coupon are recorded as sale.order.line, it may effectively blow up. We also overrode the create method on a sales order line to make an ORM command on the sales order instead of a simple create on the sales order. See: https://github.com/odoo/enterprise/blob/saas-14/sale_coupon/models/sale_order.py#L253 For the write and the unlink, this is a little more complicated because a write may trigger a write and an unlink may trigger an unlink, resulting in an infinite loop. New Solution ============ Having a method _recompute_coupon_lines on sale.order. This method do nothing if there is a key coupon_recompute in the context. ```python @multi def _recompute_coupon_lines(self): if self.env.context.get('coupon_recompute'): return self = self.with_context(coupon_recompute=True) # avoid loop [...do actual stuff...] ``` The create/write/unlink method on sale.order.line call super before calling the method _recompute_coupon_lines ```python @multi def write(self, values): result = super(SaleOrderLine, self).write(values) self.mapped('order_id')._recompute_coupon_lines() return result ``` In order (pun intended) to accelerate mass creation/edition of lines, the method create/write/unlink of sale.order should call recompute themself ```python @mutli def write(self, values): result = super(SaleOrder, self.with_context(coupon_recompute=True)).write(values) self._recompute_coupon_lines() return result ```
Languages
Python
49.6%
JavaScript
47.8%
SCSS
2%
CSS
0.3%
HTML
0.2%