Files
odoo_source/addons/website_sale_delivery/controllers/main.py
T
anhe-odoo 349c3710ae [FIX] website_*: update of the total amount according to the shipping method
Expected behaviour

When buying something on the website, the amount to be paid for the client
should take into account the choice of the shipping method.

Observed behaviour

When choosing a different shipping method than the default one, and only
if this method is a third party acquire, the total amount is updated on
the website, but the amount the client will be asked to pay doesn't take
into account this change, being computed according to the default shipping
method.

Steps to Reproduce this Issue
1. Select a product on the website and add it to the cart
2. View and validate the cart
3. Change the shipping method
4. Click on the "Pay now" button

Problem Root Cause

This issue comes from the fact that the amount was written in the view when
creating the cart view and wasn't updated by a change of shipping method.

Related issue
opw-2686369

closes odoo/odoo#81587

X-original-commit: 617ed0ef47d1496b912d5b85a494e3cda897da4d
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
Signed-off-by: Hendrickx Anthony (anhe) <anhe@odoo.com>
2021-12-17 12:51:49 +00:00

123 lines
5.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import http, _
from odoo.http import request
from odoo.addons.website_sale.controllers.main import WebsiteSale
from odoo.exceptions import UserError
class WebsiteSaleDelivery(WebsiteSale):
@http.route()
def shop_payment(self, **post):
order = request.website.sale_get_order()
carrier_id = post.get('carrier_id')
if carrier_id:
carrier_id = int(carrier_id)
if order:
order._check_carrier_quotation(force_carrier_id=carrier_id)
if carrier_id:
return request.redirect("/shop/payment")
return super(WebsiteSaleDelivery, self).shop_payment(**post)
@http.route(['/shop/update_carrier'], type='json', auth='public', methods=['POST'], website=True, csrf=False)
def update_eshop_carrier(self, **post):
order = request.website.sale_get_order()
carrier_id = int(post['carrier_id'])
if order:
order._check_carrier_quotation(force_carrier_id=carrier_id)
return self._update_website_sale_delivery_return(order, **post)
@http.route(['/shop/carrier_rate_shipment'], type='json', auth='public', methods=['POST'], website=True)
def cart_carrier_rate_shipment(self, carrier_id, **kw):
order = request.website.sale_get_order(force_create=True)
if not int(carrier_id) in order._get_delivery_methods().ids:
raise UserError(_('It seems that a delivery method is not compatible with your address. Please refresh the page and try again.'))
Monetary = request.env['ir.qweb.field.monetary']
res = {'carrier_id': carrier_id}
carrier = request.env['delivery.carrier'].sudo().browse(int(carrier_id))
rate = carrier.rate_shipment(order)
if rate.get('success'):
tax_ids = carrier.product_id.taxes_id.filtered(lambda t: t.company_id == order.company_id)
if tax_ids:
fpos = order.fiscal_position_id
tax_ids = fpos.map_tax(tax_ids)
taxes = tax_ids.compute_all(
rate['price'],
currency=order.currency_id,
quantity=1.0,
product=carrier.product_id,
partner=order.partner_shipping_id,
)
if request.env.user.has_group('account.group_show_line_subtotals_tax_excluded'):
rate['price'] = taxes['total_excluded']
else:
rate['price'] = taxes['total_included']
res['status'] = True
res['new_amount_delivery'] = Monetary.value_to_html(rate['price'], {'display_currency': order.currency_id})
res['is_free_delivery'] = not bool(rate['price'])
res['error_message'] = rate['warning_message']
else:
res['status'] = False
res['new_amount_delivery'] = Monetary.value_to_html(0.0, {'display_currency': order.currency_id})
res['error_message'] = rate['error_message']
return res
def order_lines_2_google_api(self, order_lines):
""" Transforms a list of order lines into a dict for google analytics """
order_lines_not_delivery = order_lines.filtered(lambda line: not line.is_delivery)
return super(WebsiteSaleDelivery, self).order_lines_2_google_api(order_lines_not_delivery)
def order_2_return_dict(self, order):
""" Returns the tracking_cart dict of the order for Google analytics """
ret = super(WebsiteSaleDelivery, self).order_2_return_dict(order)
delivery_line = order.order_line.filtered('is_delivery')
if delivery_line:
ret['shipping'] = delivery_line.price_unit
return ret
def _get_shop_payment_values(self, order, **kwargs):
values = super(WebsiteSaleDelivery, self)._get_shop_payment_values(order, **kwargs)
has_storable_products = any(line.product_id.type in ['consu', 'product'] for line in order.order_line)
if not order._get_delivery_methods() and has_storable_products:
values['errors'].append(
(_('Sorry, we are unable to ship your order'),
_('No shipping method is available for your current order and shipping address. '
'Please contact us for more information.')))
if has_storable_products:
if order.carrier_id and not order.delivery_rating_success:
order._remove_delivery_line()
delivery_carriers = order._get_delivery_methods()
values['deliveries'] = delivery_carriers.sudo()
values['delivery_has_storable'] = has_storable_products
values['delivery_action_id'] = request.env.ref('delivery.action_delivery_carrier_form').id
return values
def _update_website_sale_delivery_return(self, order, **post):
Monetary = request.env['ir.qweb.field.monetary']
carrier_id = int(post['carrier_id'])
currency = order.currency_id
if order:
return {
'status': order.delivery_rating_success,
'error_message': order.delivery_message,
'carrier_id': carrier_id,
'is_free_delivery': not bool(order.amount_delivery),
'new_amount_delivery': Monetary.value_to_html(order.amount_delivery, {'display_currency': currency}),
'new_amount_untaxed': Monetary.value_to_html(order.amount_untaxed, {'display_currency': currency}),
'new_amount_tax': Monetary.value_to_html(order.amount_tax, {'display_currency': currency}),
'new_amount_total': Monetary.value_to_html(order.amount_total, {'display_currency': currency}),
'new_amount_total_raw': order.amount_total,
}
return {}