diff --git a/account_cash_basis_group_base_line/README.rst b/account_cash_basis_group_base_line/README.rst new file mode 100644 index 000000000..514a7aa27 --- /dev/null +++ b/account_cash_basis_group_base_line/README.rst @@ -0,0 +1,82 @@ +=============================== +Tax Cash Basis Group Base Lines +=============================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--tools-lightgray.png?logo=github + :target: https://github.com/OCA/account-financial-tools/tree/13.0/account_cash_basis_group_base_line + :alt: OCA/account-financial-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-financial-tools-13.0/account-financial-tools-13.0-account_cash_basis_group_base_line + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/92/13.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module compact the creation of Journal Lines for Cash Basis base lines. + +Instead of creating two base lines per line with cash basis tax, let us group +the creation lines so that there are fewer lines in the Cash Basis Journal Entry. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Just Install the module. No extra configuration is needed. + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Vauxoo + +Contributors +~~~~~~~~~~~~ + +* Humberto Arocha +* Gabriela Mogollón + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/account-financial-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_cash_basis_group_base_line/__init__.py b/account_cash_basis_group_base_line/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/account_cash_basis_group_base_line/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/account_cash_basis_group_base_line/__manifest__.py b/account_cash_basis_group_base_line/__manifest__.py new file mode 100644 index 000000000..00e949c03 --- /dev/null +++ b/account_cash_basis_group_base_line/__manifest__.py @@ -0,0 +1,13 @@ +{ + "name": "Tax Cash Basis Group Base Lines", + "version": "13.0.0.0.1", + "summary": "Compacting the creation of Journal Lines for CABA base lines.", + "sequence": 5, + "category": "Accounting", + "depends": ["account"], + "author": "Vauxoo, Odoo Community Association (OCA)", + "license": "AGPL-3", + "data": [], + "installable": True, + "auto_install": False, +} diff --git a/account_cash_basis_group_base_line/i18n/account_cash_basis_group_base_line.pot b/account_cash_basis_group_base_line/i18n/account_cash_basis_group_base_line.pot new file mode 100644 index 000000000..36504f40f --- /dev/null +++ b/account_cash_basis_group_base_line/i18n/account_cash_basis_group_base_line.pot @@ -0,0 +1,20 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_cash_basis_group_base_line +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \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_cash_basis_group_base_line +#: model:ir.model,name:account_cash_basis_group_base_line.model_account_partial_reconcile +msgid "Partial Reconcile" +msgstr "" + diff --git a/account_cash_basis_group_base_line/models/__init__.py b/account_cash_basis_group_base_line/models/__init__.py new file mode 100644 index 000000000..9c0a42138 --- /dev/null +++ b/account_cash_basis_group_base_line/models/__init__.py @@ -0,0 +1 @@ +from . import account_move diff --git a/account_cash_basis_group_base_line/models/account_move.py b/account_cash_basis_group_base_line/models/account_move.py new file mode 100644 index 000000000..f28cb6f2a --- /dev/null +++ b/account_cash_basis_group_base_line/models/account_move.py @@ -0,0 +1,54 @@ +from odoo import models + + +class AccountPartialReconcile(models.Model): + _inherit = "account.partial.reconcile" + + def _get_tax_cash_basis_base_key(self, tax, move, line): + account_id = self._get_tax_cash_basis_base_account(line, tax) + tax_rep_lines = ( + tax.refund_repartition_line_ids + if line.move_id.type in ("in_refund", "out_refund") + else tax.invoice_repartition_line_ids + ) + original_base_tags = tax_rep_lines.filtered( + lambda x: x.repartition_type == "base" + ).tag_ids + base_tags = tuple(line._convert_tags_for_cash_basis(original_base_tags).ids) + return ( + move.id, + account_id.id, + tax.id, + line.tax_repartition_line_id.id, + base_tags, + line.currency_id.id, + line.partner_id.id, + line.move_id.type, + ) + + def _get_tax_cash_basis_base_common_vals(self, key, new_move): + self.ensure_one() + # pylint: disable=W0612 + ( + move, + account_id, + tax_id, + tax_repartition_line_id, + base_tags, + currency_id, + partner_id, + move_type, + ) = key + move = self.env["account.move"].browse(move) + return { + "name": move.name, + "account_id": account_id, + "journal_id": new_move.journal_id.id, + "tax_exigible": True, + "tax_ids": [(6, 0, [tax_id])], + "tag_ids": [(6, 0, base_tags)], + "move_id": new_move.id, + "currency_id": currency_id, + "partner_id": partner_id, + "tax_repartition_line_id": tax_repartition_line_id, + } diff --git a/account_cash_basis_group_base_line/readme/CONTRIBUTORS.rst b/account_cash_basis_group_base_line/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..7a7b700eb --- /dev/null +++ b/account_cash_basis_group_base_line/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Humberto Arocha +* Gabriela Mogollón diff --git a/account_cash_basis_group_base_line/readme/DESCRIPTION.rst b/account_cash_basis_group_base_line/readme/DESCRIPTION.rst new file mode 100644 index 000000000..59a7ec5ce --- /dev/null +++ b/account_cash_basis_group_base_line/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +This module compact the creation of Journal Lines for Cash Basis base lines. + +Instead of creating two base lines per line with cash basis tax, let us group +the creation lines so that there are fewer lines in the Cash Basis Journal Entry. diff --git a/account_cash_basis_group_base_line/readme/USAGE.rst b/account_cash_basis_group_base_line/readme/USAGE.rst new file mode 100644 index 000000000..fdd456511 --- /dev/null +++ b/account_cash_basis_group_base_line/readme/USAGE.rst @@ -0,0 +1 @@ +Just Install the module. No extra configuration is needed. diff --git a/account_cash_basis_group_base_line/static/description/icon.png b/account_cash_basis_group_base_line/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/account_cash_basis_group_base_line/static/description/icon.png differ diff --git a/account_cash_basis_group_base_line/static/description/index.html b/account_cash_basis_group_base_line/static/description/index.html new file mode 100644 index 000000000..e08551219 --- /dev/null +++ b/account_cash_basis_group_base_line/static/description/index.html @@ -0,0 +1,427 @@ + + + + + + +Tax Cash Basis Group Base Lines + + + +
+

Tax Cash Basis Group Base Lines

+ + +

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runbot

+

This module compact the creation of Journal Lines for Cash Basis base lines.

+

Instead of creating two base lines per line with cash basis tax, let us group +the creation lines so that there are fewer lines in the Cash Basis Journal Entry.

+

Table of contents

+ +
+

Usage

+

Just Install the module. No extra configuration is needed.

+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Vauxoo
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/account-financial-tools project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/account_cash_basis_group_base_line/tests/__init__.py b/account_cash_basis_group_base_line/tests/__init__.py new file mode 100644 index 000000000..5eaab0190 --- /dev/null +++ b/account_cash_basis_group_base_line/tests/__init__.py @@ -0,0 +1 @@ +from . import test_reconciliation diff --git a/account_cash_basis_group_base_line/tests/test_reconciliation.py b/account_cash_basis_group_base_line/tests/test_reconciliation.py new file mode 100644 index 000000000..78879ecb1 --- /dev/null +++ b/account_cash_basis_group_base_line/tests/test_reconciliation.py @@ -0,0 +1,214 @@ +from odoo.addons.account.tests.test_reconciliation import TestReconciliation + + +class TestAccountReconciliationPartial(TestReconciliation): + + """Tests for Account Reconciliation Partial""" + + def __init__(self, methodName="runTest"): + super(TestAccountReconciliationPartial, self).__init__(methodName) + # Skip original test from inherited class + custom_attributes = set(dir(TestAccountReconciliationPartial)) - set( + dir(TestReconciliation) + ) + custom_test_methods = [ + name + for name in custom_attributes + if name.startswith("test_") and callable(getattr(self, name)) + ] + + if methodName not in custom_test_methods: + method = getattr(self, methodName) + method.__dict__["__unittest_skip__"] = True + method.__dict__[ + "__unittest_skip_why__" + ] = "Test executed from original module" + + def setUp(self): + super(TestAccountReconciliationPartial, self).setUp() + self.env.ref("base.main_company").write( + { + "tax_exigibility": True, + "tax_cash_basis_journal_id": self.cash_basis_journal.id, + } + ) + + def test_reconciliation_cash_basis(self): + # Simulates an expense made up by 2 lines + # one is subject to a cash basis tax + # the other is not subject to tax + + aml_obj = self.env["account.move.line"].with_context(check_move_validity=False) + + # Purchase + purchase_move = self.env["account.move"].create( + {"name": "purchase", "journal_id": self.purchase_journal.id} + ) + + purchase_payable_line0 = aml_obj.create( + { + "account_id": self.account_rsa.id, + "credit": 1350, + "move_id": purchase_move.id, + } + ) + purchase_payable_line1 = aml_obj.create( + { + "account_id": self.account_rsa.id, + "credit": 450, + "move_id": purchase_move.id, + } + ) + aml_obj.create( + { + "name": "expenseTaxed_0", + "account_id": self.expense_account.id, + "debit": 1000, + "move_id": purchase_move.id, + "tax_ids": [(4, self.tax_cash_basis.id, False)], + "tax_exigible": False, + } + ) + aml_obj.create( + { + "name": "expenseTaxed_1", + "account_id": self.expense_account.id, + "debit": 300, + "move_id": purchase_move.id, + "tax_ids": [(4, self.tax_cash_basis.id, False)], + "tax_exigible": False, + } + ) + aml_obj.create( + { + "name": "expenseTaxed_2", + "account_id": self.expense_account.id, + "debit": 200, + "move_id": purchase_move.id, + "tax_ids": [(4, self.tax_cash_basis.id, False)], + "tax_exigible": False, + } + ) + tax_line = aml_obj.create( + { + "name": "TaxLine", + "account_id": self.tax_waiting_account.id, + "debit": 300, + "move_id": purchase_move.id, + "tax_line_id": self.tax_cash_basis.id, + "tax_exigible": False, + "tax_repartition_line_id": ( + self.tax_cash_basis.invoice_repartition_line_ids.filtered( + lambda x: x.repartition_type == "tax" + ).id + ), + "tax_base_amount": 1500, + } + ) + purchase_move.post() + + # Payment Move + payment_move = self.env["account.move"].create( + {"name": "payment", "journal_id": self.bank_journal_euro.id} + ) + payment_payable_line = aml_obj.create( + { + "account_id": self.account_rsa.id, + "debit": 1800, + "move_id": payment_move.id, + } + ) + aml_obj.create( + { + "account_id": self.account_euro.id, + "credit": 1800, + "move_id": payment_move.id, + } + ) + payment_move.post() + + to_reconcile = ( + (purchase_move + payment_move) + .mapped("line_ids") + .filtered(lambda l: l.account_id.internal_type == "payable") + ) + to_reconcile.reconcile() + + apr_ids = to_reconcile.matched_debit_ids | to_reconcile.matched_credit_ids + cash_basis_moves = self.env["account.move"].search( + [("tax_cash_basis_rec_id", "in", apr_ids.ids)], + ) + + self.assertEqual(len(cash_basis_moves), 2, "There should be Two CABA Entries") + self.assertTrue(cash_basis_moves.exists()) + + # check reconciliation in Payable account + self.assertTrue(purchase_payable_line0.full_reconcile_id.exists()) + self.assertEqual( + purchase_payable_line0.full_reconcile_id.reconciled_line_ids, + purchase_payable_line0 + purchase_payable_line1 + payment_payable_line, + ) + + cash_basis_aml_ids = cash_basis_moves.mapped("line_ids") + # check reconciliation in the tax waiting account + self.assertTrue(tax_line.full_reconcile_id.exists()) + self.assertEqual( + tax_line.full_reconcile_id.reconciled_line_ids, + cash_basis_aml_ids.filtered( + lambda l: l.account_id == self.tax_waiting_account + ) + + tax_line, + ) + + self.assertEqual(len(cash_basis_aml_ids), 8, "There should 8 lines not 16") + + # check amounts + cash_basis_move1 = cash_basis_moves.filtered(lambda m: m.amount_total == 1350) + cash_basis_move2 = cash_basis_moves.filtered(lambda m: m.amount_total == 450) + + self.assertTrue(cash_basis_move1.exists()) + self.assertTrue(cash_basis_move2.exists()) + + # For first move + move_lines = cash_basis_move1.line_ids + base_amount_tax_lines = move_lines.filtered( + lambda l: l.account_id == self.tax_base_amount_account + ) + self.assertEqual(len(base_amount_tax_lines), 2, "There should be 2 lines not 6") + self.assertAlmostEqual(sum(base_amount_tax_lines.mapped("credit")), 1125) + self.assertAlmostEqual(sum(base_amount_tax_lines.mapped("debit")), 1125) + + self.assertAlmostEqual( + (move_lines - base_amount_tax_lines) + .filtered(lambda l: l.account_id == self.tax_waiting_account) + .credit, + 225, + ) + self.assertAlmostEqual( + (move_lines - base_amount_tax_lines) + .filtered(lambda l: l.account_id == self.tax_final_account) + .debit, + 225, + ) + + # For second move + move_lines = cash_basis_move2.line_ids + base_amount_tax_lines = move_lines.filtered( + lambda l: l.account_id == self.tax_base_amount_account + ) + self.assertEqual(len(base_amount_tax_lines), 2, "There should be 2 lines not 6") + self.assertAlmostEqual(sum(base_amount_tax_lines.mapped("credit")), 375) + self.assertAlmostEqual(sum(base_amount_tax_lines.mapped("debit")), 375) + + self.assertAlmostEqual( + (move_lines - base_amount_tax_lines) + .filtered(lambda l: l.account_id == self.tax_waiting_account) + .credit, + 75, + ) + self.assertAlmostEqual( + (move_lines - base_amount_tax_lines) + .filtered(lambda l: l.account_id == self.tax_final_account) + .debit, + 75, + )