From c01e2fe122ed1d3d4447b046b8c75a8f30d3567d Mon Sep 17 00:00:00 2001 From: Date: Mon, 20 May 2013 14:31:11 +0530 Subject: [PATCH 1/5] [FIX]ir_property: If we add a property on a many2one field with multicompany the value of main company is replaced in all companies value bzr revid: ado@tinyerp.com-20130520090111-h20jboltev763mj6 --- openerp/osv/fields.py | 78 ++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index 34968a662fb..64275fafca8 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1380,50 +1380,46 @@ class property(function): return res def _get_by_id(self, obj, cr, uid, prop_name, ids, context=None): - prop = obj.pool.get('ir.property') - vids = [obj._name + ',' + str(oid) for oid in ids] - - domain = [('fields_id.model', '=', obj._name), ('fields_id.name', 'in', prop_name)] - #domain = prop._get_domain(cr, uid, prop_name, obj._name, context) - if vids: - domain = [('res_id', 'in', vids)] + domain - return prop.search(cr, uid, domain, context=context) + property_pool = obj.pool.get('ir.property') + company_pool = obj.pool.get('res.company') + reference = [obj._name + ',' + str(oid) for oid in ids] + def_id = self._field_get(cr, uid, obj._name, prop_name) + company_id = company_pool._company_default_get(cr, uid, obj._name, def_id, context=context) + #match the prop value on current user company to match + #property get and write based on current user company, + domain = [('fields_id.model', '=', obj._name), + ('fields_id.name', '=', prop_name), + ('company_id', '=', company_id)] + #add reference for more accurate property result, if any. + if reference: + domain.extend([('res_id', 'in', reference)]) + return property_pool.search(cr, uid, domain, context=context) + + def _create_property(self, obj, cr, uid, id, prop_name, id_val, old_ids, context): + company_pool = obj.pool.get('res.company') + property_pool = obj.pool.get('ir.property') + if old_ids: + property_pool.unlink(cr, uid, old_ids, context) + def_id = self._field_get(cr, uid, obj._name, prop_name) + company_id = company_pool._company_default_get(cr, uid, obj._name, def_id, context=context) + property_field = obj.pool.get('ir.model.fields').browse(cr, uid, def_id, context=context) + return property_pool.create(cr, uid, { + 'name': property_field.name, + 'value': id_val, + 'res_id': obj._name+','+str(id), + 'company_id': company_id, + 'fields_id': def_id, + 'type': self._type, + }, context=context) # TODO: to rewrite more clean def _fnct_write(self, obj, cr, uid, id, prop_name, id_val, obj_dest, context=None): - if context is None: - context = {} - - nids = self._get_by_id(obj, cr, uid, [prop_name], [id], context) - if nids: - cr.execute('DELETE FROM ir_property WHERE id IN %s', (tuple(nids),)) - - default_val = self._get_default(obj, cr, uid, prop_name, context) - - property_create = False - if isinstance(default_val, openerp.osv.orm.browse_record): - if default_val.id != id_val: - property_create = True - elif default_val != id_val: - property_create = True - - if property_create: - def_id = self._field_get(cr, uid, obj._name, prop_name) - company = obj.pool.get('res.company') - cid = company._company_default_get(cr, uid, obj._name, def_id, - context=context) - propdef = obj.pool.get('ir.model.fields').browse(cr, uid, def_id, - context=context) - prop = obj.pool.get('ir.property') - return prop.create(cr, uid, { - 'name': propdef.name, - 'value': id_val, - 'res_id': obj._name+','+str(id), - 'company_id': cid, - 'fields_id': def_id, - 'type': self._type, - }, context=context) - return False + #check the result of ir.property.get() for existing prop field value + default_val = self._get_defaults(obj, cr, uid, [prop_name], context=None)[prop_name] + #if values found same skip the unlinking the creation and creation of new records + if (isinstance(default_val, openerp.osv.orm.browse_record) and default_val.id != id_val) or (default_val != id_val): + old_ids = self._get_by_id(obj, cr, uid, prop_name, [id], context) + return self._create_property(obj, cr, uid, id, prop_name, id_val, old_ids, context) def _fnct_read(self, obj, cr, uid, ids, prop_names, obj_dest, context=None): prop = obj.pool.get('ir.property') From 266cdb3c7ec30d68b797729ecff7854297b58a28 Mon Sep 17 00:00:00 2001 From: Amit Dodiya Date: Fri, 31 May 2013 15:16:43 +0530 Subject: [PATCH 2/5] [IMP]: trml2pdf: change the fontface of pagecount text same as companies header footer text fontface bzr revid: ado@tinyerp.com-20130531094643-oyn5nx9dv0bv0ohx --- openerp/report/render/rml2pdf/trml2pdf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/report/render/rml2pdf/trml2pdf.py b/openerp/report/render/rml2pdf/trml2pdf.py index 243cc02a0b3..66ba28a07c9 100644 --- a/openerp/report/render/rml2pdf/trml2pdf.py +++ b/openerp/report/render/rml2pdf/trml2pdf.py @@ -110,7 +110,7 @@ class NumberedCanvas(canvas.Canvas): if not self.pages.get(key,False): while not self.pages.get(key,False): key += 1 - self.setFont("Helvetica", 8) + self.setFont("DejaVu Sans", 8) self.drawRightString((self._pagesize[0]-30), (self._pagesize[1]-40), " %(this)i / %(total)i" % { 'this': self._pageNumber+1, @@ -137,7 +137,7 @@ class PageCount(platypus.Flowable): def draw(self): self.canv.beginForm("pageCount%d" % self.story_count) - self.canv.setFont("Helvetica", utils.unit_get(str(8))) + self.canv.setFont("DejaVu Sans", utils.unit_get(str(8))) self.canv.drawString(0, 0, str(self.canv.getPageNumber())) self.canv.endForm() From 3668f091089d52b0ae1d694929866843eda64412 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 13 Feb 2014 11:08:36 +0100 Subject: [PATCH 3/5] [IMP] avoid changing the API by passing the company_id in context bzr revid: mat@openerp.com-20140213100836-wte9zec4easb0cmw --- openerp/osv/fields.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index baaafbce331..1ef47bc94af 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -1390,11 +1390,12 @@ class property(function): res[prop_name] = prop.get(cr, uid, prop_name, obj._name, context=context) return res - def _get_by_id(self, obj, cr, uid, prop_name, ids, context=None, company_id=False): + def _get_by_id(self, obj, cr, uid, prop_name, ids, context=None): prop = obj.pool.get('ir.property') vids = [obj._name + ',' + str(oid) for oid in ids] - domain = [('fields_id.model', '=', obj._name), ('fields_id.name', 'in', prop_name), ('company_id', '=', company_id)] - #domain = prop._get_domain(cr, uid, prop_name, obj._name, context) + domain = [('fields_id.model', '=', obj._name), ('fields_id.name', 'in', prop_name)] + if context and context.get('company_id'): + domain += [('company_id', '=', context.get('company_id'))] if vids: domain = [('res_id', 'in', vids)] + domain return prop.search(cr, uid, domain, context=context) @@ -1407,7 +1408,9 @@ class property(function): def_id = self._field_get(cr, uid, obj._name, prop_name) company = obj.pool.get('res.company') cid = company._company_default_get(cr, uid, obj._name, def_id, context=context) - nids = self._get_by_id(obj, cr, uid, [prop_name], [id], context, company_id=cid) + # TODO for trunk: add new parameter company_id to _get_by_id method + context_company = dict(context, company_id=cid) + nids = self._get_by_id(obj, cr, uid, [prop_name], [id], context_company) if nids: cr.execute('DELETE FROM ir_property WHERE id IN %s', (tuple(nids),)) From e201ea319017133477987f8dbd675d0c38dd072b Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 13 Feb 2014 14:10:09 +0100 Subject: [PATCH 4/5] [ADD] tests checking the properties fields are not overwritten by changes in parent companies bzr revid: mat@openerp.com-20140213131009-25knm17hie7uzeko --- openerp/tests/test_fields.py | 52 +++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/openerp/tests/test_fields.py b/openerp/tests/test_fields.py index 774bbf41fb2..c32b6f76e97 100644 --- a/openerp/tests/test_fields.py +++ b/openerp/tests/test_fields.py @@ -9,8 +9,12 @@ class TestRelatedField(common.TransactionCase): def setUp(self): super(TestRelatedField, self).setUp() + self.user = self.registry('res.users') self.partner = self.registry('res.partner') self.company = self.registry('res.company') + self.country = self.registry('res.country') + self.property = self.registry('ir.property') + self.imd = self.registry('ir.model.data') def test_0_related(self): """ test an usual related field """ @@ -121,4 +125,50 @@ class TestRelatedField(common.TransactionCase): # restore res.partner fields self.partner._columns = old_columns -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + def test_4_property_multicompany(self): + cr, uid = self.cr, self.uid + + parent_company_id = self.imd.get_object_reference(cr, uid, 'base', 'main_company')[1] + country_be = self.imd.get_object_reference(cr, uid, 'base', 'be')[1] + country_fr = self.imd.get_object_reference(cr, uid, 'base', 'fr')[1] + group_partner_manager = self.imd.get_object_reference(cr, uid, 'base', 'group_partner_manager')[1] + group_multi_company = self.imd.get_object_reference(cr, uid, 'base', 'group_multi_company')[1] + + sub_company = self.company.create(cr, uid, {'name': 'MegaCorp', 'parent_id': parent_company_id}) + alice = self.user.create(cr, uid, {'name': 'Alice', + 'login':'alice', + 'email':'alice@youcompany.com', + 'company_id':parent_company_id, + 'company_ids':[(6, 0, [parent_company_id, sub_company])], + 'country_id':country_be, + 'groups_id': [(6, 0, [group_partner_manager, group_multi_company])] + }) + bob = self.user.create(cr, uid, {'name': 'Bob', + 'login':'bob', + 'email':'bob@megacorp.com', + 'company_id':sub_company, + 'company_ids':[(6, 0, [parent_company_id, sub_company])], + 'country_id':country_fr, + 'groups_id': [(6, 0, [group_partner_manager, group_multi_company])] + }) + + self.partner._columns = dict(self.partner._columns) + self.partner._columns.update({ + 'property_country': fields.property('res.country', type='many2one', relation="res.country", string="Country by company", view_load=True), + }) + self.partner._all_columns.update({ + 'property_country': fields.column_info('property_country', self.partner._columns['property_country'], None, None, None), + }) + self.partner._field_create(cr) + + partner_id = self.partner.create(cr, alice, { + 'name': 'An International Partner', + 'email': 'partner@example.com', + 'company_id': parent_company_id, + }) + self.partner.write(cr, bob, [partner_id], {'property_country': country_fr}) + self.assertEqual(self.partner.browse(cr, bob, partner_id).property_country.id, country_fr, "Bob does not see the value he has set on the property field") + + self.partner.write(cr, alice, [partner_id], {'property_country': country_be}) + self.assertEqual(self.partner.browse(cr, alice, partner_id).property_country.id, country_be, "Alice does not see the value he has set on the property field") + self.assertEqual(self.partner.browse(cr, bob, partner_id).property_country.id, country_fr, "Changes made by Alice have overwritten Bob's value") From 7b41032e2a37ef9c5106772075adbeee257bd117 Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Thu, 13 Feb 2014 14:32:54 +0100 Subject: [PATCH 5/5] [IMP] move test on property fields to his own test class bzr revid: mat@openerp.com-20140213133254-ahzac9o009su3d2x --- openerp/tests/test_fields.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/openerp/tests/test_fields.py b/openerp/tests/test_fields.py index c32b6f76e97..151b96b8013 100644 --- a/openerp/tests/test_fields.py +++ b/openerp/tests/test_fields.py @@ -9,12 +9,8 @@ class TestRelatedField(common.TransactionCase): def setUp(self): super(TestRelatedField, self).setUp() - self.user = self.registry('res.users') self.partner = self.registry('res.partner') self.company = self.registry('res.company') - self.country = self.registry('res.country') - self.property = self.registry('ir.property') - self.imd = self.registry('ir.model.data') def test_0_related(self): """ test an usual related field """ @@ -125,7 +121,19 @@ class TestRelatedField(common.TransactionCase): # restore res.partner fields self.partner._columns = old_columns - def test_4_property_multicompany(self): + +class TestPropertyField(common.TransactionCase): + + def setUp(self): + super(TestPropertyField, self).setUp() + self.user = self.registry('res.users') + self.partner = self.registry('res.partner') + self.company = self.registry('res.company') + self.country = self.registry('res.country') + self.property = self.registry('ir.property') + self.imd = self.registry('ir.model.data') + + def test_1_property_multicompany(self): cr, uid = self.cr, self.uid parent_company_id = self.imd.get_object_reference(cr, uid, 'base', 'main_company')[1]