From a07a076c45fc4b83caa9ab30ca919b30016015a7 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Wed, 2 Jan 2019 13:14:08 +0000 Subject: [PATCH 1/6] [FIX] models: avoid prefetch hell when reading fields The method `read()` may be very slow when reading relational fields and computed fields, because the computed fields can be computed on a recordset that is larger than expected. The issue occurs on model 'res.partner' when reading fields 'child_ids' and 'purchase_order_count', for instance. Suppose we read those two fields on a partner with 1000 contacts. First, the one2many field is read from the database and stored to the cache; the latter adds the value ids to the prefetching of 'res.partner'. Then, the fields are fetched from the cache. When 'purchase_order_count' is accessed on the partner, the field is computed on all its children as well... closes odoo/odoo#29867 --- odoo/addons/base/tests/test_api.py | 25 +++++++++++++++++++++++++ odoo/models.py | 22 ++++++++++++---------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/odoo/addons/base/tests/test_api.py b/odoo/addons/base/tests/test_api.py index cbb63daec59..3894629d736 100644 --- a/odoo/addons/base/tests/test_api.py +++ b/odoo/addons/base/tests/test_api.py @@ -358,6 +358,31 @@ class TestAPI(common.TransactionCase): same_prefetch(empty, empty.bank_ids) same_prefetch(empty, empty.category_id) + @mute_logger('odoo.models') + def test_60_prefetch_read(self): + """ Check that reading a field computes it on self only. """ + Partner = self.env['res.partner'] + field = type(Partner).company_type + self.assertTrue(field.compute and not field.store) + + partner1 = Partner.create({'name': 'Foo'}) + partner2 = Partner.create({'name': 'Bar', 'parent_id': partner1.id}) + self.assertEqual(partner1.child_ids, partner2) + + # reading partner1 should not prefetch 'company_type' on partner2 + self.env.clear() + partner1 = partner1.with_prefetch() + partner1.read(['company_type']) + self.assertIn('company_type', partner1._cache) + self.assertNotIn('company_type', partner2._cache) + + # reading partner1 should not prefetch 'company_type' on partner2 + self.env.clear() + partner1 = partner1.with_prefetch() + partner1.read(['child_ids', 'company_type']) + self.assertIn('company_type', partner1._cache) + self.assertNotIn('company_type', partner2._cache) + @mute_logger('odoo.models') def test_70_one(self): """ Check method one(). """ diff --git a/odoo/models.py b/odoo/models.py index db2c6ed2b90..85419013c0e 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3019,17 +3019,19 @@ class BaseModel(object): # retrieve results from records; this takes values from the cache and # computes remaining fields - result = [] - name_fields = [(name, self._fields[name]) for name in (stored + inherited + computed)] + data = {record: {'id': record.id} for record in self} + missing = set() use_name_get = (load == '_classic_read') - for record in self: - try: - values = {'id': record.id} - for name, field in name_fields: - values[name] = field.convert_to_read(record[name], record, use_name_get) - result.append(values) - except MissingError: - pass + for name in (stored + inherited + computed): + convert = self._fields[name].convert_to_read + # read every field with prefetching limited to self; this avoids + # computing fields on a larger recordset than self + for record in self.with_prefetch(): + try: + data[record][name] = convert(record[name], record, use_name_get) + except MissingError: + missing.add(record) + result = [data[record] for record in self if record not in missing] return result From 11e5688d0f7dc52fef846f0a4daa037926083172 Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Tue, 23 Oct 2018 07:59:49 +0000 Subject: [PATCH 2/6] [CLA] Brainbean Apps OU signs Odoo CCLA --- doc/cla/corporate/brainbeanapps.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 doc/cla/corporate/brainbeanapps.md diff --git a/doc/cla/corporate/brainbeanapps.md b/doc/cla/corporate/brainbeanapps.md new file mode 100644 index 00000000000..8909224f807 --- /dev/null +++ b/doc/cla/corporate/brainbeanapps.md @@ -0,0 +1,15 @@ +Estonia, 23 OCT 2018 + +Brainbean Apps OU agrees to the terms of the Odoo Corporate Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Oleksii Pelykh https://github.com/alexey-pelykh + +List of contributors: + +Alexey Pelykh https://github.com/alexey-pelykh From 1ffc485689348923c3a9c941740e7ee7ba39f959 Mon Sep 17 00:00:00 2001 From: Alexey Pelykh Date: Thu, 3 Jan 2019 15:51:40 +0000 Subject: [PATCH 3/6] [FIX] hr_holidays: extra space in state check The condition was never validated closes odoo/odoo#29898 --- addons/hr_holidays/views/hr_holidays_views.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hr_holidays/views/hr_holidays_views.xml b/addons/hr_holidays/views/hr_holidays_views.xml index 91c40677696..1f263604307 100644 --- a/addons/hr_holidays/views/hr_holidays_views.xml +++ b/addons/hr_holidays/views/hr_holidays_views.xml @@ -224,7 +224,7 @@ hr.holidays.tree hr.holidays - From 9cf666288076dc4e315e62e7ca0d6fc59995a498 Mon Sep 17 00:00:00 2001 From: Jorge Pinna Puissant Date: Fri, 4 Jan 2019 10:04:06 +0000 Subject: [PATCH 4/6] [FIX] account: compute_fiscalyear_dates non leap years Before this commit, when the fiscal year was setting to 29/02. The function that compute the fiscal year dates gives an error. This occurs when the date passed as parameter wasn't a leap year. Now, for the non leap years we use the 28/02. opw-1917035 closes odoo/odoo#29932 --- addons/account/models/company.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/account/models/company.py b/addons/account/models/company.py index 72b2c1f0197..8d1a2174431 100644 --- a/addons/account/models/company.py +++ b/addons/account/models/company.py @@ -115,7 +115,11 @@ Best Regards,''') last_month = self.fiscalyear_last_month last_day = self.fiscalyear_last_day if (date.month < last_month or (date.month == last_month and date.day <= last_day)): - date = date.replace(month=last_month, day=last_day) + # FORWARD-PORT UP TO v11 + if last_month == 2 and last_day == 29 and date.year % 4 != 0: + date = date.replace(month=last_month, day=28) + else: + date = date.replace(month=last_month, day=last_day) else: if last_month == 2 and last_day == 29 and (date.year + 1) % 4 != 0: date = date.replace(month=last_month, day=28, year=date.year + 1) From 0e0c726805e4bbefee83e867cca4ca2531d0053f Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Thu, 3 Jan 2019 16:36:16 +0000 Subject: [PATCH 5/6] [FIX] purchase: don't change status when writing a note through the composer Have a RFQ in draft. Log a note or send a new message, but use the full composer to do it. Before this commit, the RFQ was set to sent After this commit, it stays rightfully in draft It is mark as sent, only if the button SEND RFQ is used OPW 1908094 closes odoo/odoo#29902 --- addons/purchase/models/purchase.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index e114915a0d7..295c434c4e2 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -302,6 +302,7 @@ class PurchaseOrder(models.Model): 'default_use_template': bool(template_id), 'default_template_id': template_id, 'default_composition_mode': 'comment', + 'purchase_mark_rfq_sent': True, }) return { 'name': _('Compose Email'), @@ -1179,7 +1180,7 @@ class MailComposeMessage(models.TransientModel): @api.multi def mail_purchase_order_on_send(self): - if not self.filtered('subtype_id.internal'): + if self._context.get('purchase_mark_rfq_sent'): order = self.env['purchase.order'].browse(self._context['default_res_id']) if order.state == 'draft': order.state = 'sent' From d4024a713c5b1e5e9b65c9fd663d5feb511ae5b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Fern=C3=A1ndez?= Date: Mon, 7 Jan 2019 10:11:41 +0100 Subject: [PATCH 6/6] [CLA] PlanetaTIC signs Odoo CCLA --- doc/cla/corporate/planetatic.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 doc/cla/corporate/planetatic.md diff --git a/doc/cla/corporate/planetatic.md b/doc/cla/corporate/planetatic.md new file mode 100644 index 00000000000..c44ee26dae8 --- /dev/null +++ b/doc/cla/corporate/planetatic.md @@ -0,0 +1,18 @@ +Spain, 2019-01-07 + +Penedestic Solucions, SLP agrees to the terms of the Odoo Corporate Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Francisco Fernández ffernandez@planetatic.com https://github.com/FFernandez-PlanetaTIC + +List of contributors: + +Àngel Manonelles amanonelles@planetatic.com https://github.com/AManonelles-PlanetaTIC +Francisco Fernández ffernandez@planetatic.com https://github.com/FFernandez-PlanetaTIC +Lluís Rovira Olivé lrovira@planetatic.com https://github.com/LRovira-PlanetaTIC +Marc Poch mpoch@planetatic.com https://github.com/MPoch-PlanetaTIC