[IMP] website_sale_payment_terms: keep default terms on order

1. Keep default payment terms on order at checkout
2. Do not set terms on order until user agrees to conditions
3. Make date context-aware for terms amount calculation
This commit is contained in:
Cedric Collins
2022-03-04 18:56:51 -06:00
parent cebc7757ab
commit 24721b0bd4
4 changed files with 62 additions and 70 deletions

View File

@@ -14,16 +14,12 @@ class WebsiteSalePaymentTerms(WebsiteSaleDelivery):
def shop_payment(self, **post): def shop_payment(self, **post):
order = request.website.sale_get_order() order = request.website.sale_get_order()
payment_term_id = post.get('payment_term_id') payment_term_id = post.get('payment_term_id')
if order.amount_total > request.website.payment_deposit_threshold:
if payment_term_id: if payment_term_id:
payment_term_id = int(payment_term_id) payment_term_id = int(payment_term_id)
if order: if order:
order._check_payment_term_quotation(payment_term_id) order._check_payment_term_quotation(payment_term_id)
if payment_term_id: if payment_term_id:
return request.redirect("/shop/payment") return request.redirect("/shop/payment")
else:
order.payment_term_id = False
return super(WebsiteSalePaymentTerms, self).shop_payment(**post) return super(WebsiteSalePaymentTerms, self).shop_payment(**post)
# Main JS driven payment term updater. # Main JS driven payment term updater.

View File

@@ -9,7 +9,7 @@ class SaleOrder(models.Model):
@api.depends('amount_total', 'payment_term_id') @api.depends('amount_total', 'payment_term_id')
def _compute_amount_due_today(self): def _compute_amount_due_today(self):
today_string = fields.Date.to_string(fields.Date.today()) today_string = fields.Date.to_string(fields.Date.context_today(self))
for order in self: for order in self:
amount = order.amount_total amount = order.amount_total
if order.website_id and order.amount_total > order.website_id.payment_deposit_threshold and order.payment_term_id: if order.website_id and order.amount_total > order.website_id.payment_deposit_threshold and order.payment_term_id:

View File

@@ -14,7 +14,6 @@ odoo.define('website_sale_payment_terms.payment_terms', function (require) {
events: { events: {
"click input[name='payment_term_id']": '_onPaymentTermClick', "click input[name='payment_term_id']": '_onPaymentTermClick',
"click #btn_accept_payment_terms": '_acceptPaymentTerms', "click #btn_accept_payment_terms": '_acceptPaymentTerms',
"click #btn_deny_payment_terms": '_denyPaymentTerms',
}, },
/** /**
@@ -25,10 +24,10 @@ odoo.define('website_sale_payment_terms.payment_terms', function (require) {
return this._super.apply(this, arguments).then(function () { return this._super.apply(this, arguments).then(function () {
var available_term = $('input[name="payment_term_id"]').length; var available_term = $('input[name="payment_term_id"]').length;
if (available_term > 0) { if (available_term > 0) {
var $payButton = $('#o_payment_form_pay'); var $payButton = $('button[name="o_payment_submit_button"]');
$payButton.prop('disabled', true); $payButton.prop('disabled', true);
var disabledReasons = $payButton.data('disabled_reasons') || {}; var disabledReasons = $payButton.data('disabled_reasons') || {};
if ($('input[name="payment_term_id"][checked]')) { if ($('input[name="payment_term_id"]:checked').length > 0) {
disabledReasons.payment_terms_selection = false; disabledReasons.payment_terms_selection = false;
} else { } else {
disabledReasons.payment_terms_selection = true; disabledReasons.payment_terms_selection = true;
@@ -48,75 +47,67 @@ odoo.define('website_sale_payment_terms.payment_terms', function (require) {
* @param {object} ev * @param {object} ev
*/ */
_onPaymentTermClick: function (ev) { _onPaymentTermClick: function (ev) {
$('#o_payment_form_pay').prop('disabled', true); ev.preventDefault();
var payment_term_id = $(ev.currentTarget).val(); $('button[name="o_payment_submit_button"]').prop('disabled', true);
var values = {'payment_term_id': payment_term_id}; // Get Payment Term note/description for modal
dp.add(this._rpc({ var selected_term = $(ev.currentTarget);
'route': '/shop/update_payment_term', var note = $.parseHTML(selected_term.attr('data-note'));
'params': values, if (!$(note).text()) {
}).then(this._onPaymentTermUpdateAnswer.bind(this))); note = $.parseHTML('<p>' + selected_term.attr('data-name') + '</p>');
}
// Open agreement modal with message
$('#payment_term_agreement_modal .success-modal-note').html(note);
$('#btn_accept_payment_terms').data('payment_term_id', selected_term.val());
$('#payment_term_agreement_modal').modal();
}, },
/** /**
* Update the total cost according to the selected shipping method * Set terms on the order
*
* @private
* @param {float} amount : The new total amount of to be paid
*/
_updatePaymentAmount: function(amount){
core.bus.trigger('update_shipping_cost', amount);
},
/**
* Show amount due if operation is a success
* *
* @private * @private
* @param {Object} result * @param {Object} result
*/ */
_onPaymentTermUpdateAnswer: function (result) { _acceptPaymentTerms: function (ev) {
if (!result.error) { var payment_term_id = $(ev.currentTarget).data('payment_term_id');
// Get Payment Term note/description for modal if (payment_term_id) {
var note = $.parseHTML(result.note); dp.add(this._rpc({
if (!$(note).text()) { 'route': '/shop/update_payment_term',
note = $.parseHTML('<p>' + result.payment_term_name + '</p>'); 'params': {'payment_term_id': payment_term_id},
}).then(this._onPaymentTermUpdateAmount.bind(this)));
} }
},
/**
* Update amount on the page
*
* @param {Object} result
*/
_onPaymentTermUpdateAmount: function(result) {
if (result.error) {
// Open error modal
console.error(result.error);
$('#payment_term_error_modal').modal();
} else {
// Change forms based on order payment requirement // Change forms based on order payment requirement
$('input[name="payment_term_id"]').filter(
(i, e)=>e.value==result.payment_term_id
).prop('checked', true);
$('#order_due_today .monetary_field').html(result.amount_due_today_html); $('#order_due_today .monetary_field').html(result.amount_due_today_html);
if(result.amount_due_today == 0.0) { if(result.amount_due_today == 0.0) {
$('#payment_method').hide(); $('#payment_method').hide();
$('#non_payment_method').show(); $('#non_payment_method').show();
} else { } else {
this._updatePaymentAmount(result.amount_due_today); // Update the total cost according to the selected shipping method
core.bus.trigger('update_shipping_cost', result.amount_due_today);
$('#payment_method').show(); $('#payment_method').show();
$('#non_payment_method').hide(); $('#non_payment_method').hide();
} }
var $payButton = $('button[name="o_payment_submit_button"]');
// Open success modal with message
$('#payment_term_success_modal .success-modal-note').html(note);
$('#payment_term_success_modal').modal();
} else {
// Open error modal
console.error(result);
$('#payment_term_error_modal').modal();
}
},
/*
* @private
*/
_acceptPaymentTerms: function () {
var $payButton = $('#o_payment_form_pay');
var disabledReasons = $payButton.data('disabled_reasons') || {}; var disabledReasons = $payButton.data('disabled_reasons') || {};
disabledReasons.payment_terms_selection = false; disabledReasons.payment_terms_selection = false;
$payButton.data('disabled_reasons', disabledReasons); $payButton.data('disabled_reasons', disabledReasons);
$payButton.prop('disabled', _.contains($payButton.data('disabled_reasons'), true)); $payButton.prop('disabled', _.contains($payButton.data('disabled_reasons'), true));
}, }
/*
* @private
*/
_denyPaymentTerms: function () {
window.location = '/shop/reject_term_agreement';
}, },
}); });

View File

@@ -9,6 +9,8 @@
<t t-if="partner_term and partner_term not in website_terms"> <t t-if="partner_term and partner_term not in website_terms">
<li class="list-group-item"> <li class="list-group-item">
<input t-att-value="partner_term.id" <input t-att-value="partner_term.id"
t-att-data-name="partner_term.name"
t-att-data-note="partner_term.note"
t-att-data-deposit-percentage="partner_term.deposit_percentage or '0'" t-att-data-deposit-percentage="partner_term.deposit_percentage or '0'"
t-att-data-deposit-flat="partner_term.deposit_flat or '0'" t-att-data-deposit-flat="partner_term.deposit_flat or '0'"
name="payment_term_id" name="payment_term_id"
@@ -23,6 +25,8 @@
<!-- Show default option set by account.payment.term boolean --> <!-- Show default option set by account.payment.term boolean -->
<li t-foreach="website_terms" t-as="term" class="list-group-item"> <li t-foreach="website_terms" t-as="term" class="list-group-item">
<input t-att-value="term.id" <input t-att-value="term.id"
t-att-data-name="term.name"
t-att-data-note="term.note"
t-att-data-deposit-percentage="term.deposit_percentage or '0'" t-att-data-deposit-percentage="term.deposit_percentage or '0'"
t-att-data-deposit-flat="term.deposit_flat or '0'" t-att-data-deposit-flat="term.deposit_flat or '0'"
t-att-id="'payment_term_%i' % term.id" t-att-id="'payment_term_%i' % term.id"
@@ -41,7 +45,7 @@
<t t-set="website_terms" t-value="website.get_payment_terms()" /> <t t-set="website_terms" t-value="website.get_payment_terms()" />
<t t-if="website_terms and website_sale_order.amount_total &gt; website.payment_deposit_threshold"> <t t-if="website_terms and website_sale_order.amount_total &gt; website.payment_deposit_threshold">
<div class="oe_payment_terms"> <div class="oe_payment_terms">
<t t-call="website_sale_payment_terms.payment_term_success_modal"/> <t t-call="website_sale_payment_terms.payment_term_agreement_modal"/>
<t t-call="website_sale_payment_terms.payment_term_error_modal"/> <t t-call="website_sale_payment_terms.payment_term_error_modal"/>
<h3 class="mb24 mt24">Payment Terms</h3> <h3 class="mb24 mt24">Payment Terms</h3>
<div class="card border-0"> <div class="card border-0">
@@ -73,9 +77,9 @@
</xpath> </xpath>
</template> </template>
<!-- Modal to handle success message --> <!-- Modal to handle agreement message -->
<template id="payment_term_success_modal"> <template id="payment_term_agreement_modal">
<div class="modal fade" id="payment_term_success_modal" role="dialog"> <div class="modal fade" id="payment_term_agreement_modal" role="dialog">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@@ -96,7 +100,8 @@
</button> </button>
<button type="button" <button type="button"
class="btn btn-default" class="btn btn-default"
id="btn_deny_payment_terms">Deny id="btn_deny_payment_terms"
data-dismiss="modal">Deny
</button> </button>
</div> </div>
</div> </div>