[IMP] payment, sale: allow to generate payment link from order and invoice

Purpose of the task is, there is no easy way to request custom online
payments on sales orders or invoices. The only way is to create an
URL manually: /website_payment/pay?reference=inv-008&amount=123&currency_id=1

So added menu 'Generate payment link' in action in sales order and invoice.
while making payment pass the partner so reconcilation account flow should not
break as partner_id on account payment is reauired to reconcile.

co-authored-by: sza-odoo <sza@odoo.com>

Task-1938635
Closes: #31575
This commit is contained in:
Barad Mahendra
2019-08-23 14:23:32 +00:00
committed by Damien Bouvy
co-authored by sza-odoo
parent ff6e905c83
commit bea0967114
8 changed files with 132 additions and 0 deletions
+1
View File
@@ -23,6 +23,7 @@
'views/res_partner_views.xml',
'security/ir.model.access.csv',
'security/payment_security.xml',
'wizards/payment_link_wizard_views.xml',
],
'installable': True,
'auto_install': True,
+1
View File
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import payment_acquirer_onboarding_wizard
from . import payment_link_wizard
@@ -0,0 +1,45 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class PaymentLinkWizard(models.TransientModel):
_name = "payment.link.wizard"
_description = "Generate Payment Link"
@api.model
def default_get(self, fields):
res = super(PaymentLinkWizard, self).default_get(fields)
res_id = self._context.get('active_id')
res_model = self._context.get('active_model')
res.update({'res_id': res_id, 'res_model': res_model})
if res_id and res_model == 'account.invoice':
record = self.env[res_model].browse(res_id)
res.update({
'description': record.reference,
'amount': record.amount_total,
'currency_id': record.currency_id.id,
'partner_id': record.partner_id.id,
'amount_max': record.amount_total
})
return res
res_model = fields.Char('Related Document Model', required=True)
res_id = fields.Integer('Related Document ID', required=True)
amount = fields.Monetary(currency_field='currency_id', required=True)
amount_max = fields.Monetary(currency_field='currency_id')
currency_id = fields.Many2one('res.currency')
partner_id = fields.Many2one('res.partner')
link = fields.Char(string='Payment Link')
description = fields.Char('Payment Ref')
@api.onchange('amount', 'description')
def _onchange_amount(self):
if self.amount_max < self.amount:
raise ValidationError(_("Please set an amount smaller than %s.") % (self.amount_max))
if self.amount <= 0:
raise ValidationError(_("The value of the payment amount must be positive."))
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
self.link = '%s/website_payment/pay?reference=%s&amount=%s&currency_id=%s&partner_id=%s' % (base_url, self.description, self.amount, self.currency_id.id, self.partner_id.id)
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="payment_link_wizard_view_form" model="ir.ui.view">
<field name="name">payment.link.wizard.form</field>
<field name="model">payment.link.wizard</field>
<field name="arch" type="xml">
<form string="Generate Payment Link">
<group>
<field name="res_id" invisible="1"/>
<field name="res_model" invisible="1"/>
<field name="partner_id" invisible="1"/>
<field name="amount_max" invisible="1"/>
<field name="description"/>
<field name="amount"/>
<field name="currency_id" invisible="1"/>
</group>
<group>
<field name="link" readonly="1" widget="CopyClipboardChar"/>
</group>
<footer>
<button string="Ok" class="btn-primary" special="cancel"/>
<button string="Cancel" special="cancel"/>
</footer>
</form>
</field>
</record>
<act_window
name="Generate a Payment Link"
res_model="payment.link.wizard"
binding_model="account.invoice"
binding_views="form"
view_mode="form"
target="new"
view_id="payment_link_wizard_view_form"
id="action_invoice_order_generate_link"
/>
</odoo>
+1
View File
@@ -35,6 +35,7 @@ This module contains all the common features of Sales Management and eCommerce.
'views/product_attribute_views.xml',
'views/product_views.xml',
'views/utm_campaign_views.xml'
'wizard/sale_payment_link_views.xml',
],
'demo': [
'data/sale_demo.xml',
+1
View File
@@ -3,3 +3,4 @@
from . import payment_acquirer_onboarding_wizard
from . import sale_make_invoice_advance
from . import sale_payment_link
+30
View File
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models
class SalePaymentLink(models.TransientModel):
_inherit = "payment.link.wizard"
_description = "Generate Sales Payment Link"
@api.model
def default_get(self, fields):
res = super(SalePaymentLink, self).default_get(fields)
if res['res_id'] and res['res_model'] == 'sale.order':
record = self.env[res['res_model']].browse(res['res_id'])
res.update({
'description': record.name,
'amount': record.amount_total - sum(record.invoice_ids.mapped('amount_total')),
'currency_id': record.currency_id.id,
'partner_id': record.partner_id.id,
'amount_max': record.amount_total
})
return res
@api.onchange('amount', 'description')
def _onchange_amount(self):
res = super(SalePaymentLink, self)._onchange_amount()
if self.res_model == 'sale.order':
self.link = "%s&order_id=%d" % (self.link, self.res_id)
return res
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<act_window
name="Generate a Payment Link"
res_model="payment.link.wizard"
binding_model="sale.order"
binding_views="form"
view_mode="form"
target="new"
view_id="payment.payment_link_wizard_view_form"
id="action_sale_order_generate_link"
/>
</odoo>