|
| 1 | +# Copyright 2023 Camptocamp SA |
| 2 | +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) |
| 3 | + |
| 4 | +from odoo import api, models, fields |
| 5 | + |
| 6 | +IS_MTO_HELP = """ |
| 7 | + Check or Uncheck this field to enable the Make To Order on the variant, |
| 8 | + independantly from its template configuration. |
| 9 | +""" |
| 10 | + |
| 11 | +class ProductProduct(models.Model): |
| 12 | + _inherit = "product.product" |
| 13 | + |
| 14 | + is_mto = fields.Boolean( |
| 15 | + string="Variant is MTO", |
| 16 | + compute="_compute_is_mto", |
| 17 | + inverse="_inverse_is_mto", |
| 18 | + store=True, |
| 19 | + help=IS_MTO_HELP, |
| 20 | + ) |
| 21 | + |
| 22 | + @api.depends("product_tmpl_id.route_ids") |
| 23 | + def _compute_is_mto(self): |
| 24 | + # We only want to force all variants `is_mto` to True when |
| 25 | + # the mto route is explicitely set on its template. |
| 26 | + # Watching the mto route is not enough, since we might |
| 27 | + # have a template with the mto route, and disabled the mto route |
| 28 | + # for a few of its variants |
| 29 | + # If a user sets another route on the variant, we do not want the |
| 30 | + # mto disabled variants to be updated. |
| 31 | + # To ensure that, the created `has_mto_route_changed` boolean field |
| 32 | + # is set to True only when the MTO route is set on a template. |
| 33 | + mto_route = self.env.ref("stock.route_warehouse0_mto", raise_if_not_found=False) |
| 34 | + templates = self.product_tmpl_id |
| 35 | + # Only variants with a template with the MTO route and has_mto_route_changed |
| 36 | + # should be updated. |
| 37 | + mto_templates = templates.filtered( |
| 38 | + lambda t: mto_route in t.route_ids and t.has_mto_route_changed |
| 39 | + ) |
| 40 | + mto_variants = self.filtered(lambda p: p.product_tmpl_id in mto_templates) |
| 41 | + mto_variants.is_mto = True |
| 42 | + # For the other variants, keep their current value. |
| 43 | + other_variants = self - mto_variants |
| 44 | + for variant in other_variants: |
| 45 | + variant.is_mto = variant.is_mto |
| 46 | + # Then set template's has_mto_route_changed to False, as it |
| 47 | + # has been handled above |
| 48 | + templates.has_mto_route_changed = False |
| 49 | + |
| 50 | + def _inverse_is_mto(self): |
| 51 | + # When all variants of a template are `is_mto == False`, drop the MTO route |
| 52 | + # from the template, otherwise do nothing |
| 53 | + mto_route = self.env.ref("stock.route_warehouse0_mto", raise_if_not_found=False) |
| 54 | + for template in self.product_tmpl_id: |
| 55 | + is_mto = False |
| 56 | + for variant in template.product_variant_ids: |
| 57 | + if variant.is_mto: |
| 58 | + is_mto = True |
| 59 | + break |
| 60 | + # If no variant is mto, then drop the route of the template. |
| 61 | + if not is_mto: |
| 62 | + template.route_ids = [(3, mto_route.id, 0)] |
0 commit comments