# Copyright (c) 2026 Patrick Motsch # All rights reserved. """Unit tests for the Abacus connector's getAccountBalances aggregation logic.""" from unittest.mock import patch import pytest from modules.features.trustee.accounting.connectors.accountingConnectorAbacus import ( AccountingConnectorAbacus, _isIncomeStatementAccount, ) class TestIsIncomeStatementAccount: @pytest.mark.parametrize("accno,expected", [ ("1020", False), ("2010", False), ("3000", True), ("8500", True), ]) def test_classification(self, accno, expected): assert _isIncomeStatementAccount(accno) == expected class TestAbacusGetAccountBalances: @pytest.mark.asyncio async def test_aggregatesFromGeneralJournalEntries(self): connector = AccountingConnectorAbacus() rawEntries = [ { "Id": "e1", "JournalDate": "2025-01-15T00:00:00", "Lines": [ {"AccountId": "1020", "DebitAmount": 1000.0, "CreditAmount": 0.0}, {"AccountId": "6000", "DebitAmount": 0.0, "CreditAmount": 1000.0}, ], }, { "Id": "e2", "JournalDate": "2025-12-20T00:00:00", "Lines": [ {"AccountId": "1020", "DebitAmount": 500.0, "CreditAmount": 0.0}, {"AccountId": "6000", "DebitAmount": 0.0, "CreditAmount": 500.0}, ], }, ] async def _fakeAuth(self, config): return {"Authorization": "Bearer X"} async def _fakeFetch(self, config, headers, dateTo): return rawEntries with patch.object(AccountingConnectorAbacus, "_buildAuthHeaders", _fakeAuth), \ patch.object(AccountingConnectorAbacus, "_fetchAllJournalEntries", _fakeFetch): balances = await connector.getAccountBalances({"apiBaseUrl": "http://x", "clientName": "y"}, years=[2025]) byPeriod = {(b.accountNumber, b.periodYear, b.periodMonth): b for b in balances} assert byPeriod[("1020", 2025, 1)].closingBalance == 1000.0 assert byPeriod[("1020", 2025, 12)].closingBalance == 1500.0 assert byPeriod[("1020", 2025, 0)].closingBalance == 1500.0 # 6000 is income statement (3xxx-9xxx) but credit-side -- closing = -1500 (net debit-credit) assert byPeriod[("6000", 2025, 0)].closingBalance == -1500.0 # ER account January opening must be 0 (no prior-year carry) assert byPeriod[("6000", 2025, 1)].openingBalance == 0.0 @pytest.mark.asyncio async def test_balanceSheetCarryOverAcrossYears(self): connector = AccountingConnectorAbacus() rawEntries = [ { "Id": "e1", "JournalDate": "2024-06-30T00:00:00", "Lines": [ {"AccountId": "1020", "DebitAmount": 7000.0, "CreditAmount": 0.0}, {"AccountId": "9999", "DebitAmount": 0.0, "CreditAmount": 7000.0}, ], }, ] async def _fakeAuth(self, config): return {"Authorization": "Bearer X"} async def _fakeFetch(self, config, headers, dateTo): return rawEntries with patch.object(AccountingConnectorAbacus, "_buildAuthHeaders", _fakeAuth), \ patch.object(AccountingConnectorAbacus, "_fetchAllJournalEntries", _fakeFetch): balances = await connector.getAccountBalances({"apiBaseUrl": "http://x", "clientName": "y"}, years=[2025]) byPeriod = {(b.accountNumber, b.periodYear, b.periodMonth): b for b in balances} # 1020 (BS) opens 2025 with 7000 from prior year, no movements in 2025 -> closes at 7000 assert byPeriod[("1020", 2025, 1)].openingBalance == 7000.0 assert byPeriod[("1020", 2025, 0)].openingBalance == 7000.0 assert byPeriod[("1020", 2025, 0)].closingBalance == 7000.0