diff --git a/frappe/core/doctype/system_settings/system_settings.json b/frappe/core/doctype/system_settings/system_settings.json index 45b9822e44..d56289f137 100644 --- a/frappe/core/doctype/system_settings/system_settings.json +++ b/frappe/core/doctype/system_settings/system_settings.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, "beta": 0, @@ -21,6 +22,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "", @@ -48,6 +50,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Country", @@ -77,6 +80,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, "label": "Language", @@ -105,6 +109,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "length": 0, @@ -132,6 +137,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Time Zone", @@ -159,6 +165,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Setup Complete", @@ -187,6 +194,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Date and Number Format", @@ -214,6 +222,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Date Format", @@ -242,6 +251,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "length": 0, @@ -269,6 +279,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Number Format", @@ -297,12 +308,13 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Float Precision", "length": 0, "no_copy": 0, - "options": "\n2\n3\n4\n5\n6", + "options": "\n2\n3\n4\n5\n6\n7\n8\n9", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -314,6 +326,37 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "If not set, the currency precision will depend on number format", + "fieldname": "currency_precision", + "fieldtype": "Select", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Currency Precision", + "length": 0, + "no_copy": 0, + "options": "\n1\n2\n3\n4\n5\n6\n7\n8\n9", + "permlevel": 0, + "precision": "", + "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, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -325,6 +368,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Backups", @@ -355,6 +399,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Number of Backups", @@ -383,6 +428,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Background Workers", @@ -412,6 +458,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Enable Scheduled Jobs", @@ -439,6 +486,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Scheduler Last Event", @@ -467,6 +515,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Security", @@ -496,6 +545,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Session Expiry", @@ -526,6 +576,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Session Expiry Mobile", @@ -554,6 +605,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "length": 0, @@ -582,6 +634,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Allow only one session per user", @@ -611,6 +664,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Ignore User Permissions If Missing", @@ -639,6 +693,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "EMail", @@ -668,6 +723,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Email Footer Address", @@ -696,6 +752,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "length": 0, @@ -723,6 +780,7 @@ "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, + "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, "label": "Disable Standard Email Footer", @@ -741,18 +799,18 @@ "unique": 0 } ], + "has_web_view": 0, "hide_heading": 0, "hide_toolbar": 0, "icon": "fa fa-cog", "idx": 0, "image_view": 0, "in_create": 0, - "in_dialog": 0, "is_submittable": 0, "issingle": 1, "istable": 0, "max_attachments": 0, - "modified": "2016-12-29 14:40:33.023468", + "modified": "2017-04-13 02:23:18.660325", "modified_by": "Administrator", "module": "Core", "name": "System Settings", @@ -769,7 +827,6 @@ "export": 0, "if_owner": 0, "import": 0, - "is_custom": 0, "permlevel": 0, "print": 0, "read": 1, @@ -784,6 +841,7 @@ "quick_entry": 1, "read_only": 0, "read_only_onload": 0, + "show_name_in_global_search": 0, "sort_order": "ASC", "track_changes": 1, "track_seen": 0 diff --git a/frappe/model/meta.py b/frappe/model/meta.py index f792e1c809..23513beea5 100644 --- a/frappe/model/meta.py +++ b/frappe/model/meta.py @@ -441,22 +441,10 @@ def get_field_precision(df, doc=None, currency=None): precision = cint(df.precision) elif df.fieldtype == "Currency": - number_format = None - if not currency and doc: - currency = get_field_currency(df, doc) - - if not currency: - # use default currency - currency = frappe.db.get_default("currency") - - if currency: - number_format = frappe.db.get_value("Currency", currency, "number_format", cache=True) - - if not number_format: + precision = cint(frappe.db.get_default("currency_precision")) + if not precision: number_format = frappe.db.get_default("number_format") or "#,###.##" - - decimal_str, comma_str, precision = get_number_format_info(number_format) - + decimal_str, comma_str, precision = get_number_format_info(number_format) else: precision = cint(frappe.db.get_default("float_precision")) or 3 diff --git a/frappe/public/js/frappe/form/control.js b/frappe/public/js/frappe/form/control.js index bbeaec99bc..fe153323f3 100755 --- a/frappe/public/js/frappe/form/control.js +++ b/frappe/public/js/frappe/form/control.js @@ -600,7 +600,11 @@ frappe.ui.form.ControlCurrency = frappe.ui.form.ControlFloat.extend({ // always round based on field precision or currency's precision // this method is also called in this.parse() if (!this.df.precision) { - this.df.precision = get_number_format_info(this.get_number_format()).precision; + if(frappe.boot.sysdefaults.currency_precision) { + this.df.precision = frappe.boot.sysdefaults.currency_precision; + } else { + this.df.precision = get_number_format_info(this.get_number_format()).precision; + } } return this.df.precision; diff --git a/frappe/public/js/frappe/form/formatters.js b/frappe/public/js/frappe/form/formatters.js index 9f8c0f9d94..5a015dc6e9 100644 --- a/frappe/public/js/frappe/form/formatters.js +++ b/frappe/public/js/frappe/form/formatters.js @@ -52,8 +52,9 @@ frappe.form.formatters = { }, Currency: function(value, docfield, options, doc) { var currency = frappe.meta.get_field_currency(docfield, doc); + var precision = docfield.precision || cint(frappe.boot.sysdefaults.currency_precision) || 2; return frappe.form.formatters._right((value==null || value==="") - ? "" : format_currency(value, currency, docfield.precision || null), options); + ? "" : format_currency(value, currency, docfield.precision), options); }, Check: function(value) { if(value) { diff --git a/frappe/public/js/frappe/misc/number_format.js b/frappe/public/js/frappe/misc/number_format.js index f9fda64320..e8bd8925bf 100644 --- a/frappe/public/js/frappe/misc/number_format.js +++ b/frappe/public/js/frappe/misc/number_format.js @@ -59,16 +59,16 @@ function strip_number_groups(v, number_format) { frappe.number_format_info = { - "#,###.##": {decimal_str:".", group_sep:",", precision:2}, - "#.###,##": {decimal_str:",", group_sep:".", precision:2}, - "# ###.##": {decimal_str:".", group_sep:" ", precision:2}, - "# ###,##": {decimal_str:",", group_sep:" ", precision:2}, - "#'###.##": {decimal_str:".", group_sep:"'", precision:2}, - "#, ###.##": {decimal_str:".", group_sep:", ", precision:2}, - "#,##,###.##": {decimal_str:".", group_sep:",", precision:2}, - "#,###.###": {decimal_str:".", group_sep:",", precision:3}, - "#.###": {decimal_str:"", group_sep:".", precision:0}, - "#,###": {decimal_str:"", group_sep:",", precision:0}, + "#,###.##": {decimal_str:".", group_sep:","}, + "#.###,##": {decimal_str:",", group_sep:"."}, + "# ###.##": {decimal_str:".", group_sep:" "}, + "# ###,##": {decimal_str:",", group_sep:" "}, + "#'###.##": {decimal_str:".", group_sep:"'"}, + "#, ###.##": {decimal_str:".", group_sep:", "}, + "#,##,###.##": {decimal_str:".", group_sep:","}, + "#,###.###": {decimal_str:".", group_sep:","}, + "#.###": {decimal_str:"", group_sep:"."}, + "#,###": {decimal_str:"", group_sep:","}, } window.format_number = function(v, format, decimals){ @@ -127,6 +127,7 @@ window.format_number = function(v, format, decimals){ function format_currency(v, currency, decimals) { var format = get_number_format(currency); var symbol = get_currency_symbol(currency); + var decimals = frappe.boot.sysdefaults.currency_precision || null; if(symbol) return symbol + " " + format_number(v, format, decimals); @@ -151,29 +152,19 @@ function get_currency_symbol(currency) { var global_number_format = null; function get_number_format(currency) { - if(!global_number_format) { - if (frappe.boot && frappe.boot.sysdefaults) { - global_number_format = frappe.boot.sysdefaults.number_format - || frappe.model.get_value(":Currency", frappe.boot.sysdefaults.currency, "number_format"); - } - - global_number_format = global_number_format || "#,###.##"; - } - - var number_format; - if(currency && frappe.boot) { - number_format = frappe.model.get_value(":Currency", currency, - "number_format"); - } - - return number_format || global_number_format; + return (frappe.boot && frappe.boot.sysdefaults.number_format) || "#,###.##"; } function get_number_format_info(format) { var info = frappe.number_format_info[format]; + if(!info) { - info = {decimal_str:".", group_sep:",", precision:2}; + info = {decimal_str:".", group_sep:","}; } + + // get the precision from the number format + info.precision = format.split(info.decimal_str).slice(1)[0].length; + return info; } diff --git a/frappe/public/js/legacy/datatype.js b/frappe/public/js/legacy/datatype.js index 9af26d8d17..6834d206c0 100644 --- a/frappe/public/js/legacy/datatype.js +++ b/frappe/public/js/legacy/datatype.js @@ -8,7 +8,7 @@ frappe.utils.full_name = function(fn, ln) { function fmt_money(v, format){ // deprecated! // for backward compatibility - return format_number(v, format); + return format_currency(v, format); } diff --git a/frappe/tests/test_fmt_money.py b/frappe/tests/test_fmt_money.py index 10fb71beed..80afdc8791 100644 --- a/frappe/tests/test_fmt_money.py +++ b/frappe/tests/test_fmt_money.py @@ -4,63 +4,7 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import flt, cstr - -def fmt_money(amount, precision=None): - """ - Convert to string with commas for thousands, millions etc - """ - - number_format = frappe.db.get_default("number_format") or "#,###.##" - decimal_str, comma_str, precision = get_number_format_info(number_format) - - - amount = '%.*f' % (precision, flt(amount)) - if amount.find('.') == -1: - decimals = '' - else: - decimals = amount.split('.')[1] - - parts = [] - minus = '' - if flt(amount) < 0: - minus = '-' - - amount = cstr(abs(flt(amount))).split('.')[0] - - if len(amount) > 3: - parts.append(amount[-3:]) - amount = amount[:-3] - - val = number_format=="#,##,###.##" and 2 or 3 - - while len(amount) > val: - parts.append(amount[-val:]) - amount = amount[:-val] - - parts.append(amount) - - parts.reverse() - - amount = comma_str.join(parts) + (precision and (decimal_str + decimals) or "") - amount = minus + amount - - return amount - -def get_number_format_info(format): - if format=="#.###": - return "", ".", 0 - elif format=="#,###": - return "", ",", 0 - elif format=="#,###.##" or format=="#,##,###.##": - return ".", ",", 2 - elif format=="#.###,##": - return ",", ".", 2 - elif format=="# ###.##": - return ".", " ", 2 - else: - return ".", ",", 2 - +from frappe.utils import flt, cstr, fmt_money import unittest class TestFmtMoney(unittest.TestCase): @@ -119,6 +63,19 @@ class TestFmtMoney(unittest.TestCase): self.assertEquals(fmt_money(-100.3), "-100") self.assertEquals(fmt_money(-1000.3), "-1,000") + def test_currency_precision(self): + frappe.db.set_default("currency_precision", "4") + frappe.db.set_default("number_format", "#,###.##") + self.assertEquals(fmt_money(100), "100.0000") + self.assertEquals(fmt_money(1000), "1,000.0000") + self.assertEquals(fmt_money(10000), "10,000.0000") + self.assertEquals(fmt_money(100000), "100,000.0000") + self.assertEquals(fmt_money(1000000), "1,000,000.0000") + self.assertEquals(fmt_money(10000000), "10,000,000.0000") + self.assertEquals(fmt_money(100000000), "100,000,000.0000") + self.assertEquals(fmt_money(1000000000), "1,000,000,000.0000") + frappe.db.set_default("currency_precision", "") + if __name__=="__main__": frappe.connect() unittest.main() \ No newline at end of file diff --git a/frappe/utils/data.py b/frappe/utils/data.py index 7f2b2176d1..acc15a99d1 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -348,12 +348,9 @@ def fmt_money(amount, precision=None, currency=None): """ Convert to string with commas for thousands, millions etc """ - number_format = None - if currency: - number_format = frappe.db.get_value("Currency", currency, "number_format", cache=True) - - if not number_format: - number_format = frappe.db.get_default("number_format") or "#,###.##" + number_format = frappe.db.get_default("number_format") or "#,###.##" + if precision is None: + precision = cint(frappe.db.get_default('currency_precision')) or None decimal_str, comma_str, number_format_precision = get_number_format_info(number_format)