summaryrefslogtreecommitdiff
path: root/odoo/addons/base/models
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2019-04-05 18:46:10 +0200
committerChristophe Simonis <chs@odoo.com>2019-04-05 18:46:10 +0200
commit3f95b074e959f0f4ac93fbf4048c0c7276f2c17a (patch)
treef4e793da5d83bcd1bd4347f71cb3f45cbc953df3 /odoo/addons/base/models
parent1a871d72438c731d08ef10e668b81b4ade900b85 (diff)
parentf2be461f0906ed47306da58c31240014b6239d80 (diff)
[MERGE] forward port branch saas-12.2 up to f2be461f090
Diffstat (limited to 'odoo/addons/base/models')
-rw-r--r--odoo/addons/base/models/res_bank.py4
-rw-r--r--odoo/addons/base/models/res_partner.py103
2 files changed, 89 insertions, 18 deletions
diff --git a/odoo/addons/base/models/res_bank.py b/odoo/addons/base/models/res_bank.py
index a4e75a2532c..d9a0433ecc2 100644
--- a/odoo/addons/base/models/res_bank.py
+++ b/odoo/addons/base/models/res_bank.py
@@ -66,7 +66,7 @@ class ResPartnerBank(models.Model):
_name = 'res.partner.bank'
_rec_name = 'acc_number'
_description = 'Bank Accounts'
- _order = 'sequence'
+ _order = 'sequence, id'
@api.model
def get_supported_account_types(self):
@@ -84,7 +84,7 @@ class ResPartnerBank(models.Model):
bank_id = fields.Many2one('res.bank', string='Bank')
bank_name = fields.Char(related='bank_id.name', readonly=False)
bank_bic = fields.Char(related='bank_id.bic', readonly=False)
- sequence = fields.Integer()
+ sequence = fields.Integer(default=10)
currency_id = fields.Many2one('res.currency', string='Currency')
company_id = fields.Many2one('res.company', 'Company', default=lambda self: self.env.user.company_id, ondelete='cascade')
qr_code_valid = fields.Boolean(string="Has all required arguments", compute="_validate_qr_code_arguments")
diff --git a/odoo/addons/base/models/res_partner.py b/odoo/addons/base/models/res_partner.py
index 603fbd6c4d2..49979b9e2c5 100644
--- a/odoo/addons/base/models/res_partner.py
+++ b/odoo/addons/base/models/res_partner.py
@@ -2,6 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
+import collections
import datetime
import hashlib
import pytz
@@ -286,8 +287,32 @@ class Partner(models.Model):
@api.depends('is_company', 'parent_id.commercial_partner_id')
def _compute_commercial_partner(self):
+ self.env.cr.execute("""
+ WITH RECURSIVE cpid(id, parent_id, commercial_partner_id, final) AS (
+ SELECT
+ id, parent_id, id,
+ (coalesce(is_company, false) OR parent_id IS NULL) as final
+ FROM res_partner
+ WHERE id = ANY(%s)
+ UNION
+ SELECT
+ cpid.id, p.parent_id, p.id,
+ (coalesce(is_company, false) OR p.parent_id IS NULL) as final
+ FROM res_partner p
+ JOIN cpid ON (cpid.parent_id = p.id)
+ WHERE NOT cpid.final
+ )
+ SELECT cpid.id, cpid.commercial_partner_id
+ FROM cpid
+ WHERE final AND id = ANY(%s);
+ """, [self.ids, self.ids])
+
+ d = dict(self.env.cr.fetchall())
for partner in self:
- if partner.is_company or not partner.parent_id:
+ fetched = d.get(partner.id)
+ if fetched is not None:
+ partner.commercial_partner_id = fetched
+ elif partner.is_company or not partner.parent_id:
partner.commercial_partner_id = partner
else:
partner.commercial_partner_id = partner.parent_id.commercial_partner_id
@@ -483,21 +508,25 @@ class Partner(models.Model):
self.update_address(onchange_vals)
# 2. To DOWNSTREAM: sync children
- if self.child_ids:
- # 2a. Commercial Fields: sync if commercial entity
- if self.commercial_partner_id == self:
- commercial_fields = self._commercial_fields()
- if any(field in values for field in commercial_fields):
- self._commercial_sync_to_children()
- for child in self.child_ids.filtered(lambda c: not c.is_company):
- if child.commercial_partner_id != self.commercial_partner_id :
- self._commercial_sync_to_children()
- break
- # 2b. Address fields: sync if address changed
- address_fields = self._address_fields()
- if any(field in values for field in address_fields):
- contacts = self.child_ids.filtered(lambda c: c.type == 'contact')
- contacts.update_address(values)
+ self._children_sync(values)
+
+ def _children_sync(self, values):
+ if not self.child_ids:
+ return
+ # 2a. Commercial Fields: sync if commercial entity
+ if self.commercial_partner_id == self:
+ commercial_fields = self._commercial_fields()
+ if any(field in values for field in commercial_fields):
+ self._commercial_sync_to_children()
+ for child in self.child_ids.filtered(lambda c: not c.is_company):
+ if child.commercial_partner_id != self.commercial_partner_id:
+ self._commercial_sync_to_children()
+ break
+ # 2b. Address fields: sync if address changed
+ address_fields = self._address_fields()
+ if any(field in values for field in address_fields):
+ contacts = self.child_ids.filtered(lambda c: c.type == 'contact')
+ contacts.update_address(values)
@api.multi
def _handle_first_contact_creation(self):
@@ -574,11 +603,53 @@ class Partner(models.Model):
tools.image_resize_images(vals, return_big=False)
tools.image_resize_images(vals, return_medium=False, return_small=False, preserve_aspect_ratio=True)
partners = super(Partner, self).create(vals_list)
+
+ if self.env.context.get('_partners_skip_fields_sync'):
+ return partners
+
for partner, vals in zip(partners, vals_list):
partner._fields_sync(vals)
partner._handle_first_contact_creation()
return partners
+ def _load_records_create(self, vals_list):
+ partners = super(Partner, self.with_context(_partners_skip_fields_sync=True))._load_records_create(vals_list)
+
+ # batch up first part of _fields_sync
+ # group partners by commercial_partner_id (if not self) and parent_id (if type == contact)
+ groups = collections.defaultdict(list)
+ for partner, vals in zip(partners, vals_list):
+ cp_id = None
+ if vals.get('parent_id') and partner.commercial_partner_id != partner:
+ cp_id = partner.commercial_partner_id.id
+
+ add_id = None
+ if partner.parent_id and partner.type == 'contact':
+ add_id = partner.parent_id.id
+ groups[(cp_id, add_id)].append(partner.id)
+
+ for (cp_id, add_id), children in groups.items():
+ # values from parents (commercial, regular) written to their common children
+ to_write = {}
+ # commercial fields from commercial partner
+ if cp_id:
+ to_write = self.browse(cp_id)._update_fields_values(self._commercial_fields())
+ # address fields from parent
+ if add_id:
+ parent = self.browse(add_id)
+ for f in self._address_fields():
+ v = parent[f]
+ if v:
+ to_write[f] = v.id if isinstance(v, models.BaseModel) else v
+ if to_write:
+ self.browse(children).write(to_write)
+
+ # do the second half of _fields_sync the "normal" way
+ for partner, vals in zip(partners, vals_list):
+ partner._children_sync(vals)
+ partner._handle_first_contact_creation()
+ return partners
+
@api.multi
def create_company(self):
self.ensure_one()