c2c-oerpscenario team mailing list archive
-
c2c-oerpscenario team
-
Mailing list archive
-
Message #03331
[Bug 485058] Re: Trunk Multi Company Improvement
[6.0rc1] Shouldn't addons/base/res/res_company_view.xml be referenced in addons/base/__openerp__.py?
The multi-company menu is not visible until I add it and reload.
--
Trunk Multi Company Improvement
https://bugs.launchpad.net/bugs/485058
You received this bug notification because you are a member of C2C
OERPScenario, which is subscribed to the OpenERP Project Group.
Status in OpenObject Addons Modules: Fix Committed
Bug description:
Specifications to Improve Multi-Company in Trunk
=======================================
These specs details security issues for the multi-company only. Others issues (sales -> purchase, outgoing -> incoming) are detailed in others specifications. The security for the multi-company is based on the following concept:
- multi-company objects have a field called 'company_id': fields.many2one('res.company', 'Company')
-> sometimes required, sometimes not. Sometimes with a default value.
- records are based on record rules that filter objects based on this field.
Modifications in the client and the server so that a user belongs to several companies have already been applied.
Merge Modules
-------------------
We do not need multi-company modules anymore. Every module most be multi-company by default.
In trunk, we must merge multi_company_XXX modules in their respective modules, put directly the
company_id field on the object, no inheritancy of object/view anymore.
Each time you put a company_id field on an object, do:
* A default value (see bellow for more info):
'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, _name, c)
I don't know if _name will work. Otherwise put the name of the object 'account.invoice'
* Some multi_company fields must be related fields. For example, in sale.order.line:
'company_id': fields.related('order_id','company_id',type='many2one',object='res.company',string='Company')
Do the same for:
- purchase.order.line
- account.invoice.line
- task.work.line
* A record rule like this one for this object:
<record id="journal_comp_rule_group" model="ir.rule.group">
<field name="name">Journal multi-company (Children+Parents)</field>
<field model="ir.model" ref="model_account_journal"/>
<field eval="True" name="global"/>
</record>
<record id="journal_comp_rule" model="ir.rule">
<field model="ir.model.fields" ref="field_account_journal_company_id"/>
<field name="domain_force">['|','|',('company_id','=',False),('company_id.child_ids','child_of',[user.company_id.id]),('company_id','child_of',[user.company_id.id])]</field>
<field name="rule_group" ref="journal_comp_rule_group"/>
</record>
This rule must be put on all generic objects (partners, products, ...)
For more sensible objects (like all accounting and sales objects), use a rule like this one:
<record id="journal_comp_rule_group" model="ir.rule.group">
<field name="name">Journal multi-company (Children)</field>
<field model="ir.model" ref="model_account_journal"/>
<field eval="True" name="global"/>
</record>
<record id="journal_comp_rule" model="ir.rule">
<field model="ir.model.fields" ref="field_account_journal_company_id"/>
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
<field name="rule_group" ref="journal_comp_rule_group"/>
</record>
-> The way record rules were defined in old multi-company modules was wrong, change all rules to be like the above one.
On the view, add a group on all company_id field, so that users belonging to a single company have a way to hide
all multi-company fields:
<field name="company_id" groups="base.multi_company"/>
The multi_company module
-----------------------------------
Develop a multi_company module (or improve the existing one). It has no code nor security rules at all.
It just define demonstration data with a several companies and assign some companies to some products, partners, ...
The default value system
--------------------------------
Put this in the base module, on res.company object:
+ def _company_default_get(self, cr, uid, object=False, context={}):
+ return self.pool.get('res.users').browse(cr, uid, uid).company_id.id
Put this in multi_company module:
+class multi_company_default(osv.osv):
+ _name = 'multi_company.default'
+ _order = 'sequence,id'
+ _columns = {
+ 'sequence': fields.integer('Sequence'),
+ 'name': fields.char('Name', size=32, required=True),
+ 'company_id': fields.many2one('res.company', 'Main Company', required=True),
+ 'company_dest_id': fields.many2one('res.company', 'Default Company', required=True),
+ 'object_id': fields.many2one('ir.model', 'Object', required=True),
+ 'expression': fields.char('Expression', required=True),
+ }
+ _defaults = {
+ 'expression': lambda *a: 'True',
+ 'sequence': lambda *a: 1
+ }
+multi_company_default()
+
+class res_company(osv.osv):
+ _inherit = 'res.company'
+ def _company_default_get(self, cr, uid, object=False, context={}):
+ proxy = self.pool.get('multi_company.default')
+ ids = proxy.search(cr, uid, [('object_id.name', '=', object)]
+ for rule in proxy.browse(cr, uid, ids, context):
+ user = self.pool.get('res.user').browse(cr, uid, uid)
+ if eval(rule.expression, {'context': context, 'user': user}):
+ return rule.company_dest_id.id
+ return super(res_company, self)._company_default_get(cr, uid, object, context)
+res_company()
Define a menu and a view to configure the multi_company.default object.
Put a security rule a multi_company security rule on this object too.