From ff1911367744093203071baa9e2ada0aa29d9c37 Mon Sep 17 00:00:00 2001 From: rtdany10 Date: Thu, 2 Sep 2021 19:52:12 +0530 Subject: [PATCH 01/21] feat: currency exchange settings --- .../currency_exchange_settings/__init__.py | 0 .../currency_exchange_settings.js | 8 ++ .../currency_exchange_settings.json | 86 +++++++++++++++++++ .../currency_exchange_settings.py | 38 ++++++++ .../test_currency_exchange_settings.py | 8 ++ .../__init__.py | 0 .../currency_exchange_settings_details.json | 40 +++++++++ .../currency_exchange_settings_details.py | 8 ++ .../__init__.py | 0 ...rency_exchange_settings_extra_details.json | 39 +++++++++ ...urrency_exchange_settings_extra_details.py | 8 ++ 11 files changed, 235 insertions(+) create mode 100644 erpnext/setup/doctype/currency_exchange_settings/__init__.py create mode 100644 erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js create mode 100644 erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json create mode 100644 erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py create mode 100644 erpnext/setup/doctype/currency_exchange_settings/test_currency_exchange_settings.py create mode 100644 erpnext/setup/doctype/currency_exchange_settings_details/__init__.py create mode 100644 erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json create mode 100644 erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py create mode 100644 erpnext/setup/doctype/currency_exchange_settings_extra_details/__init__.py create mode 100644 erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json create mode 100644 erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.py diff --git a/erpnext/setup/doctype/currency_exchange_settings/__init__.py b/erpnext/setup/doctype/currency_exchange_settings/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js new file mode 100644 index 000000000000..6b0ccb77132a --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -0,0 +1,8 @@ +// Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Currency Exchange Settings', { + // refresh: function(frm) { + + // } +}); diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json new file mode 100644 index 000000000000..b01043727165 --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json @@ -0,0 +1,86 @@ +{ + "actions": [], + "creation": "2021-09-02 14:53:50.923529", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "api_details_section", + "api_endpoint", + "column_break_3", + "result_key", + "section_break_2", + "req_params", + "column_break_4", + "extra_params" + ], + "fields": [ + { + "fieldname": "api_endpoint", + "fieldtype": "Data", + "in_list_view": 1, + "label": "API Endpoint", + "reqd": 1 + }, + { + "fieldname": "section_break_2", + "fieldtype": "Section Break", + "label": "Request Parameters" + }, + { + "fieldname": "column_break_4", + "fieldtype": "Column Break" + }, + { + "fieldname": "req_params", + "fieldtype": "Table", + "label": "Mandatory Parameters", + "options": "Currency Exchange Settings Details", + "reqd": 1 + }, + { + "fieldname": "extra_params", + "fieldtype": "Table", + "label": "Additional Parameters", + "options": "Currency Exchange Settings Extra Details" + }, + { + "fieldname": "api_details_section", + "fieldtype": "Section Break", + "label": "API Details" + }, + { + "fieldname": "column_break_3", + "fieldtype": "Column Break" + }, + { + "fieldname": "result_key", + "fieldtype": "Data", + "label": "Result Key", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "issingle": 1, + "links": [], + "modified": "2021-09-02 15:18:29.198210", + "modified_by": "Administrator", + "module": "Setup", + "name": "Currency Exchange Settings", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py new file mode 100644 index 000000000000..b726d755e45b --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -0,0 +1,38 @@ +# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +import frappe +from frappe import _ +from frappe.model.document import Document + +class CurrencyExchangeSettings(Document): + def validate(self): + if len(self.req_params) != 3: + frappe.throw(_("Make sure all the three mandatory parameters are filled.")) + req_params = { + 'transaction_date': '2021-08-01', + 'from_currency': 'USD', + 'to_currency': 'INR' + } + params = {} + for row in self.req_params: + try: + params[row.key] = req_params[row.value] + req_params.pop(row.value) + except: + frappe.throw(_("Make sure all the three mandatory parameters are filled.")) + import requests + api_url = self.api_endpoint + try: + response = requests.get(api_url, params=params) + except requests.exceptions.RequestException as e: + frappe.throw("Error: " + str(e)) + response.raise_for_status() + value = response.json() + try: + rate = value[str(self.result_key)] + except KeyError: + frappe.throw(_("Invalid result key.")) + if not isinstance(rate, (int, float)): + frappe.throw(_("Returned exchange rate is neither integer not float.")) + frappe.msgprint(_("Exchange rate of USD to INR on 01-08-2021 is ") + str(rate)) diff --git a/erpnext/setup/doctype/currency_exchange_settings/test_currency_exchange_settings.py b/erpnext/setup/doctype/currency_exchange_settings/test_currency_exchange_settings.py new file mode 100644 index 000000000000..80a9a1768d4b --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings/test_currency_exchange_settings.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt + +# import frappe +import unittest + +class TestCurrencyExchangeSettings(unittest.TestCase): + pass diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/__init__.py b/erpnext/setup/doctype/currency_exchange_settings_details/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json new file mode 100644 index 000000000000..9d49daa1eb3d --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json @@ -0,0 +1,40 @@ +{ + "actions": [], + "creation": "2021-09-02 14:54:49.033512", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "key", + "value" + ], + "fields": [ + { + "fieldname": "key", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Key", + "reqd": 1 + }, + { + "fieldname": "value", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Value", + "options": "\ntransaction_date\nfrom_currency\nto_currency", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-09-02 15:24:24.675019", + "modified_by": "Administrator", + "module": "Setup", + "name": "Currency Exchange Settings Details", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py new file mode 100644 index 000000000000..f870b11c5aef --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class CurrencyExchangeSettingsDetails(Document): + pass diff --git a/erpnext/setup/doctype/currency_exchange_settings_extra_details/__init__.py b/erpnext/setup/doctype/currency_exchange_settings_extra_details/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json b/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json new file mode 100644 index 000000000000..fb85bb167d0f --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json @@ -0,0 +1,39 @@ +{ + "actions": [], + "creation": "2021-09-02 15:18:17.888667", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "key", + "value" + ], + "fields": [ + { + "fieldname": "key", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Key", + "reqd": 1 + }, + { + "fieldname": "value", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Value", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-09-02 15:18:17.888667", + "modified_by": "Administrator", + "module": "Setup", + "name": "Currency Exchange Settings Extra Details", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.py b/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.py new file mode 100644 index 000000000000..ee5153309190 --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class CurrencyExchangeSettingsExtraDetails(Document): + pass From e093863c9e41d97a169afb6b58d4a3f33edcb41a Mon Sep 17 00:00:00 2001 From: rtdany10 Date: Fri, 3 Sep 2021 15:03:47 +0530 Subject: [PATCH 02/21] feat: fetch api details from settings --- .../currency_exchange_settings.json | 5 +-- .../currency_exchange_settings.py | 32 +++++++++++++------ .../__init__.py | 0 .../currency_exchange_settings_result.json | 31 ++++++++++++++++++ .../currency_exchange_settings_result.py | 8 +++++ erpnext/setup/utils.py | 30 +++++++++++++---- 6 files changed, 88 insertions(+), 18 deletions(-) create mode 100644 erpnext/setup/doctype/currency_exchange_settings_result/__init__.py create mode 100644 erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json create mode 100644 erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json index b01043727165..a0dfe7350413 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json @@ -55,15 +55,16 @@ }, { "fieldname": "result_key", - "fieldtype": "Data", + "fieldtype": "Table", "label": "Result Key", + "options": "Currency Exchange Settings Result", "reqd": 1 } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2021-09-02 15:18:29.198210", + "modified": "2021-09-03 13:21:16.397695", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings", diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py index b726d755e45b..1993c9bab83d 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -9,10 +9,13 @@ class CurrencyExchangeSettings(Document): def validate(self): if len(self.req_params) != 3: frappe.throw(_("Make sure all the three mandatory parameters are filled.")) - req_params = { - 'transaction_date': '2021-08-01', - 'from_currency': 'USD', - 'to_currency': 'INR' + transaction_date = '2021-08-01' + from_currency = 'USD' + to_currency = 'INR' + req_params={ + "transaction_date": transaction_date, + "from_currency": from_currency, + "to_currency": to_currency } params = {} for row in self.req_params: @@ -21,8 +24,14 @@ def validate(self): req_params.pop(row.value) except: frappe.throw(_("Make sure all the three mandatory parameters are filled.")) + for eparam in self.extra_params: + params[eparam.key] = eparam.value import requests - api_url = self.api_endpoint + api_url = self.api_endpoint.format( + transaction_date=transaction_date, + to_currency=to_currency, + from_currency=from_currency + ) try: response = requests.get(api_url, params=params) except requests.exceptions.RequestException as e: @@ -30,9 +39,14 @@ def validate(self): response.raise_for_status() value = response.json() try: - rate = value[str(self.result_key)] + for key in self.result_key: + value = value[str(key.key).format( + transaction_date=transaction_date, + to_currency=to_currency, + from_currency=from_currency + )] except KeyError: - frappe.throw(_("Invalid result key.")) - if not isinstance(rate, (int, float)): + frappe.throw(_("Invalid result key. Response: ") + response.text) + if not isinstance(value, (int, float)): frappe.throw(_("Returned exchange rate is neither integer not float.")) - frappe.msgprint(_("Exchange rate of USD to INR on 01-08-2021 is ") + str(rate)) + frappe.msgprint(_("Exchange rate of USD to INR on 01-08-2021 is ") + str(value)) diff --git a/erpnext/setup/doctype/currency_exchange_settings_result/__init__.py b/erpnext/setup/doctype/currency_exchange_settings_result/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json b/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json new file mode 100644 index 000000000000..4203b802fd37 --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json @@ -0,0 +1,31 @@ +{ + "actions": [], + "creation": "2021-09-03 13:17:22.088259", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "key" + ], + "fields": [ + { + "fieldname": "key", + "fieldtype": "Data", + "in_list_view": 1, + "label": "Key", + "reqd": 1 + } + ], + "index_web_pages_for_search": 1, + "istable": 1, + "links": [], + "modified": "2021-09-03 13:17:22.088259", + "modified_by": "Administrator", + "module": "Setup", + "name": "Currency Exchange Settings Result", + "owner": "Administrator", + "permissions": [], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py b/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py new file mode 100644 index 000000000000..2c4fb61ab9ce --- /dev/null +++ b/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +from frappe.model.document import Document + +class CurrencyExchangeSettingsResult(Document): + pass diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 409f776a4e02..76e52cdea315 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -98,15 +98,31 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No if not value: import requests - api_url = "https://api.exchangerate.host/convert" - response = requests.get(api_url, params={ - "date": transaction_date, - "from": from_currency, - "to": to_currency - }) + settings = frappe.get_single('Currency Exchange Settings') + req_params={ + "transaction_date": transaction_date, + "from_currency": from_currency, + "to_currency": to_currency + } + params = {} + for row in settings.req_params: + params[row.key] = req_params[row.value] + for eparam in settings.extra_params: + params[eparam.key] = eparam.value + response = requests.get(settings.api_endpoint.format( + transaction_date=transaction_date, + to_currency=to_currency, + from_currency=from_currency + ), params=params) # expire in 6 hours response.raise_for_status() - value = response.json()["result"] + value = response.json() + for res_key in settings.result_key: + value = value[str(res_key.key).format( + transaction_date=transaction_date, + to_currency=to_currency, + from_currency=from_currency + )] cache.setex(name=key, time=21600, value=flt(value)) return flt(value) except Exception: From d8b8032de15c53ec484260f6d72c1f4041adfd68 Mon Sep 17 00:00:00 2001 From: rtdany10 Date: Fri, 3 Sep 2021 15:50:05 +0530 Subject: [PATCH 03/21] feat: init CES default values --- .../currency_exchange_settings.py | 8 ++++---- .../currency_exchange_settings_result.json | 5 +++-- erpnext/setup/install.py | 8 +++++++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py index 1993c9bab83d..92828e60b198 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -7,8 +7,8 @@ class CurrencyExchangeSettings(Document): def validate(self): - if len(self.req_params) != 3: - frappe.throw(_("Make sure all the three mandatory parameters are filled.")) + if len(self.req_params) > 3: + frappe.throw(_("Make sure no mandatory parameters are repeated.")) transaction_date = '2021-08-01' from_currency = 'USD' to_currency = 'INR' @@ -23,7 +23,7 @@ def validate(self): params[row.key] = req_params[row.value] req_params.pop(row.value) except: - frappe.throw(_("Make sure all the three mandatory parameters are filled.")) + frappe.throw(_("Make sure no mandatory parameters are repeated.")) for eparam in self.extra_params: params[eparam.key] = eparam.value import requests @@ -42,7 +42,7 @@ def validate(self): for key in self.result_key: value = value[str(key.key).format( transaction_date=transaction_date, - to_currency=to_currency, + to_currency=to_currency, from_currency=from_currency )] except KeyError: diff --git a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json b/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json index 4203b802fd37..1b2c6238675b 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json +++ b/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json @@ -13,13 +13,14 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Key", - "reqd": 1 + "reqd": 1, + "unique": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-03 13:17:22.088259", + "modified": "2021-09-03 15:41:09.997576", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings Result", diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index bbee74cafb46..239733a48de0 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -57,7 +57,13 @@ def set_single_defaults(): pass except frappe.ValidationError: pass - + ces = frappe.get_single('Currency Exchange Settings') + ces.api_endpoint = "https://api.exchangerate.host/convert" + ces.append('result_key', {'key': 'result'}) + ces.append('req_params', {'key': 'date', 'value': 'transaction_date'}) + ces.append('req_params', {'key': 'from', 'value': 'from_currency'}) + ces.append('req_params', {'key': 'to', 'value': 'to_currency'}) + ces.save() frappe.db.set_default("date_format", "dd-mm-yyyy") From a86d9c91d0661f741bba9f3e051c9888a6207f87 Mon Sep 17 00:00:00 2001 From: rtdany10 Date: Fri, 3 Sep 2021 19:21:06 +0530 Subject: [PATCH 04/21] chore: code clean up --- .../currency_exchange_settings.json | 9 +++++++- .../currency_exchange_settings.py | 13 +++++++---- .../currency_exchange_settings_details.json | 5 ++-- ...rency_exchange_settings_extra_details.json | 5 ++-- erpnext/setup/utils.py | 23 +++++++++---------- 5 files changed, 34 insertions(+), 21 deletions(-) diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json index a0dfe7350413..bd862429ac78 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json @@ -7,6 +7,7 @@ "field_order": [ "api_details_section", "api_endpoint", + "url", "column_break_3", "result_key", "section_break_2", @@ -59,12 +60,18 @@ "label": "Result Key", "options": "Currency Exchange Settings Result", "reqd": 1 + }, + { + "fieldname": "url", + "fieldtype": "Data", + "label": "URL", + "read_only": 1 } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2021-09-03 13:21:16.397695", + "modified": "2021-09-03 19:09:02.741016", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings", diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py index 92828e60b198..1ecb0ffe31a4 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -12,7 +12,7 @@ def validate(self): transaction_date = '2021-08-01' from_currency = 'USD' to_currency = 'INR' - req_params={ + req_params = { "transaction_date": transaction_date, "from_currency": from_currency, "to_currency": to_currency @@ -25,7 +25,11 @@ def validate(self): except: frappe.throw(_("Make sure no mandatory parameters are repeated.")) for eparam in self.extra_params: - params[eparam.key] = eparam.value + params[eparam.key] = eparam.value.format( + transaction_date=transaction_date, + to_currency=to_currency, + from_currency=from_currency + ) import requests api_url = self.api_endpoint.format( transaction_date=transaction_date, @@ -46,7 +50,8 @@ def validate(self): from_currency=from_currency )] except KeyError: - frappe.throw(_("Invalid result key. Response: ") + response.text) + frappe.throw("Invalid result key. Response: " + response.text) if not isinstance(value, (int, float)): frappe.throw(_("Returned exchange rate is neither integer not float.")) - frappe.msgprint(_("Exchange rate of USD to INR on 01-08-2021 is ") + str(value)) + self.url = response.url + frappe.msgprint("Exchange rate of USD to INR on 01-08-2021 is " + str(value)) diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json index 9d49daa1eb3d..dbb886fe6002 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json +++ b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json @@ -14,7 +14,8 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Key", - "reqd": 1 + "reqd": 1, + "unique": 1 }, { "fieldname": "value", @@ -28,7 +29,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-02 15:24:24.675019", + "modified": "2021-09-03 18:50:47.145457", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings Details", diff --git a/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json b/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json index fb85bb167d0f..f21f9cef0be3 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json +++ b/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json @@ -14,7 +14,8 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Key", - "reqd": 1 + "reqd": 1, + "unique": 1 }, { "fieldname": "value", @@ -27,7 +28,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-02 15:18:17.888667", + "modified": "2021-09-03 18:50:28.482851", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings Extra Details", diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index c54f62d09b9e..9146566f6516 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -101,7 +101,7 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No if not value: import requests settings = frappe.get_single('Currency Exchange Settings') - req_params={ + req_params = { "transaction_date": transaction_date, "from_currency": from_currency, "to_currency": to_currency @@ -110,21 +110,13 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No for row in settings.req_params: params[row.key] = req_params[row.value] for eparam in settings.extra_params: - params[eparam.key] = eparam.value - response = requests.get(settings.api_endpoint.format( - transaction_date=transaction_date, - to_currency=to_currency, - from_currency=from_currency - ), params=params) + params[eparam.key] = format_ces_api(eparam.value, req_params) + response = requests.get(format_ces_api(settings.api_endpoint, req_params), params=params) # expire in 6 hours response.raise_for_status() value = response.json() for res_key in settings.result_key: - value = value[str(res_key.key).format( - transaction_date=transaction_date, - to_currency=to_currency, - from_currency=from_currency - )] + value = value[format_ces_api(str(res_key.key), req_params)] cache.setex(name=key, time=21600, value=flt(value)) return flt(value) except Exception: @@ -132,6 +124,13 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}. Please create a Currency Exchange record manually").format(from_currency, to_currency, transaction_date)) return 0.0 +def format_ces_api(data="", param={}): + return data.format( + transaction_date=param["transaction_date"], + to_currency=param["to_currency"], + from_currency=param["from_currency"] + ) + def enable_all_roles_and_domains(): """ enable all roles and domain for testing """ # add all roles to users From 227466c36539f5c6448233e3ea51c72a7367ed30 Mon Sep 17 00:00:00 2001 From: rtdany10 Date: Sat, 4 Sep 2021 14:04:56 +0530 Subject: [PATCH 05/21] chore: clean up layout and code --- .../currency_exchange_settings.json | 22 +++++----- .../currency_exchange_settings.py | 20 ++-------- .../currency_exchange_settings_details.json | 5 +-- .../__init__.py | 0 ...rency_exchange_settings_extra_details.json | 40 ------------------- ...urrency_exchange_settings_extra_details.py | 8 ---- erpnext/setup/install.py | 19 +++++---- erpnext/setup/utils.py | 4 +- 8 files changed, 29 insertions(+), 89 deletions(-) delete mode 100644 erpnext/setup/doctype/currency_exchange_settings_extra_details/__init__.py delete mode 100644 erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json delete mode 100644 erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.py diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json index bd862429ac78..d3d23043c45c 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json @@ -9,11 +9,11 @@ "api_endpoint", "url", "column_break_3", - "result_key", + "help", "section_break_2", "req_params", "column_break_4", - "extra_params" + "result_key" ], "fields": [ { @@ -35,16 +35,10 @@ { "fieldname": "req_params", "fieldtype": "Table", - "label": "Mandatory Parameters", + "label": "Parameters", "options": "Currency Exchange Settings Details", "reqd": 1 }, - { - "fieldname": "extra_params", - "fieldtype": "Table", - "label": "Additional Parameters", - "options": "Currency Exchange Settings Extra Details" - }, { "fieldname": "api_details_section", "fieldtype": "Section Break", @@ -64,14 +58,20 @@ { "fieldname": "url", "fieldtype": "Data", - "label": "URL", + "label": "Example URL", "read_only": 1 + }, + { + "fieldname": "help", + "fieldtype": "HTML", + "label": "Help", + "options": "

Currency Exchange Settings Help

\n

There are 3 variables that could be used within the endpoint, result key and in values of the parameter.

\n

Exchange rate between {from_currency} and {to_currency} on {transaction_date} is fetched by the API.

\n

Example: If your endpoint is exchange.com/2021-08-01, then, you will have to input exchange.com/{transaction_date}

" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2021-09-03 19:09:02.741016", + "modified": "2021-09-04 11:41:34.375637", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings", diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py index 1ecb0ffe31a4..badd14f159ab 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -3,29 +3,17 @@ import frappe from frappe import _ +from frappe.utils import nowdate from frappe.model.document import Document class CurrencyExchangeSettings(Document): def validate(self): - if len(self.req_params) > 3: - frappe.throw(_("Make sure no mandatory parameters are repeated.")) - transaction_date = '2021-08-01' + transaction_date = nowdate() from_currency = 'USD' to_currency = 'INR' - req_params = { - "transaction_date": transaction_date, - "from_currency": from_currency, - "to_currency": to_currency - } params = {} for row in self.req_params: - try: - params[row.key] = req_params[row.value] - req_params.pop(row.value) - except: - frappe.throw(_("Make sure no mandatory parameters are repeated.")) - for eparam in self.extra_params: - params[eparam.key] = eparam.value.format( + params[row.key] = row.value.format( transaction_date=transaction_date, to_currency=to_currency, from_currency=from_currency @@ -54,4 +42,4 @@ def validate(self): if not isinstance(value, (int, float)): frappe.throw(_("Returned exchange rate is neither integer not float.")) self.url = response.url - frappe.msgprint("Exchange rate of USD to INR on 01-08-2021 is " + str(value)) + frappe.msgprint("Exchange rate of USD to INR is " + str(value)) diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json index dbb886fe6002..886d38529efa 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json +++ b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json @@ -19,17 +19,16 @@ }, { "fieldname": "value", - "fieldtype": "Select", + "fieldtype": "Data", "in_list_view": 1, "label": "Value", - "options": "\ntransaction_date\nfrom_currency\nto_currency", "reqd": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-03 18:50:47.145457", + "modified": "2021-09-04 11:24:21.944002", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings Details", diff --git a/erpnext/setup/doctype/currency_exchange_settings_extra_details/__init__.py b/erpnext/setup/doctype/currency_exchange_settings_extra_details/__init__.py deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json b/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json deleted file mode 100644 index f21f9cef0be3..000000000000 --- a/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "actions": [], - "creation": "2021-09-02 15:18:17.888667", - "doctype": "DocType", - "editable_grid": 1, - "engine": "InnoDB", - "field_order": [ - "key", - "value" - ], - "fields": [ - { - "fieldname": "key", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Key", - "reqd": 1, - "unique": 1 - }, - { - "fieldname": "value", - "fieldtype": "Data", - "in_list_view": 1, - "label": "Value", - "reqd": 1 - } - ], - "index_web_pages_for_search": 1, - "istable": 1, - "links": [], - "modified": "2021-09-03 18:50:28.482851", - "modified_by": "Administrator", - "module": "Setup", - "name": "Currency Exchange Settings Extra Details", - "owner": "Administrator", - "permissions": [], - "sort_field": "modified", - "sort_order": "DESC", - "track_changes": 1 -} \ No newline at end of file diff --git a/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.py b/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.py deleted file mode 100644 index ee5153309190..000000000000 --- a/erpnext/setup/doctype/currency_exchange_settings_extra_details/currency_exchange_settings_extra_details.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -# import frappe -from frappe.model.document import Document - -class CurrencyExchangeSettingsExtraDetails(Document): - pass diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index ad4d90003d2b..55be9ee32a19 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -59,15 +59,18 @@ def set_single_defaults(): pass except frappe.ValidationError: pass - ces = frappe.get_single('Currency Exchange Settings') - ces.api_endpoint = "https://api.exchangerate.host/convert" - ces.append('result_key', {'key': 'result'}) - ces.append('req_params', {'key': 'date', 'value': 'transaction_date'}) - ces.append('req_params', {'key': 'from', 'value': 'from_currency'}) - ces.append('req_params', {'key': 'to', 'value': 'to_currency'}) - ces.save() - frappe.db.set_default("date_format", "dd-mm-yyyy") + frappe.db.set_default("date_format", "dd-mm-yyyy") + ces = frappe.get_single('Currency Exchange Settings') + try: + ces.api_endpoint = "https://api.exchangerate.host/convert" + ces.append('result_key', {'key': 'result'}) + ces.append('req_params', {'key': 'date', 'value': '{transaction_date}'}) + ces.append('req_params', {'key': 'from', 'value': '{from_currency}'}) + ces.append('req_params', {'key': 'to', 'value': '{to_currency}'}) + ces.save() + except frappe.ValidationError: + pass def create_compact_item_print_custom_field(): create_custom_field('Print Settings', { diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 9146566f6516..4fcd7d5936f1 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -108,9 +108,7 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No } params = {} for row in settings.req_params: - params[row.key] = req_params[row.value] - for eparam in settings.extra_params: - params[eparam.key] = format_ces_api(eparam.value, req_params) + params[row.key] = format_ces_api(row.value, req_params) response = requests.get(format_ces_api(settings.api_endpoint, req_params), params=params) # expire in 6 hours response.raise_for_status() From 06340ad08ae286cf7c9b63c637d7c47be7eca76b Mon Sep 17 00:00:00 2001 From: rtdany10 Date: Sat, 4 Sep 2021 17:53:51 +0530 Subject: [PATCH 06/21] feat: button to restore default settings --- .../currency_exchange_settings.js | 25 ++++++++++++++++--- .../currency_exchange_settings.py | 2 +- .../currency_exchange_settings_details.json | 5 ++-- .../currency_exchange_settings_result.json | 5 ++-- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js index 6b0ccb77132a..c48bca8b8f69 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -2,7 +2,26 @@ // For license information, please see license.txt frappe.ui.form.on('Currency Exchange Settings', { - // refresh: function(frm) { - - // } + refresh: function(frm) { + frm.add_custom_button(__('Restore Defaults'), function(){ + frm.doc.api_endpoint = "https://api.exchangerate.host/convert"; + frm.clear_table("req_params") + frm.clear_table("result_key") + let params = { + date: '{transaction_date}', + from: '{from_currency}', + to: '{to_currency}' + } + var row; + $.each(params, function(key, value){ + row = frm.add_child("req_params"); + row.key = key; + row.value = value; + }) + row = frm.add_child("result_key"); + row.key = 'result'; + frm.refresh_fields(); + frm.save(); + }); + } }); diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py index badd14f159ab..fa5286a4bbe6 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -37,7 +37,7 @@ def validate(self): to_currency=to_currency, from_currency=from_currency )] - except KeyError: + except Exception: frappe.throw("Invalid result key. Response: " + response.text) if not isinstance(value, (int, float)): frappe.throw(_("Returned exchange rate is neither integer not float.")) diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json index 886d38529efa..c9b27e1961a0 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json +++ b/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json @@ -14,8 +14,7 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Key", - "reqd": 1, - "unique": 1 + "reqd": 1 }, { "fieldname": "value", @@ -28,7 +27,7 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-04 11:24:21.944002", + "modified": "2021-09-04 17:49:17.383982", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings Details", diff --git a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json b/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json index 1b2c6238675b..387e245a2f82 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json +++ b/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json @@ -13,14 +13,13 @@ "fieldtype": "Data", "in_list_view": 1, "label": "Key", - "reqd": 1, - "unique": 1 + "reqd": 1 } ], "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-03 15:41:09.997576", + "modified": "2021-09-04 17:49:33.858070", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange Settings Result", From 7291d9f236a809595add2d90b7f2bfc03bfa2b82 Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Wed, 3 Nov 2021 14:13:22 +0000 Subject: [PATCH 07/21] feat: option for preconfigured selectable service providers --- .../currency_exchange_settings/__init__.py | 0 .../currency_exchange_settings.js | 49 +++++++++++++++++ .../currency_exchange_settings.json | 52 +++++++++++-------- .../currency_exchange_settings.py | 0 .../test_currency_exchange_settings.py | 8 +++ .../__init__.py | 0 .../currency_exchange_settings_details.json | 4 +- .../currency_exchange_settings_details.py | 0 .../__init__.py | 0 .../currency_exchange_settings_result.json | 4 +- .../currency_exchange_settings_result.py | 2 +- .../currency_exchange_settings.js | 27 ---------- .../test_currency_exchange_settings.py | 8 --- 13 files changed, 92 insertions(+), 62 deletions(-) rename erpnext/{setup => accounts}/doctype/currency_exchange_settings/__init__.py (100%) create mode 100644 erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js rename erpnext/{setup => accounts}/doctype/currency_exchange_settings/currency_exchange_settings.json (88%) rename erpnext/{setup => accounts}/doctype/currency_exchange_settings/currency_exchange_settings.py (100%) create mode 100644 erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py rename erpnext/{setup => accounts}/doctype/currency_exchange_settings_details/__init__.py (100%) rename erpnext/{setup => accounts}/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json (91%) rename erpnext/{setup => accounts}/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py (100%) rename erpnext/{setup => accounts}/doctype/currency_exchange_settings_result/__init__.py (100%) rename erpnext/{setup => accounts}/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json (89%) rename erpnext/{setup => accounts}/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py (69%) delete mode 100644 erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js delete mode 100644 erpnext/setup/doctype/currency_exchange_settings/test_currency_exchange_settings.py diff --git a/erpnext/setup/doctype/currency_exchange_settings/__init__.py b/erpnext/accounts/doctype/currency_exchange_settings/__init__.py similarity index 100% rename from erpnext/setup/doctype/currency_exchange_settings/__init__.py rename to erpnext/accounts/doctype/currency_exchange_settings/__init__.py diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js new file mode 100644 index 000000000000..f29183a31622 --- /dev/null +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -0,0 +1,49 @@ +// Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Currency Exchange Settings', { + service_provider: function(frm) { + if (frm.doc.service_provider == "Exchangerate.host"){ + frm.doc.api_endpoint = "https://api.exchangerate.host/convert"; + frm.clear_table("req_params") + frm.clear_table("result_key") + let params = { + date: '{transaction_date}', + from: '{from_currency}', + to: '{to_currency}' + } + var row; + $.each(params, function(key, value){ + row = frm.add_child("req_params"); + row.key = key; + row.value = value; + }) + row = frm.add_child("result_key"); + row.key = 'result'; + frm.refresh_fields(); + frm.save(); + } + else if (frm.doc.service_provider == "Frankfurter.app"){ + frm.doc.api_endpoint = "https://frankfurter.app/{transaction_date}"; + frm.clear_table("req_params") + frm.clear_table("result_key") + var row; + let result = ['rates', '{to_currency}'] + let params = { + base: '{from_currency}', + symbols: '{to_currency}' + } + $.each(params, function(key, value){ + row = frm.add_child("req_params"); + row.key = key; + row.value = value; + }) + $.each(result, function(key, value){ + row = frm.add_child("result_key"); + row.key = value; + }) + frm.refresh_fields(); + frm.save(); + } + } +}); diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json similarity index 88% rename from erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json rename to erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json index d3d23043c45c..a0530c19a303 100644 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.json +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json @@ -6,6 +6,7 @@ "engine": "InnoDB", "field_order": [ "api_details_section", + "service_provider", "api_endpoint", "url", "column_break_3", @@ -16,6 +17,11 @@ "result_key" ], "fields": [ + { + "fieldname": "api_details_section", + "fieldtype": "Section Break", + "label": "API Details" + }, { "fieldname": "api_endpoint", "fieldtype": "Data", @@ -24,14 +30,26 @@ "reqd": 1 }, { - "fieldname": "section_break_2", - "fieldtype": "Section Break", - "label": "Request Parameters" + "fieldname": "url", + "fieldtype": "Data", + "label": "Example URL", + "read_only": 1 }, { - "fieldname": "column_break_4", + "fieldname": "column_break_3", "fieldtype": "Column Break" }, + { + "fieldname": "help", + "fieldtype": "HTML", + "label": "Help", + "options": "

Currency Exchange Settings Help

\n

There are 3 variables that could be used within the endpoint, result key and in values of the parameter.

\n

Exchange rate between {from_currency} and {to_currency} on {transaction_date} is fetched by the API.

\n

Example: If your endpoint is exchange.com/2021-08-01, then, you will have to input exchange.com/{transaction_date}

" + }, + { + "fieldname": "section_break_2", + "fieldtype": "Section Break", + "label": "Request Parameters" + }, { "fieldname": "req_params", "fieldtype": "Table", @@ -40,12 +58,7 @@ "reqd": 1 }, { - "fieldname": "api_details_section", - "fieldtype": "Section Break", - "label": "API Details" - }, - { - "fieldname": "column_break_3", + "fieldname": "column_break_4", "fieldtype": "Column Break" }, { @@ -56,24 +69,19 @@ "reqd": 1 }, { - "fieldname": "url", - "fieldtype": "Data", - "label": "Example URL", - "read_only": 1 - }, - { - "fieldname": "help", - "fieldtype": "HTML", - "label": "Help", - "options": "

Currency Exchange Settings Help

\n

There are 3 variables that could be used within the endpoint, result key and in values of the parameter.

\n

Exchange rate between {from_currency} and {to_currency} on {transaction_date} is fetched by the API.

\n

Example: If your endpoint is exchange.com/2021-08-01, then, you will have to input exchange.com/{transaction_date}

" + "fieldname": "service_provider", + "fieldtype": "Select", + "label": "Service Provider", + "options": "Exchangerate.host\nFrankfurter.app\nCustom", + "reqd": 1 } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2021-09-04 11:41:34.375637", + "modified": "2021-11-03 19:27:27.922353", "modified_by": "Administrator", - "module": "Setup", + "module": "Accounts", "name": "Currency Exchange Settings", "owner": "Administrator", "permissions": [ diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py similarity index 100% rename from erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.py rename to erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py diff --git a/erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py new file mode 100644 index 000000000000..59c579978f44 --- /dev/null +++ b/erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +# import frappe +import unittest + +class TestCurrencyExchangeSettings(unittest.TestCase): + pass diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/__init__.py b/erpnext/accounts/doctype/currency_exchange_settings_details/__init__.py similarity index 100% rename from erpnext/setup/doctype/currency_exchange_settings_details/__init__.py rename to erpnext/accounts/doctype/currency_exchange_settings_details/__init__.py diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json b/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json similarity index 91% rename from erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json rename to erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json index c9b27e1961a0..30935871c66e 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json +++ b/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.json @@ -27,9 +27,9 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-04 17:49:17.383982", + "modified": "2021-11-03 19:14:55.889037", "modified_by": "Administrator", - "module": "Setup", + "module": "Accounts", "name": "Currency Exchange Settings Details", "owner": "Administrator", "permissions": [], diff --git a/erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py b/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py similarity index 100% rename from erpnext/setup/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py rename to erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py diff --git a/erpnext/setup/doctype/currency_exchange_settings_result/__init__.py b/erpnext/accounts/doctype/currency_exchange_settings_result/__init__.py similarity index 100% rename from erpnext/setup/doctype/currency_exchange_settings_result/__init__.py rename to erpnext/accounts/doctype/currency_exchange_settings_result/__init__.py diff --git a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json b/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json similarity index 89% rename from erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json rename to erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json index 387e245a2f82..fff5337616dc 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json +++ b/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.json @@ -19,9 +19,9 @@ "index_web_pages_for_search": 1, "istable": 1, "links": [], - "modified": "2021-09-04 17:49:33.858070", + "modified": "2021-11-03 19:14:40.054245", "modified_by": "Administrator", - "module": "Setup", + "module": "Accounts", "name": "Currency Exchange Settings Result", "owner": "Administrator", "permissions": [], diff --git a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py b/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py similarity index 69% rename from erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py rename to erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py index 2c4fb61ab9ce..49da97bd5e55 100644 --- a/erpnext/setup/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py +++ b/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py @@ -1,4 +1,4 @@ -# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors +# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors # For license information, please see license.txt # import frappe diff --git a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js deleted file mode 100644 index c48bca8b8f69..000000000000 --- a/erpnext/setup/doctype/currency_exchange_settings/currency_exchange_settings.js +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Currency Exchange Settings', { - refresh: function(frm) { - frm.add_custom_button(__('Restore Defaults'), function(){ - frm.doc.api_endpoint = "https://api.exchangerate.host/convert"; - frm.clear_table("req_params") - frm.clear_table("result_key") - let params = { - date: '{transaction_date}', - from: '{from_currency}', - to: '{to_currency}' - } - var row; - $.each(params, function(key, value){ - row = frm.add_child("req_params"); - row.key = key; - row.value = value; - }) - row = frm.add_child("result_key"); - row.key = 'result'; - frm.refresh_fields(); - frm.save(); - }); - } -}); diff --git a/erpnext/setup/doctype/currency_exchange_settings/test_currency_exchange_settings.py b/erpnext/setup/doctype/currency_exchange_settings/test_currency_exchange_settings.py deleted file mode 100644 index 80a9a1768d4b..000000000000 --- a/erpnext/setup/doctype/currency_exchange_settings/test_currency_exchange_settings.py +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt - -# import frappe -import unittest - -class TestCurrencyExchangeSettings(unittest.TestCase): - pass From 08b2735a7928610650a8f7e880cb63f726cdb218 Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Thu, 4 Nov 2021 05:01:37 +0000 Subject: [PATCH 08/21] fix: make fields editable only when service provider is custom --- .../currency_exchange_settings.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json index a0530c19a303..091102ce479b 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json @@ -27,6 +27,7 @@ "fieldtype": "Data", "in_list_view": 1, "label": "API Endpoint", + "read_only_depends_on": "eval: doc.service_provider != \"Custom\"", "reqd": 1 }, { @@ -55,6 +56,7 @@ "fieldtype": "Table", "label": "Parameters", "options": "Currency Exchange Settings Details", + "read_only_depends_on": "eval: doc.service_provider != \"Custom\"", "reqd": 1 }, { @@ -66,6 +68,7 @@ "fieldtype": "Table", "label": "Result Key", "options": "Currency Exchange Settings Result", + "read_only_depends_on": "eval: doc.service_provider != \"Custom\"", "reqd": 1 }, { @@ -79,7 +82,7 @@ "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2021-11-03 19:27:27.922353", + "modified": "2021-11-04 10:27:09.332768", "modified_by": "Administrator", "module": "Accounts", "name": "Currency Exchange Settings", From e65a76b21425918e6b0b0bdcadef6cf431faa503 Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Thu, 4 Nov 2021 05:04:10 +0000 Subject: [PATCH 09/21] chore: clean up --- .../currency_exchange_settings.js | 54 +++++++++---------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js index f29183a31622..58a2b8c7a43c 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -4,46 +4,44 @@ frappe.ui.form.on('Currency Exchange Settings', { service_provider: function(frm) { if (frm.doc.service_provider == "Exchangerate.host"){ - frm.doc.api_endpoint = "https://api.exchangerate.host/convert"; - frm.clear_table("req_params") - frm.clear_table("result_key") + let result = ['result'] let params = { date: '{transaction_date}', from: '{from_currency}', to: '{to_currency}' } - var row; - $.each(params, function(key, value){ - row = frm.add_child("req_params"); - row.key = key; - row.value = value; - }) - row = frm.add_child("result_key"); - row.key = 'result'; - frm.refresh_fields(); - frm.save(); + add_param(frm, "https://api.exchangerate.host/convert", params, result) } else if (frm.doc.service_provider == "Frankfurter.app"){ - frm.doc.api_endpoint = "https://frankfurter.app/{transaction_date}"; - frm.clear_table("req_params") - frm.clear_table("result_key") - var row; let result = ['rates', '{to_currency}'] let params = { base: '{from_currency}', symbols: '{to_currency}' } - $.each(params, function(key, value){ - row = frm.add_child("req_params"); - row.key = key; - row.value = value; - }) - $.each(result, function(key, value){ - row = frm.add_child("result_key"); - row.key = value; - }) - frm.refresh_fields(); - frm.save(); + add_param(frm, "https://frankfurter.app/{transaction_date}", params, result) } } }); + + +function add_param(frm, api, params, result){ + var row; + frm.clear_table("req_params") + frm.clear_table("result_key") + + frm.doc.api_endpoint = api; + + $.each(params, function(key, value){ + row = frm.add_child("req_params"); + row.key = key; + row.value = value; + }); + + $.each(result, function(key, value){ + row = frm.add_child("result_key"); + row.key = value; + }); + + frm.refresh_fields(); + frm.save(); +} From 1f8be8498570d8de0299f0cea5da6a566c39283b Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Thu, 4 Nov 2021 05:12:09 +0000 Subject: [PATCH 10/21] fix : remove mutable data structures from argument defaults --- erpnext/setup/utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 4fcd7d5936f1..c8b4374bac69 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -122,11 +122,11 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}. Please create a Currency Exchange record manually").format(from_currency, to_currency, transaction_date)) return 0.0 -def format_ces_api(data="", param={}): +def format_ces_api(data, param): return data.format( - transaction_date=param["transaction_date"], - to_currency=param["to_currency"], - from_currency=param["from_currency"] + transaction_date=param.get("transaction_date"), + to_currency=param.get("to_currency"), + from_currency=param.get("from_currency") ) def enable_all_roles_and_domains(): From 4a0f2175ad22c2e16f5b5e81e151aca69bfb4c3d Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Thu, 4 Nov 2021 05:25:48 +0000 Subject: [PATCH 11/21] fix: pre-commit issues --- .../currency_exchange_settings/currency_exchange_settings.py | 3 ++- .../test_currency_exchange_settings.py | 1 + .../currency_exchange_settings_details.py | 1 + .../currency_exchange_settings_result.py | 1 + 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py index fa5286a4bbe6..e515542f1d06 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -3,8 +3,9 @@ import frappe from frappe import _ -from frappe.utils import nowdate from frappe.model.document import Document +from frappe.utils import nowdate + class CurrencyExchangeSettings(Document): def validate(self): diff --git a/erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py index 59c579978f44..2778729f5832 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py +++ b/erpnext/accounts/doctype/currency_exchange_settings/test_currency_exchange_settings.py @@ -4,5 +4,6 @@ # import frappe import unittest + class TestCurrencyExchangeSettings(unittest.TestCase): pass diff --git a/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py b/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py index f870b11c5aef..a6ad7634a53e 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py +++ b/erpnext/accounts/doctype/currency_exchange_settings_details/currency_exchange_settings_details.py @@ -4,5 +4,6 @@ # import frappe from frappe.model.document import Document + class CurrencyExchangeSettingsDetails(Document): pass diff --git a/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py b/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py index 49da97bd5e55..177412860aaf 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py +++ b/erpnext/accounts/doctype/currency_exchange_settings_result/currency_exchange_settings_result.py @@ -4,5 +4,6 @@ # import frappe from frappe.model.document import Document + class CurrencyExchangeSettingsResult(Document): pass From 4716523c7768cb62672c06a39ab041f89256f609 Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Thu, 4 Nov 2021 05:38:00 +0000 Subject: [PATCH 12/21] fix: sider issues --- .../currency_exchange_settings.js | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js index 58a2b8c7a43c..22cfc906fb4a 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -3,41 +3,41 @@ frappe.ui.form.on('Currency Exchange Settings', { service_provider: function(frm) { - if (frm.doc.service_provider == "Exchangerate.host"){ - let result = ['result'] - let params = { - date: '{transaction_date}', - from: '{from_currency}', - to: '{to_currency}' - } - add_param(frm, "https://api.exchangerate.host/convert", params, result) - } - else if (frm.doc.service_provider == "Frankfurter.app"){ - let result = ['rates', '{to_currency}'] - let params = { - base: '{from_currency}', - symbols: '{to_currency}' - } - add_param(frm, "https://frankfurter.app/{transaction_date}", params, result) - } + if (frm.doc.service_provider == "Exchangerate.host") { + let result = ['result']; + let params = { + date: '{transaction_date}', + from: '{from_currency}', + to: '{to_currency}' + }; + add_param(frm, "https://api.exchangerate.host/convert", params, result); + } + else if (frm.doc.service_provider == "Frankfurter.app") { + let result = ['rates', '{to_currency}']; + let params = { + base: '{from_currency}', + symbols: '{to_currency}' + }; + add_param(frm, "https://frankfurter.app/{transaction_date}", params, result); + } } }); -function add_param(frm, api, params, result){ +function add_param(frm, api, params, result) { var row; - frm.clear_table("req_params") - frm.clear_table("result_key") + frm.clear_table("req_params"); + frm.clear_table("result_key"); frm.doc.api_endpoint = api; - $.each(params, function(key, value){ + $.each(params, function(key, value) { row = frm.add_child("req_params"); row.key = key; row.value = value; }); - $.each(result, function(key, value){ + $.each(result, function(key, value) { row = frm.add_child("result_key"); row.key = value; }); From e50893e99116b7bf5796ea91ca9459962e5dedb5 Mon Sep 17 00:00:00 2001 From: Dany Robert Date: Sat, 13 Nov 2021 13:12:38 +0530 Subject: [PATCH 13/21] fix: eslint brace style issue --- .../currency_exchange_settings/currency_exchange_settings.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js index 22cfc906fb4a..a3a6561d35dc 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -11,8 +11,7 @@ frappe.ui.form.on('Currency Exchange Settings', { to: '{to_currency}' }; add_param(frm, "https://api.exchangerate.host/convert", params, result); - } - else if (frm.doc.service_provider == "Frankfurter.app") { + } else if (frm.doc.service_provider == "Frankfurter.app") { let result = ['rates', '{to_currency}']; let params = { base: '{from_currency}', From 0faa116f9799f6d921ce8868a8f8eac1756ae008 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Tue, 4 Jan 2022 16:36:08 +0530 Subject: [PATCH 14/21] fix(patch): serial no whitespace trimming old data can contain trailing/leading whitespace which doesn't work well with code to find last SLE for serial no. --- erpnext/patches.txt | 1 + .../v13_0/trim_whitespace_from_serial_nos.py | 61 +++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 erpnext/patches/v13_0/trim_whitespace_from_serial_nos.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 99741eb078eb..c5e4f7e8a9c5 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -279,6 +279,7 @@ erpnext.patches.v13_0.add_custom_field_for_south_africa #2 erpnext.patches.v13_0.update_recipient_email_digest erpnext.patches.v13_0.shopify_deprecation_warning erpnext.patches.v13_0.remove_bad_selling_defaults +erpnext.patches.v13_0.trim_whitespace_from_serial_nos erpnext.patches.v13_0.migrate_stripe_api erpnext.patches.v13_0.reset_clearance_date_for_intracompany_payment_entries erpnext.patches.v13_0.einvoicing_deprecation_warning diff --git a/erpnext/patches/v13_0/trim_whitespace_from_serial_nos.py b/erpnext/patches/v13_0/trim_whitespace_from_serial_nos.py new file mode 100644 index 000000000000..4f112550c513 --- /dev/null +++ b/erpnext/patches/v13_0/trim_whitespace_from_serial_nos.py @@ -0,0 +1,61 @@ +import frappe + +from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos + + +def execute(): + broken_sles = frappe.db.sql(""" + select name, serial_no + from `tabStock Ledger Entry` + where + is_cancelled = 0 + and (serial_no like %s or serial_no like %s or serial_no like %s or serial_no like %s) + """, + ( + " %", # leading whitespace + "% ", # trailing whitespace + "%\n %", # leading whitespace on newline + "% \n%", # trailing whitespace on newline + ), + as_dict=True, + ) + + frappe.db.MAX_WRITES_PER_TRANSACTION += len(broken_sles) + + if not broken_sles: + return + + broken_serial_nos = set() + + for sle in broken_sles: + serial_no_list = get_serial_nos(sle.serial_no) + correct_sr_no = "\n".join(serial_no_list) + + if correct_sr_no == sle.serial_no: + continue + + frappe.db.set_value("Stock Ledger Entry", sle.name, "serial_no", correct_sr_no, update_modified=False) + broken_serial_nos.update(serial_no_list) + + if not broken_serial_nos: + return + + broken_sr_no_records = [sr[0] for sr in frappe.db.sql(""" + select name + from `tabSerial No` + where status='Active' + and coalesce(purchase_document_type, '') = '' + and name in %s """, (list(broken_serial_nos),) + )] + + frappe.db.MAX_WRITES_PER_TRANSACTION += len(broken_sr_no_records) + + patch_savepoint = "serial_no_patch" + for serial_no in broken_sr_no_records: + try: + frappe.db.savepoint(patch_savepoint) + sn = frappe.get_doc("Serial No", serial_no) + sn.update_serial_no_reference() + sn.db_update() + except Exception: + frappe.db.rollback(save_point=patch_savepoint) From cbaa8fdade4aad306887b23cef9bfeaa17ff07c0 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 10 Jan 2022 16:09:43 +0530 Subject: [PATCH 15/21] refactor: convert query to ORM --- .../v13_0/trim_whitespace_from_serial_nos.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/erpnext/patches/v13_0/trim_whitespace_from_serial_nos.py b/erpnext/patches/v13_0/trim_whitespace_from_serial_nos.py index 4f112550c513..8a9633d8964d 100644 --- a/erpnext/patches/v13_0/trim_whitespace_from_serial_nos.py +++ b/erpnext/patches/v13_0/trim_whitespace_from_serial_nos.py @@ -27,6 +27,7 @@ def execute(): broken_serial_nos = set() + # patch SLEs for sle in broken_sles: serial_no_list = get_serial_nos(sle.serial_no) correct_sr_no = "\n".join(serial_no_list) @@ -40,13 +41,16 @@ def execute(): if not broken_serial_nos: return - broken_sr_no_records = [sr[0] for sr in frappe.db.sql(""" - select name - from `tabSerial No` - where status='Active' - and coalesce(purchase_document_type, '') = '' - and name in %s """, (list(broken_serial_nos),) - )] + # Patch serial No documents if they don't have purchase info + # Purchase info is used for fetching incoming rate + broken_sr_no_records = frappe.get_list("Serial No", + filters={ + "status":"Active", + "name": ("in", broken_serial_nos), + "purchase_document_type": ("is", "not set") + }, + pluck="name", + ) frappe.db.MAX_WRITES_PER_TRANSACTION += len(broken_sr_no_records) From e2dab6f421c55f1a8aea1439a83c1fadedae8369 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 10 Jan 2022 17:31:38 +0530 Subject: [PATCH 16/21] fix: Cleanup and fixes --- .../currency_exchange_settings.js | 7 +-- .../currency_exchange_settings.json | 27 ++++++++- .../currency_exchange_settings.py | 59 ++++++++++++++----- erpnext/patches.txt | 3 +- .../v13_0/update_exchange_rate_settings.py | 5 ++ erpnext/setup/install.py | 17 ++++-- erpnext/setup/utils.py | 2 +- 7 files changed, 92 insertions(+), 28 deletions(-) create mode 100644 erpnext/patches/v13_0/update_exchange_rate_settings.py diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js index a3a6561d35dc..6c40f2bec0df 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.js @@ -1,9 +1,9 @@ -// Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors +// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt frappe.ui.form.on('Currency Exchange Settings', { service_provider: function(frm) { - if (frm.doc.service_provider == "Exchangerate.host") { + if (frm.doc.service_provider == "exchangerate.host") { let result = ['result']; let params = { date: '{transaction_date}', @@ -11,7 +11,7 @@ frappe.ui.form.on('Currency Exchange Settings', { to: '{to_currency}' }; add_param(frm, "https://api.exchangerate.host/convert", params, result); - } else if (frm.doc.service_provider == "Frankfurter.app") { + } else if (frm.doc.service_provider == "frankfurter.app") { let result = ['rates', '{to_currency}']; let params = { base: '{from_currency}', @@ -42,5 +42,4 @@ function add_param(frm, api, params, result) { }); frm.refresh_fields(); - frm.save(); } diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json index 091102ce479b..7921fcc2b961 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.json @@ -1,6 +1,6 @@ { "actions": [], - "creation": "2021-09-02 14:53:50.923529", + "creation": "2022-01-10 13:03:26.237081", "doctype": "DocType", "editable_grid": 1, "engine": "InnoDB", @@ -75,14 +75,14 @@ "fieldname": "service_provider", "fieldtype": "Select", "label": "Service Provider", - "options": "Exchangerate.host\nFrankfurter.app\nCustom", + "options": "frankfurter.app\nexchangerate.host\nCustom", "reqd": 1 } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2021-11-04 10:27:09.332768", + "modified": "2022-01-10 15:51:14.521174", "modified_by": "Administrator", "module": "Accounts", "name": "Currency Exchange Settings", @@ -97,9 +97,30 @@ "role": "System Manager", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "Accounts Manager", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "print": 1, + "read": 1, + "role": "Accounts User", + "share": 1, + "write": 1 } ], "sort_field": "modified", "sort_order": "DESC", + "states": [], "track_changes": 1 } \ No newline at end of file diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py index e515542f1d06..c55e28b06cd3 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -1,7 +1,8 @@ -# Copyright (c) 2021, Wahni Green Technologies Pvt. Ltd. and contributors +# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors # For license information, please see license.txt import frappe +import requests from frappe import _ from frappe.model.document import Document from frappe.utils import nowdate @@ -9,38 +10,68 @@ class CurrencyExchangeSettings(Document): def validate(self): - transaction_date = nowdate() - from_currency = 'USD' - to_currency = 'INR' + self.set_parameters_and_result() + response, value = self.validate_parameters() + self.validate_result(response, value) + + def set_parameters_and_result(self): + if self.service_provider == 'exchangerate.host': + self.set('result_key', []) + self.set('req_params', []) + + self.api_endpoint = "https://api.exchangerate.host/convert" + self.append('result_key', {'key': 'result'}) + self.append('req_params', {'key': 'date', 'value': '{transaction_date}'}) + self.append('req_params', {'key': 'from', 'value': '{from_currency}'}) + self.append('req_params', {'key': 'to', 'value': '{to_currency}'}) + elif self.service_provider == 'frankfurter.app': + self.set('result_key', []) + self.set('req_params', []) + + self.api_endpoint = "https://frankfurter.app/{transaction_date}" + self.append('result_key', {'key': 'rates'}) + self.append('result_key', {'key': '{to_currency}'}) + self.append('req_params', {'key': 'base', 'value': '{from_currency}'}) + self.append('req_params', {'key': 'symbols', 'value': '{to_currency}'}) + + def validate_parameters(self): params = {} + for row in self.req_params: params[row.key] = row.value.format( - transaction_date=transaction_date, - to_currency=to_currency, - from_currency=from_currency + transaction_date=nowdate(), + to_currency='INR', + from_currency='USD' ) - import requests + api_url = self.api_endpoint.format( - transaction_date=transaction_date, - to_currency=to_currency, - from_currency=from_currency + transaction_date=nowdate(), + to_currency='INR', + from_currency='USD' ) + try: response = requests.get(api_url, params=params) except requests.exceptions.RequestException as e: frappe.throw("Error: " + str(e)) + response.raise_for_status() value = response.json() + + return response, value + + def validate_result(self, response, value): try: for key in self.result_key: value = value[str(key.key).format( - transaction_date=transaction_date, - to_currency=to_currency, - from_currency=from_currency + transaction_date=nowdate(), + to_currency='INR', + from_currency='USD' )] except Exception: frappe.throw("Invalid result key. Response: " + response.text) if not isinstance(value, (int, float)): frappe.throw(_("Returned exchange rate is neither integer not float.")) + self.url = response.url frappe.msgprint("Exchange rate of USD to INR is " + str(value)) diff --git a/erpnext/patches.txt b/erpnext/patches.txt index d9cedab52acc..7f24273a6c6a 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -317,4 +317,5 @@ erpnext.patches.v14_0.rename_ongoing_status_in_sla_documents erpnext.patches.v14_0.migrate_crm_settings erpnext.patches.v13_0.rename_ksa_qr_field erpnext.patches.v13_0.disable_ksa_print_format_for_others # 16-12-2021 -erpnext.patches.v14_0.add_default_exit_questionnaire_notification_template \ No newline at end of file +erpnext.patches.v14_0.add_default_exit_questionnaire_notification_template +erpnext.patches.v13_0.update_exchange_rate_settings \ No newline at end of file diff --git a/erpnext/patches/v13_0/update_exchange_rate_settings.py b/erpnext/patches/v13_0/update_exchange_rate_settings.py new file mode 100644 index 000000000000..6af93dcba190 --- /dev/null +++ b/erpnext/patches/v13_0/update_exchange_rate_settings.py @@ -0,0 +1,5 @@ +from erpnext.setup.install import setup_currency_exchange + + +def execute(): + setup_currency_exchange() \ No newline at end of file diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index da397763331d..bafaab814b48 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -59,13 +59,20 @@ def set_single_defaults(): pass frappe.db.set_default("date_format", "dd-mm-yyyy") + + setup_currency_exchange() + +def setup_currency_exchange(): ces = frappe.get_single('Currency Exchange Settings') try: - ces.api_endpoint = "https://api.exchangerate.host/convert" - ces.append('result_key', {'key': 'result'}) - ces.append('req_params', {'key': 'date', 'value': '{transaction_date}'}) - ces.append('req_params', {'key': 'from', 'value': '{from_currency}'}) - ces.append('req_params', {'key': 'to', 'value': '{to_currency}'}) + ces.set('result_key', []) + ces.set('req_params', []) + + ces.api_endpoint = "https://frankfurter.app/{transaction_date}" + ces.append('result_key', {'key': 'rates'}) + ces.append('result_key', {'key': '{to_currency}'}) + ces.append('req_params', {'key': 'base', 'value': '{from_currency}'}) + ces.append('req_params', {'key': 'symbols', 'value': '{to_currency}'}) ces.save() except frappe.ValidationError: pass diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index bfa26f29d984..4441bb956279 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -100,7 +100,7 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No if not value: import requests - settings = frappe.get_single('Currency Exchange Settings') + settings = frappe.get_cached_doc('Currency Exchange Settings') req_params = { "transaction_date": transaction_date, "from_currency": from_currency, From 2d76c05175bf324da4ea24e1542a7dcb7d52c178 Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sun, 9 Jan 2022 18:41:33 +0530 Subject: [PATCH 17/21] refactor: unnecessary joining of lists --- erpnext/accounts/report/general_ledger/general_ledger.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 385c8b2b6ed8..7303bf5ef8c2 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -547,10 +547,7 @@ def get_columns(filters): "fieldname": "balance", "fieldtype": "Float", "width": 130 - } - ] - - columns.extend([ + }, { "label": _("Voucher Type"), "fieldname": "voucher_type", @@ -584,7 +581,7 @@ def get_columns(filters): "fieldname": "project", "width": 100 } - ]) + ] if filters.get("include_dimensions"): for dim in get_accounting_dimensions(as_list = False): From f195f803ff3226450cd1c0b739e4ef34114a6ffb Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Sun, 9 Jan 2022 19:23:27 +0530 Subject: [PATCH 18/21] test: account reports --- erpnext/accounts/test/test_reports.py | 48 +++++++++++++++++++++++++++ erpnext/tests/utils.py | 14 +++++--- 2 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 erpnext/accounts/test/test_reports.py diff --git a/erpnext/accounts/test/test_reports.py b/erpnext/accounts/test/test_reports.py new file mode 100644 index 000000000000..78c109ab9476 --- /dev/null +++ b/erpnext/accounts/test/test_reports.py @@ -0,0 +1,48 @@ +import unittest +from typing import List, Tuple + +from erpnext.tests.utils import ReportFilters, ReportName, execute_script_report + +DEFAULT_FILTERS = { + "company": "_Test Company", + "from_date": "2010-01-01", + "to_date": "2030-01-01", + "period_start_date": "2010-01-01", + "period_end_date": "2030-01-01" +} + + +REPORT_FILTER_TEST_CASES: List[Tuple[ReportName, ReportFilters]] = [ + ("General Ledger", {"group_by": "Group by Voucher (Consolidated)"} ), + ("General Ledger", {"group_by": "Group by Voucher (Consolidated)", "include_dimensions": 1} ), + ("Accounts Payable", {"range1": 30, "range2": 60, "range3": 90, "range4": 120}), + ("Accounts Receivable", {"range1": 30, "range2": 60, "range3": 90, "range4": 120}), + ("Consolidated Financial Statement", {"report": "Balance Sheet"} ), + ("Consolidated Financial Statement", {"report": "Profit and Loss Statement"} ), + ("Consolidated Financial Statement", {"report": "Cash Flow"} ), + ("Gross Profit", {"group_by": "Invoice"}), + ("Gross Profit", {"group_by": "Item Code"}), + ("Gross Profit", {"group_by": "Item Group"}), + ("Gross Profit", {"group_by": "Customer"}), + ("Gross Profit", {"group_by": "Customer Group"}), + ("Item-wise Sales Register", {}), + ("Item-wise Purchase Register", {}), + ("Sales Register", {}), + ("Purchase Register", {}), + ("Tax Detail", {"mode": "run", "report_name": "Tax Detail"},), +] + +OPTIONAL_FILTERS = {} + + +class TestReports(unittest.TestCase): + def test_execute_all_accounts_reports(self): + """Test that all script report in stock modules are executable with supported filters""" + for report, filter in REPORT_FILTER_TEST_CASES: + execute_script_report( + report_name=report, + module="Accounts", + filters=filter, + default_filters=DEFAULT_FILTERS, + optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None, + ) diff --git a/erpnext/tests/utils.py b/erpnext/tests/utils.py index fbf25948a79f..bc9f04e0892f 100644 --- a/erpnext/tests/utils.py +++ b/erpnext/tests/utils.py @@ -125,17 +125,23 @@ def execute_script_report( if default_filters is None: default_filters = {} + test_filters = [] report_execute_fn = frappe.get_attr(get_report_module_dotted_path(module, report_name) + ".execute") report_filters = frappe._dict(default_filters).copy().update(filters) - report_data = report_execute_fn(report_filters) + test_filters.append(report_filters) if optional_filters: for key, value in optional_filters.items(): - filter_with_optional_param = report_filters.copy().update({key: value}) - report_execute_fn(filter_with_optional_param) + test_filters.append(report_filters.copy().update({key: value})) + + for test_filter in test_filters: + try: + report_execute_fn(test_filter) + except Exception: + print(f"Report failed to execute with filters: {test_filter}") + raise - return report_data def timeout(seconds=30, error_message="Test timed out."): From ca5ea5f55faec323f3d0612de6fe25fe98965921 Mon Sep 17 00:00:00 2001 From: Deepesh Garg Date: Mon, 10 Jan 2022 21:28:29 +0530 Subject: [PATCH 19/21] fix: test cases --- .../currency_exchange_settings.py | 7 +++- .../v13_0/update_exchange_rate_settings.py | 5 +++ .../test_currency_exchange.py | 42 ++++++++++++++++++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py index c55e28b06cd3..e16ff3aa7eb2 100644 --- a/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py +++ b/erpnext/accounts/doctype/currency_exchange_settings/currency_exchange_settings.py @@ -35,8 +35,10 @@ def set_parameters_and_result(self): self.append('req_params', {'key': 'symbols', 'value': '{to_currency}'}) def validate_parameters(self): - params = {} + if frappe.flags.in_test: + return None, None + params = {} for row in self.req_params: params[row.key] = row.value.format( transaction_date=nowdate(), @@ -61,6 +63,9 @@ def validate_parameters(self): return response, value def validate_result(self, response, value): + if frappe.flags.in_test: + return + try: for key in self.result_key: value = value[str(key.key).format( diff --git a/erpnext/patches/v13_0/update_exchange_rate_settings.py b/erpnext/patches/v13_0/update_exchange_rate_settings.py index 6af93dcba190..b7ec232bbae7 100644 --- a/erpnext/patches/v13_0/update_exchange_rate_settings.py +++ b/erpnext/patches/v13_0/update_exchange_rate_settings.py @@ -1,5 +1,10 @@ +import frappe + from erpnext.setup.install import setup_currency_exchange def execute(): + frappe.reload_doc("accounts", "doctype", "currency_exchange_settings") + frappe.reload_doc("accounts", "doctype", "currency_exchange_settings_result") + frappe.reload_doc("accounts", "doctype", "currency_exchange_settings_details") setup_currency_exchange() \ No newline at end of file diff --git a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py index 2b007e9efd56..06a79b4102ca 100644 --- a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py +++ b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py @@ -62,8 +62,13 @@ def json(self): if kwargs['params'].get('date') and kwargs['params'].get('from') and kwargs['params'].get('to'): if test_exchange_values.get(kwargs['params']['date']): return PatchResponse({'result': test_exchange_values[kwargs['params']['date']]}, 200) + elif args[0].startswith("https://frankfurter.app") and kwargs.get('params'): + if kwargs['params'].get('base') and kwargs['params'].get('symbols'): + date = args[0].replace("https://frankfurter.app/", "") + if test_exchange_values.get(date): + return PatchResponse({'rates': {kwargs['params'].get('symbols'): test_exchange_values.get(date)}}, 200) - return PatchResponse({'result': None}, 404) + return PatchResponse({'rates': None}, 404) @mock.patch('requests.get', side_effect=patched_requests_get) class TestCurrencyExchange(unittest.TestCase): @@ -102,6 +107,41 @@ def test_exchange_rate(self, mock_get): self.assertFalse(exchange_rate == 60) self.assertEqual(flt(exchange_rate, 3), 65.1) + def test_exchange_rate_via_exchangerate_host(self, mock_get): + save_new_records(test_records) + + # Update Currency Exchange Rate + settings = frappe.get_single("Currency Exchange Settings") + settings.service_provider = 'exchangerate.host' + settings.save() + + # Update exchange + frappe.db.set_value("Accounts Settings", None, "allow_stale", 1) + + # Start with allow_stale is True + exchange_rate = get_exchange_rate("USD", "INR", "2016-01-01", "for_buying") + self.assertEqual(flt(exchange_rate, 3), 60.0) + + exchange_rate = get_exchange_rate("USD", "INR", "2016-01-15", "for_buying") + self.assertEqual(exchange_rate, 65.1) + + exchange_rate = get_exchange_rate("USD", "INR", "2016-01-30", "for_selling") + self.assertEqual(exchange_rate, 62.9) + + # Exchange rate as on 15th Dec, 2015 + self.clear_cache() + exchange_rate = get_exchange_rate("USD", "INR", "2015-12-15", "for_selling") + self.assertFalse(exchange_rate == 60) + self.assertEqual(flt(exchange_rate, 3), 66.999) + + exchange_rate = get_exchange_rate("USD", "INR", "2016-01-20", "for_buying") + self.assertFalse(exchange_rate == 60) + self.assertEqual(flt(exchange_rate, 3), 65.1) + + settings = frappe.get_single("Currency Exchange Settings") + settings.service_provider = 'frankfurter.app' + settings.save() + def test_exchange_rate_strict(self, mock_get): # strict currency settings frappe.db.set_value("Accounts Settings", None, "allow_stale", 0) From c62083653b528fa5d3b93fbbe35d4a6a2c475bec Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 11 Jan 2022 12:45:40 +0530 Subject: [PATCH 20/21] fix(gl-report): group by cost center only if include_dimensions is checked (#28883) --- .../report/general_ledger/general_ledger.js | 2 +- .../report/general_ledger/general_ledger.py | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/erpnext/accounts/report/general_ledger/general_ledger.js b/erpnext/accounts/report/general_ledger/general_ledger.js index b2968761c630..010284c2ea55 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.js +++ b/erpnext/accounts/report/general_ledger/general_ledger.js @@ -167,7 +167,7 @@ frappe.query_reports["General Ledger"] = { "fieldname": "include_dimensions", "label": __("Consider Accounting Dimensions"), "fieldtype": "Check", - "default": 0 + "default": 1 }, { "fieldname": "show_opening_entries", diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 7303bf5ef8c2..7f2792054779 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -448,9 +448,11 @@ def update_value_in_dict(data, key, gle): elif group_by_voucher_consolidated: keylist = [gle.get("voucher_type"), gle.get("voucher_no"), gle.get("account")] - for dim in accounting_dimensions: - keylist.append(gle.get(dim)) - keylist.append(gle.get("cost_center")) + if filters.get("include_dimensions"): + for dim in accounting_dimensions: + keylist.append(gle.get(dim)) + keylist.append(gle.get("cost_center")) + key = tuple(keylist) if key not in consolidated_gle: consolidated_gle.setdefault(key, gle) @@ -591,14 +593,14 @@ def get_columns(filters): "fieldname": dim.fieldname, "width": 100 }) - - columns.extend([ - { + columns.append({ "label": _("Cost Center"), "options": "Cost Center", "fieldname": "cost_center", "width": 100 - }, + }) + + columns.extend([ { "label": _("Against Voucher Type"), "fieldname": "against_voucher_type", From 75c8b2556e2282f15bf0bc44f9bec3afad146215 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 11 Jan 2022 13:25:42 +0530 Subject: [PATCH 21/21] fix(pos): cannot ignore pricing rule for one particular invoice (#29222) --- .../doctype/pos_invoice/pos_invoice.py | 1 - .../doctype/pos_invoice/test_pos_invoice.py | 31 +++++++++++++++++++ .../doctype/pricing_rule/test_pricing_rule.py | 4 ++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py index 11d59bcf7082..134bccf3d1a6 100644 --- a/erpnext/accounts/doctype/pos_invoice/pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/pos_invoice.py @@ -353,7 +353,6 @@ def set_pos_fields(self, for_validate=False): if not for_validate and not self.customer: self.customer = profile.customer - self.ignore_pricing_rule = profile.ignore_pricing_rule self.account_for_change_amount = profile.get('account_for_change_amount') or self.account_for_change_amount self.set_warehouse = profile.get('warehouse') or self.set_warehouse diff --git a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py index 7d31e0aa1953..56479a0b77d3 100644 --- a/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py +++ b/erpnext/accounts/doctype/pos_invoice/test_pos_invoice.py @@ -556,6 +556,37 @@ def test_pos_batch_item_qty_validation(self): batch.cancel() batch.delete() + def test_ignore_pricing_rule(self): + from erpnext.accounts.doctype.pricing_rule.test_pricing_rule import make_pricing_rule + + item_price = frappe.get_doc({ + 'doctype': 'Item Price', + 'item_code': '_Test Item', + 'price_list': '_Test Price List', + 'price_list_rate': '450', + }) + item_price.insert() + pr = make_pricing_rule(selling=1, priority=5, discount_percentage=10) + pr.save() + pos_inv = create_pos_invoice(qty=1, do_not_submit=1) + pos_inv.items[0].rate = 300 + pos_inv.save() + self.assertEquals(pos_inv.items[0].discount_percentage, 10) + # rate shouldn't change + self.assertEquals(pos_inv.items[0].rate, 405) + + pos_inv.ignore_pricing_rule = 1 + pos_inv.items[0].rate = 300 + pos_inv.save() + self.assertEquals(pos_inv.ignore_pricing_rule, 1) + # rate should change since pricing rules are ignored + self.assertEquals(pos_inv.items[0].rate, 300) + + item_price.delete() + pos_inv.delete() + pr.delete() + + def create_pos_invoice(**args): args = frappe._dict(args) pos_profile = None diff --git a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py index 314c89424b8c..5746a840f304 100644 --- a/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py +++ b/erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py @@ -650,7 +650,7 @@ def make_pricing_rule(**args): "rate": args.rate or 0.0, "margin_rate_or_amount": args.margin_rate_or_amount or 0.0, "condition": args.condition or '', - "priority": 1, + "priority": args.priority or 1, "discount_amount": args.discount_amount or 0.0, "apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0 }) @@ -676,6 +676,8 @@ def make_pricing_rule(**args): if args.get(applicable_for): doc.db_set(applicable_for, args.get(applicable_for)) + return doc + def setup_pricing_rule_data(): if not frappe.db.exists('Campaign', '_Test Campaign'): frappe.get_doc({