[IMP] website_sale: overhead on every page
website_sale adds a call to sale_get_order to ~every website page (in order to validate & display the shopping cart). Before this change, this calls get_pricelist_available() and triggers two different computations of property_product_pricelist on every page even for a public user with no cart / SO. This, in turn, generates ~20 queries and adds 20ms (total) / 10ms (sql) to ~every page load. Fix: early return if the user doesn't have an SO (either in session or in DB) and we're not in a case where we want to force one. Loading "/" with just website_sale installed on a new DB, - before: 53 queries, 31ms ±5 (sql), 75ms ±5 (all) - after: 32 queries, 21ms ±1 (sql), 53ms ±3 (all) closes odoo/odoo#32492 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
@@ -239,27 +239,32 @@ class Website(models.Model):
|
||||
self.ensure_one()
|
||||
partner = self.env.user.partner_id
|
||||
sale_order_id = request.session.get('sale_order_id')
|
||||
if not sale_order_id:
|
||||
if not sale_order_id and not self.env.user._is_public():
|
||||
last_order = partner.last_website_so_id
|
||||
available_pricelists = self.get_pricelist_available()
|
||||
# Do not reload the cart of this user last visit if the cart uses a pricelist no longer available.
|
||||
sale_order_id = last_order.pricelist_id in available_pricelists and last_order.id
|
||||
if last_order:
|
||||
available_pricelists = self.get_pricelist_available()
|
||||
# Do not reload the cart of this user last visit if the cart uses a pricelist no longer available.
|
||||
sale_order_id = last_order.pricelist_id in available_pricelists and last_order.id
|
||||
|
||||
pricelist_id = request.session.get('website_sale_current_pl') or self.get_current_pricelist().id
|
||||
# Test validity of the sale_order_id
|
||||
sale_order = self.env['sale.order'].sudo().browse(sale_order_id).exists() if sale_order_id else None
|
||||
|
||||
if not (sale_order or force_create or code):
|
||||
request.session['sale_order_id'] = None
|
||||
return self.env['sale.order']
|
||||
|
||||
if self.env['product.pricelist'].browse(force_pricelist).exists():
|
||||
pricelist_id = force_pricelist
|
||||
request.session['website_sale_current_pl'] = pricelist_id
|
||||
update_pricelist = True
|
||||
else:
|
||||
pricelist_id = request.session.get('website_sale_current_pl') or self.get_current_pricelist().id
|
||||
|
||||
if not self._context.get('pricelist'):
|
||||
self = self.with_context(pricelist=pricelist_id)
|
||||
|
||||
# Test validity of the sale_order_id
|
||||
sale_order = self.env['sale.order'].sudo().browse(sale_order_id).exists() if sale_order_id else None
|
||||
|
||||
# create so if needed
|
||||
if not sale_order and (force_create or code):
|
||||
# cart creation was requested (either explicitly or to configure a promo code)
|
||||
if not sale_order:
|
||||
# TODO cache partner_id session
|
||||
pricelist = self.env['product.pricelist'].browse(pricelist_id).sudo()
|
||||
so_data = self._prepare_sale_order_values(partner, pricelist)
|
||||
@@ -280,70 +285,65 @@ class Website(models.Model):
|
||||
|
||||
request.session['sale_order_id'] = sale_order.id
|
||||
|
||||
if sale_order:
|
||||
# case when user emptied the cart
|
||||
if not request.session.get('sale_order_id'):
|
||||
request.session['sale_order_id'] = sale_order.id
|
||||
# case when user emptied the cart
|
||||
if not request.session.get('sale_order_id'):
|
||||
request.session['sale_order_id'] = sale_order.id
|
||||
|
||||
# check for change of pricelist with a coupon
|
||||
pricelist_id = pricelist_id or partner.property_product_pricelist.id
|
||||
# check for change of pricelist with a coupon
|
||||
pricelist_id = pricelist_id or partner.property_product_pricelist.id
|
||||
|
||||
# check for change of partner_id ie after signup
|
||||
if sale_order.partner_id.id != partner.id and request.website.partner_id.id != partner.id:
|
||||
flag_pricelist = False
|
||||
if pricelist_id != sale_order.pricelist_id.id:
|
||||
flag_pricelist = True
|
||||
fiscal_position = sale_order.fiscal_position_id.id
|
||||
# check for change of partner_id ie after signup
|
||||
if sale_order.partner_id.id != partner.id and request.website.partner_id.id != partner.id:
|
||||
flag_pricelist = False
|
||||
if pricelist_id != sale_order.pricelist_id.id:
|
||||
flag_pricelist = True
|
||||
fiscal_position = sale_order.fiscal_position_id.id
|
||||
|
||||
# change the partner, and trigger the onchange
|
||||
sale_order.write({'partner_id': partner.id})
|
||||
sale_order.onchange_partner_id()
|
||||
sale_order.write({'partner_invoice_id': partner.id})
|
||||
sale_order.onchange_partner_shipping_id() # fiscal position
|
||||
sale_order['payment_term_id'] = self.sale_get_payment_term(partner)
|
||||
# change the partner, and trigger the onchange
|
||||
sale_order.write({'partner_id': partner.id})
|
||||
sale_order.onchange_partner_id()
|
||||
sale_order.write({'partner_invoice_id': partner.id})
|
||||
sale_order.onchange_partner_shipping_id() # fiscal position
|
||||
sale_order['payment_term_id'] = self.sale_get_payment_term(partner)
|
||||
|
||||
# check the pricelist : update it if the pricelist is not the 'forced' one
|
||||
values = {}
|
||||
if sale_order.pricelist_id:
|
||||
if sale_order.pricelist_id.id != pricelist_id:
|
||||
values['pricelist_id'] = pricelist_id
|
||||
update_pricelist = True
|
||||
|
||||
# if fiscal position, update the order lines taxes
|
||||
if sale_order.fiscal_position_id:
|
||||
sale_order._compute_tax_id()
|
||||
|
||||
# if values, then make the SO update
|
||||
if values:
|
||||
sale_order.write(values)
|
||||
|
||||
# check if the fiscal position has changed with the partner_id update
|
||||
recent_fiscal_position = sale_order.fiscal_position_id.id
|
||||
if flag_pricelist or recent_fiscal_position != fiscal_position:
|
||||
# check the pricelist : update it if the pricelist is not the 'forced' one
|
||||
values = {}
|
||||
if sale_order.pricelist_id:
|
||||
if sale_order.pricelist_id.id != pricelist_id:
|
||||
values['pricelist_id'] = pricelist_id
|
||||
update_pricelist = True
|
||||
|
||||
if code and code != sale_order.pricelist_id.code:
|
||||
code_pricelist = self.env['product.pricelist'].sudo().search([('code', '=', code)], limit=1)
|
||||
if code_pricelist:
|
||||
pricelist_id = code_pricelist.id
|
||||
update_pricelist = True
|
||||
elif code is not None and sale_order.pricelist_id.code:
|
||||
# code is not None when user removes code and click on "Apply"
|
||||
pricelist_id = partner.property_product_pricelist.id
|
||||
# if fiscal position, update the order lines taxes
|
||||
if sale_order.fiscal_position_id:
|
||||
sale_order._compute_tax_id()
|
||||
|
||||
# if values, then make the SO update
|
||||
if values:
|
||||
sale_order.write(values)
|
||||
|
||||
# check if the fiscal position has changed with the partner_id update
|
||||
recent_fiscal_position = sale_order.fiscal_position_id.id
|
||||
if flag_pricelist or recent_fiscal_position != fiscal_position:
|
||||
update_pricelist = True
|
||||
|
||||
# update the pricelist
|
||||
if update_pricelist:
|
||||
request.session['website_sale_current_pl'] = pricelist_id
|
||||
values = {'pricelist_id': pricelist_id}
|
||||
sale_order.write(values)
|
||||
for line in sale_order.order_line:
|
||||
if line.exists():
|
||||
sale_order._cart_update(product_id=line.product_id.id, line_id=line.id, add_qty=0)
|
||||
if code and code != sale_order.pricelist_id.code:
|
||||
code_pricelist = self.env['product.pricelist'].sudo().search([('code', '=', code)], limit=1)
|
||||
if code_pricelist:
|
||||
pricelist_id = code_pricelist.id
|
||||
update_pricelist = True
|
||||
elif code is not None and sale_order.pricelist_id.code:
|
||||
# code is not None when user removes code and click on "Apply"
|
||||
pricelist_id = partner.property_product_pricelist.id
|
||||
update_pricelist = True
|
||||
|
||||
else:
|
||||
request.session['sale_order_id'] = None
|
||||
return self.env['sale.order']
|
||||
# update the pricelist
|
||||
if update_pricelist:
|
||||
request.session['website_sale_current_pl'] = pricelist_id
|
||||
values = {'pricelist_id': pricelist_id}
|
||||
sale_order.write(values)
|
||||
for line in sale_order.order_line:
|
||||
if line.exists():
|
||||
sale_order._cart_update(product_id=line.product_id.id, line_id=line.id, add_qty=0)
|
||||
|
||||
return sale_order
|
||||
|
||||
|
||||
Reference in New Issue
Block a user