[IMP] website_sale*: methods/routes cleanup

* consistent/clear sale_get_order params (force_create is a boolean value, do not provide integers)
* use one coherent way to get website current pricelist, through the dedicated computed field

Part-of: odoo/odoo#82374
This commit is contained in:
Victor Feyens
2022-02-21 08:41:30 +00:00
parent dfd1d29938
commit 6e6d9f3b63
10 changed files with 116 additions and 116 deletions
@@ -2,23 +2,21 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
import werkzeug
from odoo import http
from odoo.http import request
from odoo.http import request, route
from odoo.addons.website_event.controllers.main import WebsiteEventController
class WebsiteEventBoothController(WebsiteEventController):
@http.route()
@route()
def event_booth_main(self, event):
pricelist = request.website.get_current_pricelist()
pricelist = request.website.pricelist_id
if pricelist:
event = event.with_context(pricelist=pricelist.id)
return super(WebsiteEventBoothController, self).event_booth_main(event)
@http.route()
@route()
def event_booth_registration_confirm(self, event, booth_category_id, event_booth_ids, **kwargs):
"""Override: Doesn't call the parent method because we go through the checkout
process which will confirm the booths when receiving the payment."""
@@ -31,7 +29,7 @@ class WebsiteEventBoothController(WebsiteEventController):
return json.dumps({'error': 'boothCategoryError'})
booth_values = self._prepare_booth_registration_values(event, kwargs)
order = request.website.sale_get_order(force_create=1)
order = request.website.sale_get_order(force_create=True)
order._cart_update(
product_id=booth_category.product_id.id,
set_qty=1,
+14 -12
View File
@@ -1,25 +1,26 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http, _
from odoo import _
from odoo.http import request, route
from odoo.addons.website_event.controllers.main import WebsiteEventController
from odoo.http import request
class WebsiteEventSaleController(WebsiteEventController):
@http.route()
@route()
def event_register(self, event, **post):
event = event.with_context(pricelist=request.website.id)
if not request.context.get('pricelist'):
pricelist = request.website.get_current_pricelist()
pricelist = request.website.pricelist_id
if pricelist:
event = event.with_context(pricelist=pricelist.id)
return super(WebsiteEventSaleController, self).event_register(event, **post)
return super().event_register(event, **post)
def _process_tickets_form(self, event, form_details):
""" Add price information on ticket order """
res = super(WebsiteEventSaleController, self)._process_tickets_form(event, form_details)
res = super()._process_tickets_form(event, form_details)
for item in res:
item['price'] = item['ticket']['price'] if item['ticket'] else 0
return res
@@ -27,7 +28,8 @@ class WebsiteEventSaleController(WebsiteEventController):
def _create_attendees_from_registration_post(self, event, registration_data):
# we have at least one registration linked to a ticket -> sale mode activate
if any(info.get('event_ticket_id') for info in registration_data):
order = request.website.sale_get_order(force_create=1)
order = request.website.sale_get_order(force_create=True)
for info in [r for r in registration_data if r.get('event_ticket_id')]:
ticket = request.env['event.event.ticket'].sudo().browse(info['event_ticket_id'])
@@ -35,17 +37,17 @@ class WebsiteEventSaleController(WebsiteEventController):
info['sale_order_id'] = order.id
info['sale_order_line_id'] = cart_values.get('line_id')
return super(WebsiteEventSaleController, self)._create_attendees_from_registration_post(event, registration_data)
return super()._create_attendees_from_registration_post(event, registration_data)
@http.route()
@route()
def registration_confirm(self, event, **post):
res = super(WebsiteEventSaleController, self).registration_confirm(event, **post)
res = super().registration_confirm(event, **post)
registrations = self._process_attendees_form(event, post)
# we have at least one registration linked to a ticket -> sale mode activate
if any(info['event_ticket_id'] for info in registrations):
order = request.website.sale_get_order(force_create=False)
order = request.website.sale_get_order()
if order.amount_total:
return request.redirect("/shop/checkout")
# free tickets -> order with amount = 0: auto-confirm, no checkout
@@ -56,7 +58,7 @@ class WebsiteEventSaleController(WebsiteEventController):
return res
def _prepare_event_values(self, name, event_start, event_end, address_values=None):
values = super(WebsiteEventSaleController, self)._prepare_event_values(name, event_start, event_end, address_values)
values = super()._prepare_event_values(name, event_start, event_end, address_values)
product = request.env.ref('event_sale.product_product_event', raise_if_not_found=False)
if product:
values.update({
+53 -55
View File
@@ -125,7 +125,7 @@ class Website(main.Website):
def autocomplete(self, search_type=None, term=None, order=None, limit=5, max_nb_chars=999, options=None):
options = options or {}
if 'display_currency' not in options:
options['display_currency'] = request.website.get_current_pricelist().currency_id
options['display_currency'] = request.website.currency_id
return super().autocomplete(search_type, term, order, limit, max_nb_chars, options)
@http.route()
@@ -153,17 +153,6 @@ class Website(main.Website):
class WebsiteSale(http.Controller):
def _get_pricelist_context(self):
pricelist_context = dict(request.env.context)
pricelist = False
if not pricelist_context.get('pricelist'):
pricelist = request.website.get_current_pricelist()
pricelist_context['pricelist'] = pricelist.id
else:
pricelist = request.env['product.pricelist'].browse(pricelist_context['pricelist'])
return pricelist_context, pricelist
def _get_search_order(self, post):
# OrderBy will be parsed in orm and so no direct sql injection
# id is added to be sure that order is a unique sort key
@@ -217,10 +206,10 @@ class WebsiteSale(http.Controller):
yield {'loc': loc}
@http.route([
'''/shop''',
'''/shop/page/<int:page>''',
'''/shop/category/<model("product.public.category"):category>''',
'''/shop/category/<model("product.public.category"):category>/page/<int:page>'''
'/shop',
'/shop/page/<int:page>',
'/shop/category/<model("product.public.category"):category>',
'/shop/category/<model("product.public.category"):category>/page/<int:page>',
], type='http', auth="public", website=True, sitemap=sitemap_shop)
def shop(self, page=0, category=None, search='', min_price=0.0, max_price=0.0, ppg=False, **post):
add_qty = int(post.get('add_qty', 1))
@@ -241,6 +230,7 @@ class WebsiteSale(http.Controller):
else:
category = Category
website = request.env['website'].get_current_website()
if ppg:
try:
ppg = int(ppg)
@@ -248,9 +238,9 @@ class WebsiteSale(http.Controller):
except ValueError:
ppg = False
if not ppg:
ppg = request.env['website'].get_current_website().shop_ppg or 20
ppg = website.shop_ppg or 20
ppr = request.env['website'].get_current_website().shop_ppr or 4
ppr = website.shop_ppr or 4
attrib_list = request.httprequest.args.getlist('attrib')
attrib_values = [[int(x) for x in v.split("-")] for v in attrib_list if v]
@@ -259,14 +249,15 @@ class WebsiteSale(http.Controller):
keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list, min_price=min_price, max_price=max_price, order=post.get('order'))
pricelist_context, pricelist = self._get_pricelist_context()
pricelist = website.get_current_pricelist()
request.context = dict(request.context, pricelist=pricelist.id, partner=request.env.user.partner_id)
filter_by_price_enabled = request.website.is_view_active('website_sale.filter_products_price')
filter_by_price_enabled = website.is_view_active('website_sale.filter_products_price')
if filter_by_price_enabled:
company_currency = request.website.company_id.currency_id
conversion_rate = request.env['res.currency']._get_conversion_rate(company_currency, pricelist.currency_id, request.website.company_id, fields.Date.today())
company_currency = website.company_id.currency_id
conversion_rate = request.env['res.currency']._get_conversion_rate(
company_currency, pricelist.currency_id, request.website.company_id, fields.Date.today())
else:
conversion_rate = 1
@@ -290,11 +281,11 @@ class WebsiteSale(http.Controller):
'display_currency': pricelist.currency_id,
}
# No limit because attributes are obtained from complete product list
product_count, details, fuzzy_search_term = request.website._search_with_fuzzy("products_only", search,
product_count, details, fuzzy_search_term = website._search_with_fuzzy("products_only", search,
limit=None, order=self._get_search_order(post), options=options)
search_product = details[0].get('results', request.env['product.template']).with_context(bin_size=True)
filter_by_price_enabled = request.website.is_view_active('website_sale.filter_products_price')
filter_by_price_enabled = website.is_view_active('website_sale.filter_products_price')
if filter_by_price_enabled:
# TODO Find an alternative way to obtain the domain through the search metadata.
Product = request.env['product.template'].with_context(bin_size=True)
@@ -324,10 +315,12 @@ class WebsiteSale(http.Controller):
max_price = max_price if max_price >= available_min_price else available_max_price
post['max_price'] = max_price
website_domain = request.website.website_domain()
website_domain = website.website_domain()
categs_domain = [('parent_id', '=', False)] + website_domain
if search:
search_categories = Category.search([('product_tmpl_ids', 'in', search_product.ids)] + website_domain).parents_and_self
search_categories = Category.search(
[('product_tmpl_ids', 'in', search_product.ids)] + website_domain
).parents_and_self
categs_domain.append(('id', 'in', search_categories.ids))
else:
search_categories = Category
@@ -336,7 +329,7 @@ class WebsiteSale(http.Controller):
if category:
url = "/shop/category/%s" % slug(category)
pager = request.website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post)
pager = website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post)
offset = pager['offset']
products = search_product[offset:offset + ppg]
@@ -352,7 +345,7 @@ class WebsiteSale(http.Controller):
layout_mode = request.session.get('website_sale_shop_layout_mode')
if not layout_mode:
if request.website.viewref('website_sale.products_list_view').active:
if website.viewref('website_sale.products_list_view').active:
layout_mode = 'list'
else:
layout_mode = 'grid'
@@ -475,8 +468,8 @@ class WebsiteSale(http.Controller):
redirect = post.get('r', '/shop/cart')
# empty promo code is used to reset/remove pricelist (see `sale_get_order()`)
if promo:
pricelist = request.env['product.pricelist'].sudo().search([('code', '=', promo)], limit=1)
if (not pricelist or (pricelist and not request.website.is_pricelist_available(pricelist.id))):
pricelist_sudo = request.env['product.pricelist'].sudo().search([('code', '=', promo)], limit=1)
if not (pricelist_sudo and request.website.is_pricelist_available(pricelist_sudo.id)):
return request.redirect("%s?code_not_available=1" % redirect)
request.website.sale_get_order(code=promo)
@@ -528,20 +521,22 @@ class WebsiteSale(http.Controller):
return request.render("website_sale.cart", values)
@http.route(['/shop/cart/update'], type='http', auth="public", methods=['POST'], website=True)
def cart_update(self, product_id, add_qty=1, set_qty=0, **kw):
def cart_update(
self, product_id, add_qty=1, set_qty=0,
product_custom_attribute_values=None, no_variant_attribute_values=None,
express=False, **kwargs
):
"""This route is called when adding a product to cart (no options)."""
sale_order = request.website.sale_get_order(force_create=True)
if sale_order.state != 'draft':
request.session['sale_order_id'] = None
sale_order = request.website.sale_get_order(force_create=True)
product_custom_attribute_values = None
if kw.get('product_custom_attribute_values'):
product_custom_attribute_values = json_scriptsafe.loads(kw.get('product_custom_attribute_values'))
if product_custom_attribute_values:
product_custom_attribute_values = json_scriptsafe.loads(product_custom_attribute_values)
no_variant_attribute_values = None
if kw.get('no_variant_attribute_values'):
no_variant_attribute_values = json_scriptsafe.loads(kw.get('no_variant_attribute_values'))
if no_variant_attribute_values:
no_variant_attribute_values = json_scriptsafe.loads(no_variant_attribute_values)
sale_order._cart_update(
product_id=int(product_id),
@@ -551,7 +546,7 @@ class WebsiteSale(http.Controller):
no_variant_attribute_values=no_variant_attribute_values
)
if kw.get('express'):
if express:
return request.redirect("/shop/checkout?express=1")
return request.redirect("/shop/cart")
@@ -564,17 +559,17 @@ class WebsiteSale(http.Controller):
- When adding a product from the wishlist.
- When adding a product to cart on the same page (without redirection).
"""
order = request.website.sale_get_order(force_create=1)
order = request.website.sale_get_order(force_create=True)
if order.state != 'draft':
request.website.sale_reset()
if kw.get('force_create'):
order = request.website.sale_get_order(force_create=1)
order = request.website.sale_get_order(force_create=True)
else:
return {}
pcav = kw.get('product_custom_attribute_values')
nvav = kw.get('no_variant_attribute_values')
value = order._cart_update(
values = order._cart_update(
product_id=product_id,
line_id=line_id,
add_qty=add_qty,
@@ -585,23 +580,26 @@ class WebsiteSale(http.Controller):
if not order.cart_quantity:
request.website.sale_reset()
return value
return values
order = request.website.sale_get_order()
value['cart_quantity'] = order.cart_quantity
values['cart_quantity'] = order.cart_quantity
if not display:
return value
return values
value['website_sale.cart_lines'] = request.env['ir.ui.view']._render_template("website_sale.cart_lines", {
'website_sale_order': order,
'date': fields.Date.today(),
'suggested_products': order._cart_accessories()
})
value['website_sale.short_cart_summary'] = request.env['ir.ui.view']._render_template("website_sale.short_cart_summary", {
'website_sale_order': order,
})
return value
values['website_sale.cart_lines'] = request.env['ir.ui.view']._render_template(
"website_sale.cart_lines", {
'website_sale_order': order,
'date': fields.Date.today(),
'suggested_products': order._cart_accessories()
}
)
values['website_sale.short_cart_summary'] = request.env['ir.ui.view']._render_template(
"website_sale.short_cart_summary", {
'website_sale_order': order,
}
)
return values
@http.route('/shop/save_shop_layout_mode', type='json', auth='public', website=True)
def save_shop_layout_mode(self, layout_mode):
@@ -637,7 +635,7 @@ class WebsiteSale(http.Controller):
return request.redirect('/shop/payment/confirmation/%s' % order.id)
def checkout_values(self, **kw):
order = request.website.sale_get_order(force_create=1)
order = request.website.sale_get_order(force_create=True)
shippings = []
if order.partner_id != request.website.user_id.sudo().partner_id:
Partner = order.partner_id.with_context(show_address=1).sudo()
@@ -21,19 +21,21 @@ class WebsiteSaleProductComparison(WebsiteSale):
@http.route(['/shop/get_product_data'], type='json', auth="public", website=True)
def get_product_data(self, product_ids, cookies=None):
ret = {}
pricelist_context, pricelist = self._get_pricelist_context()
prods = request.env['product.product'].with_context(pricelist_context, display_default_code=False).search([('id', 'in', product_ids)])
website = request.env['website'].get_current_website()
pricelist = website.pricelist_id
products = request.env['product.product'].search([('id', 'in', product_ids)])
if cookies is not None:
ret['cookies'] = json.dumps(request.env['product.product'].search([('id', 'in', list(set(product_ids + cookies)))]).ids)
prods.mapped('name')
for prod in prods:
ret[prod.id] = {
products = products.with_context(pricelist=pricelist.id, display_default_code=False)
for product in products:
ret[product.id] = {
'render': request.env['ir.ui.view']._render_template(
"website_sale_comparison.product_product",
{'product': prod, 'website': request.website}
{'product': product, 'website': website}
),
'product': dict(id=prod.id, name=prod.name, display_name=prod.display_name),
'product': dict(id=product.id, name=product.name, display_name=product.display_name),
}
return ret
@@ -1,11 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import logging
from odoo import api, fields, models
_logger = logging.getLogger(__name__)
class SaleOrder(models.Model):
_inherit = 'sale.order'
@@ -79,13 +76,13 @@ class SaleOrder(models.Model):
def _cart_update(self, *args, **kwargs):
""" Override to update carrier quotation if quantity changed """
self._remove_delivery_line()
# When you update a cart, it is not enouf to remove the "delivery cost" line
# When you update a cart, it is not enough to remove the "delivery cost" line
# The carrier might also be invalid, eg: if you bought things that are too heavy
# -> this may cause a bug if you go to the checkout screen, choose a carrier,
# then update your cart (the cart becomes uneditable)
self.write({'carrier_id': False})
if self.carrier_id:
self.carrier_id = False
return super(SaleOrder, self)._cart_update(*args, **kwargs)
return super()._cart_update(*args, **kwargs)
@@ -26,7 +26,7 @@ class WebsiteSaleProductConfiguratorController(ProductConfiguratorController):
return False
if variant_values:
kw["already_configured"] = True
return self.show_advanced_configurator(product_id, variant_values, request.website.get_current_pricelist(), **kw)
return self.show_advanced_configurator(product_id, variant_values, request.website.pricelist_id, **kw)
@http.route(['/sale_product_configurator/optional_product_items_website'], type='json', auth="public", methods=['POST'], website=True)
def optional_product_items_website(self, product_id, **kw):
@@ -34,7 +34,7 @@ class WebsiteSaleProductConfiguratorController(ProductConfiguratorController):
This route is called in JS by appending _website to the base route.
"""
kw.pop('pricelist_id')
return self.optional_product_items(product_id, request.website.get_current_pricelist(), **kw)
return self.optional_product_items(product_id, request.website.pricelist_id, **kw)
class WebsiteSale(main.WebsiteSale):
@@ -1,24 +1,24 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models
from odoo import models
class SaleOrder(models.Model):
_inherit = "sale.order"
def _cart_find_product_line(self, product_id=None, line_id=None, **kwargs):
lines = super(SaleOrder, self)._cart_find_product_line(product_id, line_id, **kwargs)
def _cart_find_product_line(
self, product_id=None, line_id=None,
linked_line_id=False, optional_product_ids=None, **kwargs
):
lines = super()._cart_find_product_line(product_id, line_id, **kwargs)
if line_id: # in this case we get the exact line we want, so filtering below would be wrong
return lines
linked_line_id = kwargs.get('linked_line_id', False)
optional_product_ids = set(kwargs.get('optional_product_ids', []))
lines = lines.filtered(lambda line: line.linked_line_id.id == linked_line_id)
if optional_product_ids:
# only match the lines with the same chosen optional products on the existing lines
lines = lines.filtered(lambda line: optional_product_ids == set(line.mapped('option_line_ids.product_id.id')))
lines = lines.filtered(lambda line: optional_product_ids == set(line.option_line_ids.product_id.id))
else:
lines = lines.filtered(lambda line: not line.option_line_ids)
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, api, fields
from odoo.tools.translate import _
from odoo import fields, models, _
class SaleOrder(models.Model):
+1 -1
View File
@@ -18,7 +18,7 @@ class Website(models.Model):
def _get_warehouse_available(self):
return (
self.warehouse_id and self.warehouse_id.id or
self.warehouse_id.id or
self.env['ir.default'].get('sale.order', 'warehouse_id', company_id=self.company_id.id) or
self.env['ir.default'].get('sale.order', 'warehouse_id') or
self.env['stock.warehouse'].sudo().search([('company_id', '=', self.company_id.id)], limit=1).id
@@ -1,18 +1,22 @@
# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale
import json
from odoo.http import request, route
from odoo.addons.website_sale.controllers.main import WebsiteSale
class WebsiteSaleWishlist(WebsiteSale):
@http.route(['/shop/wishlist/add'], type='json', auth="public", website=True)
def add_to_wishlist(self, product_id, price=False, **kw):
if not price:
pricelist_context, pl = self._get_pricelist_context()
p = request.env['product.product'].with_context(pricelist_context, display_default_code=False).browse(product_id)
price = p._get_combination_info_variant()['price']
@route(['/shop/wishlist/add'], type='json', auth="public", website=True)
def add_to_wishlist(self, product_id, **kw):
website = request.env['website'].get_current_website()
pricelist = website.pricelist_id
product = request.env['product.product'].browse(product_id)
price = product._get_combination_info_variant(
pricelist=website.pricelist_id,
)['price']
Wishlist = request.env['product.wishlist']
if request.website.is_public_user():
@@ -21,9 +25,9 @@ class WebsiteSaleWishlist(WebsiteSale):
else:
partner_id = request.env.user.partner_id.id
wish_id = Wishlist._add_to_wishlist(
pl.id,
pl.currency_id.id,
wish = Wishlist._add_to_wishlist(
pricelist.id,
pricelist.currency_id.id,
request.website.id,
price,
product_id,
@@ -31,11 +35,11 @@ class WebsiteSaleWishlist(WebsiteSale):
)
if not partner_id:
request.session['wishlist_ids'] = request.session.get('wishlist_ids', []) + [wish_id.id]
request.session['wishlist_ids'] = request.session.get('wishlist_ids', []) + [wish.id]
return wish_id
return wish
@http.route(['/shop/wishlist'], type='http', auth="public", website=True, sitemap=False)
@route(['/shop/wishlist'], type='http', auth="public", website=True, sitemap=False)
def get_wishlist(self, count=False, **kw):
values = request.env['product.wishlist'].with_context(display_default_code=False).current()
if count:
@@ -46,7 +50,7 @@ class WebsiteSaleWishlist(WebsiteSale):
return request.render("website_sale_wishlist.product_wishlist", dict(wishes=values))
@http.route(['/shop/wishlist/remove/<model("product.wishlist"):wish>'], type='json', auth="public", website=True)
@route(['/shop/wishlist/remove/<model("product.wishlist"):wish>'], type='json', auth="public", website=True)
def rm_from_wishlist(self, wish, **kw):
if request.website.is_public_user():
wish_ids = request.session.get('wishlist_ids') or []