@ -0,0 +1,48 @@ |
|||||
|
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.svg |
||||
|
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
Web Pay Shipping Methods |
||||
|
======================== |
||||
|
This Module allows users to assign shipping methods to payment providers, ensuring that only the specified shipping methods are available when a payment provider is selected during checkout. |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
* No Additional configuration is needed. |
||||
|
|
||||
|
Company |
||||
|
------- |
||||
|
* `Cybrosys Techno Solutions <https://cybrosys.com/>`__ |
||||
|
|
||||
|
License |
||||
|
------- |
||||
|
Affero General Public License, v3.0 (AGPL v3). |
||||
|
(https://www.gnu.org/licenses/agpl-3.0-standalone.html) |
||||
|
|
||||
|
Credits |
||||
|
------- |
||||
|
* Developers: (V17) Mruthul Raj |
||||
|
(V18) Aysha Shalin |
||||
|
Contact: odoo@cybrosys.com |
||||
|
|
||||
|
Contacts |
||||
|
-------- |
||||
|
* Mail Contact : odoo@cybrosys.com |
||||
|
* Website : https://cybrosys.com |
||||
|
|
||||
|
Bug Tracker |
||||
|
---------- |
||||
|
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. |
||||
|
|
||||
|
Maintainer |
||||
|
========== |
||||
|
.. image:: https://cybrosys.com/images/logo.png |
||||
|
:target: https://cybrosys.com |
||||
|
|
||||
|
This module is maintained by Cybrosys Technologies. |
||||
|
|
||||
|
For support and more information, please visit `Our Website <https://cybrosys.com/>`__ |
||||
|
|
||||
|
Further information |
||||
|
=================== |
||||
|
HTML Description: `<static/description/index.html>`__ |
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Aysha Shalin (odoo@cybrosys.com) |
||||
|
# |
||||
|
# you can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC |
||||
|
# LICENSE (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from . import controllers |
||||
|
from . import models |
@ -0,0 +1,50 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Aysha Shalin (odoo@cybrosys.com) |
||||
|
# |
||||
|
# you can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC |
||||
|
# LICENSE (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
{ |
||||
|
'name': "Web Pay Shipping Methods", |
||||
|
'version': '18.0.1.0.0', |
||||
|
'category': 'eCommerce', |
||||
|
'summary': """Select shipping methods based on payment provider.""", |
||||
|
'description': """The shipping methods assigned to a payment provider will |
||||
|
only be available when selecting that provider during the website sale |
||||
|
checkout process.""", |
||||
|
'author': "Cybrosys Techno Solutions", |
||||
|
'company': "Cybrosys Techno Solutions", |
||||
|
'maintainer': "Cybrosys Techno Solutions", |
||||
|
'website': "https://www.cybrosys.com", |
||||
|
'depends': ['website_sale'], |
||||
|
'data': [ |
||||
|
'views/payment_provider_views.xml', |
||||
|
'views/website_sale_delivery_templates.xml' |
||||
|
], |
||||
|
'assets': { |
||||
|
'web.assets_frontend': [ |
||||
|
'web_pay_shipping_methods/static/src/js/PaymentForm.js', |
||||
|
'web_pay_shipping_methods/static/src/js/DeliveryMethod.js' |
||||
|
], |
||||
|
}, |
||||
|
'images': ['static/description/banner.png'], |
||||
|
'license': 'AGPL-3', |
||||
|
'installable': True, |
||||
|
'auto_install': False, |
||||
|
'application': False, |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Aysha Shalin (odoo@cybrosys.com) |
||||
|
# |
||||
|
# you can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC |
||||
|
# LICENSE (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from . import main |
@ -0,0 +1,76 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Aysha Shalin (odoo@cybrosys.com) |
||||
|
# |
||||
|
# you can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC |
||||
|
# LICENSE (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from odoo.addons.payment.controllers import portal as payment_portal |
||||
|
|
||||
|
from odoo.http import route, request |
||||
|
from odoo.tools import str2bool |
||||
|
|
||||
|
|
||||
|
class WebsiteSale(payment_portal.PaymentPortal): |
||||
|
@route('/shop/payment', type='http', auth='public', website=True, sitemap=False) |
||||
|
def shop_payment(self, try_skip_step=None, **post): |
||||
|
""" Payment step. This page proposes several payment means based on available |
||||
|
payment.provider. State at this point : |
||||
|
|
||||
|
- a draft sales order with lines; otherwise, clean context / session and |
||||
|
back to the shop |
||||
|
- no transaction in context / session, or only a draft one, if the customer |
||||
|
did go to a payment.provider website but closed the tab without |
||||
|
paying / canceling |
||||
|
""" |
||||
|
try_skip_step = str2bool(try_skip_step or 'false') |
||||
|
order_sudo = request.website.sale_get_order() |
||||
|
|
||||
|
checkout_page_values = self._prepare_checkout_page_values(order_sudo, |
||||
|
**post) |
||||
|
|
||||
|
if redirection := self._check_cart_and_addresses(order_sudo): |
||||
|
return redirection |
||||
|
|
||||
|
render_values = self._get_shop_payment_values(order_sudo, **post) |
||||
|
render_values['only_services'] = order_sudo and order_sudo.only_services |
||||
|
|
||||
|
can_skip_delivery = True # Delivery is only needed for deliverable products. |
||||
|
if order_sudo._has_deliverable_products(): |
||||
|
available_dms = order_sudo._get_delivery_methods() |
||||
|
checkout_page_values['delivery_methods'] = available_dms |
||||
|
if delivery_method := order_sudo._get_preferred_delivery_method( |
||||
|
available_dms): |
||||
|
rate = delivery_method.rate_shipment(order_sudo) |
||||
|
render_values['delivery_methods'] = checkout_page_values['delivery_methods'] |
||||
|
if ( |
||||
|
not order_sudo.carrier_id |
||||
|
or not rate.get('success') |
||||
|
or order_sudo.amount_delivery != rate['price'] |
||||
|
): |
||||
|
order_sudo._set_delivery_method(delivery_method, rate=rate) |
||||
|
can_skip_delivery = self.can_skip_delivery_step(order_sudo, |
||||
|
available_dms) |
||||
|
|
||||
|
if try_skip_step and can_skip_delivery: |
||||
|
return request.redirect('/shop/confirm_order') |
||||
|
|
||||
|
if render_values['errors']: |
||||
|
render_values.pop('payment_methods_sudo', '') |
||||
|
render_values.pop('tokens_sudo', '') |
||||
|
|
||||
|
return request.render("website_sale.payment", render_values) |
@ -0,0 +1,6 @@ |
|||||
|
## Module <web_pay_shipping_methods> |
||||
|
|
||||
|
#### 02.11.2024 |
||||
|
#### Version 18.0.1.0.0 |
||||
|
##### ADD |
||||
|
- Initial commit for Web Pay Shipping Methods |
@ -0,0 +1,22 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Aysha Shalin (odoo@cybrosys.com) |
||||
|
# |
||||
|
# you can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC |
||||
|
# LICENSE (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from . import payment_provider |
@ -0,0 +1,34 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Cybrosys Technologies Pvt. Ltd. |
||||
|
# |
||||
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) |
||||
|
# Author: Aysha Shalin (odoo@cybrosys.com) |
||||
|
# |
||||
|
# you can modify it under the terms of the GNU AFFERO |
||||
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC |
||||
|
# LICENSE (AGPL v3) along with this program. |
||||
|
# If not, see <http://www.gnu.org/licenses/>. |
||||
|
# |
||||
|
############################################################################## |
||||
|
from odoo import fields, models |
||||
|
|
||||
|
|
||||
|
class PaymentProvider(models.Model): |
||||
|
"""Inherited payment_provider to add shipping method field""" |
||||
|
_inherit = 'payment.provider' |
||||
|
|
||||
|
delivery_carrier_ids = fields.Many2many( |
||||
|
'delivery.carrier', |
||||
|
string="Shipping Methods", |
||||
|
domain="[('website_published', '=', True)]", |
||||
|
help="Add shipping methods which will be available while" |
||||
|
" choosing this payment provider") |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 628 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 210 KiB |
After Width: | Height: | Size: 209 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 495 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 624 B |
After Width: | Height: | Size: 136 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 929 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 576 B |
After Width: | Height: | Size: 733 B |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 738 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 462 B |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 653 B |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 905 B |
After Width: | Height: | Size: 189 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 839 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 627 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 988 B |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 875 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 751 KiB |
After Width: | Height: | Size: 760 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 100 KiB |
After Width: | Height: | Size: 87 KiB |
After Width: | Height: | Size: 781 KiB |
After Width: | Height: | Size: 76 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 162 KiB |
After Width: | Height: | Size: 137 KiB |
After Width: | Height: | Size: 880 KiB |
After Width: | Height: | Size: 86 KiB |
After Width: | Height: | Size: 9.2 KiB |
@ -0,0 +1,198 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
|
||||
|
import publicWidget from "@web/legacy/js/public/public_widget"; |
||||
|
import { rpc } from "@web/core/network/rpc"; |
||||
|
import { _t } from '@web/core/l10n/translation'; |
||||
|
|
||||
|
// Extend a new widget named DeliveryMethods for loading delivery methods in payment page
|
||||
|
publicWidget.registry.DeliveryMethods = publicWidget.Widget.extend({ |
||||
|
selector: '.o_website_sale_checkout', |
||||
|
events: { |
||||
|
'click [name="o_delivery_radio"]': '_selectDeliveryMethod', |
||||
|
}, |
||||
|
init() { |
||||
|
this._super(...arguments); |
||||
|
this.orm = this.bindService("orm"); |
||||
|
}, |
||||
|
/** |
||||
|
* @override |
||||
|
*/ |
||||
|
async start() { |
||||
|
this.mainButton = document.querySelector('a[name="o_payment_submit_button"]'); |
||||
|
await this._prepareDeliveryMethods(); |
||||
|
}, |
||||
|
/** |
||||
|
* Copied from checkout.js for loading delivery method template in payment template |
||||
|
*/ |
||||
|
async _selectDeliveryMethod(ev) { |
||||
|
const checkedRadio = ev.currentTarget; |
||||
|
if (checkedRadio.disabled) { // The delivery rate request failed.
|
||||
|
return; // Failing delivery methods cannot be selected.
|
||||
|
} |
||||
|
|
||||
|
// Disable the main button while fetching delivery rates.
|
||||
|
this._disableMainButton(); |
||||
|
|
||||
|
// Fetch delivery rates and update the cart summary and the price badge accordingly.
|
||||
|
await this._updateDeliveryMethod(checkedRadio); |
||||
|
|
||||
|
// Re-enable the main button after delivery rates have been fetched.
|
||||
|
this._enableMainButton(); |
||||
|
|
||||
|
// Show a button to open the location selector if required for the selected delivery method.
|
||||
|
await this._showPickupLocation(checkedRadio); |
||||
|
}, |
||||
|
|
||||
|
async _prepareDeliveryMethods() { |
||||
|
// Load the radios from the DOM here to update them if the template is re-rendered.
|
||||
|
this.dmRadios = Array.from(document.querySelectorAll('input[name="o_delivery_radio"]')); |
||||
|
if (this.dmRadios.length > 0) { |
||||
|
const checkedRadio = document.querySelector('input[name="o_delivery_radio"]:checked'); |
||||
|
this._disableMainButton(); |
||||
|
if (checkedRadio) { |
||||
|
await this._updateDeliveryMethod(checkedRadio); |
||||
|
this._enableMainButton(); |
||||
|
} |
||||
|
} |
||||
|
// Asynchronously fetch delivery rates to mitigate delays from third-party APIs
|
||||
|
await Promise.all(this.dmRadios.filter(radio => !radio.checked).map(async radio => { |
||||
|
this._showLoadingBadge((radio)); |
||||
|
const rateData = await this._getDeliveryRate(radio); |
||||
|
this._updateAmountBadge(radio, rateData); |
||||
|
})); |
||||
|
}, |
||||
|
|
||||
|
async _updateDeliveryMethod(radio) { |
||||
|
this._showLoadingBadge(radio); |
||||
|
const result = await this._setDeliveryMethod(radio.dataset.dmId); |
||||
|
this._updateAmountBadge(radio, result); |
||||
|
this._updateCartSummary(result); |
||||
|
}, |
||||
|
|
||||
|
async _showPickupLocation(radio) { |
||||
|
if (!radio.dataset.isPickupLocationRequired || radio.disabled) { |
||||
|
return; // Fetching the delivery rate failed.
|
||||
|
} |
||||
|
const deliveryMethodContainer = this._getDeliveryMethodContainer(radio); |
||||
|
const pickupLocation = deliveryMethodContainer.querySelector('[name="o_pickup_location"]'); |
||||
|
|
||||
|
const editPickupLocationButton = pickupLocation.querySelector( |
||||
|
'span[name="o_pickup_location_selector"]' |
||||
|
); |
||||
|
if (editPickupLocationButton.dataset.pickupLocationData) { |
||||
|
await this._setPickupLocation(editPickupLocationButton.dataset.pickupLocationData); |
||||
|
} |
||||
|
|
||||
|
pickupLocation.classList.remove('d-none'); // Show the whole div.
|
||||
|
}, |
||||
|
|
||||
|
async _setPickupLocation(pickupLocationData) { |
||||
|
await rpc('/website_sale/set_pickup_location', {pickup_location_data: pickupLocationData}); |
||||
|
}, |
||||
|
_updateAmountBadge(radio, rateData) { |
||||
|
const deliveryPriceBadge = this._getDeliveryPriceBadge(radio); |
||||
|
if (rateData.success) { |
||||
|
// If it's a free delivery (`free_over` field), show 'Free', not '$ 0'.
|
||||
|
if (rateData.is_free_delivery) { |
||||
|
deliveryPriceBadge.textContent = _t("Free"); |
||||
|
} else { |
||||
|
deliveryPriceBadge.innerHTML = rateData.amount_delivery; |
||||
|
} |
||||
|
this._toggleDeliveryMethodRadio(radio); |
||||
|
} else { |
||||
|
deliveryPriceBadge.textContent = rateData.error_message; |
||||
|
this._toggleDeliveryMethodRadio(radio, true); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
_toggleDeliveryMethodRadio(radio, disable=false) { |
||||
|
const deliveryMethodContainer = this._getDeliveryMethodContainer(radio); |
||||
|
radio.disabled = disable; |
||||
|
if (disable) { |
||||
|
deliveryMethodContainer.classList.add('text-muted'); |
||||
|
} |
||||
|
else { |
||||
|
deliveryMethodContainer.classList.remove('text-muted'); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
_updateCartSummary(result) { |
||||
|
const amountDelivery = document.querySelector('#order_delivery .monetary_field'); |
||||
|
const amountUntaxed = document.querySelector('#order_total_untaxed .monetary_field'); |
||||
|
const amountTax = document.querySelector('#order_total_taxes .monetary_field'); |
||||
|
const amountTotal = document.querySelectorAll( |
||||
|
'#order_total .monetary_field, #amount_total_summary.monetary_field' |
||||
|
); |
||||
|
amountDelivery.innerHTML = result.amount_delivery; |
||||
|
amountUntaxed.innerHTML = result.amount_untaxed; |
||||
|
amountTax.innerHTML = result.amount_tax; |
||||
|
amountTotal.forEach(total => total.innerHTML = result.amount_total); |
||||
|
}, |
||||
|
|
||||
|
async _setDeliveryMethod(dmId) { |
||||
|
return await rpc('/shop/set_delivery_method', {'dm_id': dmId}); |
||||
|
}, |
||||
|
|
||||
|
async _getDeliveryRate(radio) { |
||||
|
return await rpc('/shop/get_delivery_rate', {'dm_id': radio.dataset.dmId}); |
||||
|
}, |
||||
|
|
||||
|
_disableMainButton() { |
||||
|
this.mainButton?.classList.add('disabled'); |
||||
|
}, |
||||
|
|
||||
|
_enableMainButton() { |
||||
|
if (this._isDeliveryMethodReady()) { |
||||
|
this.mainButton?.classList.remove('disabled'); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
_showLoadingBadge(radio) { |
||||
|
const deliveryPriceBadge = this._getDeliveryPriceBadge(radio); |
||||
|
this._clearElement(deliveryPriceBadge); |
||||
|
deliveryPriceBadge.appendChild(this._createLoadingElement()); |
||||
|
}, |
||||
|
|
||||
|
_clearElement(el) { |
||||
|
while (el.firstChild) { |
||||
|
el.removeChild(el.lastChild); |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
_createLoadingElement() { |
||||
|
const loadingElement = document.createElement('i'); |
||||
|
loadingElement.classList.add('fa', 'fa-circle-o-notch', 'fa-spin', 'center'); |
||||
|
return loadingElement; |
||||
|
}, |
||||
|
|
||||
|
_isDeliveryMethodReady() { |
||||
|
if (this.dmRadios.length === 0) { // No delivery method is available.
|
||||
|
return true; // Ignore the check.
|
||||
|
} |
||||
|
const checkedRadio = document.querySelector('input[name="o_delivery_radio"]:checked'); |
||||
|
return checkedRadio |
||||
|
&& !checkedRadio.disabled |
||||
|
&& !this._isPickupLocationMissing(checkedRadio); |
||||
|
}, |
||||
|
|
||||
|
_getDeliveryPriceBadge(radio) { |
||||
|
const deliveryMethodContainer = this._getDeliveryMethodContainer(radio); |
||||
|
return deliveryMethodContainer.querySelector('.o_wsale_delivery_price_badge'); |
||||
|
}, |
||||
|
|
||||
|
_isPickupLocationMissing(radio) { |
||||
|
const deliveryMethodContainer = this._getDeliveryMethodContainer(radio); |
||||
|
if (!this._isPickupLocationRequired(radio)) return false; |
||||
|
return !deliveryMethodContainer.querySelector( |
||||
|
'span[name="o_pickup_location_selector"]' |
||||
|
).dataset.locationId; |
||||
|
}, |
||||
|
|
||||
|
_getDeliveryMethodContainer(el) { |
||||
|
return el.closest('[name="o_delivery_method"]'); |
||||
|
}, |
||||
|
|
||||
|
_isPickupLocationRequired(radio) { |
||||
|
return Boolean(radio.dataset.isPickupLocationRequired); |
||||
|
}, |
||||
|
}); |
@ -0,0 +1,40 @@ |
|||||
|
/** @odoo-module **/ |
||||
|
import { patch } from "@web/core/utils/patch"; |
||||
|
import PaymentForm from '@payment/js/payment_form'; |
||||
|
import { _t } from '@web/core/l10n/translation'; |
||||
|
import { rpc } from '@web/core/network/rpc'; |
||||
|
/** |
||||
|
* Handles the selection of a payment option in the payment form. |
||||
|
* |
||||
|
* This method overrides the default behavior to hide all delivery methods initially |
||||
|
* and then show the delivery methods associated with the selected payment provider. |
||||
|
*/ |
||||
|
PaymentForm.include({ |
||||
|
async _selectPaymentOption(ev) { |
||||
|
this._super(...arguments); |
||||
|
$('.delivery_method_list').each(function(key,carrier) { |
||||
|
$(this).find('input[type="radio"]').prop('checked', false); |
||||
|
$(this).addClass('d-none'); |
||||
|
}); |
||||
|
let providerId = ev.target.dataset['providerId'] |
||||
|
let carriers = await this.orm.read("payment.provider",[parseInt(providerId)],['delivery_carrier_ids']) |
||||
|
if(carriers[0].delivery_carrier_ids.length > 0){ |
||||
|
carriers[0].delivery_carrier_ids.forEach((id)=>{ |
||||
|
if(id){ |
||||
|
let deliveryMethod = '#delivery_method_'+id |
||||
|
let deliveryElement = $(deliveryMethod)[0]; |
||||
|
// Only attempt to remove the class if the element exists
|
||||
|
if (deliveryElement) { |
||||
|
deliveryElement.classList.remove('d-none'); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
}else{ |
||||
|
let noShippingMethodElement = $('#NoShippingMethod')[0]; |
||||
|
// Only attempt to remove the class if the element exists
|
||||
|
if (noShippingMethodElement) { |
||||
|
noShippingMethodElement.classList.remove('d-none'); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
}); |
@ -0,0 +1,14 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<odoo> |
||||
|
<!-- New field Shipping method is added in Payment provider form view.--> |
||||
|
<record id="payment_provider_form" model="ir.ui.view"> |
||||
|
<field name="name">payment.provider.view.form.inherit.web.pay.shipping.methods</field> |
||||
|
<field name="model">payment.provider</field> |
||||
|
<field name="inherit_id" ref="payment.payment_provider_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<xpath expr="//field[@name='so_reference_type']" position="after"> |
||||
|
<field name="delivery_carrier_ids" widget="many2many_tags"/> |
||||
|
</xpath> |
||||
|
</field> |
||||
|
</record> |
||||
|
</odoo> |
@ -0,0 +1,49 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8" ?> |
||||
|
<odoo> |
||||
|
<!--Xpath expression specified to replace or remove the original shipping |
||||
|
method template in website payment page.--> |
||||
|
<template id="delivery_form" name="Shipping Methods" |
||||
|
inherit_id="website_sale.delivery_form"> |
||||
|
<xpath expr="//ul[@id='o_delivery_methods']" position="replace"> |
||||
|
<div class="alert alert-danger d-none" role="alert" id="NoShippingMethod"> |
||||
|
<h4> |
||||
|
Sorry, we are unable to ship your order |
||||
|
</h4> |
||||
|
No shipping method is available for the selected payment |
||||
|
method, kindly choose any other, or please contact us for more |
||||
|
information. |
||||
|
</div> |
||||
|
<ul t-if="delivery_methods" id="o_delivery_methods" class="list-group"> |
||||
|
<t t-foreach="delivery_methods" t-as="dm"> |
||||
|
<li name="o_delivery_method" class="list-group-item delivery_method_list text-muted o_outline d-none" |
||||
|
t-att-id="'delivery_method_%i' % dm.id"> |
||||
|
<t t-log="dm.id"/> |
||||
|
<t t-call="website_sale.delivery_method"> |
||||
|
<t t-set="is_selected" t-value="dm.id == selected_dm_id"/> |
||||
|
</t> |
||||
|
</li> |
||||
|
</t> |
||||
|
</ul> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
|
||||
|
<!-- Xpath expression specified to remove the original delivery methods template |
||||
|
in Delivery page. --> |
||||
|
<template id="checkout" inherit_id="website_sale.checkout"> |
||||
|
<xpath expr="//t[@t-call='website_sale.delivery_form']" position="replace"> |
||||
|
<t/> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
|
||||
|
<!-- Xpath expression specified to replace the delivery methods template |
||||
|
in Payment page. --> |
||||
|
<template id="payment" inherit_id="website_sale.payment"> |
||||
|
<xpath expr="//div[@id='oe_structure_website_sale_payment_1']" position="after"> |
||||
|
<div class="oe_structure clearfix mt-3 mb-4"> |
||||
|
<t t-call="website_sale.delivery_form"> |
||||
|
<t t-set="selected_dm_id" t-value="order.carrier_id.id"/> |
||||
|
</t> |
||||
|
</div> |
||||
|
</xpath> |
||||
|
</template> |
||||
|
</odoo> |