# HG changeset patch # User Etienne Ferriere <etienne.ferriere@xcg-consulting.fr> # Date 1606148966 -3600 # Mon Nov 23 17:29:26 2020 +0100 # Branch 11.0 # Node ID abe6fa2872620af27f2efd88102063b65223ec7f # Parent 583e8b05243f86e173edee7c052110541d6a2da3 Added an option to deactivate the automatic generation of the associated analytic codes, when an analytic dimension is bound to a model. diff --git a/MetaAnalytic.py b/MetaAnalytic.py --- a/MetaAnalytic.py +++ b/MetaAnalytic.py @@ -239,6 +239,8 @@ elif isinstance(dimension, str): dimension = {"name": dimension} + automatic_generation = dimension.get("automatic", True) + dimension_name = dimension.get("name", None) if dimension_name is None: dimension_name = nmspc.get("_description", False) or orm_name @@ -261,7 +263,9 @@ parent_column = dimension.get("parent_column", column) - bound_code_is_required = dimension.get("required", True) + bound_code_is_required = dimension.get( + "required", automatic_generation + ) rel_name = dimension.get("rel_name", tuple()) if rel_name is True: @@ -466,156 +470,172 @@ return new_code, vals - @AddMethod(superclass) - @api.model - @api.returns(orm_name, lambda value: value.id) - def create(self, vals, **kwargs): - """Create the analytic code.""" - - context = self.env.context - code_vals = {} - - if sync_parent: - cp = self._get_code_parent(vals) - if cp is not None and cp: - code_vals["code_parent_id"] = cp.id + if automatic_generation: - # Direct changes to the 'bound analytic code' field are ignored - # unless the 'force_code_id' context key is passed as True. - force_code_id = vals.pop(column, False) - - # Will be set if a new code is created - new_code = False + @AddMethod(superclass) + @api.model + @api.returns(orm_name, lambda value: value.id) + def create(self, vals, **kwargs): + """Create the analytic code.""" - if context and context.get("force_code_id", False): - self._force_code(force_code_id, code_vals) - vals[column] = force_code_id - - else: - new_code, vals = self._create_analytic_code(vals, code_vals) - - res = super(superclass, self).create(vals, **kwargs) - - if not getattr(res, column): + context = self.env.context + code_vals = {} if sync_parent: cp = self._get_code_parent(vals) if cp is not None and cp: code_vals["code_parent_id"] = cp.id - new_code, vals = self._create_analytic_code( - { - field: extract(getattr(res, field), field_data["type"]) - for field, field_data in list(res.fields_get().items()) - if field - in (list(vals.keys()) + [code_name, code_description]) - }, - code_vals, - ) - super(superclass, res).write({column: new_code.id}) + # Direct changes to the 'bound analytic code' field are ignored + # unless the 'force_code_id' context key is passed as True. + force_code_id = vals.pop(column, False) - if code_ref_ids: - self._generate_code_ref_id(res) + # Will be set if a new code is created + new_code = False - if new_code: - # These are behind-the-scenes links so bypass security rules. - new_code.sudo().write( - {"origin_id": "{},{}".format(self._name, res.id)} - ) + if context and context.get("force_code_id", False): + self._force_code(force_code_id, code_vals) + vals[column] = force_code_id - return res - - @AddMethod(superclass) - @api.multi - def write(self, vals, **kwargs): - """Update the analytic code's name if it is not inherited, - and its parent code if parent-child relations are synchronized. - """ + else: + new_code, vals = self._create_analytic_code( + vals, code_vals + ) - context = self.env.context - code_vals = {} - news = [] - standard_process = False + res = super(superclass, self).create(vals, **kwargs) - if sync_parent: - cp = self._get_code_parent(vals) - if cp is not None and cp: - code_vals["code_parent_id"] = cp.id - else: - parent = getattr(self, sync_parent) - if parent: - cp = getattr(parent, parent_column) + if not getattr(res, column): + + if sync_parent: + cp = self._get_code_parent(vals) if cp is not None and cp: code_vals["code_parent_id"] = cp.id - # Direct changes to the 'bound analytic code' field are ignored - # unless the 'force_code_id' context key is passed as True. - force_code_id = vals.pop(column, False) + new_code, vals = self._create_analytic_code( + { + field: extract( + getattr(res, field), field_data["type"] + ) + for field, field_data in list( + res.fields_get().items() + ) + if field + in ( + list(vals.keys()) + + [code_name, code_description] + ) + }, + code_vals, + ) + super(superclass, res).write({column: new_code.id}) - if context and context.get("force_code_id", False): - self._force_code(force_code_id, code_vals) - vals[column] = force_code_id + if code_ref_ids: + self._generate_code_ref_id(res) - elif use_inherits: - vals.update(code_vals) + if new_code: + # These are behind-the-scenes links so bypass security + # rules. + new_code.sudo().write( + {"origin_id": "{},{}".format(self._name, res.id)} + ) + + return res - else: - name_col = rel_name[1] if rel_name else code_name - description_col = ( - rel_description[1] if rel_description else code_description - ) - if name_col in vals: - code_vals["name"] = vals[name_col] - if description_col in vals: - code_vals["description"] = vals[description_col] - standard_process = True + @AddMethod(superclass) + @api.multi + def write(self, vals, **kwargs): + """Update the analytic code's name if it is not inherited, + and its parent code if parent-child relations are synchronized. + """ + + context = self.env.context + code_vals = {} + news = [] + standard_process = False - res = super(superclass, self).write(vals, **kwargs) + if sync_parent: + cp = self._get_code_parent(vals) + if cp is not None and cp: + code_vals["code_parent_id"] = cp.id + else: + parent = getattr(self, sync_parent) + if parent: + cp = getattr(parent, parent_column) + if cp is not None and cp: + code_vals["code_parent_id"] = cp.id - # If updating records with no code, create these. - if standard_process: - code_obj = self.env["analytic.code"] + # Direct changes to the 'bound analytic code' field are ignored + # unless the 'force_code_id' context key is passed as True. + force_code_id = vals.pop(column, False) - for rec in self: - - code = getattr(rec, column) + if context and context.get("force_code_id", False): + self._force_code(force_code_id, code_vals) + vals[column] = force_code_id - rec_code_vals = code_vals.copy() - rec_vals = dict().copy() + elif use_inherits: + vals.update(code_vals) - if not rec_code_vals.get("name"): - rec_code_vals["name"] = rec.read([name_col])[0][ - name_col - ] - if not rec_code_vals.get("description"): - rec_code_vals["description"] = self.read( - [description_col] - )[0][description_col] + else: + name_col = rel_name[1] if rel_name else code_name + description_col = ( + rel_description[1] + if rel_description + else code_description + ) + if name_col in vals: + code_vals["name"] = vals[name_col] + if description_col in vals: + code_vals["description"] = vals[description_col] + standard_process = True + + res = super(superclass, self).write(vals, **kwargs) + + # If updating records with no code, create these. + if standard_process: + code_obj = self.env["analytic.code"] + + for rec in self: + + code = getattr(rec, column) + + rec_code_vals = code_vals.copy() + rec_vals = dict().copy() - if not code and rec_code_vals.get("name"): - news.append(rec.id) - rec_code_vals["nd_id"] = rec._get_bound_dimension_id() - rec_code_vals["origin_id"] = "{},{}".format( - self._name, rec.id - ) - # These are behind-the-scenes links so bypass security - # rules. - rec_vals[column] = ( - code_obj.sudo().create(rec_code_vals).id - ) + if not rec_code_vals.get("name"): + rec_code_vals["name"] = rec.read([name_col])[0][ + name_col + ] + if not rec_code_vals.get("description"): + rec_code_vals["description"] = self.read( + [description_col] + )[0][description_col] - super(superclass, rec).write(rec_vals, **kwargs) + if not code and rec_code_vals.get("name"): + news.append(rec.id) + rec_code_vals[ + "nd_id" + ] = rec._get_bound_dimension_id() # noqa: E501 + rec_code_vals["origin_id"] = "{},{}".format( + self._name, rec.id + ) + # These are behind-the-scenes links so bypass + # security rules. + rec_vals[column] = ( + code_obj.sudo().create(rec_code_vals).id + ) - elif rec_code_vals: - # These are behind-the-scenes links so bypass security - # rules. - code.sudo().write(rec_code_vals) + super(superclass, rec).write(rec_vals, **kwargs) - if code_ref_ids and news is not False: - for new in news: - self._generate_code_ref_id(new) + elif rec_code_vals: + # These are behind-the-scenes links so bypass + # security rules. + code.sudo().write(rec_code_vals) - return res + if code_ref_ids and news is not False: + for new in news: + self._generate_code_ref_id(new) + + return res @AddMethod(superclass) def unlink(self, **kwargs):