if addr_vals:
return super(res_partner, self).write(cr, uid, ids, addr_vals, context)
+ def _commercial_fields(self, cr, uid, context=None):
+ """ Returns the list of fields that are managed by the commercial entity
+ to which a partner belongs. These fields are meant to be hidden on
+ partners that aren't `commercial entities` themselves, and will be
+ delegated to the parent `commercial entity`. The list is meant to be
+ extended by inheriting classes. """
+ return ['vat']
+
+ def _commercial_sync_from_company(self, cr, uid, partner, context=None):
+ """ Handle sync of commercial fields when a new parent commercial entity is set,
+ as if they were related fields """
+ if partner.commercial_partner_id != partner:
+ commercial_fields = self._commercial_fields(cr, uid, context=context)
+ sync_vals = self._update_fields_values(cr, uid, partner.commercial_partner_id,
+ commercial_fields, context=context)
- return self.write(cr, uid, partner.id, sync_vals, context=context)
++ partner.write(sync_vals)
+
+ def _commercial_sync_to_children(self, cr, uid, partner, context=None):
+ """ Handle sync of commercial fields to descendants """
+ commercial_fields = self._commercial_fields(cr, uid, context=context)
+ sync_vals = self._update_fields_values(cr, uid, partner.commercial_partner_id,
+ commercial_fields, context=context)
+ sync_children = [c for c in partner.child_ids if not c.is_company]
+ for child in sync_children:
+ self._commercial_sync_to_children(cr, uid, child, context=context)
+ return self.write(cr, uid, [c.id for c in sync_children], sync_vals, context=context)
+
+ def _fields_sync(self, cr, uid, partner, update_values, context=None):
+ """ Sync commercial fields and address fields from company and to children after create/update,
+ just as if those were all modeled as fields.related to the parent """
+ # 1. From UPSTREAM: sync from parent
+ if update_values.get('parent_id') or update_values.get('use_company_address'):
+ # 1a. Commercial fields: sync if parent changed
+ if update_values.get('parent_id'):
+ self._commercial_sync_from_company(cr, uid, partner, context=context)
+ # 1b. Address fields: sync if parent or use_parent changed *and* both are now set
+ if partner.parent_id and partner.use_parent_address:
+ onchange_vals = self.onchange_address(cr, uid, [partner.id],
+ use_parent_address=partner.use_parent_address,
+ parent_id=partner.parent_id.id,
+ context=context).get('value', {})
- self.update_address(cr, uid, partner.id, onchange_vals, context=context)
++ partner.update_address(onchange_vals)
+
+ # 2. To DOWNSTREAM: sync children
+ if partner.child_ids:
+ # 2a. Commercial Fields: sync if commercial entity
+ if partner.commercial_partner_id == partner:
+ self._commercial_sync_to_children(cr, uid, partner, context=context)
+ # 2b. Address fields: sync if address changed
+ address_fields = self._address_fields(cr, uid, context=context)
+ if any(field in update_values for field in address_fields):
+ domain_children = [('parent_id', '=', partner.id), ('use_parent_address', '=', True)]
+ update_ids = self.search(cr, uid, domain_children, context=context)
+ self.update_address(cr, uid, update_ids, update_values, context=context)
+
+ def _handle_first_contact_creation(self, cr, uid, partner, context=None):
+ """ On creation of first contact for a company (or root) that has no address, assume contact address
+ was meant to be company address """
+ parent = partner.parent_id
+ address_fields = self._address_fields(cr, uid, context=context)
+ if parent and (parent.is_company or not parent.parent_id) and len(parent.child_ids) == 1 and \
+ any(partner[f] for f in address_fields) and not any(parent[f] for f in address_fields):
+ addr_vals = self._update_fields_values(cr, uid, partner, address_fields, context=context)
+ parent.update_address(addr_vals)
+ if not parent.is_company:
+ parent.write({'is_company': True})
+
+ def write(self, cr, uid, ids, vals, context=None):
+ if isinstance(ids, (int, long)):
+ ids = [ids]
+ result = super(res_partner,self).write(cr, uid, ids, vals, context=context)
+ for partner in self.browse(cr, uid, ids, context=context):
+ self._fields_sync(cr, uid, partner, vals, context)
+ return result
+
+ def create(self, cr, uid, vals, context=None):
+ new_id = super(res_partner, self).create(cr, uid, vals, context=context)
+ partner = self.browse(cr, uid, new_id, context=context)
+ self._fields_sync(cr, uid, partner, vals, context)
+ self._handle_first_contact_creation(cr, uid, partner, context)
+ return new_id
+
+ def open_commercial_entity(self, cr, uid, ids, context=None):
+ """ Utility method used to add an "Open Company" button in partner views """
+ partner = self.browse(cr, uid, ids[0], context=context)
+ return {'type': 'ir.actions.act_window',
+ 'res_model': 'res.partner',
+ 'view_mode': 'form',
+ 'res_id': partner.commercial_partner_id.id,
+ 'target': 'new',
+ 'flags': {'form': {'action_buttons': True}}}
+
+ def open_parent(self, cr, uid, ids, context=None):
+ """ Utility method used to add an "Open Parent" button in partner views """
+ partner = self.browse(cr, uid, ids[0], context=context)
+ return {'type': 'ir.actions.act_window',
+ 'res_model': 'res.partner',
+ 'view_mode': 'form',
+ 'res_id': partner.parent_id.id,
+ 'target': 'new',
+ 'flags': {'form': {'action_buttons': True}}}
+
def name_get(self, cr, uid, ids, context=None):
if context is None:
context = {}