-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ADD] add new module account_payment_multi to create payment links fo…
…r multiples invoices closes #370 X-original-commit: 157c914 Signed-off-by: augusto-weiss <[email protected]>
- Loading branch information
1 parent
8c7c3c3
commit 19d5e54
Showing
12 changed files
with
461 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
.. |company| replace:: ADHOC SA | ||
|
||
.. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png | ||
:alt: ADHOC SA | ||
:target: https://www.adhoc.com.ar | ||
|
||
.. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png | ||
|
||
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png | ||
:target: https://www.gnu.org/licenses/agpl | ||
:alt: License: AGPL-3 | ||
|
||
============== | ||
account_payment_multi | ||
============== | ||
|
||
This module extends the online invoice payment functionality by allowing you to generate a singlep ayment links to pay multiple invoices. | ||
It is available both from the backend and from the customer portal. | ||
|
||
Installation | ||
============ | ||
|
||
To install this module, you need to: | ||
|
||
#. Do this ... | ||
|
||
Configuration | ||
============= | ||
|
||
To configure this module, you need to: | ||
|
||
#. Go to ... | ||
|
||
Usage | ||
===== | ||
|
||
To use this module, you need to: | ||
|
||
#. Go to ... | ||
|
||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas | ||
:alt: Try me on Runbot | ||
:target: http://runbot.adhoc.com.ar/ | ||
|
||
Bug Tracker | ||
=========== | ||
|
||
Bugs are tracked on `GitHub Issues | ||
<https://github.com/ingadhoc/account_payment/issues>`_. In case of trouble, please | ||
check there if your issue has already been reported. If you spotted it first, | ||
help us smashing it by providing a detailed and welcomed feedback. | ||
|
||
Credits | ||
======= | ||
|
||
Images | ||
------ | ||
|
||
* |company| |icon| | ||
|
||
Contributors | ||
------------ | ||
|
||
Maintainer | ||
---------- | ||
|
||
|company_logo| | ||
|
||
This module is maintained by the |company|. | ||
|
||
To contribute to this module, please visit https://www.adhoc.com.ar. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from . import controllers | ||
from . import wizards |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
'name': "Account payment multi", | ||
'description': """ | ||
Allows payment multiple invoices with a single payment link | ||
""", | ||
'author': 'ADHOC SA', | ||
'website': "https://www.adhoc.com.ar", | ||
'category': 'Technical', | ||
'version': "15.0.1.0.0", | ||
'depends': ['account_payment'], | ||
'license': 'LGPL-3', | ||
'images': [ | ||
], | ||
'installable': True, | ||
'assets': { | ||
'web.assets_frontend': [ | ||
'account_payment_multi/static/src/js/payment_form.js', | ||
'account_payment_multi/static/src/js/payment_multi.js', | ||
], | ||
}, | ||
'data': [ | ||
'views/payment_templates.xml', | ||
'views/account_portal_templates.xml', | ||
'wizards/payment_link_wizard_views.xml', | ||
], | ||
'demo': [ | ||
], | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import portal |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
############################################################################## | ||
# For copyright and license notices, see __manifest__.py file in module root | ||
# directory | ||
############################################################################## | ||
|
||
from odoo import _, http | ||
from odoo.exceptions import ValidationError | ||
from odoo.fields import Command | ||
from odoo.http import request | ||
|
||
from odoo.addons.portal.controllers import portal | ||
from odoo.tools import float_compare | ||
|
||
|
||
class PaymentPortal(portal.CustomerPortal): | ||
|
||
@http.route('/payment/invoice_multi_link', type='json', auth='user') | ||
def invoice_multi_transaction(self, invoice_ids, amount, **kwargs): | ||
invoices_sudo = request.env['account.move'].sudo() | ||
for invoice in invoice_ids: | ||
# Check the invoice id | ||
invoices_sudo += self._document_check_access('account.move', invoice['id'], invoice.get('token')) | ||
payment_link = request.env['payment.link.wizard'].sudo().with_context(active_id=invoices_sudo[0].id, active_ids=invoices_sudo.ids, active_model='account.move').create({}) | ||
|
||
if float_compare(payment_link.amount_max, amount, precision_rounding=payment_link.currency_id.rounding or 0.01) == -1: | ||
raise ValidationError(_("Incorrect amount")) | ||
return payment_link.link | ||
|
||
@http.route() | ||
def payment_pay( | ||
self, reference=None, amount=None, currency_id=None, partner_id=None, company_id=None, | ||
acquirer_id=None, access_token=None, invoice_id=None, **kwargs | ||
): | ||
|
||
amount = self._cast_as_float(amount) | ||
if 'invoice_ids' in kwargs: | ||
invoice_ids = [int(x) for x in kwargs['invoice_ids'].split(',') if x.isdigit()] | ||
invoices_sudo = request.env['account.move'].sudo().browse(invoice_ids).exists() | ||
if not invoices_sudo: | ||
raise ValidationError(_("The provided parameters are invalid.")) | ||
if len(invoices_sudo.mapped('commercial_partner_id')) > 1: | ||
raise ValidationError(_("Only pay invoices from the same customer.")) | ||
if len(invoices_sudo.mapped('currency_id')) > 1: | ||
raise ValidationError(_("Only pay invoices from the same currency.")) | ||
if len(invoices_sudo.mapped('company_id')) > 1: | ||
raise ValidationError(_("Only pay invoices from the same company.")) | ||
first_invoice_sudo = invoices_sudo[0] | ||
# Check the access token against the invoice values. Done after fetching the invoice | ||
# as we need the invoice fields to check the access token. | ||
# if not payment_utils.check_access_token( | ||
# access_token, first_invoice_sudo.partner_id.id, amount, first_invoice_sudo.currency_id.id | ||
# ): | ||
# raise ValidationError(_("The provided parameters are invalid.")) | ||
currency_id = first_invoice_sudo.currency_id.id | ||
partner_id = first_invoice_sudo.commercial_partner_id.id | ||
company_id = first_invoice_sudo.company_id.id | ||
|
||
kwargs.update({ | ||
'invoice_ids': invoice_ids, | ||
}) | ||
return super().payment_pay( | ||
reference=reference, amount=amount, currency_id=currency_id, partner_id=partner_id, company_id=company_id, | ||
acquirer_id=acquirer_id, access_token=access_token, invoice_id=invoice_id, **kwargs | ||
|
||
) | ||
|
||
def _get_custom_rendering_context_values(self, invoice_ids=None, **kwargs): | ||
""" Override of `payment` to add the invoice id in the custom rendering context values. | ||
:param int invoice_id: The invoice for which a payment id made, as an `account.move` id. | ||
:param dict kwargs: Optional data. This parameter is not used here. | ||
:return: The extended rendering context values. | ||
:rtype: dict | ||
""" | ||
rendering_context_values = super()._get_custom_rendering_context_values(**kwargs) | ||
if invoice_ids: | ||
rendering_context_values['invoice_ids'] = invoice_ids | ||
|
||
# Interrupt the payment flow if the invoice has been canceled. | ||
# invoice_sudo = request.env['account.move'].sudo().browse(invoice_ids) | ||
#if invoice_sudo.state == 'cancel': | ||
# rendering_context_values['amount'] = 0.0 | ||
return rendering_context_values | ||
|
||
def _create_transaction(self, *args, invoice_ids=None, custom_create_values=None, **kwargs): | ||
""" Override of `payment` to add the invoice id in the custom create values. | ||
:param int invoice_id: The invoice for which a payment id made, as an `account.move` id. | ||
:param dict custom_create_values: Additional create values overwriting the default ones. | ||
:param dict kwargs: Optional data. This parameter is not used here. | ||
:return: The result of the parent method. | ||
:rtype: recordset of `payment.transaction` | ||
""" | ||
##import pdb; pdb.set_trace() | ||
if invoice_ids: | ||
if custom_create_values is None: | ||
custom_create_values = {} | ||
custom_create_values['invoice_ids'] = [Command.set(invoice_ids)] | ||
return super()._create_transaction( | ||
*args, custom_create_values=custom_create_values, **kwargs | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
odoo.define('account_payment_multi.payment_form', require => { | ||
'use strict'; | ||
|
||
const checkoutForm = require('payment.checkout_form'); | ||
const manageForm = require('payment.manage_form'); | ||
|
||
const PaymentMixin = { | ||
|
||
//-------------------------------------------------------------------------- | ||
// Private | ||
//-------------------------------------------------------------------------- | ||
|
||
/** | ||
* Add `invoice_id` to the transaction route params if it is provided. | ||
* | ||
* @override method from payment.payment_form_mixin | ||
* @private | ||
* @param {string} code - The provider code of the selected payment option. | ||
* @param {number} paymentOptionId - The id of the selected payment option. | ||
* @param {string} flow - The online payment flow of the selected payment option. | ||
* @return {object} The extended transaction route params. | ||
*/ | ||
_prepareTransactionRouteParams: function (code, paymentOptionId, flow) { | ||
const transactionRouteParams = this._super(...arguments); | ||
return { | ||
...transactionRouteParams, | ||
'invoice_ids': this.txContext.invoiceIds ? this.txContext.invoiceIds : null, | ||
}; | ||
}, | ||
|
||
}; | ||
|
||
checkoutForm.include(PaymentMixin); | ||
manageForm.include(PaymentMixin); | ||
|
||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
odoo.define('account_payment.multi', function (require) { | ||
'use strict'; | ||
|
||
const core = require('web.core'); | ||
const publicWidget = require('web.public.widget'); | ||
const Dialog = require('web.Dialog'); | ||
const _t = core._t; | ||
|
||
publicWidget.registry.AccountPaymentWidget = publicWidget.Widget.extend({ | ||
selector: '.payment_multi_table', | ||
events: { | ||
'change .checkbox_amount_residual': '_onChangeCheckboxAmountResidual', | ||
'click .oe_multi_pay_now': '_onPayNowBtnClick', | ||
}, | ||
init: function () { | ||
this._super.apply(this, arguments); | ||
//this._computeAmount(); | ||
}, | ||
_onChangeCheckboxAmountResidual: function(event) { | ||
this._computeAmount() | ||
}, | ||
_computeAmount: function(){ | ||
var items = this.el.getElementsByClassName('checkbox_amount_residual'); | ||
let total = 0; | ||
let currency = false; | ||
let old_group = false; | ||
let group = false; | ||
console.log(group); | ||
for (let i = 0; i < items.length; i++) { | ||
if (items[i].checked){ | ||
old_group = group; | ||
group = items[i].dataset.invoiceGroup; | ||
currency = items[i].dataset.currencyName; | ||
if (old_group && group != old_group){ | ||
items[i].checked = false; | ||
return new Dialog(null, { | ||
title: _t("Error in selection"), | ||
size: 'medium', | ||
$content: _t(`<p>selected invoices must be in the same currency, partner and company</p>`), | ||
buttons: [{text: _t("Ok"), close: true}] | ||
}).open(); | ||
|
||
} | ||
total = total + parseFloat(items[i].dataset.amountResidual); | ||
} | ||
} | ||
this.el.querySelectorAll('.oe_amount').forEach((selector) =>selector.innerHTML=currency + ' ' + total.toFixed(2)); | ||
if (total){ | ||
this.el.querySelectorAll('.multi_payment_selector').forEach((selector) =>selector.classList.remove('invisible')); | ||
} else { | ||
this.el.querySelectorAll('.multi_payment_selector').forEach((selector) =>selector.classList.add('invisible')); | ||
} | ||
}, | ||
_onPayNowBtnClick: function(event){ | ||
var items = this.el.getElementsByClassName('checkbox_amount_residual'); | ||
let total = 0; | ||
let invoices = []; | ||
for (let i = 0; i < items.length; i++) { | ||
if (items[i].checked){ | ||
total = total + parseFloat(items[i].dataset.amountResidual); | ||
invoices.push({id : parseInt(items[i].dataset.invoiceId), token: items[i].dataset.accessToken}) | ||
} | ||
} | ||
let params = {invoice_ids: invoices, amount: total} | ||
return this._rpc({ | ||
route: "/payment/invoice_multi_link", | ||
params: params, | ||
}).then(async data => { | ||
window.location = data; | ||
}); | ||
|
||
} | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<odoo> | ||
|
||
<template id="portal_my_invoices_payment" name="Payment on My Invoices" inherit_id="account.portal_my_invoices"> | ||
<xpath expr="//t[@t-call='portal.portal_table']/thead/tr/th[1]" position="before"> | ||
<th></th> | ||
</xpath> | ||
<xpath expr="//t[@t-foreach='invoices']/tr/td[1]" position="before"> | ||
<td class="text-center"> | ||
<input | ||
id="pay_amount_residual" | ||
t-att-data-invoice-group = "'%s-%s-%s' % (invoice.currency_id.id, invoice.commercial_partner_id.id , invoice.company_id.id)" | ||
t-att-data-invoice-id = "invoice.id" | ||
t-att-data-currency-name = "invoice.currency_id.name" | ||
t-att-data-access-token = "invoice.access_token" | ||
t-att-data-amount-residual = "invoice.amount_residual" | ||
type="checkbox" | ||
t-att-class="'checkbox_amount_residual'" | ||
t-if="invoice.state == 'posted' and invoice.payment_state in ('not_paid', 'partial') and invoice.amount_total and invoice.move_type == 'out_invoice'"/> | ||
</td> | ||
</xpath> | ||
<xpath expr="//t[@t-foreach='invoices']" position="before"> | ||
<tr> | ||
<td class="text-center"><i class="fa fa-arrow-down"></i></td> | ||
<td><strong class="oe_zeroAmount">Select invoices to pay</strong></td> | ||
<td colspan="10"> | ||
<span class="multi_payment_selector invisible"> | ||
<a href="#" title="Pay Now" aria-label="Pay now" class="btn btn-sm btn-primary oe_multi_pay_now" role="button"> | ||
<i class="fa fa-arrow-circle-right"/><span class='d-none d-md-inline'> Pay <span class="oe_amount"></span> Now</span> | ||
</a> | ||
</span> | ||
</td> | ||
</tr> | ||
</xpath> | ||
|
||
<xpath expr="//t[@t-foreach='invoices']" position="after"> | ||
<tr> | ||
<td class="text-center"></td> | ||
<td></td> | ||
<td colspan="10"> | ||
<span class="multi_payment_selector invisible"> | ||
<a href="#" title="Pay Now" aria-label="Pay now" class="btn btn-sm btn-primary oe_multi_pay_now" role="button"> | ||
<i class="fa fa-arrow-circle-right"/><span class='d-none d-md-inline'> Pay <span class="oe_amount"></span> Now</span> | ||
</a> | ||
</span> | ||
</td> | ||
</tr> | ||
</xpath> | ||
<t t-call="portal.portal_table" position="before"> | ||
<t t-set="classes" t-value="'payment_multi_table'"/> | ||
</t> | ||
|
||
</template> | ||
|
||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<odoo> | ||
<template id="payment_checkout_inherit" inherit_id="payment.checkout"> | ||
<xpath expr="//form[@name='o_payment_checkout']" position="attributes"> | ||
<attribute name="t-att-data-invoice-ids">invoice_ids</attribute> | ||
</xpath> | ||
</template> | ||
|
||
<template id="payment_manage_inherit" inherit_id="payment.manage"> | ||
<xpath expr="//form[@name='o_payment_manage']" position="attributes"> | ||
<attribute name="t-att-data-invoice-ids">invoice_ids</attribute> | ||
</xpath> | ||
</template> | ||
</odoo> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from . import payment_link_wizard |
Oops, something went wrong.