Skip to content
Browse files

[IMP] website_sale_delivery: load carrier price async

Before this commit:
User landing on checkout payment step had to select a carrier.
These carriers only showed 'Select to compute price'. This was done to
prevent the page to take seconds to load, since it would compute all the
carrier price by querying these carrier API then display the page.
The users would still click on every carrier anyway to check all the prices and
select the cheapest one.

Once the page is loaded, we will asynchronously retrieve every carrier prices.
That way, the page rendering page will not be affected and the user will be
able to see the price of every carrier after a few seconds without having to do

  • Loading branch information...
rdeodoo committed Mar 18, 2019
1 parent 751de46 commit caa2bbc3bed7d094b71804c54e7c591af917f6be
@@ -29,6 +29,22 @@ def update_eshop_carrier(self, **post):
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 =
res = {'carrier_id': carrier_id}
carrier = request.env['delivery.carrier'].browse(int(carrier_id))
rate = carrier.rate_shipment(order)
if rate.get('success'):
res['status'] = True
res['new_amount_delivery'] = rate['price']
res['error_message'] = rate['warning_message']
res['status'] = False
res['new_amount_delivery'] = 0.0
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)
@@ -19,20 +19,41 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
* @override
start: function () {
var self = this;
var $carriers = $('#delivery_carrier input[name="delivery_type"]');
// Workaround to:
// - update the amount/error on the label at first rendering
// - prevent clicking on 'Pay Now' if the shipper rating fails
if ($carriers.length > 0) {

// Asynchronously retrieve every carrier price
_.each($carriers, function (carrierInput, k) {
route: '/shop/carrier_rate_shipment',
params: {
carrier_id: carrierInput.value,

return this._super.apply(this, arguments);

// Private

* @private
* @param {jQuery} $carrierInput
_showLoading: function ($carrierInput) {
$carrierInput.siblings('.o_delivery_compute').removeClass('d-none').html('<span class="fa fa-spinner fa-spin"/>');
* @private
* @param {Object} result
@@ -94,6 +115,7 @@ publicWidget.registry.websiteSaleDelivery = publicWidget.Widget.extend({
_onCarrierClick: function (ev) {
var $radio = $(ev.currentTarget).find('input[type="radio"]');
$radio.prop("checked", true);
var $payButton = $('#o_payment_form_pay');
$payButton.prop('disabled', true);
@@ -31,7 +31,7 @@
<span t-else="" t-att-class="badge_class">Free</span>
<t t-else="">
<span t-attf-class="#{badge_class} d-none" t-field="delivery.fixed_price" t-options='{"widget": "monetary", "from_currency": delivery.product_id.company_id.currency_id, "display_currency": website_sale_order.currency_id}'/>
<span t-attf-class="#{badge_class} o_delivery_badge_price d-none" t-field="delivery.fixed_price" t-options='{"widget": "monetary", "from_currency": delivery.product_id.company_id.currency_id, "display_currency": website_sale_order.currency_id}'/>
<span t-attf-class="#{badge_class} o_delivery_compute">Select to compute delivery rate</span>
<t t-if="delivery.website_description">

0 comments on commit caa2bbc

Please sign in to comment.
You can’t perform that action at this time.