diff options
| author | qsm-odoo <qsm@odoo.com> | 2019-02-06 14:29:07 +0000 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2019-02-26 17:09:22 +0000 |
| commit | 27fca749af30d7dce448f6632132422df8d8a7c1 (patch) | |
| tree | c644db5efbb12cde722d059d250a83ec0de8aed7 /addons/payment/static/src | |
| parent | c3da83b40a6431f607cf69b8c2a7a922a6e5b52c (diff) | |
[REF] *: use 'frontend' system in non-website apps
* account, auth_signup, payment, portal, project, sale, sale_management,
web_unsplash, website, website_mail, website_rating, website_sale
This commit does probably not do what is stated for all non-website apps
but it is a first step. It also uses the system in apps which could have
already used it but did not.
Part of https://github.com/odoo/odoo/pull/29442
task-1932066
Diffstat (limited to 'addons/payment/static/src')
| -rw-r--r-- | addons/payment/static/src/js/payment_form.js | 826 |
1 files changed, 432 insertions, 394 deletions
diff --git a/addons/payment/static/src/js/payment_form.js b/addons/payment/static/src/js/payment_form.js index 7494f50bf03..6bbe4604dd4 100644 --- a/addons/payment/static/src/js/payment_form.js +++ b/addons/payment/static/src/js/payment_form.js @@ -1,234 +1,163 @@ odoo.define('payment.payment_form', function (require) { - "use strict"; - - var ajax = require('web.ajax'); - var config = require('web.config'); - var core = require('web.core'); - var dom = require('web.dom'); - var Dialog = require("web.Dialog"); - var Widget = require("web.Widget"); - var rpc = require("web.rpc"); - var _t = core._t; - - var PaymentForm = Widget.extend({ - - events: { - 'click #o_payment_form_pay': 'payEvent', - 'click #o_payment_form_add_pm': 'addPmEvent', - 'click button[name="delete_pm"]': 'deletePmEvent', - 'click .o_payment_acquirer_select': 'radioClickEvent', - 'click .o_payment_form_pay_icon_more': 'onClickMorePaymentIcon', - }, - - init: function(parent, options) { - this._super.apply(this, arguments); - this.options = _.extend(options || {}, { - }); - - // TODO simplify this using the 'async' keyword in the events - // property definition as soon as this widget is converted in - // frontend widget. - this.payEvent = dom.makeButtonHandler(this.payEvent); - }, - - start: function () { - this.updateNewPaymentDisplayStatus(); - $('[data-toggle="tooltip"]').tooltip(); - }, - - payEvent: function (ev) { - ev.preventDefault(); - var form = this.el; - var checked_radio = this.$('input[type="radio"]:checked'); - var self = this; - var button = ev.target; - - // first we check that the user has selected a payment method - if (checked_radio.length === 1) { - checked_radio = checked_radio[0]; - - // we retrieve all the input inside the acquirer form and 'serialize' them to an indexed array - var acquirer_id = this.getAcquirerIdFromRadio(checked_radio); - var acquirer_form = false; - if (this.isNewPaymentRadio(checked_radio)) { - acquirer_form = this.$('#o_payment_add_token_acq_' + acquirer_id); - } else { - acquirer_form = this.$('#o_payment_form_acq_' + acquirer_id); - } - var inputs_form = $('input', acquirer_form); - var ds = $('input[name="data_set"]', acquirer_form)[0]; - - // if the user is adding a new payment - if (this.isNewPaymentRadio(checked_radio)) { - if (this.options.partnerId === undefined) { - console.warn('payment_form: unset partner_id when adding new token; things could go wrong'); - } - var form_data = this.getFormData(inputs_form); - var wrong_input = false; - - inputs_form.toArray().forEach(function (element) { - //skip the check of non visible inputs - if ($(element).attr('type') == 'hidden') { - return true; - } - $(element).closest('div.form-group').removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid'); - $(element).siblings( ".o_invalid_field" ).remove(); - //force check of forms validity (useful for Firefox that refill forms automatically on f5) - $(element).trigger("focusout"); - if (element.dataset.isRequired && element.value.length === 0) { - $(element).closest('div.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); - $(element).closest('div.form-group').append('<div style="color: red" class="o_invalid_field" aria-invalid="true">' + _.str.escapeHTML("The value is invalid.") + '</div>'); - wrong_input = true; - } - else if ($(element).closest('div.form-group').hasClass('o_has_error')) { - wrong_input = true; - $(element).closest('div.form-group').append('<div style="color: red" class="o_invalid_field" aria-invalid="true">' + _.str.escapeHTML("The value is invalid.") + '</div>'); - } - }); - - if (wrong_input) { - return; - } - - $(button).attr('disabled', true); - $(button).children('.fa-plus-circle').removeClass('fa-plus-circle') - $(button).prepend('<span class="o_loader"><i class="fa fa-refresh fa-spin"></i> </span>'); - - var verify_validity = this.$el.find('input[name="verify_validity"]'); +"use strict"; + +var core = require('web.core'); +var Dialog = require('web.Dialog'); +var publicWidget = require('web.public.widget'); + +var _t = core._t; + +publicWidget.registry.PaymentForm = publicWidget.Widget.extend({ + selector: '.o_payment_form', + events: { + 'click #o_payment_form_pay': 'async payEvent', + 'click #o_payment_form_add_pm': 'addPmEvent', + 'click button[name="delete_pm"]': 'deletePmEvent', + 'click .o_payment_form_pay_icon_more': 'onClickMorePaymentIcon', + 'click .o_payment_acquirer_select': 'radioClickEvent', + }, + + /** + * @override + */ + start: function () { + this.options = _.extend(this.$el.data(), this.options); + this.updateNewPaymentDisplayStatus(); + $('[data-toggle="tooltip"]').tooltip(); + return this._super.apply(this, arguments); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + * @param {string} title + * @param {string} message + */ + displayError: function (title, message) { + var $checkedRadio = this.$('input[type="radio"]:checked'), + acquirerID = this.getAcquirerIdFromRadio($checkedRadio[0]); + var $acquirerForm; + if (this.isNewPaymentRadio($checkedRadio[0])) { + $acquirerForm = this.$('#o_payment_add_token_acq_' + acquirerID); + } + else if (this.isFormPaymentRadio($checkedRadio[0])) { + $acquirerForm = this.$('#o_payment_form_acq_' + acquirerID); + } - if (verify_validity.length>0) { - form_data.verify_validity = verify_validity[0].value === "1"; - } + if ($checkedRadio.length === 0) { + return new Dialog(null, { + title: _t('Error: ') + _.str.escapeHTML(title), + size: 'medium', + $content: "<p>" + (_.str.escapeHTML(message) || "") + "</p>" , + buttons: [ + {text: _t('Ok'), close: true}]}).open(); + } else { + // removed if exist error message + this.$('#payment_error').remove(); + var messageResult = '<div class="alert alert-danger mb4" id="payment_error">'; + if (title != '') { + messageResult = messageResult + '<b>' + _.str.escapeHTML(title) + ':</b></br>'; + } + messageResult = messageResult + _.str.escapeHTML(message) + '</div>'; + $acquirerForm.append(messageResult); + } + }, + /** + * @private + * @param {DOMElement} element + */ + getAcquirerIdFromRadio: function (element) { + return $(element).data('acquirer-id'); + }, + /** + * @private + * @param {jQuery} $form + */ + getFormData: function ($form) { + var unindexed_array = $form.serializeArray(); + var indexed_array = {}; + + $.map(unindexed_array, function (n, i) { + indexed_array[n.name] = n.value; + }); + return indexed_array; + }, + /** + * @private + * @param {DOMElement} element + */ + isFormPaymentRadio: function (element) { + return $(element).data('form-payment') === 'True'; + }, + /** + * @private + * @param {DOMElement} element + */ + isNewPaymentRadio: function (element) { + return $(element).data('s2s-payment') === 'True'; + }, + /** + * @private + */ + updateNewPaymentDisplayStatus: function () { + var checked_radio = this.$('input[type="radio"]:checked'); + // we hide all the acquirers form + this.$('[id*="o_payment_add_token_acq_"]').addClass('d-none'); + this.$('[id*="o_payment_form_acq_"]').addClass('d-none'); + if (checked_radio.length !== 1) { + return; + } + checked_radio = checked_radio[0]; + var acquirer_id = this.getAcquirerIdFromRadio(checked_radio); - // do the call to the route stored in the 'data_set' input of the acquirer form, the data must be called 'create-route' - return ajax.jsonRpc(ds.dataset.createRoute, 'call', form_data).then(function (data) { - // if the server has returned true - if (data.result) { - // and it need a 3DS authentication - if (data['3d_secure'] !== false) { - // then we display the 3DS page to the user - $("body").html(data['3d_secure']); - } - else { - checked_radio.value = data.id; // set the radio value to the new card id - form.submit(); - return $.Deferred(); - } - } - // if the server has returned false, we display an error - else { - if (data.error) { - self.displayError( - '', - data.error); - } else { // if the server doesn't provide an error message - self.displayError( - _t('Server Error'), - _t('e.g. Your credit card details are wrong. Please verify.')); - } - } - // here we remove the 'processing' icon from the 'add a new payment' button - $(button).attr('disabled', false); - $(button).children('.fa').addClass('fa-plus-circle') - $(button).find('span.o_loader').remove(); - }).fail(function (error, event) { - // if the rpc fails, pretty obvious - $(button).attr('disabled', false); - $(button).children('.fa').addClass('fa-plus-circle') - $(button).find('span.o_loader').remove(); + // if we clicked on an add new payment radio, display its form + if (this.isNewPaymentRadio(checked_radio)) { + this.$('#o_payment_add_token_acq_' + acquirer_id).removeClass('d-none'); + } + else if (this.isFormPaymentRadio(checked_radio)) { + this.$('#o_payment_form_acq_' + acquirer_id).removeClass('d-none'); + } + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {Event} ev + */ + payEvent: function (ev) { + ev.preventDefault(); + var form = this.el; + var checked_radio = this.$('input[type="radio"]:checked'); + var self = this; + var button = ev.target; + + // first we check that the user has selected a payment method + if (checked_radio.length === 1) { + checked_radio = checked_radio[0]; - self.displayError( - _t('Server Error'), - _t("We are not able to add your payment method at the moment.") + - error.data.message - ); - }); - } - // if the user is going to pay with a form payment, then - else if (this.isFormPaymentRadio(checked_radio)) { - var $tx_url = this.$el.find('input[name="prepare_tx_url"]'); - // if there's a prepare tx url set - if ($tx_url.length === 1) { - // if the user wants to save his credit card info - var form_save_token = acquirer_form.find('input[name="o_payment_form_save_token"]').prop('checked'); - // then we call the route to prepare the transaction - return ajax.jsonRpc($tx_url[0].value, 'call', { - 'acquirer_id': parseInt(acquirer_id), - 'save_token': form_save_token, - 'access_token': self.options.accessToken, - 'success_url': self.options.successUrl, - 'error_url': self.options.errorUrl, - 'callback_method': self.options.callbackMethod, - 'order_id': self.options.orderId, - }).then(function (result) { - if (result) { - // if the server sent us the html form, we create a form element - var newForm = document.createElement('form'); - newForm.setAttribute("method", "post"); // set it to post - newForm.setAttribute("provider", checked_radio.dataset.provider); - newForm.hidden = true; // hide it - newForm.innerHTML = result; // put the html sent by the server inside the form - var action_url = $(newForm).find('input[name="data_set"]').data('actionUrl'); - newForm.setAttribute("action", action_url); // set the action url - $(document.getElementsByTagName('body')[0]).append(newForm); // append the form to the body - $(newForm).find('input[data-remove-me]').remove(); // remove all the input that should be removed - if(action_url) { - newForm.submit(); // and finally submit the form - return $.Deferred(); - } - } - else { - self.displayError( - _t('Server Error'), - _t("We are not able to redirect you to the payment form.") - ); - } - }).fail(function (error, event) { - self.displayError( - _t('Server Error'), - _t("We are not able to redirect you to the payment form. ") + - error.data.message - ); - }); - } - else { - // we append the form to the body and send it. - this.displayError( - _t("Cannot set-up the payment"), - _t("We're unable to process your payment.") - ); - } - } - else { // if the user is using an old payment then we just submit the form - form.submit(); - return $.Deferred(); - } - } - else { - this.displayError( - _t('No payment method selected'), - _t('Please select a payment method.') - ); + // we retrieve all the input inside the acquirer form and 'serialize' them to an indexed array + var acquirer_id = this.getAcquirerIdFromRadio(checked_radio); + var acquirer_form = false; + if (this.isNewPaymentRadio(checked_radio)) { + acquirer_form = this.$('#o_payment_add_token_acq_' + acquirer_id); + } else { + acquirer_form = this.$('#o_payment_form_acq_' + acquirer_id); } - }, - // event handler when clicking on the button to add a new payment method - addPmEvent: function (ev) { - ev.stopPropagation(); - ev.preventDefault(); - var checked_radio = this.$('input[type="radio"]:checked'); - var self = this; - var button = ev.target; + var inputs_form = $('input', acquirer_form); + var ds = $('input[name="data_set"]', acquirer_form)[0]; - // we check if the user has selected a 'add a new payment' option - if (checked_radio.length === 1 && this.isNewPaymentRadio(checked_radio[0])) { - // we retrieve which acquirer is used - checked_radio = checked_radio[0]; - var acquirer_id = this.getAcquirerIdFromRadio(checked_radio); - var acquirer_form = this.$('#o_payment_add_token_acq_' + acquirer_id); - // we retrieve all the input inside the acquirer form and 'serialize' them to an indexed array - var inputs_form = $('input', acquirer_form); + // if the user is adding a new payment + if (this.isNewPaymentRadio(checked_radio)) { + if (this.options.partnerId === undefined) { + console.warn('payment_form: unset partner_id when adding new token; things could go wrong'); + } var form_data = this.getFormData(inputs_form); - var ds = $('input[name="data_set"]', acquirer_form)[0]; var wrong_input = false; inputs_form.toArray().forEach(function (element) { @@ -242,30 +171,34 @@ odoo.define('payment.payment_form', function (require) { $(element).trigger("focusout"); if (element.dataset.isRequired && element.value.length === 0) { $(element).closest('div.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); - var message = '<div style="color: red" class="o_invalid_field" aria-invalid="true">' + _.str.escapeHTML("The value is invalid.") + '</div>'; - $(element).closest('div.form-group').append(message); + $(element).closest('div.form-group').append('<div style="color: red" class="o_invalid_field" aria-invalid="true">' + _.str.escapeHTML("The value is invalid.") + '</div>'); wrong_input = true; } else if ($(element).closest('div.form-group').hasClass('o_has_error')) { wrong_input = true; - var message = '<div style="color: red" class="o_invalid_field" aria-invalid="true">' + _.str.escapeHTML("The value is invalid.") + '</div>'; - $(element).closest('div.form-group').append(message); + $(element).closest('div.form-group').append('<div style="color: red" class="o_invalid_field" aria-invalid="true">' + _.str.escapeHTML("The value is invalid.") + '</div>'); } }); if (wrong_input) { return; } - // We add a 'processing' icon into the 'add a new payment' button + $(button).attr('disabled', true); - $(button).children('.fa-plus-circle').removeClass('fa-plus-circle') + $(button).children('.fa-plus-circle').removeClass('fa-plus-circle'); $(button).prepend('<span class="o_loader"><i class="fa fa-refresh fa-spin"></i> </span>'); - // we force the check when adding a card trough here - form_data.verify_validity = true; + var verify_validity = this.$el.find('input[name="verify_validity"]'); + + if (verify_validity.length>0) { + form_data.verify_validity = verify_validity[0].value === "1"; + } // do the call to the route stored in the 'data_set' input of the acquirer form, the data must be called 'create-route' - ajax.jsonRpc(ds.dataset.createRoute, 'call', form_data).then( function (data) { + return this._rpc({ + route: ds.dataset.createRoute, + params: form_data, + }).then(function (data) { // if the server has returned true if (data.result) { // and it need a 3DS authentication @@ -273,15 +206,10 @@ odoo.define('payment.payment_form', function (require) { // then we display the 3DS page to the user $("body").html(data['3d_secure']); } - // if it doesn't require 3DS else { - // we just go to the return_url or reload the page - if (form_data.return_url) { - window.location = form_data.return_url; - } - else { - window.location.reload(); - } + checked_radio.value = data.id; // set the radio value to the new card id + form.submit(); + return $.Deferred(); } } // if the server has returned false, we display an error @@ -298,186 +226,296 @@ odoo.define('payment.payment_form', function (require) { } // here we remove the 'processing' icon from the 'add a new payment' button $(button).attr('disabled', false); - $(button).children('.fa').addClass('fa-plus-circle') + $(button).children('.fa').addClass('fa-plus-circle'); $(button).find('span.o_loader').remove(); }).fail(function (error, event) { // if the rpc fails, pretty obvious $(button).attr('disabled', false); - $(button).children('.fa').addClass('fa-plus-circle') + $(button).children('.fa').addClass('fa-plus-circle'); $(button).find('span.o_loader').remove(); self.displayError( - _t('Server error'), - _t("We are not able to add your payment method at the moment.</p>") + - error.data.message + _t('Server Error'), + _t("We are not able to add your payment method at the moment.") + + error.data.message ); }); } - else { - this.displayError( - _t('No payment method selected'), - _t('Please select the option to add a new payment method.') - ); - } - }, - // event handler when clicking on a button to delete a payment method - deletePmEvent: function (ev) { - ev.stopPropagation(); - ev.preventDefault(); - var self = this; - var pm_id = parseInt(ev.target.value); - - var tokenDelete = function () { - rpc.query({ - model: 'payment.token', - method: 'unlink', - args: [pm_id], - }) - .then(function (result) { - if ( result === true) { - ev.target.closest('div').remove(); + // if the user is going to pay with a form payment, then + else if (this.isFormPaymentRadio(checked_radio)) { + var $tx_url = this.$el.find('input[name="prepare_tx_url"]'); + // if there's a prepare tx url set + if ($tx_url.length === 1) { + // if the user wants to save his credit card info + var form_save_token = acquirer_form.find('input[name="o_payment_form_save_token"]').prop('checked'); + // then we call the route to prepare the transaction + return this._rpc({ + route: $tx_url[0].value, + params: { + 'acquirer_id': parseInt(acquirer_id), + 'save_token': form_save_token, + 'access_token': self.options.accessToken, + 'success_url': self.options.successUrl, + 'error_url': self.options.errorUrl, + 'callback_method': self.options.callbackMethod, + 'order_id': self.options.orderId, + }, + }).then(function (result) { + if (result) { + // if the server sent us the html form, we create a form element + var newForm = document.createElement('form'); + newForm.setAttribute("method", "post"); // set it to post + newForm.setAttribute("provider", checked_radio.dataset.provider); + newForm.hidden = true; // hide it + newForm.innerHTML = result; // put the html sent by the server inside the form + var action_url = $(newForm).find('input[name="data_set"]').data('actionUrl'); + newForm.setAttribute("action", action_url); // set the action url + $(document.getElementsByTagName('body')[0]).append(newForm); // append the form to the body + $(newForm).find('input[data-remove-me]').remove(); // remove all the input that should be removed + if(action_url) { + newForm.submit(); // and finally submit the form + return $.Deferred(); + } } - }, function () { + else { + self.displayError( + _t('Server Error'), + _t("We are not able to redirect you to the payment form.") + ); + } + }).fail(function (error, event) { self.displayError( _t('Server Error'), - _t("We are not able to delete your payment method at the moment.") + _t("We are not able to redirect you to the payment form. ") + + error.data.message ); }); - }; + } + else { + // we append the form to the body and send it. + this.displayError( + _t("Cannot set-up the payment"), + _t("We're unable to process your payment.") + ); + } + } + else { // if the user is using an old payment then we just submit the form + form.submit(); + return $.Deferred(); + } + } + else { + this.displayError( + _t('No payment method selected'), + _t('Please select a payment method.') + ); + } + }, + /** + * Called when clicking on the button to add a new payment method. + * + * @private + * @param {Event} ev + */ + addPmEvent: function (ev) { + ev.stopPropagation(); + ev.preventDefault(); + var checked_radio = this.$('input[type="radio"]:checked'); + var self = this; + var button = ev.target; + + // we check if the user has selected a 'add a new payment' option + if (checked_radio.length === 1 && this.isNewPaymentRadio(checked_radio[0])) { + // we retrieve which acquirer is used + checked_radio = checked_radio[0]; + var acquirer_id = this.getAcquirerIdFromRadio(checked_radio); + var acquirer_form = this.$('#o_payment_add_token_acq_' + acquirer_id); + // we retrieve all the input inside the acquirer form and 'serialize' them to an indexed array + var inputs_form = $('input', acquirer_form); + var form_data = this.getFormData(inputs_form); + var ds = $('input[name="data_set"]', acquirer_form)[0]; + var wrong_input = false; + + inputs_form.toArray().forEach(function (element) { + //skip the check of non visible inputs + if ($(element).attr('type') == 'hidden') { + return true; + } + $(element).closest('div.form-group').removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid'); + $(element).siblings( ".o_invalid_field" ).remove(); + //force check of forms validity (useful for Firefox that refill forms automatically on f5) + $(element).trigger("focusout"); + if (element.dataset.isRequired && element.value.length === 0) { + $(element).closest('div.form-group').addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); + var message = '<div style="color: red" class="o_invalid_field" aria-invalid="true">' + _.str.escapeHTML("The value is invalid.") + '</div>'; + $(element).closest('div.form-group').append(message); + wrong_input = true; + } + else if ($(element).closest('div.form-group').hasClass('o_has_error')) { + wrong_input = true; + var message = '<div style="color: red" class="o_invalid_field" aria-invalid="true">' + _.str.escapeHTML("The value is invalid.") + '</div>'; + $(element).closest('div.form-group').append(message); + } + }); + + if (wrong_input) { + return; + } + // We add a 'processing' icon into the 'add a new payment' button + $(button).attr('disabled', true); + $(button).children('.fa-plus-circle').removeClass('fa-plus-circle'); + $(button).prepend('<span class="o_loader"><i class="fa fa-refresh fa-spin"></i> </span>'); + + // we force the check when adding a card trough here + form_data.verify_validity = true; + + // do the call to the route stored in the 'data_set' input of the acquirer form, the data must be called 'create-route' + this._rpc({ + route: ds.dataset.createRoute, + params: form_data, + }).then(function (data) { + // if the server has returned true + if (data.result) { + // and it need a 3DS authentication + if (data['3d_secure'] !== false) { + // then we display the 3DS page to the user + $("body").html(data['3d_secure']); + } + // if it doesn't require 3DS + else { + // we just go to the return_url or reload the page + if (form_data.return_url) { + window.location = form_data.return_url; + } + else { + window.location.reload(); + } + } + } + // if the server has returned false, we display an error + else { + if (data.error) { + self.displayError( + '', + data.error); + } else { // if the server doesn't provide an error message + self.displayError( + _t('Server Error'), + _t('e.g. Your credit card details are wrong. Please verify.')); + } + } + // here we remove the 'processing' icon from the 'add a new payment' button + $(button).attr('disabled', false); + $(button).children('.fa').addClass('fa-plus-circle'); + $(button).find('span.o_loader').remove(); + }).fail(function (error, event) { + // if the rpc fails, pretty obvious + $(button).attr('disabled', false); + $(button).children('.fa').addClass('fa-plus-circle'); + $(button).find('span.o_loader').remove(); - rpc.query({ + self.displayError( + _t('Server error'), + _t("We are not able to add your payment method at the moment.</p>") + + error.data.message + ); + }); + } + else { + this.displayError( + _t('No payment method selected'), + _t('Please select the option to add a new payment method.') + ); + } + }, + /** + * Called when clicking on a button to delete a payment method. + * + * @private + * @param {Event} ev + */ + deletePmEvent: function (ev) { + ev.stopPropagation(); + ev.preventDefault(); + var self = this; + var pm_id = parseInt(ev.target.value); + + var tokenDelete = function () { + self._rpc({ model: 'payment.token', - method: 'get_linked_records', + method: 'unlink', args: [pm_id], }).then(function (result) { - if (result[pm_id].length > 0) { - // if there's records linked to this payment method - var content = ''; - result[pm_id].forEach(function (sub) { - content += '<p><a href="' + sub.url + '" title="' + sub.description + '">' + sub.name + '</a><p/>'; - }); - - content = $('<div>').html(_t('<p>This card is currently linked to the following records:<p/>') + content); - // Then we display the list of the records and ask the user if he really want to remove the payment method. - new Dialog(self, { - title: _t('Warning!'), - size: 'medium', - $content: content, - buttons: [ - {text: _t('Confirm Deletion'), classes: 'btn-primary', close: true, click: tokenDelete}, - {text: _t('Cancel'), close: true}] - }).open(); - } - else { - // if there's no records linked to this payment method, then we delete it - tokenDelete(); + if (result === true) { + ev.target.closest('div').remove(); } - }, function (err, event) { + }, function () { self.displayError( _t('Server Error'), - _t("We are not able to delete your payment method at the moment.") + err.data.message + _t("We are not able to delete your payment method at the moment.") ); }); - }, - - // event handler when clicking on 'and more' to show more payment icon - onClickMorePaymentIcon: function (ev) { - ev.preventDefault(); - ev.stopPropagation(); - var $listItems = $(ev.currentTarget).parents('ul').children('li'); - var $moreItem = $(ev.currentTarget).parents('li'); - $listItems.removeClass('d-none'); - $moreItem.addClass('d-none'); - }, - - // event handler when clicking on a radio button - radioClickEvent: function (ev) { - // radio button checked when we click on entire zone(body) of the payment acquirer - $(ev.currentTarget).find('input[type="radio"]').prop("checked", true); - this.updateNewPaymentDisplayStatus(); - }, - updateNewPaymentDisplayStatus: function () - { - var checked_radio = this.$('input[type="radio"]:checked'); - // we hide all the acquirers form - this.$('[id*="o_payment_add_token_acq_"]').addClass('d-none'); - this.$('[id*="o_payment_form_acq_"]').addClass('d-none'); - if (checked_radio.length !== 1) { - return; - } - checked_radio = checked_radio[0]; - var acquirer_id = this.getAcquirerIdFromRadio(checked_radio); - - // if we clicked on an add new payment radio, display its form - if (this.isNewPaymentRadio(checked_radio)) { - this.$('#o_payment_add_token_acq_' + acquirer_id).removeClass('d-none'); - } - else if (this.isFormPaymentRadio(checked_radio)) { - this.$('#o_payment_form_acq_' + acquirer_id).removeClass('d-none'); - } - }, - isNewPaymentRadio: function (element) { - return $(element).data('s2s-payment') === 'True'; - }, - isFormPaymentRadio: function (element) { - return $(element).data('form-payment') === 'True'; - }, - getAcquirerIdFromRadio: function (element) { - return $(element).data('acquirer-id'); - }, - displayError: function (title, message) { - var $checkedRadio = this.$('input[type="radio"]:checked'), - acquirerID = this.getAcquirerIdFromRadio($checkedRadio[0]); - var $acquirerForm; - if (this.isNewPaymentRadio($checkedRadio[0])) { - $acquirerForm = this.$('#o_payment_add_token_acq_' + acquirerID); - } - else if (this.isFormPaymentRadio($checkedRadio[0])) { - $acquirerForm = this.$('#o_payment_form_acq_' + acquirerID); - } + }; + + this._rpc({ + model: 'payment.token', + method: 'get_linked_records', + args: [pm_id], + }).then(function (result) { + if (result[pm_id].length > 0) { + // if there's records linked to this payment method + var content = ''; + result[pm_id].forEach(function (sub) { + content += '<p><a href="' + sub.url + '" title="' + sub.description + '">' + sub.name + '</a><p/>'; + }); - if ($checkedRadio.length === 0) { - return new Dialog(null, { - title: _t('Error: ') + _.str.escapeHTML(title), + content = $('<div>').html(_t('<p>This card is currently linked to the following records:<p/>') + content); + // Then we display the list of the records and ask the user if he really want to remove the payment method. + new Dialog(self, { + title: _t('Warning!'), size: 'medium', - $content: "<p>" + (_.str.escapeHTML(message) || "") + "</p>" , + $content: content, buttons: [ - {text: _t('Ok'), close: true}]}).open(); - } else { - // removed if exist error message - this.$('#payment_error').remove(); - var messageResult = '<div class="alert alert-danger mb4" id="payment_error">'; - if (title != '') { - messageResult = messageResult + '<b>' + _.str.escapeHTML(title) + ':</b></br>'; - } - messageResult = messageResult + _.str.escapeHTML(message) + '</div>'; - $acquirerForm.append(messageResult); + {text: _t('Confirm Deletion'), classes: 'btn-primary', close: true, click: tokenDelete}, + {text: _t('Cancel'), close: true}] + }).open(); } - }, - getFormData: function ($form) { - var unindexed_array = $form.serializeArray(); - var indexed_array = {}; - - $.map(unindexed_array, function (n, i) { - indexed_array[n.name] = n.value; - }); - return indexed_array; - }, - }); - - $(function () { - // TODO move this to another module, requiring dom_ready and rejecting - // the returned deferred to get the proper message - if (!$('.o_payment_form').length) { - console.log("DOM doesn't contain '.o_payment_form'"); - return; - } - $('.o_payment_form').each(function () { - var $elem = $(this); - var form = new PaymentForm(null, $elem.data()); - form.attachTo($elem); + else { + // if there's no records linked to this payment method, then we delete it + tokenDelete(); + } + }, function (err, event) { + self.displayError( + _t('Server Error'), + _t("We are not able to delete your payment method at the moment.") + err.data.message + ); }); - }); - - return PaymentForm; + }, + /** + * Called when clicking on 'and more' to show more payment icon. + * + * @private + * @param {Event} ev + */ + onClickMorePaymentIcon: function (ev) { + ev.preventDefault(); + ev.stopPropagation(); + var $listItems = $(ev.currentTarget).parents('ul').children('li'); + var $moreItem = $(ev.currentTarget).parents('li'); + $listItems.removeClass('d-none'); + $moreItem.addClass('d-none'); + }, + /** + * Called when clicking on a radio button. + * + * @private + * @param {Event} ev + */ + radioClickEvent: function (ev) { + // radio button checked when we click on entire zone(body) of the payment acquirer + $(ev.currentTarget).find('input[type="radio"]').prop("checked", true); + this.updateNewPaymentDisplayStatus(); + }, +}); +return publicWidget.registry.PaymentForm; }); |
