[IMP] account_reconcile_oca: Reconcile multiple lines

pull/786/head
Simone Rubino 2025-01-20 18:57:58 +01:00
parent 99b8269256
commit f24694eb71
No known key found for this signature in database
GPG Key ID: 989F89B988B07126
12 changed files with 221 additions and 14 deletions

View File

@ -52,12 +52,20 @@ Access Invoicing / Accounting / Actions / Reconcile All the possible
reconcile options will show and you will be able to reconcile properly. reconcile options will show and you will be able to reconcile properly.
You can access the same widget from accounts and Partners. You can access the same widget from accounts and Partners.
Applying a reconcilation model to multiple lines
------------------------------------------------
1. Select multiple transactions (account.bank.statement.line)
2. Actions -> Reconcile with model
3. In the wizard, select the model
4. Run
Known issues / Roadmap Known issues / Roadmap
====================== ======================
The following bugs are already detected: The following bugs are already detected:
- Creation of activities on the chatter do show automatically - Creation of activities on the chatter do show automatically
Bug Tracker Bug Tracker
=========== ===========
@ -81,7 +89,8 @@ Authors
Contributors Contributors
------------ ------------
- Enric Tobella - Enric Tobella
- Simone Rubino
Maintainers Maintainers
----------- -----------

View File

@ -1,2 +1,3 @@
from . import models from . import models
from . import wizards
from .hooks import post_init_hook from .hooks import post_init_hook

View File

@ -25,6 +25,7 @@
"views/account_move.xml", "views/account_move.xml",
"views/account_account.xml", "views/account_account.xml",
"views/account_bank_statement.xml", "views/account_bank_statement.xml",
"wizards/reconcile_multiple_lines views.xml",
], ],
"demo": ["demo/demo.xml"], "demo": ["demo/demo.xml"],
"post_init_hook": "post_init_hook", "post_init_hook": "post_init_hook",

View File

@ -1 +1,2 @@
- Enric Tobella - Enric Tobella
- Simone Rubino

View File

@ -8,3 +8,10 @@ capabilities. Select reconcile on the journal of your choice.
Access Invoicing / Accounting / Actions / Reconcile All the possible Access Invoicing / Accounting / Actions / Reconcile All the possible
reconcile options will show and you will be able to reconcile properly. reconcile options will show and you will be able to reconcile properly.
You can access the same widget from accounts and Partners. You can access the same widget from accounts and Partners.
## Applying a reconcilation model to multiple lines
1. Select multiple transactions (account.bank.statement.line)
2. Actions -> Reconcile with model
3. In the wizard, select the model
4. Run

View File

@ -1,3 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_account_reconcile,account.account.reconcile,model_account_account_reconcile,account.group_account_user,1,1,0,0 access_account_account_reconcile,account.account.reconcile,model_account_account_reconcile,account.group_account_user,1,1,0,0
access_account_account_reconcile_data,account.account.reconcile,model_account_account_reconcile_data,account.group_account_user,1,1,1,1 access_account_account_reconcile_data,account.account.reconcile,model_account_account_reconcile_data,account.group_account_user,1,1,1,1
account_reconcile_oca.access_account_reconcile_oca_reconcile_multiple_lines,Allow account user to reconcile multiple lines with a reconciliation model,account_reconcile_oca.model_account_reconcile_oca_reconcile_multiple_lines,account.group_account_user,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_account_account_reconcile account.account.reconcile model_account_account_reconcile account.group_account_user 1 1 0 0
3 access_account_account_reconcile_data account.account.reconcile model_account_account_reconcile_data account.group_account_user 1 1 1 1
4 account_reconcile_oca.access_account_reconcile_oca_reconcile_multiple_lines Allow account user to reconcile multiple lines with a reconciliation model account_reconcile_oca.model_account_reconcile_oca_reconcile_multiple_lines account.group_account_user 1 1 1 1

View File

@ -378,14 +378,15 @@ reconcile.</p>
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a><ul> <li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a><ul>
<li><a class="reference internal" href="#bank-reconcile" id="toc-entry-2">Bank reconcile</a></li> <li><a class="reference internal" href="#bank-reconcile" id="toc-entry-2">Bank reconcile</a></li>
<li><a class="reference internal" href="#account-reconcile" id="toc-entry-3">Account reconcile</a></li> <li><a class="reference internal" href="#account-reconcile" id="toc-entry-3">Account reconcile</a></li>
<li><a class="reference internal" href="#applying-a-reconcilation-model-to-multiple-lines" id="toc-entry-4">Applying a reconcilation model to multiple lines</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-4">Known issues / Roadmap</a></li> <li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-5">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-5">Bug Tracker</a></li> <li><a class="reference internal" href="#bug-tracker" id="toc-entry-6">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-6">Credits</a><ul> <li><a class="reference internal" href="#credits" id="toc-entry-7">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-7">Authors</a></li> <li><a class="reference internal" href="#authors" id="toc-entry-8">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-8">Contributors</a></li> <li><a class="reference internal" href="#contributors" id="toc-entry-9">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-9">Maintainers</a></li> <li><a class="reference internal" href="#maintainers" id="toc-entry-10">Maintainers</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
@ -403,16 +404,25 @@ capabilities. Select reconcile on the journal of your choice.</p>
reconcile options will show and you will be able to reconcile properly. reconcile options will show and you will be able to reconcile properly.
You can access the same widget from accounts and Partners.</p> You can access the same widget from accounts and Partners.</p>
</div> </div>
<div class="section" id="applying-a-reconcilation-model-to-multiple-lines">
<h2><a class="toc-backref" href="#toc-entry-4">Applying a reconcilation model to multiple lines</a></h2>
<ol class="arabic simple">
<li>Select multiple transactions (account.bank.statement.line)</li>
<li>Actions -&gt; Reconcile with model</li>
<li>In the wizard, select the model</li>
<li>Run</li>
</ol>
</div>
</div> </div>
<div class="section" id="known-issues-roadmap"> <div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-4">Known issues / Roadmap</a></h1> <h1><a class="toc-backref" href="#toc-entry-5">Known issues / Roadmap</a></h1>
<p>The following bugs are already detected:</p> <p>The following bugs are already detected:</p>
<ul class="simple"> <ul class="simple">
<li>Creation of activities on the chatter do show automatically</li> <li>Creation of activities on the chatter do show automatically</li>
</ul> </ul>
</div> </div>
<div class="section" id="bug-tracker"> <div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-5">Bug Tracker</a></h1> <h1><a class="toc-backref" href="#toc-entry-6">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-reconcile/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/account-reconcile/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed If you spotted it first, help us to smash it by providing a detailed and welcomed
@ -420,22 +430,23 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-6">Credits</a></h1> <h1><a class="toc-backref" href="#toc-entry-7">Credits</a></h1>
<div class="section" id="authors"> <div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-7">Authors</a></h2> <h2><a class="toc-backref" href="#toc-entry-8">Authors</a></h2>
<ul class="simple"> <ul class="simple">
<li>CreuBlanca</li> <li>CreuBlanca</li>
<li>Dixmit</li> <li>Dixmit</li>
</ul> </ul>
</div> </div>
<div class="section" id="contributors"> <div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-8">Contributors</a></h2> <h2><a class="toc-backref" href="#toc-entry-9">Contributors</a></h2>
<ul class="simple"> <ul class="simple">
<li>Enric Tobella</li> <li>Enric Tobella</li>
<li>Simone Rubino</li>
</ul> </ul>
</div> </div>
<div class="section" id="maintainers"> <div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-9">Maintainers</a></h2> <h2><a class="toc-backref" href="#toc-entry-10">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p> <p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"> <a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /> <img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />

View File

@ -1,2 +1,3 @@
from . import test_bank_account_reconcile from . import test_bank_account_reconcile
from . import test_account_reconcile from . import test_account_reconcile
from . import test_reconcile_multiple_lines

View File

@ -0,0 +1,88 @@
# Copyright 2025 Simone Rubino
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import Command
from odoo.tests import Form, tagged
from odoo.addons.account_reconcile_model_oca.tests.common import (
TestAccountReconciliationCommon,
)
@tagged("post_install", "-at_install")
class TestReconcileMultipleLines(TestAccountReconciliationCommon):
@classmethod
def setUpClass(cls, chart_template_ref=None):
super().setUpClass(chart_template_ref=chart_template_ref)
(cls.reconcile_account,) = cls.env["account.account"].create(
[
{
"name": "Test account for reconciliation",
"code": "TSTREC",
"account_type": "liability_payable",
}
]
)
cls.bank_journal = cls.company_data["default_journal_bank"]
(
cls.bank_line_1,
cls.bank_line_2,
) = cls.env["account.bank.statement.line"].create(
[
{
"journal_id": cls.bank_journal.id,
"date": "2020-01-01",
"amount": 100,
},
{
"journal_id": cls.bank_journal.id,
"date": "2020-01-01",
"amount": 600,
},
],
)
(cls.reconcile_model,) = cls.env["account.reconcile.model"].create(
[
{
"name": "Test Writeoff",
"rule_type": "writeoff_button",
"line_ids": [
Command.create(
{
"account_id": cls.reconcile_account.id,
}
),
],
},
]
)
def _get_wizard(self, statement_lines, reconcile_model):
selection_context = {
"active_model": statement_lines._name,
"active_ids": statement_lines.ids,
}
wizard_model = self.env[
"account_reconcile_oca.reconcile_multiple_lines"
].with_context(**selection_context)
wizard_form = Form(wizard_model)
wizard_form.manual_model_id = reconcile_model
return wizard_form.save()
def test_writeoff_2_lines(self):
"""The wizard can writeoff 2 statement lines."""
# Arrange
reconcile_account = self.reconcile_account
statement_lines = self.bank_line_1 | self.bank_line_2
writeoff_reconcile_model = self.reconcile_model
wizard = self._get_wizard(statement_lines, writeoff_reconcile_model)
# pre-condition
self.assertEqual(writeoff_reconcile_model.rule_type, "writeoff_button")
self.assertNotIn(reconcile_account, statement_lines.line_ids.account_id)
# Act
wizard.run()
# Assert
self.assertIn(reconcile_account, statement_lines.line_ids.account_id)

View File

@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from . import reconcile_multiple_lines

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
~ Copyright 2025 Simone Rubino
~ License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="reconcile_multiple_lines_view_form" model="ir.ui.view">
<field
name="name"
>Form view to reconcile multiple lines with a reconciliation model</field>
<field name="model">account_reconcile_oca.reconcile_multiple_lines</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<field name="manual_model_id" />
</group>
</sheet>
<footer>
<button string="Run" class="btn-primary" type="object" name="run" />
<button string="Cancel" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="reconcile_multiple_lines_action" model="ir.actions.act_window">
<field name="name">Reconcile with model</field>
<field name="res_model">account_reconcile_oca.reconcile_multiple_lines</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field
name="binding_model_id"
ref="account.model_account_bank_statement_line"
/>
</record>
</odoo>

View File

@ -0,0 +1,46 @@
# Copyright 2025 Simone Rubino
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import _, fields, models
from odoo.exceptions import UserError
class ReconcileMultipleLines(models.TransientModel):
_name = "account_reconcile_oca.reconcile_multiple_lines"
_description = "Reconcile multiple lines with a reconciliation model"
manual_model_id = fields.Many2one(
comodel_name="account.reconcile.model",
required=True,
)
def _get_statement_lines(self):
model = self.env.context.get("active_model")
ids = self.env.context.get("active_ids")
statement_lines = self.env[model].browse(ids)
return statement_lines
def _apply_model_to_line(self, reconciliation_model, statement_line):
reconciliation_model.ensure_one()
statement_line.ensure_one()
partner = reconciliation_model._get_partner_from_mapping(statement_line)
if not reconciliation_model._is_applicable_for(statement_line, partner):
raise UserError(
_(
"Reconcilation model %(model)s "
"cannot be applied to line %(line)s.\n"
"Please select a compatible reconciliation model "
"or deselect the line.",
model=reconciliation_model.display_name,
line=statement_line.display_name,
)
)
statement_line.manual_model_id = reconciliation_model
statement_line._onchange_manual_model_id()
statement_line.reconcile_bank_line()
def run(self):
statement_lines = self._get_statement_lines()
reconciliation_model = self.manual_model_id
for line in statement_lines:
self._apply_model_to_line(reconciliation_model, line)