From 2bfe846b3022418b1f9b73354f6730022d18b3ad Mon Sep 17 00:00:00 2001 From: tundebabzy Date: Tue, 23 Jan 2018 15:52:12 +0100 Subject: [PATCH] move new functions from `general_ledger.py` to new module --- .../accounts/report/financial_statements.py | 2 +- .../report/general_ledger/general_ledger.py | 124 +----------------- erpnext/accounts/report/utils.py | 124 ++++++++++++++++++ 3 files changed, 127 insertions(+), 123 deletions(-) create mode 100644 erpnext/accounts/report/utils.py diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 14b94a732a1..1f9f5450db6 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe import re -from erpnext.accounts.report.general_ledger.general_ledger import convert_to_presentation_currency, get_currency +from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency from frappe import _ from frappe.utils import (flt, getdate, get_first_day, get_last_day, date_diff, add_months, add_days, formatdate, cint) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index e8133f4ae6b..4d41b23985d 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -4,17 +4,11 @@ from __future__ import unicode_literals import frappe from erpnext import get_company_currency, get_default_company -from erpnext.setup.utils import get_exchange_rate -from frappe.utils import getdate, cstr, flt, cint, nowdate +from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency +from frappe.utils import getdate, cstr, flt from frappe import _, _dict from erpnext.accounts.utils import get_account_currency -__exchange_rates = {} - -P_OR_L_ACCOUNTS = list( - sum(frappe.get_list('Account', fields=['account_name'], or_filters=[{'root_type': 'Income'}, {'root_type': 'Expense'}], as_list=True), ()) -) - def get_appropriate_company(filters): if filters.get('company'): @@ -136,120 +130,6 @@ def get_result(filters, account_details): return result -def get_currency(filters): - """ - Returns a dictionary containing currency information. The keys of the dict are - - company: The company for which we are fetching currency information. if no - company is specified, it will fallback to the default company. - - company currency: The functional currency of the said company. - - presentation currency: The presentation currency to use. Only currencies that - have been used for transactions will be allowed. - - report date: The report date. - :param filters: Report filters - :type filters: dict - - :return: str - Currency - """ - company = get_appropriate_company(filters) - company_currency = get_company_currency(company) - presentation_currency = filters['presentation_currency'] if filters.get('presentation_currency') else company_currency - report_date = filters.get('to_date') or filters.get('to_fiscal_year') - - currency_map = dict(company=company, company_currency=company_currency, presentation_currency=presentation_currency, report_date=report_date) - - return currency_map - - -def convert(value, from_, to, date): - """ - convert `value` from `from_` to `to` on `date` - :param value: Amount to be converted - :param from_: Currency of `value` - :param to: Currency to convert to - :param date: exchange rate as at this date - :return: Result of converting `value` - """ - rate = get_rate_as_at(date, from_, to) - converted_value = value / (rate or 1) - return converted_value - - -def get_rate_as_at(date, from_currency, to_currency): - """ - Gets exchange rate as at `date` for `from_currency` - `to_currency` exchange rate. - This calls `get_exchange_rate` so that we can get the correct exchange rate as per - the user's Accounts Settings. - It is made efficient by memoising results to `__exchange_rates` - :param date: exchange rate as at this date - :param from_currency: Base currency - :param to_currency: Quote currency - :return: Retrieved exchange rate - """ - rate = __exchange_rates.get('{0}-{1}@{2}'.format(from_currency, to_currency, date)) - if not rate: - rate = get_exchange_rate(from_currency, to_currency, date) or 1 - __exchange_rates['{0}-{1}@{2}'.format(from_currency, to_currency, date)] = rate - - return rate - - -def is_p_or_l_account(account_name): - """ - Check if the given `account_name` is an `Account` with `root_type` of either 'Income' - or 'Expense'. - :param account_name: - :return: Boolean - """ - # Remove company abbreviation part - abbr_start = account_name.rfind('-') - account_name = account_name[:abbr_start].strip() - - return account_name in P_OR_L_ACCOUNTS - - -def convert_to_presentation_currency(gl_entries, currency_info): - """ - Take a list of GL Entries and change the 'debit' and 'credit' values to currencies - in `currency_info`. - :param gl_entries: - :param currency_info: - :return: - """ - converted_gl_list = [] - presentation_currency = currency_info['presentation_currency'] - company_currency = currency_info['company_currency'] - - for entry in gl_entries: - account = entry['account'] - debit = cint(entry['debit']) - credit = cint(entry['credit']) - debit_in_account_currency = cint(entry['debit_in_account_currency']) - credit_in_account_currency = cint(entry['credit_in_account_currency']) - account_currency = entry['account_currency'] - - if account_currency != presentation_currency or (account_currency == presentation_currency and not is_p_or_l_account(account)): - value = debit or credit - - date = currency_info['report_date'] if not is_p_or_l_account(account) else entry['posting_date'] - - converted_value = convert(value, presentation_currency, company_currency, date) - - if entry.get('debit'): - entry['debit'] = converted_value - else: - entry['credit'] = converted_value - - elif account_currency == presentation_currency: - if entry.get('debit'): - entry['debit'] = debit_in_account_currency - else: - entry['credit'] = credit_in_account_currency - - converted_gl_list.append(entry) - - return converted_gl_list - - def get_gl_entries(filters): currency_map = get_currency(filters) select_fields = """, sum(debit_in_account_currency) as debit_in_account_currency, diff --git a/erpnext/accounts/report/utils.py b/erpnext/accounts/report/utils.py new file mode 100644 index 00000000000..610bb13a68e --- /dev/null +++ b/erpnext/accounts/report/utils.py @@ -0,0 +1,124 @@ +import frappe +from erpnext import get_company_currency +from erpnext.accounts.report.general_ledger.general_ledger import get_appropriate_company +from erpnext.setup.utils import get_exchange_rate +from frappe.utils import cint + +__exchange_rates = {} +P_OR_L_ACCOUNTS = list( + sum(frappe.get_list('Account', fields=['account_name'], or_filters=[{'root_type': 'Income'}, {'root_type': 'Expense'}], as_list=True), ()) +) + + +def get_currency(filters): + """ + Returns a dictionary containing currency information. The keys of the dict are + - company: The company for which we are fetching currency information. if no + company is specified, it will fallback to the default company. + - company currency: The functional currency of the said company. + - presentation currency: The presentation currency to use. Only currencies that + have been used for transactions will be allowed. + - report date: The report date. + :param filters: Report filters + :type filters: dict + + :return: str - Currency + """ + company = get_appropriate_company(filters) + company_currency = get_company_currency(company) + presentation_currency = filters['presentation_currency'] if filters.get('presentation_currency') else company_currency + report_date = filters.get('to_date') or filters.get('to_fiscal_year') + + currency_map = dict(company=company, company_currency=company_currency, presentation_currency=presentation_currency, report_date=report_date) + + return currency_map + + +def convert(value, from_, to, date): + """ + convert `value` from `from_` to `to` on `date` + :param value: Amount to be converted + :param from_: Currency of `value` + :param to: Currency to convert to + :param date: exchange rate as at this date + :return: Result of converting `value` + """ + rate = get_rate_as_at(date, from_, to) + converted_value = value / (rate or 1) + return converted_value + + +def get_rate_as_at(date, from_currency, to_currency): + """ + Gets exchange rate as at `date` for `from_currency` - `to_currency` exchange rate. + This calls `get_exchange_rate` so that we can get the correct exchange rate as per + the user's Accounts Settings. + It is made efficient by memoising results to `__exchange_rates` + :param date: exchange rate as at this date + :param from_currency: Base currency + :param to_currency: Quote currency + :return: Retrieved exchange rate + """ + rate = __exchange_rates.get('{0}-{1}@{2}'.format(from_currency, to_currency, date)) + if not rate: + rate = get_exchange_rate(from_currency, to_currency, date) or 1 + __exchange_rates['{0}-{1}@{2}'.format(from_currency, to_currency, date)] = rate + + return rate + + +def is_p_or_l_account(account_name): + """ + Check if the given `account_name` is an `Account` with `root_type` of either 'Income' + or 'Expense'. + :param account_name: + :return: Boolean + """ + # Remove company abbreviation part + abbr_start = account_name.rfind('-') + account_name = account_name[:abbr_start].strip() + + return account_name in P_OR_L_ACCOUNTS + + +def convert_to_presentation_currency(gl_entries, currency_info): + """ + Take a list of GL Entries and change the 'debit' and 'credit' values to currencies + in `currency_info`. + :param gl_entries: + :param currency_info: + :return: + """ + converted_gl_list = [] + presentation_currency = currency_info['presentation_currency'] + company_currency = currency_info['company_currency'] + + for entry in gl_entries: + account = entry['account'] + debit = cint(entry['debit']) + credit = cint(entry['credit']) + debit_in_account_currency = cint(entry['debit_in_account_currency']) + credit_in_account_currency = cint(entry['credit_in_account_currency']) + account_currency = entry['account_currency'] + + if account_currency != presentation_currency or (account_currency == presentation_currency and not is_p_or_l_account(account)): + value = debit or credit + + date = currency_info['report_date'] if not is_p_or_l_account(account) else entry['posting_date'] + + converted_value = convert(value, presentation_currency, company_currency, date) + + if entry.get('debit'): + entry['debit'] = converted_value + else: + entry['credit'] = converted_value + + elif account_currency == presentation_currency: + if entry.get('debit'): + entry['debit'] = debit_in_account_currency + else: + entry['credit'] = credit_in_account_currency + + converted_gl_list.append(entry) + + return converted_gl_list \ No newline at end of file