diff --git a/addons/delivery_mondialrelay/__init__.py b/addons/delivery_mondialrelay/__init__.py
new file mode 100644
index 00000000000..35e7c9600c5
--- /dev/null
+++ b/addons/delivery_mondialrelay/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+
+from . import models
+from . import wizard
diff --git a/addons/delivery_mondialrelay/__manifest__.py b/addons/delivery_mondialrelay/__manifest__.py
new file mode 100644
index 00000000000..65302a814ba
--- /dev/null
+++ b/addons/delivery_mondialrelay/__manifest__.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+{
+ 'name': "delivery_mondialrelay",
+ 'summary': """ Let's choose a Point Relais® as shipping address """,
+
+ 'description': """
+ This module allow your customer to choose a Point Relais® and use it as shipping address.
+ This module doesn't implement the WebService. It is only the integration of the widget.
+
+ Delivery price pre-configured is an example, you need to adapt the pricing's rules.
+ """,
+ 'category': 'Inventory/Delivery',
+ 'version': '0.1',
+ 'depends': ['delivery'],
+ 'data': [
+ 'data/data.xml',
+ 'views/views.xml',
+ 'wizard/choose_delivery_carrier_views.xml',
+ ],
+ 'assets': {
+ 'web.assets_backend': [
+ 'delivery_mondialrelay/static/src/js/mondialrelay.js',
+ 'delivery_mondialrelay/static/src/scss/mondialrelay.scss',
+ ],
+ },
+ 'license': 'LGPL-3',
+}
diff --git a/addons/delivery_mondialrelay/data/data.xml b/addons/delivery_mondialrelay/data/data.xml
new file mode 100644
index 00000000000..826aea363b1
--- /dev/null
+++ b/addons/delivery_mondialrelay/data/data.xml
@@ -0,0 +1,88 @@
+
+
+
+
+
+ Mondial Relay
+ MR
+ service
+
+
+
+ 5
+ order
+
+
+
+ Mondial Relay
+ 30
+ base_on_rule
+ rate
+
+
+
+
+
+
+
+
+
+
+ >=
+
+
+
+
+
+ Mondial Relay
+ 31
+ base_on_rule
+ rate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >=
+
+
+
+
+
+ Mondial Relay
+ 32
+ base_on_rule
+ rate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >=
+
+
+
+
+
diff --git a/addons/delivery_mondialrelay/models/__init__.py b/addons/delivery_mondialrelay/models/__init__.py
new file mode 100644
index 00000000000..35f8120f52d
--- /dev/null
+++ b/addons/delivery_mondialrelay/models/__init__.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+
+from . import delivery_carrier
+from . import res_partner
+from . import sale_order
diff --git a/addons/delivery_mondialrelay/models/delivery_carrier.py b/addons/delivery_mondialrelay/models/delivery_carrier.py
new file mode 100644
index 00000000000..2c8b6a69210
--- /dev/null
+++ b/addons/delivery_mondialrelay/models/delivery_carrier.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models, api
+
+
+class DeliveryCarrierMondialRelay(models.Model):
+ _inherit = 'delivery.carrier'
+
+ is_mondialrelay = fields.Boolean(compute='_compute_is_mondialrelay')
+ mondialrelay_brand = fields.Char(string='Brand Code', default='BDTEST ', groups="base.group_system")
+ mondialrelay_packagetype = fields.Char(default="24R", groups="base.group_system") # Advanced
+
+ @api.depends('product_id.default_code')
+ def _compute_is_mondialrelay(self):
+ for c in self:
+ c.is_mondialrelay = c.product_id.default_code == "MR"
+
+ def fixed_get_tracking_link(self, picking):
+ return self.base_on_rule_get_tracking_link(picking)
+
+ def base_on_rule_get_tracking_link(self, picking):
+ if self.is_mondialrelay:
+ return 'https://www.mondialrelay.com/public/permanent/tracking.aspx?ens=%(brand)s&exp=%(track)s&language=%(lang)s' % {
+ 'brand': picking.carrier_id.mondialrelay_brand,
+ 'track': picking.carrier_tracking_ref,
+ 'lang': (picking.partner_id.lang or 'fr').split('_')[0],
+ }
+ return super().based_on_rule_get_tracking_link(picking)
diff --git a/addons/delivery_mondialrelay/models/res_partner.py b/addons/delivery_mondialrelay/models/res_partner.py
new file mode 100644
index 00000000000..8952d9e5c5b
--- /dev/null
+++ b/addons/delivery_mondialrelay/models/res_partner.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models, api
+
+
+class ResPartnerMondialRelay(models.Model):
+ _inherit = 'res.partner'
+
+ is_mondialrelay = fields.Boolean(compute='_compute_is_mondialrelay')
+
+ @api.depends('ref')
+ def _compute_is_mondialrelay(self):
+ for p in self:
+ p.is_mondialrelay = p.ref and p.ref.startswith('MR#')
+
+ @api.model
+ def _mondialrelay_search_or_create(self, data):
+ ref = 'MR#%s' % data['id']
+ partner = self.search([
+ ('id', 'child_of', self.commercial_partner_id.ids),
+ ('ref', '=', ref),
+ # fast check that address always the same
+ ('street', '=', data['street']),
+ ('zip', '=', data['zip']),
+ ])
+ if not partner:
+ partner = self.create({
+ 'ref': ref,
+ 'name': data['name'],
+ 'street': data['street'],
+ 'street2': data['street2'],
+ 'zip': data['zip'],
+ 'city': data['city'],
+ 'country_id': self.env.ref('base.%s' % data['country_code']).id,
+ 'type': 'delivery',
+ 'parent_id': self.id,
+ })
+ return partner
diff --git a/addons/delivery_mondialrelay/models/sale_order.py b/addons/delivery_mondialrelay/models/sale_order.py
new file mode 100644
index 00000000000..c492e31fc57
--- /dev/null
+++ b/addons/delivery_mondialrelay/models/sale_order.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models, _
+from odoo.exceptions import UserError
+
+
+class SaleOrderMondialRelay(models.Model):
+ _inherit = 'sale.order'
+
+ def action_confirm(self):
+ unmatch = self.filtered(lambda so: so.carrier_id.is_mondialrelay != so.partner_shipping_id.is_mondialrelay)
+ if unmatch:
+ error = _('Mondial Relay mismatching between delivery method and shipping address.')
+ if len(self) > 1:
+ error += ' (%s)' % ','.join(unmatch.mapped('name'))
+ raise UserError(error)
+ return super().action_confirm()
diff --git a/addons/delivery_mondialrelay/static/src/img/truck_mr.png b/addons/delivery_mondialrelay/static/src/img/truck_mr.png
new file mode 100644
index 00000000000..1810acdcca1
Binary files /dev/null and b/addons/delivery_mondialrelay/static/src/img/truck_mr.png differ
diff --git a/addons/delivery_mondialrelay/static/src/js/mondialrelay.js b/addons/delivery_mondialrelay/static/src/js/mondialrelay.js
new file mode 100644
index 00000000000..bbb6fd6061a
--- /dev/null
+++ b/addons/delivery_mondialrelay/static/src/js/mondialrelay.js
@@ -0,0 +1,70 @@
+/** @odoo-module **/
+
+import AbstractField from 'web.AbstractField';
+import fieldRegistry from 'web.field_registry';
+
+
+var MondialRelayWidget = AbstractField.extend({
+ resetOnAnyFieldChange: true,
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ * @private
+ */
+ _render: function () {
+ if (this.recordData.is_mondialrelay) {
+ if (!this.mondialRelayInitialized) {
+ const script = document.createElement('script');
+ script.src = "https://widget.mondialrelay.com/parcelshop-picker/jquery.plugin.mondialrelay.parcelshoppicker.min.js";
+ script.onload = () => {
+ this.mondialRelayInitialized = true;
+ this._loadWidget();
+ };
+ document.body.appendChild(script);
+ } else {
+ this._loadWidget();
+ }
+ } else {
+ this.$el.hide();
+ }
+ },
+
+ /**
+ *
+ * @private
+ */
+ _loadWidget: function () {
+ const params = {
+ Target: "", // required but handled by OnParcelShopSelected
+ Brand: this.recordData.mondialrelay_brand,
+ ColLivMod: this.recordData.mondial_realy_colLivMod,
+ AllowedCountries: this.recordData.mondialrelay_allowed_countries,
+ PostCode: this.recordData.shipping_zip || '',
+ Country: this.recordData.shipping_country_code || '',
+ Responsive: true,
+ ShowResultsOnMap: true,
+ AutoSelect: this.recordData.mondialrelay_last_selected_id,
+ OnParcelShopSelected: (RelaySelected) => {
+ const values = JSON.stringify({
+ 'id': RelaySelected.ID,
+ 'name': RelaySelected.Nom,
+ 'street': RelaySelected.Adresse1,
+ 'street2': RelaySelected.Adresse2,
+ 'zip': RelaySelected.CP,
+ 'city': RelaySelected.Ville,
+ 'country': RelaySelected.Pays,
+ });
+ this._setValue(values);
+ },
+ };
+ this.$el.show();
+ this.$el.MR_ParcelShopPicker(params);
+ this.$el.trigger("MR_RebindMap");
+ },
+
+});
+
+fieldRegistry.add("mondialrelay_relay", MondialRelayWidget);
diff --git a/addons/delivery_mondialrelay/static/src/scss/mondialrelay.scss b/addons/delivery_mondialrelay/static/src/scss/mondialrelay.scss
new file mode 100644
index 00000000000..00e7ed919c5
--- /dev/null
+++ b/addons/delivery_mondialrelay/static/src/scss/mondialrelay.scss
@@ -0,0 +1,5 @@
+.MRW-Search .MRW-Container {
+ input.iArg0, input.Arg2 {
+ display: inline !important,
+ }
+}
diff --git a/addons/delivery_mondialrelay/views/views.xml b/addons/delivery_mondialrelay/views/views.xml
new file mode 100644
index 00000000000..56566676f51
--- /dev/null
+++ b/addons/delivery_mondialrelay/views/views.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ delivery.carrier.form.provider.mondialrelay
+ delivery.carrier
+
+
+
+
+
+
+
+
+
+
+ delivery.carrier.tree.provider.mondialrelay
+ delivery.carrier
+
+
+
+
+
+
+
+
+
+ view_partner_form_mondialrelay
+ res.partner
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/addons/delivery_mondialrelay/wizard/__init__.py b/addons/delivery_mondialrelay/wizard/__init__.py
new file mode 100644
index 00000000000..718862762ba
--- /dev/null
+++ b/addons/delivery_mondialrelay/wizard/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import choose_delivery_carrier
diff --git a/addons/delivery_mondialrelay/wizard/choose_delivery_carrier.py b/addons/delivery_mondialrelay/wizard/choose_delivery_carrier.py
new file mode 100644
index 00000000000..70507e63822
--- /dev/null
+++ b/addons/delivery_mondialrelay/wizard/choose_delivery_carrier.py
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import fields, models, api, _
+from odoo.tools.json import scriptsafe as json_safe
+from odoo.exceptions import ValidationError
+
+
+class ChooseDeliveryCarrier(models.TransientModel):
+ _inherit = 'choose.delivery.carrier'
+
+ shipping_zip = fields.Char(related='order_id.partner_shipping_id.zip')
+ shipping_country_code = fields.Char(related='order_id.partner_shipping_id.country_id.code')
+
+ is_mondialrelay = fields.Boolean(compute='_compute_is_mondialrelay')
+ mondialrelay_last_selected = fields.Char(string="Last Relay Selected")
+ mondialrelay_last_selected_id = fields.Char(compute='_compute_mr_last_selected_id')
+ mondialrelay_brand = fields.Char(related='carrier_id.mondialrelay_brand')
+ mondialrelay_colLivMod = fields.Char(related='carrier_id.mondialrelay_packagetype')
+ mondialrelay_allowed_countries = fields.Char(compute='_compute_mr_allowed_countries')
+
+ @api.depends('carrier_id')
+ def _compute_is_mondialrelay(self):
+ self.ensure_one()
+ self.is_mondialrelay = self.carrier_id.product_id.default_code == "MR"
+
+ @api.depends('carrier_id', 'order_id.partner_shipping_id')
+ def _compute_mr_last_selected_id(self):
+ self.ensure_one()
+ if self.order_id.partner_shipping_id.is_mondialrelay:
+ self.mondialrelay_last_selected_id = '%s-%s' % (
+ self.shipping_country_code,
+ self.order_id.partner_shipping_id.ref.lstrip('MR#'),
+ )
+ else:
+ self.mondialrelay_last_selected_id = ''
+
+ @api.depends('carrier_id')
+ def _compute_mr_allowed_countries(self):
+ self.ensure_one()
+ self.mondialrelay_allowed_countries = ','.join(self.carrier_id.country_ids.mapped('code')).upper() or ''
+
+ def button_confirm(self):
+ if self.carrier_id.is_mondialrelay:
+ if not self.mondialrelay_last_selected:
+ raise ValidationError(_('Please, choose a Parcel Point'))
+ data = json_safe.loads(self.mondialrelay_last_selected)
+ partner_shipping = self.order_id.partner_id._mondialrelay_search_or_create({
+ 'id': data['id'],
+ 'name': data['name'],
+ 'street': data['street'],
+ 'street2': data['street2'],
+ 'zip': data['zip'],
+ 'city': data['city'],
+ 'country_code': data['country'][:2].lower(),
+ })
+ if partner_shipping != self.order_id.partner_shipping_id:
+ self.order_id.partner_shipping_id = partner_shipping
+ self.order_id.onchange_partner_shipping_id()
+
+ return super().button_confirm()
diff --git a/addons/delivery_mondialrelay/wizard/choose_delivery_carrier_views.xml b/addons/delivery_mondialrelay/wizard/choose_delivery_carrier_views.xml
new file mode 100644
index 00000000000..1333fbc10d4
--- /dev/null
+++ b/addons/delivery_mondialrelay/wizard/choose_delivery_carrier_views.xml
@@ -0,0 +1,21 @@
+
+
+
+ choose.delivery.carrier.form
+ choose.delivery.carrier
+
+
+
+
+
+
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index 86025f97846..53c584c4e78 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -739,6 +739,7 @@ class WebsiteSale(http.Controller):
order.partner_shipping_id = partner_id
# TDE FIXME: don't ever do this
+ # -> TDE: you are the guy that did what we should never do in commit e6f038a
order.message_partner_ids = [(4, partner_id), (3, request.website.partner_id.id)]
if not errors:
return request.redirect(kw.get('callback') or '/shop/confirm_order')
diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml
index 978876e343f..839dc9f8cc0 100644
--- a/addons/website_sale/views/templates.xml
+++ b/addons/website_sale/views/templates.xml
@@ -1223,6 +1223,7 @@
+
@@ -1238,20 +1239,20 @@
-
+
-
+
@@ -1287,7 +1288,7 @@
-
-
-
Edit
-
-
Billing & Shipping:
-
Shipping:
-
+
+
diff --git a/addons/website_sale_delivery/views/website_sale_delivery_templates.xml b/addons/website_sale_delivery/views/website_sale_delivery_templates.xml
index e31703f0196..04df661a90a 100644
--- a/addons/website_sale_delivery/views/website_sale_delivery_templates.xml
+++ b/addons/website_sale_delivery/views/website_sale_delivery_templates.xml
@@ -36,7 +36,7 @@
-
+
@@ -46,6 +46,9 @@
+
+
+
diff --git a/addons/website_sale_delivery_mondialrelay/__init__.py b/addons/website_sale_delivery_mondialrelay/__init__.py
new file mode 100644
index 00000000000..aa4d0fd63a9
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/__init__.py
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+
+from . import controllers
+from . import models
diff --git a/addons/website_sale_delivery_mondialrelay/__manifest__.py b/addons/website_sale_delivery_mondialrelay/__manifest__.py
new file mode 100644
index 00000000000..92ebd70f3be
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/__manifest__.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+{
+ 'name': "website_sale_delivery_mondialrelay",
+ 'summary': """ Let's choose Point Relais® on your ecommerce """,
+
+ 'description': """
+ This module allow your customer to choose a Point Relais® and use it as shipping address.
+ """,
+ 'category': 'Website/Website',
+ 'version': '0.1',
+ 'depends': ['website_sale_delivery', 'delivery_mondialrelay'],
+ 'data': [
+ 'views/templates.xml',
+ ],
+ 'assets': {
+ 'web.assets_frontend': [
+ 'website_sale_delivery_mondialrelay/static/src/js/website_sale_delivery_mondialrelay.js',
+ ],
+ },
+ 'license': 'LGPL-3',
+ 'auto_install': True,
+}
diff --git a/addons/website_sale_delivery_mondialrelay/controllers/__init__.py b/addons/website_sale_delivery_mondialrelay/controllers/__init__.py
new file mode 100644
index 00000000000..b0f26a9a602
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/controllers/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import controllers
diff --git a/addons/website_sale_delivery_mondialrelay/controllers/controllers.py b/addons/website_sale_delivery_mondialrelay/controllers/controllers.py
new file mode 100644
index 00000000000..6b495769d9f
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/controllers/controllers.py
@@ -0,0 +1,87 @@
+# -*- coding: utf-8 -*-
+from odoo import http, _
+from odoo.addons.website_sale.controllers.main import WebsiteSale, PaymentPortal
+from odoo.addons.website_sale_delivery.controllers.main import WebsiteSaleDelivery
+
+from odoo.exceptions import AccessDenied, ValidationError, UserError
+from odoo.http import request
+
+
+class MondialRelay(http.Controller):
+
+ @http.route(['/website_sale_delivery_mondialrelay/update_shipping'], type='json', auth="public", website=True)
+ def mondial_relay_update_shipping(self, **data):
+ order = request.website.sale_get_order()
+
+ if order.partner_id == request.website.user_id.sudo().partner_id:
+ raise AccessDenied('Customer of the order cannot be the public user at this step.')
+
+ if order.carrier_id.country_ids:
+ country_is_allowed = data['Pays'][:2].upper() in order.carrier_id.country_ids.mapped(lambda c: c.code.upper())
+ assert country_is_allowed, _("%s is not allowed for this delivery carrier.", data['Pays'])
+
+ partner_shipping = order.partner_id.sudo()._mondialrelay_search_or_create({
+ 'id': data['ID'],
+ 'name': data['Nom'],
+ 'street': data['Adresse1'],
+ 'street2': data['Adresse2'],
+ 'zip': data['CP'],
+ 'city': data['Ville'],
+ 'country_code': data['Pays'][:2].lower(),
+ })
+ if order.partner_shipping_id != partner_shipping:
+ order.partner_shipping_id = partner_shipping
+ order.onchange_partner_shipping_id()
+
+ return {
+ 'address': request.env['ir.qweb']._render('website_sale.address_on_payment', {
+ 'order': order,
+ 'only_services': order and order.only_services,
+ }),
+ 'new_partner_shipping_id': order.partner_shipping_id.id,
+ }
+
+
+class WebsiteSaleMondialrelay(WebsiteSale):
+
+ @http.route()
+ def address(self, **kw):
+ res = super().address(**kw)
+ Partner_sudo = request.env['res.partner'].sudo()
+ partner_id = res.qcontext.get('partner_id', 0)
+ if partner_id > 0 and Partner_sudo.browse(partner_id).is_mondialrelay:
+ raise UserError(_('You cannot edit the address of a Point Relais®.'))
+ return res
+
+
+class WebsiteSaleDeliveryMondialrelay(WebsiteSaleDelivery):
+
+ def _update_website_sale_delivery_return(self, order, **post):
+ res = super()._update_website_sale_delivery_return(order, **post)
+ if order.carrier_id.is_mondialrelay:
+ res['mondial_relay'] = {
+ 'brand': order.carrier_id.mondialrelay_brand,
+ 'col_liv_mod': order.carrier_id.mondialrelay_packagetype,
+ 'partner_zip': order.partner_shipping_id.zip,
+ 'partner_country_code': order.partner_shipping_id.country_id.code.upper(),
+ 'allowed_countries': ','.join(order.carrier_id.country_ids.mapped('code')).upper(),
+ }
+ if order.partner_shipping_id.is_mondialrelay:
+ res['mondial_relay']['current'] = '%s-%s' % (
+ res['mondial_relay']['partner_country_code'],
+ order.partner_shipping_id.ref.lstrip('MR#'),
+ )
+
+ return res
+
+
+class PaymentPortalMondialRelay(PaymentPortal):
+
+ @http.route()
+ def shop_payment_transaction(self, *args, **kwargs):
+ order = request.website.sale_get_order()
+ if order.partner_shipping_id.is_mondialrelay and not order.carrier_id.is_mondialrelay:
+ raise ValidationError(_('Point Relais® can only be used with the delivery method Mondial Relay.'))
+ elif not order.partner_shipping_id.is_mondialrelay and order.carrier_id.is_mondialrelay:
+ raise ValidationError(_('Delivery method Mondial Relay can only ship to Point Relais®.'))
+ return super().shop_payment_transaction(*args, **kwargs)
diff --git a/addons/website_sale_delivery_mondialrelay/models/__init__.py b/addons/website_sale_delivery_mondialrelay/models/__init__.py
new file mode 100644
index 00000000000..1beda913b56
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/models/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+
+from . import website
diff --git a/addons/website_sale_delivery_mondialrelay/models/website.py b/addons/website_sale_delivery_mondialrelay/models/website.py
new file mode 100644
index 00000000000..46afa1b2b5c
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/models/website.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from odoo import models
+
+
+class WebsiteMondialRelay(models.Model):
+ _inherit = 'website'
+
+ def _prepare_sale_order_values(self, partner, pricelist):
+ self.ensure_one()
+ values = super()._prepare_sale_order_values(partner, pricelist)
+ # never use Mondial Relay shipping address as default.
+ shipping_address = self.env['res.partner'].browse(values['partner_shipping_id'])
+ if shipping_address.id != values['partner_invoice_id'] and shipping_address.is_mondialrelay:
+ values['partner_shipping_id'] = values['partner_invoice_id']
+ return values
diff --git a/addons/website_sale_delivery_mondialrelay/static/src/img/logo.png b/addons/website_sale_delivery_mondialrelay/static/src/img/logo.png
new file mode 100644
index 00000000000..4271942be4d
Binary files /dev/null and b/addons/website_sale_delivery_mondialrelay/static/src/img/logo.png differ
diff --git a/addons/website_sale_delivery_mondialrelay/static/src/js/website_sale_delivery_mondialrelay.js b/addons/website_sale_delivery_mondialrelay/static/src/js/website_sale_delivery_mondialrelay.js
new file mode 100644
index 00000000000..1c8e512902c
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/static/src/js/website_sale_delivery_mondialrelay.js
@@ -0,0 +1,105 @@
+/** @odoo-module **/
+
+import publicWidget from "web.public.widget";
+import "website_sale_delivery.checkout";
+import {qweb as QWeb} from "web.core";
+
+const WebsiteSaleDeliveryWidget = publicWidget.registry.websiteSaleDelivery;
+
+
+WebsiteSaleDeliveryWidget.include({
+ xmlDependencies: (WebsiteSaleDeliveryWidget.prototype.xmlDependencies || []).concat([
+ '/website_sale_delivery_mondialrelay/static/src/xml/website_sale_delivery_mondialrelay.xml',
+ ]),
+ events: _.extend({
+ "click #btn_confirm_relay": "_onClickBtnConfirmRelay",
+ }, WebsiteSaleDeliveryWidget.prototype.events),
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * Loads Mondial Relay the first time, else show it.
+ *
+ * @override
+ */
+ _handleCarrierUpdateResult: function (result) {
+ this._super(...arguments);
+ if (result.mondial_relay) {
+ if (!$('#modal_mondialrelay').length) {
+ this._loadMondialRelayModal(result);
+ } else {
+ this.$modal_mondialrelay.find('#btn_confirm_relay').toggleClass('disabled', !result.mondial_relay.current);
+ this.$modal_mondialrelay.modal('show');
+ }
+ }
+ },
+ /**
+ * This method render the modal, and inject it in dom with the Modial Relay Widgets script.
+ * Once script loaded, it initialize the widget pre-configured with the information of result
+ *
+ * @private
+ *
+ * @param {Object} result: dict returned by call of _update_website_sale_delivery_return (python)
+ */
+ _loadMondialRelayModal: function (result) {
+ // add modal to body and bind 'save' button
+ $(QWeb.render('website_sale_delivery_mondialrelay', {})).appendTo('body');
+ this.$modal_mondialrelay = $('#modal_mondialrelay');
+ this.$modal_mondialrelay.find('#btn_confirm_relay').on('click', this._onClickBtnConfirmRelay.bind(this));
+
+ // load mondial relay script
+ const script = document.createElement('script');
+ script.src = "https://widget.mondialrelay.com/parcelshop-picker/jquery.plugin.mondialrelay.parcelshoppicker.min.js";
+ script.onload = () => {
+ // instanciate MondialRelay widget
+ const params = {
+ Target: "", // required but handled by OnParcelShopSelected
+ Brand: result.mondial_relay.brand,
+ ColLivMod: result.mondial_relay.col_liv_mod,
+ AllowedCountries: result.mondial_relay.allowed_countries,
+ Country: result.mondial_relay.partner_country_code,
+ PostCode: result.mondial_relay.partner_zip,
+ Responsive: true,
+ ShowResultsOnMap: true,
+ AutoSelect: result.mondial_relay.current,
+ OnParcelShopSelected: (RelaySelected) => {
+ this.lastRelaySelected = RelaySelected;
+ this.$modal_mondialrelay.find('#btn_confirm_relay').removeClass('disabled');
+ },
+ };
+ this.$modal_mondialrelay.find('#o_zone_widget').MR_ParcelShopPicker(params);
+ this.$modal_mondialrelay.modal('show');
+ this.$modal_mondialrelay.find('#o_zone_widget').trigger("MR_RebindMap");
+ };
+ document.body.appendChild(script);
+
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+
+ /**
+ * Update the shipping address on the order and refresh the UI.
+ *
+ * @private
+ *
+ */
+ _onClickBtnConfirmRelay: function () {
+ if (!this.lastRelaySelected) {
+ return;
+ }
+ this._rpc({
+ route: '/website_sale_delivery_mondialrelay/update_shipping',
+ params: {
+ ...this.lastRelaySelected,
+ },
+ }).then((o) => {
+ $('#address_on_payment').html(o.address);
+ this.$modal_mondialrelay.modal('hide');
+ });
+ },
+});
diff --git a/addons/website_sale_delivery_mondialrelay/static/src/xml/website_sale_delivery_mondialrelay.xml b/addons/website_sale_delivery_mondialrelay/static/src/xml/website_sale_delivery_mondialrelay.xml
new file mode 100644
index 00000000000..cf69a0b0aaa
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/static/src/xml/website_sale_delivery_mondialrelay.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
diff --git a/addons/website_sale_delivery_mondialrelay/views/templates.xml b/addons/website_sale_delivery_mondialrelay/views/templates.xml
new file mode 100644
index 00000000000..79fdfdde676
--- /dev/null
+++ b/addons/website_sale_delivery_mondialrelay/views/templates.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/odoo/addons/base/views/res_partner_views.xml b/odoo/addons/base/views/res_partner_views.xml
index 205e80d572f..f1925fac1d0 100644
--- a/odoo/addons/base/views/res_partner_views.xml
+++ b/odoo/addons/base/views/res_partner_views.xml
@@ -271,8 +271,10 @@