def setup_modifiers(self, node, field=None, context=None, current_node_path=None): """Processes node attributes and field descriptors to generate the ``modifiers`` node attribute and set it on the provided node. Alters its first argument in-place. :param node: ``field`` node from an OpenERP view :type node: lxml.etree._Element :param dict field: field descriptor corresponding to the provided node :param dict context: execution context used to evaluate node attributes :param bool current_node_path: triggers the ``column_invisible`` code path (separate from ``invisible``): in tree view there are two levels of invisibility, cell content (a column is present but the cell itself is not displayed) with ``invisible`` and column invisibility (the whole column is hidden) with ``column_invisible``. :returns: nothing """ modifiers = {} if field is not None: transfer_field_to_modifiers(field=field, modifiers=modifiers) transfer_node_to_modifiers( node=node, modifiers=modifiers, context=context, current_node_path=current_node_path, ) transfer_modifiers_to_node(modifiers=modifiers, node=node)
def _add_pricelist_domain( self, doc, xpath_expr, attrs_key, domain_operator=expression.OR, field_operator="=", ): """Add the delivery type domain for 'pricelist' in attrs""" nodes = doc.xpath(xpath_expr) for field in nodes: attrs = safe_eval(field.attrib.get("attrs", "{}")) if not attrs[attrs_key]: continue invisible_domain = domain_operator([ attrs[attrs_key], [("delivery_type", field_operator, "pricelist")] ]) attrs[attrs_key] = invisible_domain field.set("attrs", str(attrs)) modifiers = {} transfer_node_to_modifiers(field, modifiers, self.env.context, in_tree_view=True) transfer_modifiers_to_node(modifiers, field)
def setup_modifiers(node, field=None, context=None, in_tree_view=False): modifiers = {} if field is not None: transfer_field_to_modifiers(field, modifiers) transfer_node_to_modifiers( node, modifiers, context=context, in_tree_view=in_tree_view) transfer_modifiers_to_node(modifiers, node)
def setup_modifiers(self, node, field=None, context=None, current_node_path=None): modifiers = {} if field is not None: ir_ui_view.transfer_field_to_modifiers(field, modifiers) ir_ui_view.transfer_node_to_modifiers( node, modifiers, context=context, current_node_path=current_node_path ) ir_ui_view.transfer_modifiers_to_node(modifiers, node)
def _fields_view_get_add_exclusive_selection_attrs(self, doc): """Make the readonly and required attrs dynamic for putaway rules By default, product_id and category_id fields have static domains such as they are mutually exclusive: both fields are required, as soon as we select a product, the category becomes readonly and not required, if we select a category, the product becomes readonly and not required. If we add a third field, such as "route_id", the domains for the readonly and required attrs should now include "route_id" as well, and if we add a fourth field, again. We can't extend them this way from XML, so this method dynamically generate these domains and set it on the fields attrs. The only requirement is to have exclusive_selection set in the options of the field: :: <field name="route_id" options="{'no_create': True, 'no_open': True, 'exclusive_selection': True}" readonly="context.get('putaway_route', False)" force_save="1" /> Look in module stock_putaway_by_route (where this is tested as well). """ exclusive_fields = set() nodes = doc.xpath("//field[@options]") for field in nodes: options = safe_eval(field.attrib.get("options", "{}")) if options.get("exclusive_selection"): exclusive_fields.add(field) for field in exclusive_fields: readonly_domain = OR([[(other.attrib["name"], "!=", False)] for other in exclusive_fields if other != field]) required_domain = AND([[(other.attrib["name"], "=", False)] for other in exclusive_fields if other != field]) if field.attrib.get("attrs"): attrs = safe_eval(field.attrib["attrs"]) else: attrs = {} attrs["readonly"] = readonly_domain attrs["required"] = required_domain field.set("attrs", str(attrs)) modifiers = {} transfer_node_to_modifiers(field, modifiers, self.env.context, in_tree_view=True) transfer_modifiers_to_node(modifiers, field)
def fields_view_get(self, view_id=None, view_type="form", toolbar=False, submenu=False): """Thirdparty fields are added to the form view only if they don't exist previously (l10n_es_aeat_sii_oca addon also has the same field names). """ res = super().fields_view_get( view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu, ) if view_type == "form": doc = etree.XML(res["arch"]) node = doc.xpath("//field[@name='thirdparty_invoice']") if node: return res for node in doc.xpath("//field[@name='ref'][last()]"): attrs = { "required": [("thirdparty_invoice", "=", True)], "invisible": [("thirdparty_invoice", "=", False)], } elem = etree.Element( "field", { "name": "thirdparty_number", "attrs": str(attrs) }, ) modifiers = {} transfer_node_to_modifiers(elem, modifiers) transfer_modifiers_to_node(modifiers, elem) node.addnext(elem) res["fields"].update(self.fields_get(["thirdparty_number"])) attrs = { "invisible": [( "move_type", "not in", ("in_invoice", "out_invoice", "out_refund", "in_refund"), )], } elem = etree.Element("field", { "name": "thirdparty_invoice", "attrs": str(attrs) }) transfer_node_to_modifiers(elem, modifiers) transfer_modifiers_to_node(modifiers, elem) node.addnext(elem) res["fields"].update(self.fields_get(["thirdparty_invoice"])) res["arch"] = etree.tostring(doc) return res
def fields_view_get(self, view_id=None, view_type="form", toolbar=False, submenu=False): result = super(ProductProduct, self).fields_view_get( view_id, view_type, toolbar=toolbar, submenu=submenu, ) doc = etree.XML(result["arch"]) name = result.get("name", False) if name == "product.product.pricelist.price": for placeholder in doc.xpath("//field[@name='type']"): for pricelist in self.env["product.pricelist"].search([ ("display_pricelist_price", "=", True) ]): field_name = "product_price_pricelist_%s" % (pricelist.id) tag_name = "Sales Price (%s)" % (pricelist.name) elem = etree.Element( "field", { "name": field_name, "readonly": "True", "optional": "hide" }, ) modifiers = {} transfer_node_to_modifiers(elem, modifiers) transfer_modifiers_to_node(elem, modifiers) placeholder.addnext(elem) result["fields"].update({ field_name: { "domain": [], "context": {}, "string": tag_name, "type": "float", } }) result["arch"] = etree.tostring(doc) return result
def _fields_view_get_adapt_send_to_shipper_attrs(self, view_arch): """Hide 'Send to Shipper' button if 'delivery_notification_sent' is True.""" doc = etree.XML(view_arch) xpath_expr = "//button[@name='send_to_shipper']" attrs_key = "invisible" nodes = doc.xpath(xpath_expr) for field in nodes: attrs = safe_eval(field.attrib.get("attrs", "{}")) if not attrs[attrs_key]: continue invisible_domain = expression.OR( [attrs[attrs_key], [("delivery_notification_sent", "=", True)]] ) attrs[attrs_key] = invisible_domain field.set("attrs", str(attrs)) modifiers = {} transfer_node_to_modifiers( field, modifiers, self.env.context, in_tree_view=True ) transfer_modifiers_to_node(modifiers, field) return etree.tostring(doc, encoding="unicode")
def _setup_modifiers(self, node): modifiers = {} ir_ui_view.transfer_node_to_modifiers(node, modifiers) ir_ui_view.transfer_modifiers_to_node(modifiers, node)