Skip to content

Commit

Permalink
[IMP] calculate opening debit, credit from balance of opening lines
Browse files Browse the repository at this point in the history
only consider posted move lines for opening balance
  • Loading branch information
hbrunn committed Mar 19, 2024
1 parent 352cf71 commit 30dd0e0
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 31 deletions.
34 changes: 16 additions & 18 deletions l10n_nl_xaf_auditfile_export/models/xaf_auditfile_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,33 +254,31 @@ def get_taxes(self):
@api.multi
def get_ob_totals(self):
"""return totals of opening balance"""
self.env.cr.execute(
"select sum(l.credit), sum(l.debit), count(distinct a.id) "
"from account_move_line l, account_account a, "
" account_account_type t "
"where a.user_type_id = t.id "
"and l.account_id = a.id "
"and l.date < %s "
"and l.company_id=%s "
"and t.include_initial_balance = true ",
(self.date_start, self.company_id.id),
)
row = self.env.cr.fetchall()[0]
return dict(
credit=round(row[0] or 0.0, 2),
debit=round(row[1] or 0.0, 2),
count=row[2] or 0,
result = dict(
credit=0.0,
debit=0.0,
count=0
)
for line in self.get_ob_lines():
balance = line['balance']
if balance > 0:
result['debit'] += balance
else:
result['credit'] -= balance
result['count'] += 1
return result

@api.multi
def get_ob_lines(self):
"""return opening balance entries"""
self.env.cr.execute(
"select a.id, a.code, sum(l.balance) "
# pylint: disable=sql-injection
"select a.id, a.code, sum(l.balance) " +
"from account_move_line l, account_account a, "
" account_account_type t "
" account_move m, account_account_type t "
"where a.user_type_id = t.id "
"and a.id = l.account_id and l.date < %s "
"and l.move_id = m.id and m.state = 'posted' "
"and l.company_id=%s "
"and t.include_initial_balance = true "
"group by a.id, a.code",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

import base64
from datetime import timedelta
from lxml import etree
from io import BytesIO
import os
from zipfile import ZipFile


from odoo.tests.common import TransactionCase
from odoo.tools import mute_logger


def get_transaction_line_count_from_xml(auditfile):
''' Helper XML method to parse and return the transaction line count '''
line_count = 0
def xaf_xpath(auditfile, query):
with ZipFile(BytesIO(base64.b64decode(auditfile)), 'r') as z:
contents = z.read(z.filelist[-1]).decode()
parser = etree.XMLParser(
Expand All @@ -23,16 +23,29 @@ def get_transaction_line_count_from_xml(auditfile):
remove_blank_text=True
)
root = etree.XML(bytes(contents, encoding='utf8'), parser=parser)
# xpath query to select all element nodes in namespace
# Source: https://stackoverflow.com/a/30233635
query = "descendant-or-self::*[namespace-uri()!='']"
for element in root.xpath(query):
element.tag = etree.QName(element).localname
journals = root.xpath("/auditfile/company/transactions/journal")
for journal in journals:
transactions = journal.xpath("transaction/trLine")
for _ in transactions:
line_count += 1
for element in root.xpath(
query, namespaces={'a': 'http://www.auditfiles.nl/XAF/3.2'}
):
yield element


def get_transaction_line_count_from_xml(auditfile):
''' Helper XML method to parse and return the transaction line count '''
line_count = 0
# xpath query to select all element nodes in namespace
# Source: https://stackoverflow.com/a/30233635
query = "descendant-or-self::*[namespace-uri()!='']"
root = None
for element in xaf_xpath(auditfile, query):
element.tag = etree.QName(element).localname
root = root or element.getroottree()
if not root:
return 0

Check warning on line 43 in l10n_nl_xaf_auditfile_export/tests/test_l10n_nl_xaf_auditfile_export.py

View check run for this annotation

Codecov / codecov/patch

l10n_nl_xaf_auditfile_export/tests/test_l10n_nl_xaf_auditfile_export.py#L43

Added line #L43 was not covered by tests
journals = root.xpath("/auditfile/company/transactions/journal")
for journal in journals:
transactions = journal.xpath("transaction/trLine")
for _ in transactions:
line_count += 1
return line_count


Expand Down Expand Up @@ -146,3 +159,67 @@ def test_06_include_moves_from_inactive_journals(self):
line_count_after = record_after.get_move_line_count()
parsed_count_after = get_transaction_line_count_from_xml(record_after.auditfile)
self.assertTrue(parsed_line_count == parsed_count_after == line_count_after)

def test_07_opening_balance(self):
"""Test that we calculate the opening balance correctly"""
record = self.env['xaf.auditfile.export'].create({})

acc_receivable = self.env['account.account'].search([
(
'user_type_id', '=',
self.env.ref('account.data_account_type_receivable').id
),
], limit=1)
acc_payable = self.env['account.account'].search([
('user_type_id', '=', self.env.ref('account.data_account_type_payable').id),
], limit=1)
acc_revenue = self.env['account.account'].search([
('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id),
], limit=1)
journal = self.env['account.journal'].search([], limit=1)

move_receivable = self.env['account.move'].create({
'journal_id': journal.id,
'date': record.date_start - timedelta(days=1),
'line_ids': [
(0, 0, {'account_id': acc_receivable.id, 'credit': 42, 'debit': 0}),
(0, 0, {'account_id': acc_revenue.id, 'credit': 0, 'debit': 42}),
]
})
move_payable = self.env['account.move'].create({
'journal_id': journal.id,
'date': record.date_start - timedelta(days=1),
'line_ids': [
(0, 0, {'account_id': acc_payable.id, 'credit': 0, 'debit': 4242}),
(0, 0, {'account_id': acc_revenue.id, 'credit': 4242, 'debit': 0}),
]
})

move_receivable.post()
record.button_generate()

def xaf_val(auditfile, xpath):
return float(''.join(xaf_xpath(auditfile, xpath)))

total_credit = xaf_val(
record.auditfile, '//a:openingBalance/a:totalCredit/text()')
self.assertEqual(total_credit, 42)
total_debit = xaf_val(
record.auditfile, '//a:openingBalance/a:totalDebit/text()')
self.assertEqual(total_debit, 0)
lines_count = xaf_val(
record.auditfile, '//a:openingBalance/a:linesCount/text()')
self.assertEqual(lines_count, 1)

move_payable.post()
record = self.env['xaf.auditfile.export'].create({})
record.button_generate()
total_credit = xaf_val(
record.auditfile, '//a:openingBalance/a:totalCredit/text()')
self.assertEqual(total_credit, 42)
total_debit = xaf_val(
record.auditfile, '//a:openingBalance/a:totalDebit/text()')
self.assertEqual(total_debit, 4242)
lines_count = xaf_val(
record.auditfile, '//a:openingBalance/a:linesCount/text()')
self.assertEqual(lines_count, 2)

0 comments on commit 30dd0e0

Please sign in to comment.