From 288a18e0cc74a58fdd2f109b8b9f8b04a516c1d1 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 8 Dec 2016 15:36:23 +0530 Subject: [PATCH] Fixes and patch for Currency Exchange based on date --- erpnext/controllers/accounts_controller.py | 8 +-- erpnext/manufacturing/doctype/bom/bom.py | 4 +- erpnext/patches.txt | 3 +- .../v7_1/set_currency_exchange_date.py | 9 ++++ erpnext/public/js/controllers/transaction.js | 10 ++-- .../currency_exchange/currency_exchange.json | 10 +--- .../test_currency_exchange.py | 17 +++++- .../currency_exchange/test_records.json | 6 +-- erpnext/setup/utils.py | 12 ++--- .../material_request_item.json | 52 ++++++++++++++++++- 10 files changed, 98 insertions(+), 33 deletions(-) create mode 100644 erpnext/patches/v7_1/set_currency_exchange_date.py diff --git a/erpnext/controllers/accounts_controller.py b/erpnext/controllers/accounts_controller.py index f726db819b..fb3333006e 100644 --- a/erpnext/controllers/accounts_controller.py +++ b/erpnext/controllers/accounts_controller.py @@ -128,9 +128,9 @@ class AccountsController(TransactionBase): def set_price_list_currency(self, buying_or_selling): if self.meta.get_field("posting_date"): - translation_date = self.posting_date + transaction_date = self.posting_date else: - translation_date = self.transaction_date + transaction_date = self.transaction_date if self.meta.get_field("currency"): # price list part @@ -144,7 +144,7 @@ class AccountsController(TransactionBase): self.plc_conversion_rate = 1.0 elif not self.plc_conversion_rate: - self.plc_conversion_rate = get_exchange_rate(translation_date, + self.plc_conversion_rate = get_exchange_rate(transaction_date, self.price_list_currency, self.company_currency) # currency @@ -154,7 +154,7 @@ class AccountsController(TransactionBase): elif self.currency == self.company_currency: self.conversion_rate = 1.0 elif not self.conversion_rate: - self.conversion_rate = get_exchange_rate(translation_date, self.currency, + self.conversion_rate = get_exchange_rate(transaction_date, self.currency, self.company_currency) def set_missing_item_details(self, for_validate=False): diff --git a/erpnext/manufacturing/doctype/bom/bom.py b/erpnext/manufacturing/doctype/bom/bom.py index 2a27922c7f..783df20d97 100644 --- a/erpnext/manufacturing/doctype/bom/bom.py +++ b/erpnext/manufacturing/doctype/bom/bom.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals import frappe -from frappe.utils import cint, cstr, flt +from frappe.utils import cint, cstr, flt, nowdate from frappe import _ from erpnext.setup.utils import get_exchange_rate from frappe.model.document import Document @@ -229,7 +229,7 @@ class BOM(Document): frappe.throw(_("Currency of the price list {0} is not similar with the selected currency {1}").format(self.buying_price_list, self.currency)) def set_conversion_rate(self): - self.conversion_rate = get_exchange_rate(self.currency, self.company_currency()) + self.conversion_rate = get_exchange_rate(nowdate(), self.currency, self.company_currency()) def validate_materials(self): """ Validate raw material entries """ diff --git a/erpnext/patches.txt b/erpnext/patches.txt index c4b66e7a12..94212ec62e 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -354,4 +354,5 @@ erpnext.patches.v7_1.rename_quality_inspection_field erpnext.patches.v7_0.update_autoname_field erpnext.patches.v7_1.update_bom_base_currency erpnext.patches.v7_0.update_status_of_po_so -erpnext.patches.v7_1.set_budget_against_as_cost_center \ No newline at end of file +erpnext.patches.v7_1.set_budget_against_as_cost_center +erpnext.patches.v7_1.set_currency_exchange_date \ No newline at end of file diff --git a/erpnext/patches/v7_1/set_currency_exchange_date.py b/erpnext/patches/v7_1/set_currency_exchange_date.py new file mode 100644 index 0000000000..7d8e4f0415 --- /dev/null +++ b/erpnext/patches/v7_1/set_currency_exchange_date.py @@ -0,0 +1,9 @@ +import frappe + +def execute(): + frappe.reload_doctype("Currency Exchange") + frappe.db.sql(""" + update `tabCurrency Exchange` + set `date` = '2010-01-01' + where date is null or date = '' or date = '0000-00-00' + """) \ No newline at end of file diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js index b82f142812..c31b0c84a8 100644 --- a/erpnext/public/js/controllers/transaction.js +++ b/erpnext/public/js/controllers/transaction.js @@ -413,7 +413,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ transaction_date: function() { if (this.frm.doc.transaction_date) { this.frm.transaction_date = this.frm.doc.transaction_date; - frappe.ui.form.trigger(me.frm.doc.doctype, "currency"); + frappe.ui.form.trigger(this.frm.doc.doctype, "currency"); } }, @@ -455,7 +455,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ currency: function() { /* manqala 19/09/2016: let the translation date be whichever of the transaction_date or posting_date is available */ - translation_date = this.frm.doc.transaction_date || this.frm.doc.posting_date; + var transaction_date = this.frm.doc.transaction_date || this.frm.doc.posting_date; /* end manqala */ var me = this; @@ -465,7 +465,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ // Added `ignore_pricing_rule` to determine if document is loading after mapping from another doc if(this.frm.doc.currency && this.frm.doc.currency !== company_currency && !this.frm.doc.ignore_pricing_rule) { - this.get_exchange_rate(translation_date, this.frm.doc.currency, company_currency, + this.get_exchange_rate(transaction_date, this.frm.doc.currency, company_currency, function(exchange_rate) { me.frm.set_value("conversion_rate", exchange_rate); }); @@ -493,11 +493,11 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({ } }, - get_exchange_rate: function(translation_date, from_currency, to_currency, callback) { + get_exchange_rate: function(transaction_date, from_currency, to_currency, callback) { return frappe.call({ method: "erpnext.setup.utils.get_exchange_rate", args: { - translation_date: translation_date, + transaction_date: transaction_date, from_currency: from_currency, to_currency: to_currency }, diff --git a/erpnext/setup/doctype/currency_exchange/currency_exchange.json b/erpnext/setup/doctype/currency_exchange/currency_exchange.json index 56e914a691..76e1a6b97e 100644 --- a/erpnext/setup/doctype/currency_exchange/currency_exchange.json +++ b/erpnext/setup/doctype/currency_exchange/currency_exchange.json @@ -79,12 +79,8 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, -<<<<<<< HEAD "in_list_view": 1, "in_standard_filter": 1, -======= - "in_list_view": 0, ->>>>>>> 4a0c8400762adb857c8e929d3af56ba83d8c3f76 "label": "To Currency", "length": 0, "no_copy": 0, @@ -142,11 +138,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, -<<<<<<< HEAD - "modified": "2016-11-07 05:28:09.772560", -======= - "modified": "2016-09-05 22:47:38.746711", ->>>>>>> 4a0c8400762adb857c8e929d3af56ba83d8c3f76 + "modified": "2016-11-08 05:28:09.772560", "modified_by": "Administrator", "module": "Setup", "name": "Currency Exchange", diff --git a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py index 00776307de..69ca1c2a10 100644 --- a/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py +++ b/erpnext/setup/doctype/currency_exchange/test_currency_exchange.py @@ -3,5 +3,18 @@ from __future__ import unicode_literals -import frappe -test_records = frappe.get_test_records('Currency Exchange') \ No newline at end of file +import frappe, unittest +test_records = frappe.get_test_records('Currency Exchange') + +class TestCurrencyExchange(unittest.TestCase): + def test_exchnage_rate(self): + from erpnext.setup.utils import get_exchange_rate + + # Exchange rate as on 15th Jan, 2016, should be fetched from Currency Exchange record + exchange_rate = get_exchange_rate("2016-01-15", "USD", "INR") + self.assertEqual(exchange_rate, 60.0) + + # Exchange rate as on 15th Dec, 2015, should be fetched from fixer.io + exchange_rate = get_exchange_rate("2015-12-15", "USD", "INR") + self.assertFalse(exchange_rate==60) + \ No newline at end of file diff --git a/erpnext/setup/doctype/currency_exchange/test_records.json b/erpnext/setup/doctype/currency_exchange/test_records.json index 17ca1a5f24..23edd8a799 100644 --- a/erpnext/setup/doctype/currency_exchange/test_records.json +++ b/erpnext/setup/doctype/currency_exchange/test_records.json @@ -1,21 +1,21 @@ [ { "doctype": "Currency Exchange", - "date": "01-01-2016", + "date": "2016-01-01", "exchange_rate": 60.0, "from_currency": "USD", "to_currency": "INR" }, { "doctype": "Currency Exchange", - "date": "01-01-2016", + "date": "2016-01-01", "exchange_rate": 0.773, "from_currency": "USD", "to_currency": "EUR" }, { "doctype": "Currency Exchange", - "date": "01-01-2016", + "date": "2016-01-01", "exchange_rate": 0.0167, "from_currency": "INR", "to_currency": "USD" diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 3adca5671e..9a8ae07113 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -65,22 +65,22 @@ def before_tests(): frappe.db.commit() @frappe.whitelist() -def get_exchange_rate(translation_date, from_currency, to_currency): - if not (translation_date and from_currency and to_currency): +def get_exchange_rate(transaction_date, from_currency, to_currency): + if not (transaction_date and from_currency and to_currency): # manqala 19/09/2016: Should this be an empty return or should it throw and exception? return if from_currency == to_currency: return 1 - # cksgb 19/09/2016: get all entries in Currency Exchange with from_currency and to_currency. Order by date desc. Top one is the required exchange rate + # cksgb 19/09/2016: get last entry in Currency Exchange with from_currency and to_currency. entries = frappe.get_all("Currency Exchange", fields = ["exchange_rate"], filters=[ - ["date", "<=", get_datetime_str(translation_date)], + ["date", "<=", get_datetime_str(transaction_date)], ["from_currency", "=", from_currency], ["to_currency", "=", to_currency] ], order_by="date desc", limit=1) - + if entries: return flt(entries[0].exchange_rate) @@ -102,5 +102,5 @@ def get_exchange_rate(translation_date, from_currency, to_currency): return flt(value) except: - frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}").format(from_currency, to_currency, translation_date)) + frappe.msgprint(_("Unable to find exchange rate for {0} to {1} for key date {2}").format(from_currency, to_currency, transaction_date)) return 0.0 \ No newline at end of file diff --git a/erpnext/stock/doctype/material_request_item/material_request_item.json b/erpnext/stock/doctype/material_request_item/material_request_item.json index f7ca7d9915..b1d6ec0cb6 100644 --- a/erpnext/stock/doctype/material_request_item/material_request_item.json +++ b/erpnext/stock/doctype/material_request_item/material_request_item.json @@ -23,6 +23,7 @@ "ignore_xss_filter": 0, "in_filter": 1, "in_list_view": 1, + "in_standard_filter": 0, "label": "Item Code", "length": 0, "no_copy": 0, @@ -34,6 +35,7 @@ "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 1, @@ -53,12 +55,14 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -77,6 +81,7 @@ "ignore_xss_filter": 0, "in_filter": 1, "in_list_view": 0, + "in_standard_filter": 0, "label": "Item Name", "length": 0, "no_copy": 0, @@ -87,6 +92,7 @@ "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 1, @@ -106,6 +112,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Description", "length": 0, "no_copy": 0, @@ -114,6 +121,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -132,6 +140,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Description", "length": 0, "no_copy": 0, @@ -142,6 +151,7 @@ "print_hide_if_no_value": 0, "print_width": "250px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -161,6 +171,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, @@ -168,6 +179,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -186,6 +198,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Image", "length": 0, "no_copy": 0, @@ -194,6 +207,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -212,6 +226,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Quantity and Warehouse", "length": 0, "no_copy": 0, @@ -219,6 +234,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -237,6 +253,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Quantity", "length": 0, "no_copy": 0, @@ -247,6 +264,7 @@ "print_hide_if_no_value": 0, "print_width": "80px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -266,6 +284,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Stock UOM", "length": 0, "no_copy": 0, @@ -277,6 +296,7 @@ "print_hide_if_no_value": 0, "print_width": "70px", "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -296,6 +316,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "For Warehouse", "length": 0, "no_copy": 0, @@ -307,6 +328,7 @@ "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -326,12 +348,14 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -351,6 +375,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 1, + "in_standard_filter": 0, "label": "Required Date", "length": 0, "no_copy": 0, @@ -361,6 +386,7 @@ "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, "search_index": 0, @@ -380,6 +406,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "More Information", "length": 0, "no_copy": 0, @@ -387,6 +414,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -406,6 +434,7 @@ "ignore_xss_filter": 0, "in_filter": 1, "in_list_view": 0, + "in_standard_filter": 0, "label": "Item Group", "length": 0, "no_copy": 0, @@ -416,6 +445,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 1, @@ -434,6 +464,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Brand", "length": 0, "no_copy": 0, @@ -445,6 +476,7 @@ "print_hide_if_no_value": 0, "print_width": "100px", "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -464,6 +496,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Lead Time Date", "length": 0, "no_copy": 1, @@ -473,6 +506,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -491,6 +525,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Sales Order", "length": 0, "no_copy": 0, @@ -499,6 +534,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -517,6 +553,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Project", "length": 0, "no_copy": 0, @@ -526,6 +563,7 @@ "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -544,12 +582,14 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "length": 0, "no_copy": 0, "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -568,6 +608,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Min Order Qty", "length": 0, "no_copy": 1, @@ -578,6 +619,7 @@ "print_hide_if_no_value": 0, "print_width": "70px", "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -597,6 +639,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Projected Qty", "length": 0, "no_copy": 1, @@ -607,6 +650,7 @@ "print_hide_if_no_value": 0, "print_width": "70px", "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -626,6 +670,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Actual Qty", "length": 0, "no_copy": 1, @@ -634,6 +679,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 1, "reqd": 0, "search_index": 0, @@ -652,6 +698,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Completed Qty", "length": 0, "no_copy": 1, @@ -661,6 +708,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 1, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -679,6 +727,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, + "in_standard_filter": 0, "label": "Page Break", "length": 0, "no_copy": 1, @@ -688,6 +737,7 @@ "print_hide": 1, "print_hide_if_no_value": 0, "read_only": 0, + "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, @@ -705,7 +755,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2016-10-17 04:58:33.317145", + "modified": "2016-12-08 14:49:48.397015", "modified_by": "Administrator", "module": "Stock", "name": "Material Request Item",