From f30e7c9b9899ed60a6ad0fa49e126e016bcaec24 Mon Sep 17 00:00:00 2001 From: Simone Rubino Date: Mon, 20 Jan 2025 18:57:58 +0100 Subject: [PATCH] [IMP] account_reconcile_oca: Reconcile multiple lines --- account_reconcile_oca/README.rst | 11 ++- account_reconcile_oca/__init__.py | 1 + account_reconcile_oca/__manifest__.py | 1 + account_reconcile_oca/readme/CONTRIBUTORS.md | 1 + account_reconcile_oca/readme/USAGE.md | 7 ++ .../security/ir.model.access.csv | 1 + .../static/description/index.html | 37 +++++--- account_reconcile_oca/tests/__init__.py | 1 + .../tests/test_reconcile_multiple_lines.py | 88 +++++++++++++++++++ account_reconcile_oca/wizards/__init__.py | 3 + .../reconcile_multiple_lines views.xml | 38 ++++++++ .../wizards/reconcile_multiple_lines.py | 46 ++++++++++ 12 files changed, 221 insertions(+), 14 deletions(-) create mode 100644 account_reconcile_oca/tests/test_reconcile_multiple_lines.py create mode 100644 account_reconcile_oca/wizards/__init__.py create mode 100644 account_reconcile_oca/wizards/reconcile_multiple_lines views.xml create mode 100644 account_reconcile_oca/wizards/reconcile_multiple_lines.py diff --git a/account_reconcile_oca/README.rst b/account_reconcile_oca/README.rst index ceaf846b75..a3739ff3e9 100644 --- a/account_reconcile_oca/README.rst +++ b/account_reconcile_oca/README.rst @@ -7,7 +7,7 @@ Account Reconcile Oca !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:fa8f7f5af2e7a631cb39b699ebbc41f1bc6cca067be28665f5d4590c752f3054 + !! source digest: sha256:b15b5402e37deee0e1b65e9884ddead837cf2813d7b85799d6f14994d06c00df !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -52,6 +52,14 @@ Access Invoicing / Accounting / Actions / Reconcile All the possible reconcile options will show and you will be able to reconcile properly. 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 ====================== @@ -82,6 +90,7 @@ Contributors ------------ - Enric Tobella +- Simone Rubino Maintainers ----------- diff --git a/account_reconcile_oca/__init__.py b/account_reconcile_oca/__init__.py index cc6b6354ad..a0f653930e 100644 --- a/account_reconcile_oca/__init__.py +++ b/account_reconcile_oca/__init__.py @@ -1,2 +1,3 @@ from . import models +from . import wizards from .hooks import post_init_hook diff --git a/account_reconcile_oca/__manifest__.py b/account_reconcile_oca/__manifest__.py index b34888a213..360aedea2f 100644 --- a/account_reconcile_oca/__manifest__.py +++ b/account_reconcile_oca/__manifest__.py @@ -25,6 +25,7 @@ "views/account_move.xml", "views/account_account.xml", "views/account_bank_statement.xml", + "wizards/reconcile_multiple_lines views.xml", ], "demo": ["demo/demo.xml"], "post_init_hook": "post_init_hook", diff --git a/account_reconcile_oca/readme/CONTRIBUTORS.md b/account_reconcile_oca/readme/CONTRIBUTORS.md index c84bf49d7c..2a3cbdd789 100644 --- a/account_reconcile_oca/readme/CONTRIBUTORS.md +++ b/account_reconcile_oca/readme/CONTRIBUTORS.md @@ -1 +1,2 @@ - Enric Tobella +- Simone Rubino diff --git a/account_reconcile_oca/readme/USAGE.md b/account_reconcile_oca/readme/USAGE.md index 2a053a39f6..6c9ae7c496 100644 --- a/account_reconcile_oca/readme/USAGE.md +++ b/account_reconcile_oca/readme/USAGE.md @@ -8,3 +8,10 @@ capabilities. Select reconcile on the journal of your choice. Access Invoicing / Accounting / Actions / Reconcile All the possible reconcile options will show and you will be able to reconcile properly. 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 diff --git a/account_reconcile_oca/security/ir.model.access.csv b/account_reconcile_oca/security/ir.model.access.csv index d73fa145dd..66529426c4 100644 --- a/account_reconcile_oca/security/ir.model.access.csv +++ b/account_reconcile_oca/security/ir.model.access.csv @@ -1,3 +1,4 @@ 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_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 diff --git a/account_reconcile_oca/static/description/index.html b/account_reconcile_oca/static/description/index.html index 280f37dba3..56c1ff31ba 100644 --- a/account_reconcile_oca/static/description/index.html +++ b/account_reconcile_oca/static/description/index.html @@ -367,7 +367,7 @@

Account Reconcile Oca

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:fa8f7f5af2e7a631cb39b699ebbc41f1bc6cca067be28665f5d4590c752f3054 +!! source digest: sha256:b15b5402e37deee0e1b65e9884ddead837cf2813d7b85799d6f14994d06c00df !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/account-reconcile Translate me on Weblate Try me on Runboat

This addon allows to reconcile bank statements and account marked as @@ -378,14 +378,15 @@

Account Reconcile Oca

  • Usage
  • -
  • Known issues / Roadmap
  • -
  • Bug Tracker
  • -
  • Credits @@ -403,16 +404,25 @@

    Account reconcile

    reconcile options will show and you will be able to reconcile properly. 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. +
    3. Actions -> Reconcile with model
    4. +
    5. In the wizard, select the model
    6. +
    7. Run
    8. +
    +
    -

    Known issues / Roadmap

    +

    Known issues / Roadmap

    The following bugs are already detected:

    • Creation of activities on the chatter do show automatically
    -

    Bug Tracker

    +

    Bug Tracker

    Bugs are tracked on GitHub Issues. 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 @@ -420,22 +430,23 @@

    Bug Tracker

    Do not contact contributors directly about support or help with technical issues.

    -

    Credits

    +

    Credits

    -

    Authors

    +

    Authors

    • CreuBlanca
    • Dixmit
    -

    Contributors

    +

    Contributors

    • Enric Tobella
    • +
    • Simone Rubino
    -

    Maintainers

    +

    Maintainers

    This module is maintained by the OCA.

    Odoo Community Association diff --git a/account_reconcile_oca/tests/__init__.py b/account_reconcile_oca/tests/__init__.py index 17f193edb5..d3a4dc27ac 100644 --- a/account_reconcile_oca/tests/__init__.py +++ b/account_reconcile_oca/tests/__init__.py @@ -1,2 +1,3 @@ from . import test_bank_account_reconcile from . import test_account_reconcile +from . import test_reconcile_multiple_lines diff --git a/account_reconcile_oca/tests/test_reconcile_multiple_lines.py b/account_reconcile_oca/tests/test_reconcile_multiple_lines.py new file mode 100644 index 0000000000..5b2aced62e --- /dev/null +++ b/account_reconcile_oca/tests/test_reconcile_multiple_lines.py @@ -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) diff --git a/account_reconcile_oca/wizards/__init__.py b/account_reconcile_oca/wizards/__init__.py new file mode 100644 index 0000000000..bc02c4a825 --- /dev/null +++ b/account_reconcile_oca/wizards/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import reconcile_multiple_lines diff --git a/account_reconcile_oca/wizards/reconcile_multiple_lines views.xml b/account_reconcile_oca/wizards/reconcile_multiple_lines views.xml new file mode 100644 index 0000000000..edaefe50f6 --- /dev/null +++ b/account_reconcile_oca/wizards/reconcile_multiple_lines views.xml @@ -0,0 +1,38 @@ + + + + + + Form view to reconcile multiple lines with a reconciliation model + account_reconcile_oca.reconcile_multiple_lines + +
    + + + + + +
    +
    +
    +
    +
    + + + Reconcile with model + account_reconcile_oca.reconcile_multiple_lines + form + new + + +
    diff --git a/account_reconcile_oca/wizards/reconcile_multiple_lines.py b/account_reconcile_oca/wizards/reconcile_multiple_lines.py new file mode 100644 index 0000000000..a37b6fc364 --- /dev/null +++ b/account_reconcile_oca/wizards/reconcile_multiple_lines.py @@ -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)