Steps: - Install eCommerce and a delivery method (here, UPS) - Go to Website > Configuration > Settings - Select Pricing > Product Prices > Tax-Included - Go to Configuration > eCommerce/Shipping Methods - Click UPS US and publish it - Go to the eCommerce - Add a product to the cart (here, Customizable Desk) - Click My Cart > Process Checkout - UPS has a delivery price - Select UPS Bug: The delivery price of the UPS line has changed Explanation: When we first arrive to the delivery selection, prices are computed by calling the carrier's API and are shown straight away. However, when a list item is clicked, a "Delivery" sale order line is generated and the price on the list is copied from that sale order line. Before 13.0, we explicitly asked customers to click on a delivery method to see its price. Now, it's automatically computed. This fix makes sure the taxes are applied to the delivery prices before clicking on them. opw:2392281 closes odoo/odoo#62806 X-original-commit: bc2615d8ab5135f21c488c5a260c59605b0da498 Signed-off-by: backspac <backspac@users.noreply.github.com>
122 lines
5.8 KiB
Python
122 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(['/shop/payment'], type='http', auth="public", website=True)
|
|
def 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).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, carrier.product_id, order.partner_shipping_id)
|
|
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)
|
|
for line in order.order_line:
|
|
if line.is_delivery:
|
|
ret['transaction']['shipping'] = 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}),
|
|
}
|
|
return {}
|