diff --git a/account_move_line_cumulated_balance/README.rst b/account_move_line_cumulated_balance/README.rst index fcd83be3c..251fc6913 100644 --- a/account_move_line_cumulated_balance/README.rst +++ b/account_move_line_cumulated_balance/README.rst @@ -58,8 +58,13 @@ Usage Known issues / Roadmap ====================== -* For v14, there's only need to migrate the field amount_currency_balance, as - the other one already exists in core. +* For v14, there's a similar feature, but it doesn't cumulate in an absolute way like + this one, and there's no cumulated in amount currency, so this module may be fully + preserved. +* There's no support for filtering at the same time by several entries state (posted, + not posted, cancel, etc). +* In the partner ledger, removing the group by partner won't make the cumulated balances + to be considered globally by account. Bug Tracker =========== diff --git a/account_move_line_cumulated_balance/models/account_move_line.py b/account_move_line_cumulated_balance/models/account_move_line.py index 636d11e2d..92c02b64a 100644 --- a/account_move_line_cumulated_balance/models/account_move_line.py +++ b/account_move_line_cumulated_balance/models/account_move_line.py @@ -28,46 +28,50 @@ class AccountMoveLine(models.Model): @api.model def search_read(self, domain=None, fields=None, offset=0, limit=None, order=None): - def to_tuple(t): - return tuple(map(to_tuple, t)) if isinstance(t, (list, tuple)) else t - - # Add the domain and order by in order to compute the cumulated - # balance in _compute_cumulated_balance - order = (order or self._order) + ", id desc" + # Add the significant domain in order to compute the cumulated balance in + # _compute_cumulated_balance. + cumulated_domain = [] + for term in domain: + if isinstance(term, (tuple, list)) and term[0] == "move_id.state": + # TODO: Allow multiple state conditions joined by OR + cumulated_domain.append(("parent_state", term[1], term[2])) + elif term[0] == "full_reconcile_id": + cumulated_domain.append(tuple(term)) return super( - AccountMoveLine, self.with_context(order_cumulated_balance=order,), + AccountMoveLine, + self.with_context(domain_cumulated_balance=cumulated_domain), ).search_read(domain, fields, offset, limit, order) - @api.depends_context("order_cumulated_balance") + @api.depends_context("domain_cumulated_balance", "partner_ledger") def _compute_cumulated_balance(self): self.cumulated_balance = 0 self.cumulated_balance_currency = 0 - order_cumulated_balance = ( - self.env.context.get("order_cumulated_balance", self._order) + ", id" - ) - order_string = ", ".join( - self._generate_order_by_inner( - self._table, order_cumulated_balance, "", reverse_direction=False, - ) - ) - query = sql.SQL( - """SELECT account_move_line.id, - SUM(account_move_line.balance) OVER ( - ORDER BY {order_by_clause} - ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW - ), - SUM(account_move_line.amount_currency) OVER ( - ORDER BY {order_by_clause} - ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW - ) - FROM account_move_line - LEFT JOIN account_move on account_move_line.move_id = account_move.id - WHERE - account_move.state = 'posted' - """ - ).format(order_by_clause=sql.SQL(order_string),) - self.env.cr.execute(query) - result = {r[0]: (r[1], r[2]) for r in self.env.cr.fetchall()} + query = self._where_calc(self.env.context.get("domain_cumulated_balance") or []) + _f, where_clause, where_clause_params = query.get_sql() for record in self: - record.cumulated_balance = result[record.id][0] - record.cumulated_balance_currency = result[record.id][1] + query_args = where_clause_params + [ + record.account_id.id, + record.company_id.id, + record.date, + record.date, + record.id, + ] + # WHERE clause last line is set according order in view where this is used + query = sql.SQL( + """ + SELECT SUM(balance), SUM(amount_currency) + FROM account_move_line + WHERE {} + AND account_id = %s + AND company_id = %s + AND (date < %s OR (date=%s AND id <= %s)) + """ + ).format(sql.SQL(where_clause or "TRUE")) + if self.env.context.get("partner_ledger"): + # If showing partner ledger group by partner by default + query_args.append(record.partner_id.id) + query += sql.SQL("AND partner_id = %s") + self.env.cr.execute(query, tuple(query_args)) + result = self.env.cr.fetchone() + record.cumulated_balance = result[0] + record.cumulated_balance_currency = result[1] diff --git a/account_move_line_cumulated_balance/readme/ROADMAP.rst b/account_move_line_cumulated_balance/readme/ROADMAP.rst index 9df7956b3..441e9d96e 100644 --- a/account_move_line_cumulated_balance/readme/ROADMAP.rst +++ b/account_move_line_cumulated_balance/readme/ROADMAP.rst @@ -1,2 +1,7 @@ -* For v14, there's only need to migrate the field amount_currency_balance, as - the other one already exists in core. +* For v14, there's a similar feature, but it doesn't cumulate in an absolute way like + this one, and there's no cumulated in amount currency, so this module may be fully + preserved. +* There's no support for filtering at the same time by several entries state (posted, + not posted, cancel, etc). +* In the partner ledger, removing the group by partner won't make the cumulated balances + to be considered globally by account. diff --git a/account_move_line_cumulated_balance/tests/test_account_move_line_cumulated_balance.py b/account_move_line_cumulated_balance/tests/test_account_move_line_cumulated_balance.py index a8fd9c71c..edb71240a 100644 --- a/account_move_line_cumulated_balance/tests/test_account_move_line_cumulated_balance.py +++ b/account_move_line_cumulated_balance/tests/test_account_move_line_cumulated_balance.py @@ -1,31 +1,20 @@ # Copyright 2020 Tecnativa - Víctor Martínez # License AGPL-3 - See https://www.gnu.org/licenses/agpl-3.0.html -from odoo.tests import Form +from odoo.tests import Form, tagged from odoo.tests.common import SavepointCase +@tagged("post_install", "-at_install") class TestAccount(SavepointCase): @classmethod def setUpClass(cls): super().setUpClass() cls.account_account_type_model = cls.env["account.account.type"] cls.account_account_model = cls.env["account.account"] - cls.account_type_receivable = cls.account_account_type_model.create( - {"name": "Test Receivable", "type": "receivable", "internal_group": "asset"} - ) cls.account_type_regular = cls.account_account_type_model.create( {"name": "Test Regular", "type": "other", "internal_group": "income"} ) - - cls.account_receivable = cls.account_account_model.create( - { - "name": "Test Receivable", - "code": "TEST_AR", - "user_type_id": cls.account_type_receivable.id, - "reconcile": True, - } - ) cls.account_income = cls.account_account_model.create( { "name": "Test Income", @@ -34,21 +23,7 @@ class TestAccount(SavepointCase): "reconcile": False, } ) - cls.partner = cls.env["res.partner"].create( - { - "name": "Test customer", - "customer_rank": 1, - "property_account_receivable_id": cls.account_receivable.id, - } - ) - cls.journal = cls.env["account.journal"].create( - { - "name": "Test journal", - "type": "sale", - "code": "test-sale-jorunal", - "company_id": cls.env.company.id, - } - ) + cls.partner = cls.env["res.partner"].create({"name": "Test customer"}) cls.product = cls.env["product.product"].create( {"name": "Test product", "type": "service"} ) @@ -58,27 +33,36 @@ class TestAccount(SavepointCase): ) ) invoice.partner_id = cls.partner - invoice.journal_id = cls.journal with invoice.invoice_line_ids.new() as line_form: line_form.name = cls.product.name line_form.product_id = cls.product line_form.quantity = 1.0 line_form.price_unit = 10 line_form.account_id = cls.account_income + with invoice.invoice_line_ids.new() as line_form: + line_form.name = cls.product.name + line_form.product_id = cls.product + line_form.quantity = 2.0 + line_form.price_unit = 10 + line_form.account_id = cls.account_income invoice = invoice.save() invoice.action_post() cls.invoice = invoice - def test_remove_invoice_error(self): - # Delete invoice while name isn't / + def test_basic_check(self): lines = ( self.env["account.move.line"] - .with_context(order_cumulated_balance="date desc, id desc") + .with_context(domain_cumulated_balance=[("parent_state", "=", "posted")]) .search( - [("move_id.state", "=", "posted"), ("move_id", "=", self.invoice.id)] + [ + ("account_id", "=", self.account_income.id), + ("move_id", "=", self.invoice.id), + ], + order="date asc, id asc", ) ) - self.assertAlmostEqual(lines[0].cumulated_balance, 0) + self.assertAlmostEqual(lines[0].cumulated_balance, -10) + # TODO: Test other currency balances self.assertAlmostEqual(lines[0].cumulated_balance_currency, 0) - self.assertAlmostEqual(lines[1].cumulated_balance, 10) + self.assertAlmostEqual(lines[1].cumulated_balance, -30) self.assertAlmostEqual(lines[1].cumulated_balance_currency, 0) diff --git a/account_move_line_cumulated_balance/views/account_move_views.xml b/account_move_line_cumulated_balance/views/account_move_views.xml index 2bbf6cf6d..f1b9b2391 100644 --- a/account_move_line_cumulated_balance/views/account_move_views.xml +++ b/account_move_line_cumulated_balance/views/account_move_views.xml @@ -6,7 +6,7 @@ - date asc + date asc, id asc @@ -26,9 +26,9 @@ - date asc + date asc, id asc - + @@ -40,4 +40,13 @@ + + + {'partner_ledger': 1, 'journal_type':'general', 'search_default_group_by_partner': 1, 'search_default_posted':1, 'search_default_payable':1, 'search_default_receivable':1, 'search_default_unreconciled':1} +