Company dependent field is not working in RECORD-RULE DOMAIN with multi-company configured system.
Problem Area: Scenario
I want to write a record rule with domain based on the company_dependent fields (means that field value is storing in ir.property Model).
Means, I have one field i.e. x_company_dependent_field in product.category Model and I want to write one record rule in product. In record-rule domain, I want to compare the product.category field's value with the User fields i.e. x_any_field (normal field).
so that domain on product.product / product.template Model can be like below.
Like(domain), [('categ_id.x_company_dependent_field', '=', user.x_any_field)]
Issue with the User Company ID:
When we work with multi-company scenario that means if user logged into their account system should show his company in code i.e. self.env.user.company_id. Instead of this everytime system takes ADMIN(2) user company.
So that record-rule does not satisfied.
Problem-statement
Followings are the output from odoo files.
file: odoo/models.py [def _search(). line-4130]
Working-Condiiton with Main Company
When I login with the current company then query prepare with proper product.category company dependent fields. In this condition domain is properly taking main company id i.e. 3.
below is final query :
auto-prepared domain: ir.property() -->[('fields_id', '=', 10385), ('company_id', 'in', [3, False]), ('value_reference', 'in', ['x_business_team,2', 'x_business_team,5'])]
ir.property query
<osv.Query: "SELECT ... FROM "ir_property" WHERE ((("ir_property"."fields_id" = %s) AND (("ir_property"."company_id" in (%s)) OR "ir_property"."company_id" IS NULL)) AND ("ir_property"."value_reference" in (%s,%s)))" with params: [10385, 3, 'x_business_team,2', 'x_business_team,5']>
Query:
<osv.Query: "SELECT ... FROM "product_category" WHERE ("product_category"."id" in (%s,%s,%s,%s,%s,%s,%s,%s))" with params: [14, 15, 16, 17, 18, 64, 40, 71]>
we can see, quer is taking product.category proper id based on the company-dependent fields i.e. from ir.property
SELECT count(1) FROM "product_template" LEFT JOIN
(SELECT res_id, value FROM "ir_translation"
WHERE type='model' AND name=%s AND lang=%s AND value!='')
as "product_template__name" ON ("product_template"."id" = "product_template__name"."res_id") WHERE (("product_template"."active" = %s) AND ("product_template"."type" in (%s,%s))) AND ((((("product_template"."company_id" in (%s,%s)) OR ("product_template"."company_id" in (%s))) OR "product_template"."company_id" IS NULL ) OR ("product_template"."id" in (SELECT "product_template_id" FROM "x_product_template_res_partner_rel" WHERE "res_partner_id" IN %s))) AND ("product_template"."categ_id" in (%s,%s,%s,%s,%s,%s,%s,%s))) ['product.template,name', 'en_US', True, 'consu', 'product', 3, 1, 3, (8,), 14, 64, 15, 16, 17, 18, 71, 40]
Not working-condition with other company
When I login with the other company then query prepare with product.category company dependent fields as FALSE condition. Because in condition domain, we can see its taking main company i.e. id=3 but current company is 10.
auto-prepared domain: ir.property() [('fields_id', '=', 10385), ('company_id', 'in', [3, False]), ('value_reference', 'in', ['x_business_team,33'])]
ir.property query:
"SELECT ... FROM "ir_property" WHERE ((("ir_property"."fields_id" = %s) AND (("ir_property"."company_id" in (%s)) OR "ir_property"."company_id" IS NULL)) AND ("ir_property"."value_reference" in (%s)))" with params: [10385, 3, 'x_business_team,33']>
Query
<osv.Query: "SELECT ... FROM "product_category" WHERE FALSE" with params: []>
But here is coming as False.
SELECT count(1) FROM "product_template" LEFT JOIN
(SELECT res_id, value FROM "ir_translation"
WHERE type='model' AND name=%s AND lang=%s AND value!='')
as "product_template__name" ON ("product_template"."id" = "product_template__name"."res_id")
WHERE ("product_product"."active" = %s) AND ("product_product"."product_tmpl_id"="product_product__product_tmpl_id"."id") AND (FALSE AND ("product_product__product_tmpl_id"."categ_id" in (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s))) AND ((((("product_product__product_tmpl_id"."company_id" in (%s,%s)) OR ("product_product__product_tmpl_id"."company_id" in (%s))) OR "product_product__product_tmpl_id"."company_id" IS NULL ) OR ("product_product__product_tmpl_id"."id" in (SELECT "product_template_id" FROM "x_product_template_res_partner_rel" WHERE "res_partner_id" IN %s))) AND FALSE)
That means, because of the company comparison it is not taking product.category company-dependent fields value from ir.property model.
Solutions Explanation:
In ir.rule model, method: def domain_get(), we can make self as current company after check 'force_company' not in self.env.context. by using,
self = self.with_context({'force_company': self.env.user.company_id.id})
then call super method.
In ir.rule model, method: def _compute_domain_keys(), we can append 'force_company' in returned list after super method call.
res.append('force_company')
Exapmle:
class Rule(models.Model):
_inherit = 'ir.rule'
@api.model
def domain_get(self, model_name, mode='read'):
if 'force_company' not in self._context:
self = self.with_context(force_company = self.env.user.company_id.id)
return super(Rule, self).domain_get(model_name, mode)
def _compute_domain_keys(self):
res = super(Rule, self)._compute_domain_keys() or []
res.append('force_company')
return res
After this we can see the company is now showing properly and RECORD-RULE Domain is working fine.
working query:
its taking proper company i.e. 10 in domain
ir.property query:
ir.property() [('fields_id', '=', 10385), ('company_id', 'in', [10, False]), ('value_reference', 'in', ['x_business_team,33', 'x_business_team,34'])]
<osv.Query: "SELECT ... FROM "ir_property" WHERE ((("ir_property"."fields_id" = %s) AND (("ir_property"."company_id" in (%s)) OR "ir_property"."company_id" IS NULL)) AND ("ir_property"."value_reference" in (%s,%s)))" with params: [10385, 10, 'x_business_team,33', 'x_business_team,34']>
<osv.Query: "SELECT ... FROM "ir_property" WHERE ((("ir_property"."fields_id" = %s) AND (("ir_property"."company_id" in (%s)) OR "ir_property"."company_id" IS NULL)) AND ("ir_property"."value_reference" in (%s,%s)))" with params: [10385, 10, 'x_business_team,33', 'x_business_team,34']>
product.category query:
<osv.Query: "SELECT ... FROM "product_category" WHERE ("product_category"."id" in (%s,%s,%s))" with params: [70, 71, 72]>
main query:
SELECT count(1) FROM "product_template" LEFT JOIN
(SELECT res_id, value FROM "ir_translation"
WHERE type='model' AND name=%s AND lang=%s AND value!='')
as "product_template__name" ON ("product_template"."id" = "product_template__name"."res_id") WHERE (("product_template"."active" = %s) AND ("product_template"."type" in (%s,%s))) AND ((((("product_template"."company_id" in (%s,%s)) OR ("product_template"."company_id" in (%s))) OR "product_template"."company_id" IS NULL ) OR ("product_template"."id" in (SELECT "product_template_id" FROM "x_product_template_res_partner_rel" WHERE "res_partner_id" IN %s))) AND (("product_template"."categ_id" in (%s,%s,%s)) AND (("product_template"."categ_id" in (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)) OR ("product_template"."categ_id" in (%s,%s,%s))))) ['product.template,name', 'en_US', True, 'consu', 'product', 10, 1, 10, (6662,), 70, 71, 72, 38, 39, 1, 56, 3, 14, 65, 79, 80, 81, 64, 15, 16, 17, 18, 86, 70, 71, 72, 82, 83, 84, 76, 77, 78, 66, 68, 67, 85, 73, 74, 75, 40, 41, 42, 43, 44, 57, 45, 46, 48, 49, 50, 51, 52, 55, 53, 54, 47, 70, 71, 72]
Comments
Post a Comment