Merge pull request #49712 from diptanilsaha/consolidated_tb

feat: consolidated trial balance report
This commit is contained in:
Diptanil Saha
2025-10-07 22:23:19 +05:30
committed by GitHub
9 changed files with 813 additions and 20 deletions

View File

@@ -0,0 +1 @@
{% include "accounts/report/financial_statements.html" %}

View File

@@ -0,0 +1,101 @@
// Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.query_reports["Consolidated Trial Balance"] = {
filters: [
{
fieldname: "company",
label: __("Company"),
fieldtype: "MultiSelectList",
options: "Company",
get_data: function (txt) {
return frappe.db.get_link_options("Company", txt);
},
reqd: 1,
},
{
fieldname: "fiscal_year",
label: __("Fiscal Year"),
fieldtype: "Link",
options: "Fiscal Year",
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today()),
reqd: 1,
on_change: function (query_report) {
var fiscal_year = query_report.get_values().fiscal_year;
if (!fiscal_year) {
return;
}
frappe.model.with_doc("Fiscal Year", fiscal_year, function (r) {
var fy = frappe.model.get_doc("Fiscal Year", fiscal_year);
frappe.query_report.set_filter_value({
from_date: fy.year_start_date,
to_date: fy.year_end_date,
});
});
},
},
{
fieldname: "from_date",
label: __("From Date"),
fieldtype: "Date",
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
},
{
fieldname: "to_date",
label: __("To Date"),
fieldtype: "Date",
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
},
{
fieldname: "finance_book",
label: __("Finance Book"),
fieldtype: "Link",
options: "Finance Book",
},
{
fieldname: "presentation_currency",
label: __("Currency"),
fieldtype: "Select",
options: erpnext.get_presentation_currency_list(),
},
{
fieldname: "with_period_closing_entry_for_opening",
label: __("With Period Closing Entry For Opening Balances"),
fieldtype: "Check",
default: 1,
},
{
fieldname: "with_period_closing_entry_for_current_period",
label: __("Period Closing Entry For Current Period"),
fieldtype: "Check",
default: 1,
},
{
fieldname: "show_zero_values",
label: __("Show zero values"),
fieldtype: "Check",
},
{
fieldname: "show_unclosed_fy_pl_balances",
label: __("Show unclosed fiscal year's P&L balances"),
fieldtype: "Check",
},
{
fieldname: "include_default_book_entries",
label: __("Include Default FB Entries"),
fieldtype: "Check",
default: 1,
},
{
fieldname: "show_group_accounts",
label: __("Show Group Accounts"),
fieldtype: "Check",
default: 1,
},
],
formatter: erpnext.financial_statements.formatter,
tree: true,
name_field: "account",
parent_field: "parent_account",
initial_depth: 3,
};

View File

@@ -0,0 +1,34 @@
{
"add_total_row": 0,
"add_translate_data": 0,
"columns": [],
"creation": "2025-09-03 00:53:22.230646",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 0,
"is_standard": "Yes",
"letterhead": null,
"modified": "2025-09-03 00:53:22.230646",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Consolidated Trial Balance",
"owner": "Administrator",
"prepared_report": 0,
"ref_doctype": "GL Entry",
"report_name": "Consolidated Trial Balance",
"report_type": "Script Report",
"roles": [
{
"role": "Accounts User"
},
{
"role": "Accounts Manager"
},
{
"role": "Auditor"
}
],
"timeout": 0
}

View File

@@ -0,0 +1,469 @@
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import frappe
from frappe import _
from frappe.utils import flt, getdate, now_datetime, nowdate
import erpnext
from erpnext.accounts.doctype.account.account import get_root_company
from erpnext.accounts.report.financial_statements import (
filter_accounts,
filter_out_zero_value_rows,
set_gl_entries_by_account,
)
from erpnext.accounts.report.trial_balance.trial_balance import (
accumulate_values_into_parents,
calculate_values,
get_opening_balances,
hide_group_accounts,
prepare_opening_closing,
value_fields,
)
from erpnext.accounts.report.trial_balance.trial_balance import (
validate_filters as tb_validate_filters,
)
from erpnext.accounts.report.utils import get_rate_as_at
from erpnext.accounts.utils import get_zero_cutoff
from erpnext.setup.utils import get_exchange_rate
def execute(filters: dict | None = None):
"""Return columns and data for the report.
This is the main entry point for the report. It accepts the filters as a
dictionary and should return columns and data. It is called by the framework
every time the report is refreshed or a filter is updated.
"""
validate_filters(filters=filters)
columns = get_columns()
data = get_data(filters)
return columns, data
def validate_filters(filters):
validate_companies(filters)
filters.show_net_values = True
tb_validate_filters(filters)
def validate_companies(filters):
if not filters.company:
return
root_company = get_root_company(filters.company[0])
root_company = root_company[0] if root_company else filters.company[0]
lft, rgt = frappe.db.get_value("Company", root_company, fieldname=["lft", "rgt"])
company_subtree = frappe.db.get_all(
"Company",
{"lft": [">=", lft], "rgt": ["<=", rgt]},
"name",
order_by="lft",
pluck="name",
)
for company in filters.company:
if company not in company_subtree:
frappe.throw(
_("Consolidated Trial Balance can be generated for Companies having same root Company.")
)
sort_companies(filters)
def sort_companies(filters):
companies = frappe.db.get_all(
"Company", {"name": ["in", filters.company]}, "name", order_by="lft", pluck="name"
)
filters.company = companies
def get_data(filters) -> list[list]:
"""Return data for the report.
The report data is a list of rows, with each row being a list of cell values.
"""
data = []
if filters.company:
reporting_currency, ignore_reporting_currency = get_reporting_currency(filters)
else:
return data
for company in filters.company:
company_filter = frappe._dict(filters)
company_filter.company = company
tb_data = get_company_wise_tb_data(company_filter, reporting_currency, ignore_reporting_currency)
consolidate_trial_balance_data(data, tb_data)
for d in data:
prepare_opening_closing(d)
total_row = calculate_total_row(data, reporting_currency)
data.extend([{}, total_row])
if not filters.get("show_group_accounts"):
data = hide_group_accounts(data)
if filters.get("presentation_currency"):
update_to_presentation_currency(
data,
reporting_currency,
filters.get("presentation_currency"),
filters.get("to_date"),
ignore_reporting_currency,
)
return data
def get_company_wise_tb_data(filters, reporting_currency, ignore_reporting_currency):
accounts = frappe.db.sql(
"""select name, account_number, parent_account, account_name, root_type, report_type, account_type, is_group, lft, rgt
from `tabAccount` where company=%s order by lft""",
filters.company,
as_dict=True,
)
ignore_is_opening = frappe.get_single_value("Accounts Settings", "ignore_is_opening_check_for_reporting")
default_currency = erpnext.get_company_currency(filters.company)
opening_exchange_rate = get_exchange_rate(
default_currency,
reporting_currency,
filters.get("from_date"),
)
current_date = (
filters.get("to_date") if getdate(filters.get("to_date")) <= now_datetime().date() else nowdate()
)
closing_exchange_rate = get_exchange_rate(
default_currency,
reporting_currency,
current_date,
)
if not (opening_exchange_rate and closing_exchange_rate):
frappe.throw(
_(
"Consolidated Trial balance could not be generated as Exchange Rate from {0} to {1} is not available for {2}.",
).format(default_currency, reporting_currency, current_date)
)
if not accounts:
return []
accounts, accounts_by_name, parent_children_map = filter_accounts(accounts)
gl_entries_by_account = {}
opening_balances = get_opening_balances(
filters,
ignore_is_opening,
exchange_rate=opening_exchange_rate,
ignore_reporting_currency=ignore_reporting_currency,
)
set_gl_entries_by_account(
filters.company,
filters.from_date,
filters.to_date,
filters,
gl_entries_by_account,
root_lft=None,
root_rgt=None,
ignore_closing_entries=not flt(filters.with_period_closing_entry_for_current_period),
ignore_opening_entries=True,
group_by_account=True,
ignore_reporting_currency=ignore_reporting_currency,
)
calculate_values(
accounts,
gl_entries_by_account,
opening_balances,
filters.get("show_net_values"),
ignore_is_opening=ignore_is_opening,
exchange_rate=closing_exchange_rate,
ignore_reporting_currency=ignore_reporting_currency,
)
accumulate_values_into_parents(accounts, accounts_by_name)
data = prepare_companywise_tb_data(accounts, filters, parent_children_map, reporting_currency)
data = filter_out_zero_value_rows(
data, parent_children_map, show_zero_values=filters.get("show_zero_values")
)
return data
def prepare_companywise_tb_data(accounts, filters, parent_children_map, reporting_currency):
data = []
for d in accounts:
# Prepare opening closing for group account
if parent_children_map.get(d.account) and filters.get("show_net_values"):
prepare_opening_closing(d)
has_value = False
row = {
"account": d.name,
"parent_account": d.parent_account,
"indent": d.indent,
"from_date": filters.from_date,
"to_date": filters.to_date,
"currency": reporting_currency,
"is_group_account": d.is_group,
"acc_name": d.account_name,
"acc_number": d.account_number,
"account_name": (
f"{d.account_number} - {d.account_name}" if d.account_number else d.account_name
),
"root_type": d.root_type,
"account_type": d.account_type,
}
for key in value_fields:
row[key] = flt(d.get(key, 0.0), 3)
if abs(row[key]) >= get_zero_cutoff(reporting_currency):
# ignore zero values
has_value = True
row["has_value"] = has_value
data.append(row)
return data
def calculate_total_row(data, reporting_currency):
total_row = {
"account": "'" + _("Total") + "'",
"account_name": "'" + _("Total") + "'",
"warn_if_negative": True,
"opening_debit": 0.0,
"opening_credit": 0.0,
"debit": 0.0,
"credit": 0.0,
"closing_debit": 0.0,
"closing_credit": 0.0,
"parent_account": None,
"indent": 0,
"has_value": True,
"currency": reporting_currency,
}
for d in data:
if not d.get("parent_account"):
for field in value_fields:
total_row[field] += d[field]
calculate_foreign_currency_translation_reserve(total_row, data)
return total_row
def calculate_foreign_currency_translation_reserve(total_row, data):
opening_dr_cr_diff = total_row["opening_debit"] - total_row["opening_credit"]
dr_cr_diff = total_row["debit"] - total_row["credit"]
idx = get_fctr_root_row_index(data)
fctr_row = {
"account": _("Foreign Currency Translation Reserve"),
"account_name": _("Foreign Currency Translation Reserve"),
"warn_if_negative": True,
"opening_debit": abs(opening_dr_cr_diff) if opening_dr_cr_diff < 0 else 0.0,
"opening_credit": abs(opening_dr_cr_diff) if opening_dr_cr_diff > 0 else 0.0,
"debit": abs(dr_cr_diff) if dr_cr_diff < 0 else 0.0,
"credit": abs(dr_cr_diff) if dr_cr_diff > 0 else 0.0,
"closing_debit": 0.0,
"closing_credit": 0.0,
"root_type": data[idx].get("root_type"),
"account_type": "Equity",
"parent_account": data[idx].get("account"),
"indent": data[idx].get("indent") + 1,
"has_value": True,
"currency": total_row.get("currency"),
}
fctr_row["closing_debit"] = fctr_row["opening_debit"] + fctr_row["debit"]
fctr_row["closing_credit"] = fctr_row["opening_credit"] + fctr_row["credit"]
prepare_opening_closing(fctr_row)
data.insert(idx + 1, fctr_row)
for field in value_fields:
total_row[field] += fctr_row[field]
def get_fctr_root_row_index(data):
"""
Returns: index, root_type, parent_account
"""
liabilities_idx, equity_idx, tmp_idx = -1, -1, 0
for d in data:
if liabilities_idx == -1 and d.get("root_type") == "Liability":
liabilities_idx = tmp_idx
if equity_idx == -1 and d.get("root_type") == "Equity":
equity_idx = tmp_idx
tmp_idx += 1
if equity_idx == -1:
return liabilities_idx
return equity_idx
def consolidate_trial_balance_data(data, tb_data):
if not data:
data.extend(list(tb_data))
return
for entry in tb_data:
if entry:
consolidate_gle_data(data, entry, tb_data)
def get_reporting_currency(filters):
reporting_currency = frappe.get_cached_value("Company", filters.company[0], "reporting_currency")
default_currency = None
for company in filters.company:
company_default_currency = erpnext.get_company_currency(company)
if not default_currency:
default_currency = company_default_currency
if company_default_currency != default_currency:
return (reporting_currency, False)
return (default_currency, True)
def consolidate_gle_data(data, entry, tb_data):
entry_gle_exists = False
for gle in data:
if gle and gle["account_name"] == entry["account_name"]:
entry_gle_exists = True
gle["closing_credit"] += entry["closing_credit"]
gle["closing_debit"] += entry["closing_debit"]
gle["credit"] += entry["credit"]
gle["debit"] += entry["debit"]
gle["opening_credit"] += entry["opening_credit"]
gle["opening_debit"] += entry["opening_debit"]
gle["has_value"] = 1
if not entry_gle_exists:
entry_parent_account = next(
(d for d in tb_data if d.get("account") == entry.get("parent_account")), None
)
parent_account_in_data = None
if entry_parent_account:
parent_account_in_data = next(
(d for d in data if d and d.get("account_name") == entry_parent_account.get("account_name")),
None,
)
if parent_account_in_data:
entry["parent_account"] = parent_account_in_data.get("account")
entry["indent"] = (parent_account_in_data.get("indent") or 0) + 1
data.insert(data.index(parent_account_in_data) + 1, entry)
else:
entry["parent_account"] = None
entry["indent"] = 0
data.append(entry)
def update_to_presentation_currency(data, from_currency, to_currency, date, ignore_reporting_currency):
if from_currency == to_currency:
return
exchange_rate = get_rate_as_at(date, from_currency, to_currency)
for d in data:
if not ignore_reporting_currency:
for field in value_fields:
if d.get(field):
d[field] = d[field] * flt(exchange_rate)
d.update(currency=to_currency)
def get_columns():
return [
{
"fieldname": "account_name",
"label": _("Account"),
"fieldtype": "Data",
"width": 300,
},
{
"fieldname": "acc_name",
"label": _("Account Name"),
"fieldtype": "Data",
"hidden": 1,
"width": 250,
},
{
"fieldname": "acc_number",
"label": _("Account Number"),
"fieldtype": "Data",
"hidden": 1,
"width": 120,
},
{
"fieldname": "currency",
"label": _("Currency"),
"fieldtype": "Link",
"options": "Currency",
"hidden": 1,
},
{
"fieldname": "opening_debit",
"label": _("Opening (Dr)"),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"fieldname": "opening_credit",
"label": _("Opening (Cr)"),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"fieldname": "debit",
"label": _("Debit"),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"fieldname": "credit",
"label": _("Credit"),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"fieldname": "closing_debit",
"label": _("Closing (Dr)"),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"fieldname": "closing_credit",
"label": _("Closing (Cr)"),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
]

View File

@@ -0,0 +1,123 @@
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
import frappe
from frappe import _
from frappe.tests import IntegrationTestCase
from frappe.utils import flt, today
from erpnext.accounts.report.consolidated_trial_balance.consolidated_trial_balance import execute
from erpnext.setup.utils import get_exchange_rate
class ForeignCurrencyTranslationReserveNotFoundError(frappe.ValidationError):
pass
class TestConsolidatedTrialBalance(IntegrationTestCase):
@classmethod
def setUpClass(cls):
from erpnext.accounts.report.trial_balance.test_trial_balance import create_company
from erpnext.accounts.utils import get_fiscal_year
# Group Company
create_company(company_name="Parent Group Company India", is_group=1)
create_company(company_name="Child Company India", parent_company="Parent Group Company India")
# Child Company with different currency
create_company(
company_name="Child Company US",
country="United States",
currency="USD",
parent_company="Parent Group Company India",
)
create_journal_entry(
company="Parent Group Company India",
acc1="Marketing Expenses - PGCI",
acc2="Cash - PGCI",
amount=100000,
)
create_journal_entry(
company="Child Company India", acc1="Cash - CCI", acc2="Secured Loans - CCI", amount=50000
)
create_journal_entry(
company="Child Company US", acc1="Marketing Expenses - CCU", acc2="Cash - CCU", amount=1000
)
cls.fiscal_year = get_fiscal_year(today(), company="Parent Group Company India")[0]
def test_single_company_report(self):
filters = frappe._dict({"company": ["Parent Group Company India"], "fiscal_year": self.fiscal_year})
report = execute(filters)
total_row = report[1][-1]
self.assertEqual(total_row["closing_debit"], total_row["closing_credit"])
self.assertEqual(total_row["closing_credit"], 100000)
def test_child_company_report_with_same_default_currency_as_parent_company(self):
filters = frappe._dict(
{
"company": ["Parent Group Company India", "Child Company India"],
"fiscal_year": self.fiscal_year,
}
)
report = execute(filters)
total_row = report[1][-1]
self.assertEqual(total_row["closing_debit"], total_row["closing_credit"])
def test_child_company_with_different_default_currency_from_parent_company(self):
filters = frappe._dict(
{
"company": ["Parent Group Company India", "Child Company US"],
"fiscal_year": self.fiscal_year,
}
)
report = execute(filters)
total_row = report[1][-1]
exchange_rate = get_exchange_rate("USD", "INR")
fctr = [d for d in report[1] if d.get("account") == _("Foreign Currency Translation Reserve")]
if not fctr:
raise ForeignCurrencyTranslationReserveNotFoundError
ccu_total_credit = 1000 * flt(exchange_rate)
self.assertEqual(total_row["closing_debit"], total_row["closing_credit"])
self.assertNotEqual(total_row["closing_credit"], ccu_total_credit)
self.assertEqual(total_row["closing_credit"], flt(100000 + ccu_total_credit))
def create_journal_entry(**args):
args = frappe._dict(args)
je = frappe.new_doc("Journal Entry")
je.posting_date = args.posting_date or today()
je.company = args.company
je.set(
"accounts",
[
{
"account": args.acc1,
"debit_in_account_currency": args.amount if args.amount > 0 else 0,
"credit_in_account_currency": abs(args.amount) if args.amount < 0 else 0,
},
{
"account": args.acc2,
"credit_in_account_currency": args.amount if args.amount > 0 else 0,
"debit_in_account_currency": abs(args.amount) if args.amount < 0 else 0,
},
],
)
je.save()
je.submit()

View File

@@ -443,6 +443,7 @@ def set_gl_entries_by_account(
ignore_closing_entries=False,
ignore_opening_entries=False,
group_by_account=False,
ignore_reporting_currency=True,
):
"""Returns a dict like { "account": [gl entries], ... }"""
gl_entries = []
@@ -473,6 +474,7 @@ def set_gl_entries_by_account(
ignore_closing_entries,
last_period_closing_voucher[0].name,
group_by_account=group_by_account,
ignore_reporting_currency=ignore_reporting_currency,
)
from_date = add_days(last_period_closing_voucher[0].period_end_date, 1)
ignore_opening_entries = True
@@ -488,9 +490,10 @@ def set_gl_entries_by_account(
ignore_closing_entries,
ignore_opening_entries=ignore_opening_entries,
group_by_account=group_by_account,
ignore_reporting_currency=ignore_reporting_currency,
)
if filters and filters.get("presentation_currency"):
if filters and filters.get("presentation_currency") and ignore_reporting_currency:
convert_to_presentation_currency(gl_entries, get_currency(filters))
for entry in gl_entries:
@@ -511,6 +514,7 @@ def get_accounting_entries(
period_closing_voucher=None,
ignore_opening_entries=False,
group_by_account=False,
ignore_reporting_currency=True,
):
gl_entry = frappe.qb.DocType(doctype)
query = (
@@ -530,6 +534,16 @@ def get_accounting_entries(
.where(gl_entry.company == filters.company)
)
if not ignore_reporting_currency:
query = query.select(
gl_entry.debit_in_reporting_currency
if not group_by_account
else Sum(gl_entry.debit_in_reporting_currency).as_("debit_in_reporting_currency"),
gl_entry.credit_in_reporting_currency
if not group_by_account
else Sum(gl_entry.credit_in_reporting_currency).as_("credit_in_reporting_currency"),
)
ignore_is_opening = frappe.get_single_value("Accounts Settings", "ignore_is_opening_check_for_reporting")
if doctype == "GL Entry":

View File

@@ -75,6 +75,8 @@ def create_company(**args):
"company_name": args.company_name or "Trial Balance Company",
"country": args.country or "India",
"default_currency": args.currency or "INR",
"parent_company": args.get("parent_company"),
"is_group": args.get("is_group"),
}
)
company.insert(ignore_if_duplicate=True)

View File

@@ -135,15 +135,21 @@ def get_data(filters):
return data
def get_opening_balances(filters, ignore_is_opening):
balance_sheet_opening = get_rootwise_opening_balances(filters, "Balance Sheet", ignore_is_opening)
pl_opening = get_rootwise_opening_balances(filters, "Profit and Loss", ignore_is_opening)
def get_opening_balances(filters, ignore_is_opening, exchange_rate=None, ignore_reporting_currency=True):
balance_sheet_opening = get_rootwise_opening_balances(
filters, "Balance Sheet", ignore_is_opening, exchange_rate, ignore_reporting_currency
)
pl_opening = get_rootwise_opening_balances(
filters, "Profit and Loss", ignore_is_opening, exchange_rate, ignore_reporting_currency
)
balance_sheet_opening.update(pl_opening)
return balance_sheet_opening
def get_rootwise_opening_balances(filters, report_type, ignore_is_opening):
def get_rootwise_opening_balances(
filters, report_type, ignore_is_opening, exchange_rate=None, ignore_reporting_currency=True
):
gle = []
last_period_closing_voucher = ""
@@ -168,6 +174,7 @@ def get_rootwise_opening_balances(filters, report_type, ignore_is_opening):
accounting_dimensions,
period_closing_voucher=last_period_closing_voucher[0].name,
ignore_is_opening=ignore_is_opening,
ignore_reporting_currency=ignore_reporting_currency,
)
# Report getting generate from the mid of a fiscal year
@@ -180,24 +187,41 @@ def get_rootwise_opening_balances(filters, report_type, ignore_is_opening):
accounting_dimensions,
start_date=start_date,
ignore_is_opening=ignore_is_opening,
ignore_reporting_currency=ignore_reporting_currency,
)
else:
gle = get_opening_balance(
"GL Entry", filters, report_type, accounting_dimensions, ignore_is_opening=ignore_is_opening
"GL Entry",
filters,
report_type,
accounting_dimensions,
ignore_is_opening=ignore_is_opening,
ignore_reporting_currency=ignore_reporting_currency,
)
opening = frappe._dict()
for d in gle:
opening.setdefault(
d.account,
{
"account": d.account,
"opening_debit": 0.0,
"opening_credit": 0.0,
},
)
opening[d.account]["opening_debit"] += flt(d.debit)
opening[d.account]["opening_credit"] += flt(d.credit)
opening_dr_cr = {
"account": d.account,
"opening_debit": 0.0,
"opening_credit": 0.0,
}
opening.setdefault(d.account, opening_dr_cr)
if ignore_reporting_currency:
opening[d.account]["opening_debit"] += flt(d.debit)
opening[d.account]["opening_credit"] += flt(d.credit)
else:
if d.get("report_type") == "Balance Sheet" and not (
d.get("root_type") == "Equity" or d.get("account_type") == "Equity"
):
opening[d.account]["opening_debit"] += flt(d.debit) * flt(exchange_rate)
opening[d.account]["opening_credit"] += flt(d.credit) * flt(exchange_rate)
else:
opening[d.account]["opening_debit"] += flt(d.debit_in_reporting_currency)
opening[d.account]["opening_credit"] += flt(d.credit_in_reporting_currency)
return opening
@@ -210,6 +234,7 @@ def get_opening_balance(
period_closing_voucher=None,
start_date=None,
ignore_is_opening=0,
ignore_reporting_currency=True,
):
closing_balance = frappe.qb.DocType(doctype)
accounts = frappe.db.get_all("Account", filters={"report_type": report_type}, pluck="name")
@@ -228,6 +253,12 @@ def get_opening_balance(
.groupby(closing_balance.account)
)
if not ignore_reporting_currency:
opening_balance = opening_balance.select(
Sum(closing_balance.debit_in_reporting_currency).as_("debit_in_reporting_currency"),
Sum(closing_balance.credit_in_reporting_currency).as_("credit_in_reporting_currency"),
)
if period_closing_voucher:
opening_balance = opening_balance.where(
closing_balance.period_closing_voucher == period_closing_voucher
@@ -315,13 +346,21 @@ def get_opening_balance(
gle = opening_balance.run(as_dict=1)
if filters and filters.get("presentation_currency"):
if filters and filters.get("presentation_currency") and ignore_reporting_currency:
convert_to_presentation_currency(gle, get_currency(filters))
return gle
def calculate_values(accounts, gl_entries_by_account, opening_balances, show_net_values, ignore_is_opening=0):
def calculate_values(
accounts,
gl_entries_by_account,
opening_balances,
show_net_values,
ignore_is_opening=0,
exchange_rate=None,
ignore_reporting_currency=True,
):
init = {
"opening_debit": 0.0,
"opening_credit": 0.0,
@@ -340,8 +379,18 @@ def calculate_values(accounts, gl_entries_by_account, opening_balances, show_net
for entry in gl_entries_by_account.get(d.name, []):
if cstr(entry.is_opening) != "Yes" or ignore_is_opening:
d["debit"] += flt(entry.debit)
d["credit"] += flt(entry.credit)
if ignore_reporting_currency:
d["debit"] += flt(entry.debit)
d["credit"] += flt(entry.credit)
else:
if d.report_type == "Balance Sheet" and not (
d.root_type == "Equity" or d.account_type == "Equity"
):
d["debit"] += flt(entry.debit) * flt(exchange_rate)
d["credit"] += flt(entry.credit) * flt(exchange_rate)
else:
d["debit"] += flt(entry.debit_in_reporting_currency)
d["credit"] += flt(entry.credit_in_reporting_currency)
d["closing_debit"] = d["opening_debit"] + d["debit"]
d["closing_credit"] = d["opening_credit"] + d["credit"]