Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][BIG] Large refactoring/improvement/cleanup of OCA/bank-payment #1174

Open
wants to merge 33 commits into
base: 16.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
caad76b
Large refactoring/improvement/cleanup of OCA/bank-payment
alexis-via Nov 7, 2023
c7391e0
Add support for regulatory reporting in PAIN files
alexis-via Nov 15, 2023
7924a94
[16.0] FIX account_payment_order communication full
mourad-ehm May 15, 2024
8fe91c9
account_payment_mode: add payment_method_code as invisible in payment…
alexis-via Jun 15, 2024
f1d288c
[FIX] always exclude cancel moves in account.payment.line.create wizard
alexis-via Aug 21, 2024
472145e
account_payment_order: remove view inheritance that is not needed any…
alexis-via Aug 21, 2024
489f4fe
account_banking_pain_base: use _rec_names_search for account.pain.reg…
alexis-via Aug 21, 2024
00cb70c
Big cleanup of PAIN XML code generation
alexis-via Aug 21, 2024
e0ccf2d
account_banking_pain_base: structured address in XML
alexis-via Aug 22, 2024
5f1e105
[IMP] add support for PAIN 001.001.09 + 008.001.08 (adopted by EPC)
alexis-via Aug 22, 2024
f814d98
account_banking_pain_base: hide pain_version in payment method views …
alexis-via Aug 22, 2024
43dd15e
account_banking_pain_base: change group for full-access ACL for accou…
alexis-via Aug 23, 2024
7d08c20
[FIX] Layout of SEPA section of accounting config page
alexis-via Aug 23, 2024
5cb6f26
[FIX] res.partner.bank form view layout
alexis-via Aug 23, 2024
47c621b
[FIX] account_banking_mandate: add mandate_id to grouping fields
alexis-via Aug 23, 2024
c2518b2
account_payment_partner: remove code that works well natively on v16 …
alexis-via Aug 23, 2024
c4770fe
[FIX] account_payment_order: compute of bank account on payment line
alexis-via Aug 23, 2024
8eb0b3e
[FIX] account_banking_mandate: hide mandate_id field on payment lines…
alexis-via Aug 23, 2024
e05f3dc
account_banking_mandate: remove constraint that is handled natively b…
alexis-via Aug 23, 2024
2e9a083
[IMP] account_banking_mandate: add constraint on payment method
alexis-via Aug 23, 2024
f1cd3db
[IMP] account_banking_mandate: mandate_id is now a computed field on …
alexis-via Aug 23, 2024
518fbec
[FIX] account_banking_sepa_direct_debit: SEPA mandates must be linked…
alexis-via Aug 24, 2024
8ab98dd
[IMP] account_payment_order: get d/l pop-up when generating file
alexis-via Aug 27, 2024
5aae5bd
[IMP] add related field payment_method_code on account.move and accou…
alexis-via Aug 27, 2024
f98ab6c
Improve link between mandate and bank accounts
alexis-via Aug 27, 2024
713160e
[IMP] account_payment_order: set no_debit_before_maturity to True by …
alexis-via Aug 28, 2024
4bae9e5
[IMP] account_payment_order: set default_date_prefered to "due" by de…
alexis-via Aug 28, 2024
6ba906f
[IMP] account_payment_mode: add archived filter in payment mode searc…
alexis-via Nov 25, 2024
8ee86dc
[FIX] account_payment_order: access rights issues on invoice
alexis-via Dec 11, 2024
8c2360b
[IMP] account_payment_mode: note field text -> html
alexis-via Dec 13, 2024
795ec55
account_payment_order: add fields needed to make account_reconcile_pa…
alexis-via Dec 13, 2024
f68e96a
[FIX] account_payment_order: date_prefered computation
alexis-via Dec 24, 2024
bf9da9d
[IMP] account_payment_mode: view cleanup
alexis-via Dec 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 8 additions & 15 deletions account_banking_mandate/tests/test_invoice_mandate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from unittest.mock import patch

from odoo import fields
from odoo import Command, fields
from odoo.exceptions import UserError
from odoo.tests.common import TransactionCase

Expand All @@ -28,7 +28,6 @@ def test_post_invoice_01(self):

payment_order = self.env["account.payment.order"].search([])
self.assertEqual(len(payment_order.ids), 1)
payment_order.payment_mode_id_change()
payment_order.draft2open()
payment_order.open2generated()
payment_order.generated2uploaded()
Expand Down Expand Up @@ -272,18 +271,12 @@ def setUp(self):
.id
)

invoice_vals = [
(
0,
0,
{
"product_id": self.env.ref("product.product_product_4").id,
"quantity": 1.0,
"account_id": invoice_line_account,
"price_unit": 200.00,
},
)
]
line_vals = {
"product_id": self.env.ref("product.product_product_4").id,
"quantity": 1.0,
"account_id": invoice_line_account,
"price_unit": 200.00,
}

self.invoice = self.env["account.move"].create(
{
Expand All @@ -296,7 +289,7 @@ def setUp(self):
limit=1,
)
.id,
"invoice_line_ids": invoice_vals,
"invoice_line_ids": [Command.create(line_vals)],
}
)

Expand Down
33 changes: 27 additions & 6 deletions account_banking_mandate/tests/test_mandate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,29 @@

from datetime import timedelta

from odoo import fields
from odoo import Command, fields
from odoo.exceptions import UserError, ValidationError
from odoo.tests.common import TransactionCase


class TestMandate(TransactionCase):
def setUp(self):
super(TestMandate, self).setUp()
self.company = self.env.company
self.company = self.env.ref("base.main_company")
self.company_2 = self.env["res.company"].create({"name": "company 2"})
self.company_2.partner_id.company_id = self.company_2.id
self.bank_account = self.env.ref("account_payment_mode.res_partner_12_iban")
self.bank_account.partner_id.company_id = self.company.id
self.partner = self.env["res.partner"].create(
{
"name": "My little company Sprl",
"company_id": self.company.id,
}
)
self.bank_account = self.env["res.partner.bank"].create(
{
"acc_number": "FR382222 3333 4444 5555 6666 999",
"partner_id": self.partner.id,
}
)
self.mandate = self.env["account.banking.mandate"].create(
{
"partner_bank_id": self.bank_account.id,
Expand Down Expand Up @@ -49,7 +59,18 @@ def test_mandate_04(self):
self.mandate.cancel()

def test_onchange_methods(self):
bank_account_2 = self.env.ref("account_payment_mode.res_partner_2_iban")
partner_2 = self.env["res.partner"].create(
{
"name": "Big company Sprl",
"company_id": self.company.id,
}
)
bank_account_2 = self.env["res.partner.bank"].create(
{
"acc_number": "FR621111 9999 8888 5555 6666 777",
"partner_id": partner_2.id,
}
)
self.mandate.partner_bank_id = bank_account_2
self.mandate.mandate_partner_bank_change()
self.assertEqual(self.mandate.partner_id, bank_account_2.partner_id)
Expand Down Expand Up @@ -89,7 +110,7 @@ def test_constrains_04(self):
}
)
with self.assertRaises(UserError):
bank_account.write({"mandate_ids": [(6, 0, mandate.ids)]})
bank_account.write({"mandate_ids": [Command.set(mandate.ids)]})

def test_mandate_reference_01(self):
"""
Expand Down
2 changes: 1 addition & 1 deletion account_banking_pain_base/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Account Banking PAIN Base Module
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:cb0a3e1e489965d9fd1e4540fb54b404f630887d8a913484c222034edbe91786
!! source digest: sha256:b830f262c5a7db70d35218b9b420e0d1614bbb20c17e2a3cb4197609a514d2da
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 2 additions & 0 deletions account_banking_pain_base/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
"external_dependencies": {"python": ["unidecode", "lxml"]},
"data": [
"security/security.xml",
"security/ir.model.access.csv",
"views/account_payment_line.xml",
"views/account_payment_order.xml",
"views/account_payment_mode.xml",
"views/res_config_settings.xml",
"views/account_payment_method.xml",
"views/account_pain_regulatory_reporting.xml",
],
"post_init_hook": "set_default_initiating_party",
"installable": True,
Expand Down
1 change: 1 addition & 0 deletions account_banking_pain_base/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from . import account_payment_line
from . import account_payment_order
from . import account_payment_mode
from . import account_pain_regulatory_reporting
from . import res_company
from . import res_config_settings
from . import account_payment_method
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2023 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, fields, models


class AccountPainRegulatoryReporting(models.Model):
_name = "account.pain.regulatory.reporting"
_description = "Regulatory Reporting Codes for ISO 20022/PAIN banking standard"
_order = "code, country_id"

code = fields.Char(required=True, copy=False, size=10)
name = fields.Char(required=True, translate=True, copy=False)
country_id = fields.Many2one("res.country", ondelete="restrict", required=False)
active = fields.Boolean(default=True)

_sql_constraints = [
(
"code_country_unique",
"unique(code, country_id)",
"This code already exists for that country.",
)
]

@api.depends("code", "name")
def name_get(self):
res = []
for rec in self:
res.append((rec.id, "[%s] %s" % (rec.code, rec.name)))
return res

def _name_search(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this, you can just put _rec_names_search = ["code", "name"].

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Thanks for your remark!

self, name="", args=None, operator="ilike", limit=100, name_get_uid=None
):
if args is None:
args = []
ids = []
if name and operator == "ilike":
ids = list(self._search([("code", "=", name)] + args, limit=limit))
if ids:
return ids
return super()._name_search(
name=name,
args=args,
operator=operator,
limit=limit,
name_get_uid=name_get_uid,
)
48 changes: 41 additions & 7 deletions account_banking_pain_base/models/account_payment_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# Copyright 2014-2022 Tecnativa - Pedro M. Baeza
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from lxml import etree

from odoo import api, fields, models


Expand Down Expand Up @@ -163,18 +165,50 @@ class AccountPaymentLine(models.Model):
help="If neither your bank nor your local regulations oblige you to "
"set the category purpose, leave the field empty.",
)
# Regulatory Reporting codes are provided by national central banks for the countries
# where this data is required in specific circumstances
regulatory_reporting_id = fields.Many2one(
"account.pain.regulatory.reporting",
ondelete="restrict",
domain="[('country_id', 'in', (False, company_country_id))]",
)
company_country_id = fields.Many2one(related="company_id.country_id")
# PAIN allows 140 characters
communication = fields.Char(size=140)
# The field struct_communication_type has been dropped in v9
# We now use communication_type ; you should add an option
# in communication_type with selection_add=[]
communication_type = fields.Selection(
selection_add=[("ISO", "ISO")], ondelete={"ISO": "cascade"}
)

@api.model
def _get_payment_line_grouping_fields(self):
"""Add specific PAIN fields to the grouping criteria."""
res = super()._get_payment_line_grouping_fields()
res += ["priority", "local_instrument", "category_purpose", "purpose"]
res += [
"priority",
"local_instrument",
"category_purpose",
"purpose",
"regulatory_reporting_id",
]
return res

def generate_regulatory_reporting(self, parent_node, gen_args):
if self.regulatory_reporting_id:
regulatory_reporting = etree.SubElement(parent_node, "RgltryRptg")
regulatory_reporting_details = etree.SubElement(
regulatory_reporting, "Dtls"
)
regulatory_reporting_details_code = etree.SubElement(
regulatory_reporting_details, "Cd"
)
regulatory_reporting_details_code.text = self.env[
"account.payment.order"
]._prepare_field(
"Regulatory Details Code",
"line.regulatory_reporting_id.code",
{"line": self},
10,
gen_args=gen_args,
)

def generate_purpose(self, parent_node):
if self.purpose:
purpose = etree.SubElement(parent_node, "Purp")
etree.SubElement(purpose, "Cd").text = self.purpose
19 changes: 7 additions & 12 deletions account_banking_pain_base/models/account_payment_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,6 @@ def _validate_xml(self, xml_string, gen_args):
)
% str(e)
) from None
return True

def finalize_sepa_file_creation(self, xml_root, gen_args):
xml_string = etree.tostring(
Expand Down Expand Up @@ -461,7 +460,6 @@ def generate_initiating_party_block(self, parent_node, gen_args):
)
% self.company_id.name
)
return True

@api.model
def generate_party_agent(
Expand Down Expand Up @@ -495,7 +493,6 @@ def generate_party_agent(
# for Credit Transfers, in the 'C' block, if BIC is not provided,
# we should not put the 'Creditor Agent' block at all,
# as per the guidelines of the EPC
return True

@api.model
def generate_party_id(self, parent_node, party_type, partner):
Expand All @@ -519,7 +516,9 @@ def generate_party_acc_number(
party_account_other = etree.SubElement(party_account_id, "Othr")
party_account_other_id = etree.SubElement(party_account_other, "Id")
party_account_other_id.text = partner_bank.sanitized_acc_number
return True
if party_type == "Dbtr" and partner_bank.currency_id:
party_account_current = etree.SubElement(party_account, "Ccy")
party_account_current.text = partner_bank.currency_id.name

@api.model
def generate_address_block(self, parent_node, partner, gen_args):
Expand Down Expand Up @@ -567,7 +566,6 @@ def generate_address_block(self, parent_node, partner, gen_args):
gen_args=gen_args,
)
adrline2.text = val
return True

@api.model
def generate_party_block(
Expand Down Expand Up @@ -625,13 +623,12 @@ def generate_party_block(
gen_args,
bank_line=bank_line,
)
return True

@api.model
def generate_remittance_info_block(self, parent_node, line, gen_args):
remittance_info = etree.SubElement(parent_node, "RmtInf")
communication_type = line.payment_line_ids[:1].communication_type
if communication_type == "normal":
if communication_type == "free":
remittance_info_unstructured = etree.SubElement(remittance_info, "Ustrd")
remittance_info_unstructured.text = self._prepare_field(
"Remittance Unstructured Information",
Expand All @@ -640,7 +637,7 @@ def generate_remittance_info_block(self, parent_node, line, gen_args):
140,
gen_args=gen_args,
)
else:
elif communication_type == "structured":
remittance_info_structured = etree.SubElement(remittance_info, "Strd")
creditor_ref_information = etree.SubElement(
remittance_info_structured, "CdtrRefInf"
Expand All @@ -657,7 +654,7 @@ def generate_remittance_info_block(self, parent_node, line, gen_args):
creditor_ref_info_type_issuer = etree.SubElement(
creditor_ref_info_type, "Issr"
)
creditor_ref_info_type_issuer.text = communication_type
creditor_ref_info_type_issuer.text = "ISO"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexis-via please keep communication_type. We need it for belgium where (IIRC) it must become bba.
https://github.com/OCA/l10n-belgium/tree/10.0/l10n_be_iso20022_pain

cc/ @luc-demeyer

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbidoul
I fully agree.
Small remark on l10n_be_iso20022_pain: should be 'BBA' (uppercase), cf. my comment on 16.0 PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out. Let's talk about this during the next code sprint, because the datamodel for structured communication type is really messy and unclean. I'm confident that we'll agree on a nice and clear datamodel on this, that will make the l10n_be_iso20022_pain simpler and make the XML generation code simpler.

creditor_reference = etree.SubElement(
creditor_ref_information, "CdtrRef"
)
Expand All @@ -676,7 +673,7 @@ def generate_remittance_info_block(self, parent_node, line, gen_args):
creditor_ref_info_type_issuer = etree.SubElement(
creditor_ref_info_type, "Issr"
)
creditor_ref_info_type_issuer.text = communication_type
creditor_ref_info_type_issuer.text = "ISO"

creditor_reference = etree.SubElement(creditor_ref_information, "Ref")

Expand All @@ -687,7 +684,6 @@ def generate_remittance_info_block(self, parent_node, line, gen_args):
35,
gen_args=gen_args,
)
return True

@api.model
def generate_creditor_scheme_identification(
Expand All @@ -709,4 +705,3 @@ def generate_creditor_scheme_identification(
csi_scheme_name = etree.SubElement(csi_other, "SchmeNm")
csi_scheme_name_proprietary = etree.SubElement(csi_scheme_name, "Prtry")
csi_scheme_name_proprietary.text = scheme_name_proprietary
return True
3 changes: 3 additions & 0 deletions account_banking_pain_base/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_pain_regulatory_reporting_read,Read access on account.pain.regulatory.reporting,model_account_pain_regulatory_reporting,base.group_user,1,0,0,0
access_account_pain_regulatory_reporting_full,Full access on account.pain.regulatory.reporting,model_account_pain_regulatory_reporting,account.group_account_manager,1,1,1,1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be the full right access the "Payment" group?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

2 changes: 1 addition & 1 deletion account_banking_pain_base/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ <h1 class="title">Account Banking PAIN Base Module</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:cb0a3e1e489965d9fd1e4540fb54b404f630887d8a913484c222034edbe91786
!! source digest: sha256:b830f262c5a7db70d35218b9b420e0d1614bbb20c17e2a3cb4197609a514d2da
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/bank-payment/tree/16.0/account_banking_pain_base"><img alt="OCA/bank-payment" src="https://img.shields.io/badge/github-OCA%2Fbank--payment-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/bank-payment-16-0/bank-payment-16-0-account_banking_pain_base"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/bank-payment&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module contains fields and functions that are used by the module for SEPA
Expand Down
Loading