Fix initial balance computation
parent
ccda04526e
commit
2b1e69fb41
|
@ -50,6 +50,7 @@ Contributors
|
|||
* Francesco Apruzzese <opencode@e-ware.org>
|
||||
* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
|
||||
* Julien Coux <julien.coux@camptocamp.com>
|
||||
* Akim Juillerat <akim.juillerat@camptocamp.com>
|
||||
|
||||
Much of the work in this module was done at a sprint in Sorrento, Italy in
|
||||
April 2016.
|
||||
|
|
|
@ -263,7 +263,8 @@ class GeneralLedgerReportCompute(models.TransientModel):
|
|||
# Refresh cache because all data are computed with SQL requests
|
||||
self.refresh()
|
||||
|
||||
def _get_account_sub_subquery_sum_amounts(self, include_initial_balance):
|
||||
def _get_account_sub_subquery_sum_amounts(
|
||||
self, include_initial_balance, date_included):
|
||||
""" Return subquery used to compute sum amounts on accounts """
|
||||
sub_subquery_sum_amounts = """
|
||||
SELECT
|
||||
|
@ -278,8 +279,16 @@ class GeneralLedgerReportCompute(models.TransientModel):
|
|||
INNER JOIN
|
||||
account_move_line ml
|
||||
ON a.id = ml.account_id
|
||||
"""
|
||||
|
||||
if date_included:
|
||||
sub_subquery_sum_amounts += """
|
||||
AND ml.date <= %s
|
||||
"""
|
||||
else:
|
||||
sub_subquery_sum_amounts += """
|
||||
AND ml.date < %s
|
||||
"""
|
||||
|
||||
if not include_initial_balance:
|
||||
sub_subquery_sum_amounts += """
|
||||
|
@ -309,8 +318,8 @@ class GeneralLedgerReportCompute(models.TransientModel):
|
|||
"""
|
||||
return sub_subquery_sum_amounts
|
||||
|
||||
def _inject_account_values(self):
|
||||
"""Inject report values for report_general_ledger_qweb_account."""
|
||||
def _get_final_account_sub_subquery_sum_amounts(self, date_included):
|
||||
""" Return final subquery used to compute sum amounts on accounts """
|
||||
subquery_sum_amounts = """
|
||||
SELECT
|
||||
sub.account_id AS account_id,
|
||||
|
@ -321,19 +330,23 @@ class GeneralLedgerReportCompute(models.TransientModel):
|
|||
(
|
||||
"""
|
||||
subquery_sum_amounts += self._get_account_sub_subquery_sum_amounts(
|
||||
include_initial_balance=False
|
||||
include_initial_balance=False, date_included=date_included
|
||||
)
|
||||
subquery_sum_amounts += """
|
||||
UNION
|
||||
"""
|
||||
subquery_sum_amounts += self._get_account_sub_subquery_sum_amounts(
|
||||
include_initial_balance=True
|
||||
include_initial_balance=True, date_included=date_included
|
||||
)
|
||||
subquery_sum_amounts += """
|
||||
) sub
|
||||
GROUP BY
|
||||
sub.account_id
|
||||
"""
|
||||
return subquery_sum_amounts
|
||||
|
||||
def _inject_account_values(self):
|
||||
"""Inject report values for report_general_ledger_qweb_account."""
|
||||
query_inject_account = """
|
||||
WITH
|
||||
accounts AS
|
||||
|
@ -386,10 +399,18 @@ WITH
|
|||
GROUP BY
|
||||
a.id
|
||||
"""
|
||||
|
||||
init_subquery = self._get_final_account_sub_subquery_sum_amounts(
|
||||
date_included=False
|
||||
)
|
||||
final_subquery = self._get_final_account_sub_subquery_sum_amounts(
|
||||
date_included=True
|
||||
)
|
||||
|
||||
query_inject_account += """
|
||||
),
|
||||
initial_sum_amounts AS ( """ + subquery_sum_amounts + """ ),
|
||||
final_sum_amounts AS ( """ + subquery_sum_amounts + """ )
|
||||
initial_sum_amounts AS ( """ + init_subquery + """ ),
|
||||
final_sum_amounts AS ( """ + final_subquery + """ )
|
||||
INSERT INTO
|
||||
report_general_ledger_qweb_account
|
||||
(
|
||||
|
@ -496,7 +517,7 @@ AND
|
|||
self.env.cr.execute(query_inject_account, query_inject_account_params)
|
||||
|
||||
def _get_partner_sub_subquery_sum_amounts(
|
||||
self, only_empty_partner, include_initial_balance
|
||||
self, only_empty_partner, include_initial_balance, date_included
|
||||
):
|
||||
""" Return subquery used to compute sum amounts on partners """
|
||||
sub_subquery_sum_amounts = """
|
||||
|
@ -511,8 +532,15 @@ AND
|
|||
INNER JOIN
|
||||
account_move_line ml
|
||||
ON ap.account_id = ml.account_id
|
||||
"""
|
||||
if date_included:
|
||||
sub_subquery_sum_amounts += """
|
||||
AND ml.date <= %s
|
||||
"""
|
||||
else:
|
||||
sub_subquery_sum_amounts += """
|
||||
AND ml.date < %s
|
||||
"""
|
||||
if not only_empty_partner:
|
||||
sub_subquery_sum_amounts += """
|
||||
AND ap.partner_id = ml.partner_id
|
||||
|
@ -548,11 +576,10 @@ AND
|
|||
"""
|
||||
return sub_subquery_sum_amounts
|
||||
|
||||
def _inject_partner_values(self, only_empty_partner=False):
|
||||
""" Inject report values for report_general_ledger_qweb_partner.
|
||||
def _get_final_partner_sub_subquery_sum_amounts(self, only_empty_partner,
|
||||
date_included):
|
||||
"""Return final subquery used to compute sum amounts on partners"""
|
||||
|
||||
Only for "partner" accounts (payable and receivable).
|
||||
"""
|
||||
subquery_sum_amounts = """
|
||||
|
||||
SELECT
|
||||
|
@ -566,20 +593,30 @@ AND
|
|||
"""
|
||||
subquery_sum_amounts += self._get_partner_sub_subquery_sum_amounts(
|
||||
only_empty_partner,
|
||||
include_initial_balance=False
|
||||
include_initial_balance=False,
|
||||
date_included=date_included
|
||||
)
|
||||
subquery_sum_amounts += """
|
||||
UNION
|
||||
"""
|
||||
subquery_sum_amounts += self._get_partner_sub_subquery_sum_amounts(
|
||||
only_empty_partner,
|
||||
include_initial_balance=True
|
||||
include_initial_balance=True,
|
||||
date_included=date_included
|
||||
)
|
||||
subquery_sum_amounts += """
|
||||
) sub
|
||||
GROUP BY
|
||||
sub.account_id, sub.partner_id
|
||||
"""
|
||||
return subquery_sum_amounts
|
||||
|
||||
def _inject_partner_values(self, only_empty_partner=False):
|
||||
""" Inject report values for report_general_ledger_qweb_partner.
|
||||
|
||||
Only for "partner" accounts (payable and receivable).
|
||||
"""
|
||||
|
||||
query_inject_partner = """
|
||||
WITH
|
||||
accounts_partners AS
|
||||
|
@ -645,6 +682,16 @@ WITH
|
|||
AND
|
||||
p.id IN %s
|
||||
"""
|
||||
|
||||
init_subquery = self._get_final_partner_sub_subquery_sum_amounts(
|
||||
only_empty_partner,
|
||||
date_included=False
|
||||
)
|
||||
final_subquery = self._get_final_partner_sub_subquery_sum_amounts(
|
||||
only_empty_partner,
|
||||
date_included=True
|
||||
)
|
||||
|
||||
query_inject_partner += """
|
||||
GROUP BY
|
||||
ra.id,
|
||||
|
@ -652,8 +699,8 @@ WITH
|
|||
p.id,
|
||||
at.include_initial_balance
|
||||
),
|
||||
initial_sum_amounts AS ( """ + subquery_sum_amounts + """ ),
|
||||
final_sum_amounts AS ( """ + subquery_sum_amounts + """ )
|
||||
initial_sum_amounts AS ( """ + init_subquery + """ ),
|
||||
final_sum_amounts AS ( """ + final_subquery + """ )
|
||||
INSERT INTO
|
||||
report_general_ledger_qweb_partner
|
||||
(
|
||||
|
@ -1190,7 +1237,7 @@ WHERE id = %s
|
|||
INNER JOIN
|
||||
account_move_line ml
|
||||
ON a.id = ml.account_id
|
||||
AND ml.date <= %s
|
||||
AND ml.date < %s
|
||||
"""
|
||||
|
||||
if not include_initial_balance:
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import time
|
||||
from . import abstract_test
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestGeneralLedger(abstract_test.AbstractTest):
|
||||
|
@ -50,3 +51,347 @@ class TestGeneralLedger(abstract_test.AbstractTest):
|
|||
'centralize': True
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class TestGeneralLedgerReport(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestGeneralLedgerReport, self).setUp()
|
||||
|
||||
self.previous_fy_date_end = '2015-12-31'
|
||||
self.fy_date_start = '2016-01-01'
|
||||
self.fy_date_end = '2016-12-31'
|
||||
self.receivable_account = self.env['account.account'].search([
|
||||
('user_type_id.name', '=', 'Receivable')
|
||||
], limit=1)
|
||||
self.income_account = self.env['account.account'].search([
|
||||
('user_type_id.name', '=', 'Income')
|
||||
], limit=1)
|
||||
self.unaffected_account = self.env['account.account'].search([
|
||||
(
|
||||
'user_type_id',
|
||||
'=',
|
||||
self.env.ref('account.data_unaffected_earnings').id
|
||||
)], limit=1)
|
||||
|
||||
def _add_move(
|
||||
self,
|
||||
date,
|
||||
receivable_debit,
|
||||
receivable_credit,
|
||||
income_debit,
|
||||
income_credit,
|
||||
unaffected_debit=0,
|
||||
unaffected_credit=0
|
||||
):
|
||||
move_name = 'expense accrual'
|
||||
journal = self.env['account.journal'].search([
|
||||
('code', '=', 'MISC')])
|
||||
partner = self.env.ref('base.res_partner_12')
|
||||
move_vals = {
|
||||
'journal_id': journal.id,
|
||||
'partner_id': partner.id,
|
||||
'name': move_name,
|
||||
'date': date,
|
||||
'line_ids': [
|
||||
(0, 0, {
|
||||
'name': move_name,
|
||||
'debit': receivable_debit,
|
||||
'credit': receivable_credit,
|
||||
'account_id': self.receivable_account.id}),
|
||||
(0, 0, {
|
||||
'name': move_name,
|
||||
'debit': income_debit,
|
||||
'credit': income_credit,
|
||||
'account_id': self.income_account.id}),
|
||||
(0, 0, {
|
||||
'name': move_name,
|
||||
'debit': unaffected_debit,
|
||||
'credit': unaffected_credit,
|
||||
'account_id': self.unaffected_account.id}),
|
||||
]}
|
||||
move = self.env['account.move'].create(move_vals)
|
||||
move.post()
|
||||
|
||||
def _get_report_lines(self, with_partners=False):
|
||||
company = self.env.ref('base.main_company')
|
||||
general_ledger = self.env['report_general_ledger_qweb'].create({
|
||||
'date_from': self.fy_date_start,
|
||||
'date_to': self.fy_date_end,
|
||||
'only_posted_moves': True,
|
||||
'hide_account_balance_at_0': False,
|
||||
'company_id': company.id,
|
||||
'fy_start_date': self.fy_date_start,
|
||||
})
|
||||
general_ledger.compute_data_for_report(
|
||||
with_line_details=True, with_partners=with_partners
|
||||
)
|
||||
lines = {}
|
||||
report_account_model = self.env['report_general_ledger_qweb_account']
|
||||
lines['receivable'] = report_account_model.search([
|
||||
('report_id', '=', general_ledger.id),
|
||||
('account_id', '=', self.receivable_account.id),
|
||||
])
|
||||
lines['income'] = report_account_model.search([
|
||||
('report_id', '=', general_ledger.id),
|
||||
('account_id', '=', self.income_account.id),
|
||||
])
|
||||
lines['unaffected'] = report_account_model.search([
|
||||
('report_id', '=', general_ledger.id),
|
||||
('account_id', '=', self.unaffected_account.id),
|
||||
])
|
||||
if with_partners:
|
||||
report_partner_model = self.env[
|
||||
'report_general_ledger_qweb_partner'
|
||||
]
|
||||
lines['partner_receivable'] = report_partner_model.search([
|
||||
('report_account_id', '=', lines['receivable'].id),
|
||||
('partner_id', '=', self.env.ref('base.res_partner_12').id),
|
||||
])
|
||||
return lines
|
||||
|
||||
def test_01_account_balance(self):
|
||||
# Generate the general ledger line
|
||||
lines = self._get_report_lines()
|
||||
self.assertEqual(len(lines['receivable']), 0)
|
||||
self.assertEqual(len(lines['income']), 0)
|
||||
|
||||
# Add a move at the previous day of the first day of fiscal year
|
||||
# to check the initial balance
|
||||
self._add_move(
|
||||
date=self.previous_fy_date_end,
|
||||
receivable_debit=1000,
|
||||
receivable_credit=0,
|
||||
income_debit=0,
|
||||
income_credit=1000
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines()
|
||||
self.assertEqual(len(lines['receivable']), 1)
|
||||
self.assertEqual(len(lines['income']), 0)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['receivable'].initial_debit, 1000)
|
||||
self.assertEqual(lines['receivable'].initial_credit, 0)
|
||||
self.assertEqual(lines['receivable'].initial_balance, 1000)
|
||||
self.assertEqual(lines['receivable'].final_debit, 1000)
|
||||
self.assertEqual(lines['receivable'].final_credit, 0)
|
||||
self.assertEqual(lines['receivable'].final_balance, 1000)
|
||||
|
||||
# Add reversale move of the initial move the first day of fiscal year
|
||||
# to check the first day of fiscal year is not used
|
||||
# to compute the initial balance
|
||||
self._add_move(
|
||||
date=self.fy_date_start,
|
||||
receivable_debit=0,
|
||||
receivable_credit=1000,
|
||||
income_debit=1000,
|
||||
income_credit=0
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines()
|
||||
self.assertEqual(len(lines['receivable']), 1)
|
||||
self.assertEqual(len(lines['income']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['receivable'].initial_debit, 1000)
|
||||
self.assertEqual(lines['receivable'].initial_credit, 0)
|
||||
self.assertEqual(lines['receivable'].initial_balance, 1000)
|
||||
self.assertEqual(lines['receivable'].final_debit, 1000)
|
||||
self.assertEqual(lines['receivable'].final_credit, 1000)
|
||||
self.assertEqual(lines['receivable'].final_balance, 0)
|
||||
|
||||
self.assertEqual(lines['income'].initial_debit, 0)
|
||||
self.assertEqual(lines['income'].initial_credit, 0)
|
||||
self.assertEqual(lines['income'].initial_balance, 0)
|
||||
self.assertEqual(lines['income'].final_debit, 1000)
|
||||
self.assertEqual(lines['income'].final_credit, 0)
|
||||
self.assertEqual(lines['income'].final_balance, 1000)
|
||||
|
||||
# Add another move at the end day of fiscal year
|
||||
# to check that it correctly used on report
|
||||
self._add_move(
|
||||
date=self.fy_date_end,
|
||||
receivable_debit=0,
|
||||
receivable_credit=1000,
|
||||
income_debit=1000,
|
||||
income_credit=0
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines()
|
||||
self.assertEqual(len(lines['receivable']), 1)
|
||||
self.assertEqual(len(lines['income']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['receivable'].initial_debit, 1000)
|
||||
self.assertEqual(lines['receivable'].initial_credit, 0)
|
||||
self.assertEqual(lines['receivable'].initial_balance, 1000)
|
||||
self.assertEqual(lines['receivable'].final_debit, 1000)
|
||||
self.assertEqual(lines['receivable'].final_credit, 2000)
|
||||
self.assertEqual(lines['receivable'].final_balance, -1000)
|
||||
|
||||
self.assertEqual(lines['income'].initial_debit, 0)
|
||||
self.assertEqual(lines['income'].initial_credit, 0)
|
||||
self.assertEqual(lines['income'].initial_balance, 0)
|
||||
self.assertEqual(lines['income'].final_debit, 2000)
|
||||
self.assertEqual(lines['income'].final_credit, 0)
|
||||
self.assertEqual(lines['income'].final_balance, 2000)
|
||||
|
||||
def test_02_partner_balance(self):
|
||||
# Generate the general ledger line
|
||||
lines = self._get_report_lines(with_partners=True)
|
||||
self.assertEqual(len(lines['partner_receivable']), 0)
|
||||
|
||||
# Add a move at the previous day of the first day of fiscal year
|
||||
# to check the initial balance
|
||||
self._add_move(
|
||||
date=self.previous_fy_date_end,
|
||||
receivable_debit=1000,
|
||||
receivable_credit=0,
|
||||
income_debit=0,
|
||||
income_credit=1000
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines(with_partners=True)
|
||||
self.assertEqual(len(lines['partner_receivable']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['partner_receivable'].initial_debit, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].initial_credit, 0)
|
||||
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].final_debit, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].final_credit, 0)
|
||||
self.assertEqual(lines['partner_receivable'].final_balance, 1000)
|
||||
|
||||
# Add reversale move of the initial move the first day of fiscal year
|
||||
# to check the first day of fiscal year is not used
|
||||
# to compute the initial balance
|
||||
self._add_move(
|
||||
date=self.fy_date_start,
|
||||
receivable_debit=0,
|
||||
receivable_credit=1000,
|
||||
income_debit=1000,
|
||||
income_credit=0
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines(with_partners=True)
|
||||
self.assertEqual(len(lines['partner_receivable']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['partner_receivable'].initial_debit, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].initial_credit, 0)
|
||||
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].final_debit, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].final_credit, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].final_balance, 0)
|
||||
|
||||
# Add another move at the end day of fiscal year
|
||||
# to check that it correctly used on report
|
||||
self._add_move(
|
||||
date=self.fy_date_end,
|
||||
receivable_debit=0,
|
||||
receivable_credit=1000,
|
||||
income_debit=1000,
|
||||
income_credit=0
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines(with_partners=True)
|
||||
self.assertEqual(len(lines['partner_receivable']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['partner_receivable'].initial_debit, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].initial_credit, 0)
|
||||
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].final_debit, 1000)
|
||||
self.assertEqual(lines['partner_receivable'].final_credit, 2000)
|
||||
self.assertEqual(lines['partner_receivable'].final_balance, -1000)
|
||||
|
||||
def test_03_unaffected_account_balance(self):
|
||||
# Generate the general ledger line
|
||||
lines = self._get_report_lines()
|
||||
self.assertEqual(len(lines['unaffected']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['unaffected'].initial_debit, 0)
|
||||
self.assertEqual(lines['unaffected'].initial_credit, 0)
|
||||
self.assertEqual(lines['unaffected'].initial_balance, 0)
|
||||
self.assertEqual(lines['unaffected'].final_debit, 0)
|
||||
self.assertEqual(lines['unaffected'].final_credit, 0)
|
||||
self.assertEqual(lines['unaffected'].final_balance, 0)
|
||||
|
||||
# Add a move at the previous day of the first day of fiscal year
|
||||
# to check the initial balance
|
||||
self._add_move(
|
||||
date=self.previous_fy_date_end,
|
||||
receivable_debit=1000,
|
||||
receivable_credit=0,
|
||||
income_debit=0,
|
||||
income_credit=1000
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines()
|
||||
self.assertEqual(len(lines['unaffected']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['unaffected'].initial_debit, 0)
|
||||
self.assertEqual(lines['unaffected'].initial_credit, 0)
|
||||
self.assertEqual(lines['unaffected'].initial_balance, -1000)
|
||||
self.assertEqual(lines['unaffected'].final_debit, -0)
|
||||
self.assertEqual(lines['unaffected'].final_credit, 0)
|
||||
self.assertEqual(lines['unaffected'].final_balance, -1000)
|
||||
|
||||
# Add reversale move of the initial move the first day of fiscal year
|
||||
# to check the first day of fiscal year is not used
|
||||
# to compute the initial balance
|
||||
self._add_move(
|
||||
date=self.fy_date_start,
|
||||
receivable_debit=0,
|
||||
receivable_credit=0,
|
||||
income_debit=0,
|
||||
income_credit=1000,
|
||||
unaffected_debit=1000,
|
||||
unaffected_credit=0
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines()
|
||||
self.assertEqual(len(lines['unaffected']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['unaffected'].initial_debit, 0)
|
||||
self.assertEqual(lines['unaffected'].initial_credit, 0)
|
||||
self.assertEqual(lines['unaffected'].initial_balance, -1000)
|
||||
self.assertEqual(lines['unaffected'].final_debit, 1000)
|
||||
self.assertEqual(lines['unaffected'].final_credit, 0)
|
||||
self.assertEqual(lines['unaffected'].final_balance, 0)
|
||||
|
||||
# Add another move at the end day of fiscal year
|
||||
# to check that it correctly used on report
|
||||
self._add_move(
|
||||
date=self.fy_date_end,
|
||||
receivable_debit=3000,
|
||||
receivable_credit=0,
|
||||
income_debit=0,
|
||||
income_credit=0,
|
||||
unaffected_debit=0,
|
||||
unaffected_credit=3000
|
||||
)
|
||||
|
||||
# Re Generate the general ledger line
|
||||
lines = self._get_report_lines()
|
||||
self.assertEqual(len(lines['unaffected']), 1)
|
||||
|
||||
# Check the initial and final balance
|
||||
self.assertEqual(lines['unaffected'].initial_debit, 0)
|
||||
self.assertEqual(lines['unaffected'].initial_credit, 0)
|
||||
self.assertEqual(lines['unaffected'].initial_balance, -1000)
|
||||
self.assertEqual(lines['unaffected'].final_debit, 1000)
|
||||
self.assertEqual(lines['unaffected'].final_credit, 3000)
|
||||
self.assertEqual(lines['unaffected'].final_balance, -3000)
|
||||
|
|
Loading…
Reference in New Issue