Skip to content

Commit

Permalink
[FIX] account_payment: allow disabling payment of invoices on portal
Browse files Browse the repository at this point in the history
Since e3eb7d9, the accounting logic
has been moved out of the payment module, to be only in the
account_payment bridge module.

This bridge module has been set as strict dependency of
module providing payment & invoicing abilities, e.g. sale .

Nevertheless, the account_payment module also held the logic to
allow users to pay for their invoices on the portal and there
was no dedicated setting to enable/disable this feature.
This means that in 16.0+, you cannot disable online invoices
payment without removing sale and subsequent modules.

This commit introduces a temporary bugfix module to allow
disabling invoices payment without uninstalling the
account_payment module.  It will be merged in the core
account_payment afterwards.

opw-3114860

closes #110177

Related: odoo/documentation#3383
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
  • Loading branch information
Feyensv committed Jan 23, 2023
1 parent df783ad commit cedf97b
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 0 deletions.
5 changes: 5 additions & 0 deletions addons/account_payment/controllers/portal.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ class PortalAccount(portal.PortalAccount):

def _invoice_get_page_view_values(self, invoice, access_token, **kwargs):
values = super()._invoice_get_page_view_values(invoice, access_token, **kwargs)

if not invoice._has_to_be_paid():
# Do not compute payment-related stuff if given invoice doesn't have to be paid.
return values

logged_in = not request.env.user._is_public()
# We set partner_id to the partner id of the current user if logged in, otherwise we set it
# to the invoice partner id. We do this to ensure that payment tokens are assigned to the
Expand Down
16 changes: 16 additions & 0 deletions addons/account_payment/models/account_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ def _compute_amount_paid(self):
).mapped('amount')
)

def _has_to_be_paid(self):
self.ensure_one()
transactions = self.transaction_ids.filtered(lambda tx: tx.state in ('authorized', 'done'))
return bool(
(
self.amount_residual
# FIXME someplace we check amount_residual and some other amount_paid < amount_total
# what is the correct heuristic to check ?
or not transactions
)
and self.state == 'posted'
and self.payment_state in ('not_paid', 'partial')
and self.amount_total
and self.move_type == 'out_invoice'
)

def get_portal_last_transaction(self):
self.ensure_one()
return self.with_context(active_test=False).transaction_ids._get_last()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import models
from . import wizards
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

{
'name': "Payment - Account / Invoice Online Payment Patch",
'category': 'Accounting/Accounting',
'depends': ['account_payment'],
'auto_install': True,
'data': [
'data/ir_config_parameter.xml',

'views/account_portal_templates.xml',

'wizards/res_config_settings_views.xml',
],
'license': 'LGPL-3',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo noupdate="1">

<record id="enable_portal_payment" model="ir.config_parameter" forcecreate="0">
<field name="key">account_payment.enable_portal_payment</field>
<field name="value">True</field>
</record>

</odoo>
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_payment_extension
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-17 15:34+0000\n"
"PO-Revision-Date: 2023-01-17 15:34+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.portal_my_invoices_payment
msgid ""
"<span class=\"badge rounded-pill text-bg-info\"><i class=\"fa fa-fw fa-"
"clock-o\" aria-label=\"Opened\" title=\"Opened\" role=\"img\"/><span "
"class=\"d-none d-md-inline\"> Waiting for Payment</span></span>"
msgstr ""

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.portal_my_invoices_payment
msgid ""
"<span class=\"badge rounded-pill text-bg-info\"><i class=\"fa fa-fw fa-"
"clock-o\"/><span class=\"d-none d-md-inline\"> Waiting for "
"Payment</span></span>"
msgstr ""

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.portal_my_invoices_payment
msgid ""
"<span class=\"badge rounded-pill text-bg-primary\"><i class=\"fa fa-fw fa-"
"check\"/><span class=\"d-none d-md-inline\"> Authorized</span></span>"
msgstr ""

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.portal_my_invoices_payment
msgid ""
"<span class=\"badge rounded-pill text-bg-success\"><i class=\"fa fa-fw fa-"
"check\" aria-label=\"Paid\" title=\"Paid\" role=\"img\"/><span "
"class=\"d-none d-md-inline\"> Paid</span></span>"
msgstr ""

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.portal_my_invoices_payment
msgid ""
"<span class=\"badge rounded-pill text-bg-success\"><i class=\"fa fa-fw fa-"
"check\" aria-label=\"Reversed\" title=\"Reversed\" role=\"img\"/><span "
"class=\"d-none d-md-inline\"> Reversed</span></span>"
msgstr ""

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.portal_my_invoices_payment
msgid ""
"<span class=\"badge rounded-pill text-bg-success\"><i class=\"fa fa-fw fa-"
"check\"/><span class=\"d-none d-md-inline\"> Paid</span></span>"
msgstr ""

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.portal_my_invoices_payment
msgid ""
"<span class=\"badge rounded-pill text-bg-warning\"><i class=\"fa fa-fw fa-"
"remove\" aria-label=\"Cancelled\" title=\"Cancelled\" role=\"img\"/><span "
"class=\"d-none d-md-inline\"> Cancelled</span></span>"
msgstr ""

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.portal_my_invoices_payment
msgid ""
"<span class=\"badge rounded-pill text-bg-warning\"><span class=\"d-none "
"d-md-inline\"> Pending</span></span>"
msgstr ""

#. module: account_payment_extension
#: model:ir.model,name:account_payment_extension.model_res_config_settings
msgid "Config Settings"
msgstr ""

#. module: account_payment_extension
#: model_terms:ir.ui.view,arch_db:account_payment_extension.res_config_settings_view_form
msgid "Invoice Online Payment"
msgstr ""

#. module: account_payment_extension
#: model:ir.model,name:account_payment_extension.model_account_move
msgid "Journal Entry"
msgstr ""

#. module: account_payment_extension
#: model:ir.model.fields,field_description:account_payment_extension.field_res_config_settings__pay_invoices_online
msgid "Pay Invoices Online"
msgstr ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import account_move
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import models
from odoo.tools import str2bool


class AccountMove(models.Model):
_inherit = 'account.move'

def _has_to_be_paid(self):
enabled_feature = str2bool(
self.env['ir.config_parameter'].sudo().get_param(
'account_payment.enable_portal_payment'
)
)
return enabled_feature and super()._has_to_be_paid()
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>

<template id="portal_my_invoices_payment" inherit_id="account_payment.portal_my_invoices_payment">
<xpath expr="//t[@t-foreach='invoices']/tr/td[count(t)=2]/t[@t-set='pending_manual_txs']/following-sibling::a[i]" position="attributes">
<attribute name="t-if">
invoice._has_to_be_paid()
</attribute>
</xpath>
<xpath expr="//t[@t-foreach='invoices']/tr/td[hasclass('tx_status')]" position="replace">
<td class="tx_status text-center">
<t t-if="last_tx">
<!-- c/p of account_payment -->
<t t-if="invoice.state == 'posted' and invoice.payment_state in ('not_paid', 'partial') and (last_tx.state not in ['pending', 'authorized', 'done', 'cancel'] or (last_tx.state == 'pending' and last_tx.provider_code in ('none', 'custom')))">
<span class="badge rounded-pill text-bg-info"><i class="fa fa-fw fa-clock-o"></i><span class="d-none d-md-inline"> Waiting for Payment</span></span>
</t>
<t t-if="invoice.state == 'posted' and last_tx.state == 'authorized'">
<span class="badge rounded-pill text-bg-primary"><i class="fa fa-fw fa-check"/><span class="d-none d-md-inline"> Authorized</span></span>
</t>
<t t-if="invoice.state == 'posted' and last_tx.state == 'pending' and last_tx.provider_code not in ('none', 'custom')">
<span class="badge rounded-pill text-bg-warning"><span class="d-none d-md-inline"> Pending</span></span>
</t>
<t t-if="invoice.state == 'posted' and invoice.payment_state in ('paid', 'in_payment') or last_tx.state == 'done'">
<span class="badge rounded-pill text-bg-success"><i class="fa fa-fw fa-check"></i><span class="d-none d-md-inline"> Paid</span></span>
</t>
</t>
<t t-else="">
<!-- c/p of account -->
<t t-if="invoice.state == 'posted' and invoice.payment_state not in ('in_payment', 'paid', 'reversed')">
<span class="badge rounded-pill text-bg-info"><i class="fa fa-fw fa-clock-o" aria-label="Opened" title="Opened" role="img"></i><span class="d-none d-md-inline"> Waiting for Payment</span></span>
</t>
<t t-if="invoice.state == 'posted' and invoice.payment_state in ('paid', 'in_payment')">
<span class="badge rounded-pill text-bg-success"><i class="fa fa-fw fa-check" aria-label="Paid" title="Paid" role="img"></i><span class="d-none d-md-inline"> Paid</span></span>
</t>
<t t-if="invoice.state == 'posted' and invoice.payment_state == 'reversed'">
<span class="badge rounded-pill text-bg-success"><i class="fa fa-fw fa-check" aria-label="Reversed" title="Reversed" role="img"></i><span class="d-none d-md-inline"> Reversed</span></span>
</t>
<t t-if="invoice.state == 'cancel'">
<span class="badge rounded-pill text-bg-warning"><i class="fa fa-fw fa-remove" aria-label="Cancelled" title="Cancelled" role="img"></i><span class="d-none d-md-inline"> Cancelled</span></span>
</t>
</t>
</td>
</xpath>
</template>

<template id="portal_invoice_page_inherit_payment" inherit_id="account_payment.portal_invoice_page_inherit_payment">
<xpath expr="//div[@id='portal_pay']" position="attributes">
<attribute name="t-if">
invoice._has_to_be_paid()
</attribute>
</xpath>
<xpath expr="//t[@t-call='portal.portal_record_sidebar']//div[hasclass('d-grid')]//a[starts-with(@href, '#')][i]" position="attributes">
<attribute name="t-if">
invoice._has_to_be_paid()
</attribute>
</xpath>
</template>

</odoo>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import res_config_settings
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import fields, models


class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'

pay_invoices_online = fields.Boolean(config_parameter='account_payment.enable_portal_payment')
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.account</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
<field name="arch" type="xml">
<field name="module_account_payment" position="replace">
<field name="pay_invoices_online"/>
</field>

<xpath expr="//label[@for='module_account_payment']" position="replace">
<label for="pay_invoices_online" string="Invoice Online Payment"/>
</xpath>
</field>
</record>

</odoo>

0 comments on commit cedf97b

Please sign in to comment.