From 623d6a066b4e3fee4e1a349870d5229c273a3ce5 Mon Sep 17 00:00:00 2001 From: Victor Feyens Date: Mon, 24 Feb 2020 11:08:21 +0000 Subject: [PATCH] [FIX] delivery, sale: improve invoice_status performance. * Avoid reading all lines invoice_status when the SO isn't confirmed. * Do not use _default_product_id to discern down_payment lines, use is_downpayment instead (one ref = one query less by compute call) * Do not consider display_type lines for SO invoice_status. X-original-commit: 76a6d0475872f9ffa21cb917f13bc553c720eafd --- addons/delivery/models/sale_order.py | 2 ++ addons/sale/models/sale.py | 29 ++++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/addons/delivery/models/sale_order.py b/addons/delivery/models/sale_order.py index 1d95abd4f1b..22dc8231345 100644 --- a/addons/delivery/models/sale_order.py +++ b/addons/delivery/models/sale_order.py @@ -127,6 +127,8 @@ class SaleOrder(models.Model): def _get_invoice_status(self): super()._get_invoice_status() for order in self: + if order.invoice_status in ['no', 'invoiced']: + continue order_lines = order.order_line.filtered(lambda x: not x.is_delivery and not x.is_downpayment and not x.display_type) if all(line.product_id.invoice_policy == 'delivery' and line.invoice_status == 'no' for line in order_lines): order.invoice_status = 'no' diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index bf28f32b30e..5b8ef4b22ae 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -73,17 +73,22 @@ class SaleOrder(models.Model): - invoiced: if all SO lines are invoiced, the SO is invoiced. - upselling: if all SO lines are invoiced or upselling, the status is upselling. """ - # Ignore the status of the deposit product - deposit_product_id = self.env['sale.advance.payment.inv']._default_product_id() - line_data = self.env['sale.order.line'].read_group( - domain=[('order_id', 'in', self.ids), ('product_id', '!=', deposit_product_id.id)], - fields=['order_id', 'invoice_status'], - groupby=['order_id', 'invoice_status'], - lazy=False) - line_invoice_status_all = [(d['order_id'][0], d['invoice_status']) for d in line_data] - for order in self: - order_id = order.id or order._origin and order._origin.id - line_invoice_status = [d[1] for d in line_invoice_status_all if d[0] == order_id] + unconfirmed_orders = self.filtered(lambda so: so.state not in ['sale', 'done']) + unconfirmed_orders.invoice_status = 'no' + confirmed_orders = self - unconfirmed_orders + if not confirmed_orders: + return + line_invoice_status_all = [ + (d['order_id'][0], d['invoice_status']) + for d in self.env['sale.order.line'].read_group([ + ('order_id', 'in', confirmed_orders.ids), + ('is_downpayment', '=', False), + ('display_type', '=', False), + ], + ['order_id', 'invoice_status'], + ['order_id', 'invoice_status'], lazy=False)] + for order in confirmed_orders: + line_invoice_status = [d[1] for d in line_invoice_status_all if d[0] == order.id] if order.state not in ('sale', 'done'): order.invoice_status = 'no' elif any(invoice_status == 'to invoice' for invoice_status in line_invoice_status): @@ -181,7 +186,7 @@ class SaleOrder(models.Model): pricelist_id = fields.Many2one( 'product.pricelist', string='Pricelist', check_company=True, # Unrequired company required=True, readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]}, - domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=1, + domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]", tracking=1, help="If you change the pricelist, only newly added lines will be affected.") currency_id = fields.Many2one("res.currency", related='pricelist_id.currency_id', string="Currency", readonly=True, required=True) analytic_account_id = fields.Many2one(