from lxml import etree from odoo import models, api, fields def _hide_margin_fields_in_view(env, res): if env.user.x_hide_margin: for view_type, view_data in res.get('views', {}).items(): arch = view_data.get('arch') if arch: doc = etree.fromstring(arch) # Hide field elements matching margin or margin_percent for field_node in doc.xpath("//field[@name='margin' or @name='margin_percent']"): field_node.set('invisible', '1') field_node.set('column_invisible', 'True') # Hide label elements matching margin or margin_percent for label_node in doc.xpath("//label[@for='margin' or @for='margin_percent']"): label_node.set('invisible', '1') # Hide the container div matching field margin for div_node in doc.xpath("//div[field[@name='margin']]"): div_node.set('invisible', '1') # Remove measure fields in pivot/graph views for measure_node in doc.xpath("//field[@name='margin' and @type='measure']"): measure_node.getparent().remove(measure_node) # Hide filters/groupby on margin or margin_percent in search views for filter_node in doc.xpath("//filter[@name='margin' or @name='margin_percent' or contains(@context, 'margin') or contains(@domain, 'margin')]"): filter_node.getparent().remove(filter_node) view_data['arch'] = etree.tostring(doc, encoding='utf-8', xml_declaration=False).decode('utf-8') return res def _hide_margin_fields_in_fields_get(env, res): if env.user.x_hide_margin: for field in ['margin', 'margin_percent']: if field in res: res[field]['invisible'] = True res[field]['searchable'] = False res[field]['sortable'] = False return res def _hide_margin_fields_in_read_group_dict(env, res): if env.user.x_hide_margin: for group in res: for key in list(group.keys()): if 'margin' in key: group[key] = 0.0 return res def _hide_margin_fields_in_read_group(env, groupby, aggregates, res): if env.user.x_hide_margin: margin_indices = [ i for i, agg in enumerate(aggregates) if 'margin' in agg ] groupby_margin_indices = [ i for i, field in enumerate(groupby) if 'margin' in field ] if margin_indices or groupby_margin_indices: new_res = [] offset = len(groupby) for row in res: row_list = list(row) for idx in margin_indices: if offset + idx < len(row_list): row_list[offset + idx] = 0.0 for idx in groupby_margin_indices: if idx < len(row_list): row_list[idx] = 0.0 new_res.append(tuple(row_list)) return new_res return res def _hide_margin_fields_in_read_grouping_sets(env, grouping_sets, aggregates, res): if env.user.x_hide_margin: margin_indices = [ idx for idx, agg in enumerate(aggregates) if 'margin' in agg ] new_res = [] for groupby, group_results in zip(grouping_sets, res): groupby_margin_indices = [ idx for idx, field in enumerate(groupby) if 'margin' in field ] if margin_indices or groupby_margin_indices: new_group_results = [] offset = len(groupby) for row in group_results: row_list = list(row) for idx in margin_indices: if offset + idx < len(row_list): row_list[offset + idx] = 0.0 for idx in groupby_margin_indices: if idx < len(row_list): row_list[idx] = 0.0 new_group_results.append(tuple(row_list)) new_res.append(new_group_results) else: new_res.append(group_results) return new_res return res def _hide_margin_fields_in_read(env, res): if env.user.x_hide_margin: for record in res: for key in list(record.keys()): if 'margin' in key: record[key] = 0.0 return res class PosOrder(models.Model): _inherit = 'pos.order' def _compute_margin(self): super()._compute_margin() if self.env.user.x_hide_margin: for order in self: order.margin = 0.0 order.margin_percent = 0.0 @api.model def get_views(self, views, options=None): res = super().get_views(views, options) return _hide_margin_fields_in_view(self.env, res) def fields_get(self, allfields=None, attributes=None): res = super().fields_get(allfields, attributes) return _hide_margin_fields_in_fields_get(self.env, res) @api.model def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True): res = super().read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy) return _hide_margin_fields_in_read_group_dict(self.env, res) @api.model def _read_group(self, domain, groupby=(), aggregates=(), having=(), offset=0, limit=None, order=None): res = super()._read_group(domain, groupby, aggregates, having, offset, limit, order) return _hide_margin_fields_in_read_group(self.env, groupby, aggregates, res) @api.model def _read_grouping_sets(self, domain, grouping_sets, aggregates=(), order=None): res = super()._read_grouping_sets(domain, grouping_sets, aggregates, order) return _hide_margin_fields_in_read_grouping_sets(self.env, grouping_sets, aggregates, res) def read(self, fields=None, load='_classic_read'): res = super().read(fields, load=load) return _hide_margin_fields_in_read(self.env, res) class PosOrderLine(models.Model): _inherit = 'pos.order.line' def _compute_margin(self): super()._compute_margin() if self.env.user.x_hide_margin: for line in self: line.margin = 0.0 line.margin_percent = 0.0 @api.model def get_views(self, views, options=None): res = super().get_views(views, options) return _hide_margin_fields_in_view(self.env, res) def fields_get(self, allfields=None, attributes=None): res = super().fields_get(allfields, attributes) return _hide_margin_fields_in_fields_get(self.env, res) def read(self, fields=None, load='_classic_read'): res = super().read(fields, load=load) return _hide_margin_fields_in_read(self.env, res) class ReportPosOrder(models.Model): _inherit = 'report.pos.order' @api.model def get_views(self, views, options=None): res = super().get_views(views, options) return _hide_margin_fields_in_view(self.env, res) def fields_get(self, allfields=None, attributes=None): res = super().fields_get(allfields, attributes) return _hide_margin_fields_in_fields_get(self.env, res) @api.model def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True): res = super().read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy) return _hide_margin_fields_in_read_group_dict(self.env, res) @api.model def _read_group(self, domain, groupby=(), aggregates=(), having=(), offset=0, limit=None, order=None): res = super()._read_group(domain, groupby, aggregates, having, offset, limit, order) return _hide_margin_fields_in_read_group(self.env, groupby, aggregates, res) @api.model def _read_grouping_sets(self, domain, grouping_sets, aggregates=(), order=None): res = super()._read_grouping_sets(domain, grouping_sets, aggregates, order) return _hide_margin_fields_in_read_grouping_sets(self.env, grouping_sets, aggregates, res) def read(self, fields=None, load='_classic_read'): res = super().read(fields, load=load) return _hide_margin_fields_in_read(self.env, res)