mirror of
https://github.com/OCA/account-reconcile.git
synced 2025-01-20 12:27:39 +02:00
[ADD] account_reconcile_model_strict_match_amount
This commit is contained in:
1
account_reconcile_model_strict_match_amount/__init__.py
Normal file
1
account_reconcile_model_strict_match_amount/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
19
account_reconcile_model_strict_match_amount/__manifest__.py
Normal file
19
account_reconcile_model_strict_match_amount/__manifest__.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Copyright 2020 Camptocamp SA
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
{
|
||||
"name": "Account Reconciliation Model Strict Match Amount",
|
||||
"summary": "Restrict reconciliation propositions to matching amount parameter",
|
||||
"version": "12.0.1.0.0",
|
||||
"category": "Accounting",
|
||||
"website": "https://github.com/OCA/account-reconcile",
|
||||
"author": "Camptocamp, Odoo Community Association (OCA)",
|
||||
"license": "AGPL-3",
|
||||
"application": False,
|
||||
"installable": True,
|
||||
"depends": [
|
||||
"account",
|
||||
],
|
||||
"data": [
|
||||
"views/account_reconcile_model.xml",
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
from . import account_reconcile_model
|
||||
@@ -0,0 +1,42 @@
|
||||
# Copyright 2020 Camptocamp SA
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class AccountReconcileModel(models.Model):
|
||||
|
||||
_inherit = 'account.reconcile.model'
|
||||
|
||||
strict_match_total_amount = fields.Boolean(
|
||||
string="Strict Amount Matching",
|
||||
help="Avoid bypassing the Amount Matching parameter in case of a "
|
||||
"statement line communication matching exactly existing entries."
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def _get_select_communication_flag(self):
|
||||
if not self.match_total_amount or not self.strict_match_total_amount:
|
||||
return super()._get_select_communication_flag()
|
||||
else:
|
||||
regexp = r"'[^0-9|^\s]', '', 'g'), '\S(?:.*\S)*'), '\s+'"
|
||||
return r'''
|
||||
-- Determine a matching or not with the statement line communication using the move.name or move.ref.
|
||||
-- only digits are considered and reference are split by any space characters
|
||||
COALESCE(
|
||||
regexp_split_to_array(substring(REGEXP_REPLACE(move.name, {regexp})
|
||||
&& regexp_split_to_array(substring(REGEXP_REPLACE(st_line.name, {regexp})
|
||||
OR
|
||||
(
|
||||
move.ref IS NOT NULL
|
||||
AND
|
||||
regexp_split_to_array(substring(REGEXP_REPLACE(move.ref, {regexp})
|
||||
&&
|
||||
regexp_split_to_array(substring(REGEXP_REPLACE(st_line.name, {regexp})
|
||||
), FALSE)
|
||||
AND
|
||||
CASE
|
||||
WHEN abs(st_line.amount) < abs(aml.balance) THEN abs(st_line.amount) / abs(aml.balance) * 100
|
||||
WHEN abs(st_line.amount) > abs(aml.balance) THEN abs(aml.balance) / abs(st_line.amount) * 100
|
||||
ELSE 100
|
||||
END >= {match_total_amount_param} AS communication_flag
|
||||
'''.format(regexp=regexp, match_total_amount_param=self.match_total_amount_param)
|
||||
@@ -0,0 +1 @@
|
||||
* Akim Juillerat <akim.juillerat@camptocamp.com>
|
||||
@@ -0,0 +1,4 @@
|
||||
This module allows to cancel the bypassing of Amount Matching feature on
|
||||
Reconciliation models "in case of a statement line communication matching
|
||||
exactly existing entries", to ensure only statement lines matching the total
|
||||
amount (or according to its percentage) will be reconciled automatically.
|
||||
@@ -0,0 +1 @@
|
||||
from . import test_account_reconcile_model_strict_match_amount
|
||||
@@ -0,0 +1,80 @@
|
||||
# Copyright 2020 Camptocamp SA
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||||
from odoo.addons.account.tests.test_reconciliation_matching_rules import TestReconciliationMatchingRules
|
||||
|
||||
|
||||
class TestAccountReconcileModelStrictMatchAmount(TestReconciliationMatchingRules):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.partner_3 = self.env['res.partner'].create({'name': 'partner_3'})
|
||||
self.partner_4 = self.env['res.partner'].create({'name': 'partner_4'})
|
||||
self.invoice_line_5 = self._create_invoice_line(
|
||||
150, self.partner_3, 'out_invoice'
|
||||
)
|
||||
self.invoice_line_5.ref = 'ABC001XYZ'
|
||||
self.invoice_line_6 = self._create_invoice_line(
|
||||
300, self.partner_4, 'out_invoice'
|
||||
)
|
||||
self.invoice_line_6.name = 'ABC002XYZ'
|
||||
|
||||
self.bank_st_2 = self.env['account.bank.statement'].create({
|
||||
'name': 'test bank journal 2', 'journal_id': self.bank_journal.id,
|
||||
})
|
||||
|
||||
self.bank_line_3 = self.env['account.bank.statement.line'].create({
|
||||
'statement_id': self.bank_st_2.id,
|
||||
'name': 'ABC001XYZ',
|
||||
'partner_id': self.partner_3.id,
|
||||
'amount': 70,
|
||||
'sequence': 1,
|
||||
})
|
||||
self.bank_line_4 = self.env['account.bank.statement.line'].create({
|
||||
'statement_id': self.bank_st_2.id,
|
||||
'name': 'ABC002XYZ',
|
||||
'partner_id': self.partner_4.id,
|
||||
'amount': 270,
|
||||
'sequence': 1,
|
||||
})
|
||||
|
||||
def test_auto_reconcile_strict_match_100(self):
|
||||
my_rule = self.env['account.reconcile.model'].create({
|
||||
'name': 'Strict Invoice matching amount 100%',
|
||||
'rule_type': 'invoice_matching',
|
||||
'auto_reconcile': True,
|
||||
'match_nature': 'both',
|
||||
'match_partner': True,
|
||||
'match_same_currency': True,
|
||||
'match_total_amount': True,
|
||||
'match_total_amount_param': 100.0,
|
||||
'strict_match_total_amount': True,
|
||||
# 'match_partner_ids': [
|
||||
# (6, 0, [self.partner_3.id, self.partner_4.id])
|
||||
# ],
|
||||
})
|
||||
|
||||
self._check_statement_matching(my_rule, {
|
||||
self.bank_line_3.id: {'aml_ids': []},
|
||||
self.bank_line_4.id: {'aml_ids': []},
|
||||
}, statements=self.bank_st_2)
|
||||
|
||||
def test_auto_reconcile_strict_match_80(self):
|
||||
my_rule = self.env['account.reconcile.model'].create({
|
||||
'name': 'Strict Invoice matching amount 80%',
|
||||
'rule_type': 'invoice_matching',
|
||||
'auto_reconcile': True,
|
||||
'match_nature': 'both',
|
||||
'match_partner': True,
|
||||
'match_same_currency': True,
|
||||
'match_total_amount': True,
|
||||
'match_total_amount_param': 80.0,
|
||||
'strict_match_total_amount': True,
|
||||
# 'match_partner_ids': [
|
||||
# (6, 0, [self.partner_3.id, self.partner_4.id])
|
||||
# ],
|
||||
})
|
||||
|
||||
self._check_statement_matching(my_rule, {
|
||||
self.bank_line_3.id: {'aml_ids': []},
|
||||
self.bank_line_4.id: {'aml_ids': [self.invoice_line_6.id], 'model': my_rule, 'status': 'reconciled'},
|
||||
}, statements=self.bank_st_2)
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<record id="view_account_reconcile_model_form" model="ir.ui.view">
|
||||
<field name="name">account.reconcile.model.form</field>
|
||||
<field name="model">account.reconcile.model</field>
|
||||
<field name="inherit_id" ref="account.view_account_reconcile_model_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[field[@name='match_total_amount']]" position="after">
|
||||
<field name="strict_match_total_amount" attrs="{'invisible': ['|', ('rule_type', '!=', 'invoice_matching'), ('match_total_amount', '=', False)]}"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[field[@name='match_total_amount']]/div[@class='text-muted']" position="attributes">
|
||||
<attribute name="attrs">{'invisible': ['|', '|', ('rule_type', '!=', 'invoice_matching'), ('match_total_amount', '=', False), ('strict_match_total_amount', '=', True)]}</attribute>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user