diff --git a/plm/models/product_product.py b/plm/models/product_product.py index 2c363a48..c0c8972d 100755 --- a/plm/models/product_product.py +++ b/plm/models/product_product.py @@ -304,13 +304,13 @@ def on_change_tmptreatment(self): self.engineering_treatment = str(self.tmp_treatment.name) @api.model - def getParentBomStructure(self, filterBomType=''): + def getParentBomStructure(self, + filterBomType=''): bom_line_filter = [('product_id', '=', self.id)] if filterBomType: bom_line_filter.append(('type', '=', filterBomType)) - mrpBomLines = self.env['mrp.bom.line'].search(bom_line_filter) out = [] - for mrpBomLine in mrpBomLines: + for mrpBomLine in self.env['mrp.bom.line'].search(bom_line_filter): out.append((self.env['mrp.bom'].where_used_header(mrpBomLine), mrpBomLine.bom_id.get_where_used_structure(filterBomType))) return out @@ -910,51 +910,62 @@ def _action_release(self): action to be executed for Released state """ for comp_obj in self: - children_product_to_emit = [] - product_tmpl_ids = [] - defaults = {} + allProdObjs = comp_obj exclude_statuses = ['released', 'undermodify', 'obsoleted'] include_statuses = self.env.context.get("PLM_STATE_RELEASE" ,['confirmed']) errors, product_ids = comp_obj._get_recursive_parts(exclude_statuses, include_statuses) - children_products = product_ids.copy() + children_products_ids = product_ids.copy() if len(product_ids) < 1 or len(errors) > 0: raise UserError(errors) - children_products.remove(comp_obj.id) - if children_products: - self.browse(children_products).action_release() + children_products_ids.remove(comp_obj.id) available_status = self._fields.get('state')._description_selection(self.env) dict_status = dict(available_status) - allProdObjs = self.browse(product_ids) + if children_products_ids: + children_products= self.browse(children_products_ids) + children_products.action_release() + allProdObjs+=children_products allProdObjs = allProdObjs.filtered(lambda x: x.engineering_code not in [False, '']) - for productBrw in allProdObjs: - old_revision = self._getbyrevision(productBrw.engineering_code, productBrw.engineering_revision - 1) - if old_revision: - defaults['engineering_writable'] = False - defaults['state'] = 'obsoleted' - old_revision.product_tmpl_id.write(defaults) - old_revision.write(defaults) - status_lable = dict_status.get(defaults.get('state', ''), '') - old_revision.wf_message_post(body=_('Status moved to: %s by %s.' % (status_lable, self.env.user.name))) - productBrw._action_ondocuments('release', include_statuses) - defaults['engineering_writable'] = False - defaults['state'] = 'released' - defaults['release_user'] = self.env.uid - defaults['release_date'] = datetime.now() - for currentProductId in allProdObjs: - if not currentProductId.release_date: - currentProductId.release_date = datetime.now() - currentProductId.release_user = self.env.uid - if currentProductId.id not in self.ids: - children_product_to_emit.append(currentProductId.id) - product_tmpl_ids.append(currentProductId.product_tmpl_id.id) - if children_product_to_emit: - self.browse(children_product_to_emit).perform_action('release') - self.browse(children_product_to_emit).write(defaults) - for objId in self.env['product.template'].browse(product_tmpl_ids): - objId.write(defaults) + for product_product_id in allProdObjs: + if product_product_id.engineering_revision>0: + old_revision = self._getbyrevision(product_product_id.engineering_code, + product_product_id.engineering_revision - 1) + # + # Set all revision status + # + if old_revision: + old_revision.product_tmpl_id.engineering_writable = False + old_revision.product_tmpl_id.state = 'obsoleted' + old_revision.engineering_writable = False + old_revision.state = 'obsoleted' + status_lable = dict_status.get('obsoleted') + old_revision.wf_message_post(body=_('Status moved to: %s by %s.' % (status_lable, + self.env.user.name))) + else: + logging.error(f"Missing previews version for {product_product_id.engineering_code}") + # + # Move the related document + # + product_product_id._action_ondocuments('release', include_statuses) + # + # Work on active product product + # + defaults = {} + defaults['engineering_writable'] = False + defaults['state'] = 'released' + defaults['release_user'] = self.env.uid + defaults['release_date'] = datetime.now() + product_product_id.write(defaults) + # + # wotk on product.template + # + product_template_id = product_product_id.product_tmpl_id + product_template_id.write(defaults) + # + # Notifie on chatter + # status_lable = dict_status.get(defaults.get('state', ''), '') - self.browse(product_ids).wf_message_post(body=_('Status moved to: %s by %s.' % (status_lable, self.env.user.name))) - comp_obj.write(defaults) + product_product_id.wf_message_post(body=_('Status moved to: %s by %s.' % (status_lable, + self.env.user.name))) return True def action_obsolete(self): diff --git a/plm/security/base_plm_security.xml b/plm/security/base_plm_security.xml index b02b7452..d90e7848 100755 --- a/plm/security/base_plm_security.xml +++ b/plm/security/base_plm_security.xml @@ -29,7 +29,7 @@ Unrelease User - + diff --git a/plm_automatic_weight/models/product_product.py b/plm_automatic_weight/models/product_product.py index e64dfe4c..f1827994 100755 --- a/plm_automatic_weight/models/product_product.py +++ b/plm_automatic_weight/models/product_product.py @@ -78,7 +78,7 @@ def write(self, vals): if product_product_id.state not in self.weight_allowed_state and not self.env.context.get('plm_force_weight',False): if 'weight' in vals: del vals['weight'] - logging.info("Modification in status %s not allowed for the weight" % product_product_id.state) + logging.info(f"Modification of field weight not allowed for product {product_product_id.display_name} in status {product_product_id.state}") weight_additional = product_product_id.weight_additional if 'weight_additional' in vals: weight_additional = vals['weight_additional'] diff --git a/plm_date_bom/models/mrp_bom.py b/plm_date_bom/models/mrp_bom.py index ca248dd8..1b81ad75 100755 --- a/plm_date_bom/models/mrp_bom.py +++ b/plm_date_bom/models/mrp_bom.py @@ -61,11 +61,13 @@ def _obsolete_compute(self): # If store = True is set you need to provide @api.depends because odoo has to know when to compute that field. # If you decide to compute that field each time without store you have always to put it in the view or the field will not be computed - obsolete_presents_computed = fields.Boolean(string=_("Obsolete presents computed"), compute='_obsolete_compute') + obsolete_presents_computed = fields.Boolean(string=_("Obsolete presents computed"), + compute='_obsolete_compute') obsolete_presents = fields.Boolean(_("Obsolete presents")) # This fields has not to be computed fields because bom may be very big and the time too - obsolete_presents_recursive = fields.Boolean(_("Obsolete presents Recursive"), default=False) + obsolete_presents_recursive = fields.Boolean(_("Obsolete presents Recursive"), + default=False) @api.onchange('bom_line_ids') def onchangeBomLine(self): diff --git a/plm_date_bom/models/product_product.py b/plm_date_bom/models/product_product.py index c6f31bf5..42861e12 100755 --- a/plm_date_bom/models/product_product.py +++ b/plm_date_bom/models/product_product.py @@ -29,15 +29,17 @@ class ProductExtension(models.Model): _inherit = 'product.template' @api.model - def updateObsoleteRecursive(self, prodBrws, presentsFlag=True): - bomTmpl = self.env['mrp.bom'] - struct = prodBrws.getParentBomStructure() + def updateObsoleteRecursive(self, + product_product_id, + presentsFlag=True): + mrp_bom_id = self.env['mrp.bom'] + struct = product_product_id.getParentBomStructure() def recursion(struct2, isRoot=False): for vals, parentsList in struct2: bom_id = vals.get('bom_id', False) if bom_id: - bomBrws = bomTmpl.browse(bom_id) + bomBrws = mrp_bom_id.browse(bom_id) bomBrws._obsolete_compute() if not isRoot: bomBrws.obsolete_presents_recursive = presentsFlag @@ -45,13 +47,34 @@ def recursion(struct2, isRoot=False): recursion(struct, isRoot=True) + def update_used_bom(self, product_product_id): + mrp_bom_line = self.env['mrp.bom.line'] + product_computed = [] + # + def _update_used_bom(product_product_id): + if product_product_id.id in product_computed: + return + product_computed.append(product_product_id.id) + # + for mrp_bom_line_id in mrp_bom_line.search([('product_id','=',product_product_id.id), + ('bom_id.type','not in',['ebom'])]): + bom_id = mrp_bom_line_id.bom_id + bom_id.sudo().obsolete_presents_recursive=True + bom_id.sudo().obsolete_presents = True + bom_id.sudo().obsolete_presents_computed = True + for product_product_id in bom_id.product_tmpl_id.product_variant_ids: + _update_used_bom(product_product_id) + # + _update_used_bom(product_product_id) + def write(self, vals): res = super(ProductExtension, self).write(vals) statePresent = vals.get('state', None) if statePresent == 'obsoleted': # Here I force compute obsolete presents flag in all boms - for prodTmplBrws in self: - for prodBrws in prodTmplBrws.product_variant_ids: - self.updateObsoleteRecursive(prodBrws) + for product_template_id in self: + for product_product_id in product_template_id.product_variant_ids: + #self.updateObsoleteRecursive(product_product_id) + self.update_used_bom(product_product_id) return res