diff --git a/public/js/wn/misc/number_format.js b/public/js/wn/misc/number_format.js index 3d4662ecd7..733c160351 100644 --- a/public/js/wn/misc/number_format.js +++ b/public/js/wn/misc/number_format.js @@ -153,6 +153,7 @@ function get_number_format_info(format) { } function roundNumber(num, dec) { + dec = cint(dec); var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); return result; } diff --git a/webnotes/model/code.py b/webnotes/model/code.py index 954fd27bc8..dceedef96e 100644 --- a/webnotes/model/code.py +++ b/webnotes/model/code.py @@ -134,12 +134,14 @@ def get_module_name(doctype, module, prefix): return '%s.doctype.%s.%s%s' % (_module, _doctype, prefix, _doctype) def load_doctype_module(doctype, module, prefix=""): + import webnotes from webnotes.modules import scrub _doctype, _module = scrub(doctype), scrub(module) try: module = __import__(get_module_name(doctype, module, prefix), fromlist=['']) return module except ImportError, e: + # webnotes.errprint(webnotes.getTraceback()) return None def get_obj(dt = None, dn = None, doc=None, doclist=[], with_children = 0): diff --git a/webnotes/model/controller.py b/webnotes/model/controller.py index a7ffccdce1..2a8858c2ac 100644 --- a/webnotes/model/controller.py +++ b/webnotes/model/controller.py @@ -24,6 +24,7 @@ from __future__ import unicode_literals import webnotes from webnotes import msgprint, _ from webnotes.utils import flt, cint, cstr +from webnotes.model.meta import get_field_precision error_coniditon_map = { "=": "!=", @@ -73,3 +74,26 @@ class DocListController(object): # raise passed exception or True msgprint(msg, raise_exception=raise_exception or True) + + def round_floats_in_doc(self, doc, parentfield=None): + for df in self.meta.get({"doctype": "DocField", "parent": doc.doctype, + "fieldtype": ["in", ["Currency", "Float"]]}): + doc.fields[df.fieldname] = flt(doc.fields.get(df.fieldname), self.precision_of(df.fieldname, parentfield)) + + def precision_of(self, fieldname, parentfield=None): + if not hasattr(self, "_precision"): + self._precision = webnotes._dict({ + "default_precision": cint(webnotes.conn.get_default("float_precision")) or 6, + "options": {} + }) + + if self._precision.setdefault(parentfield or "main", {}).get(fieldname) is None: + df = self.meta.get_field(fieldname, parentfield=parentfield) + + if df.fieldtype == "Currency" and df.options and not self._precision.options.get(df.options): + self._precision.options[df.options] = get_field_precision(df, self.doc) + + self._precision[parentfield or "main"][fieldname] = cint(self._precision.options.get(df.options)) or \ + self._precision.default_precision + + return self._precision[parentfield or "main"][fieldname] \ No newline at end of file diff --git a/webnotes/model/doctype.py b/webnotes/model/doctype.py index deb0a5869f..028b6851f2 100644 --- a/webnotes/model/doctype.py +++ b/webnotes/model/doctype.py @@ -74,9 +74,6 @@ def get(doctype, processed=False, cached=True): # add validators #add_validators(doctype, doclist) - # add precision - add_precision(doctype, doclist) - to_cache(doctype, processed, doclist) if processed: @@ -146,7 +143,6 @@ def sort_fields(doclist): doclist.get({"doctype":["!=", "DocField"]}).extend(newlist) def apply_property_setters(doctype, doclist): - from webnotes.utils import cint for ps in webnotes.conn.sql("""select * from `tabProperty Setter` where doc_type=%s""", doctype, as_dict=1): if ps['doctype_or_field']=='DocType': @@ -367,15 +363,6 @@ def update_language(doclist): messages[webnotes.lang] = webnotes._dict({}) messages[webnotes.lang].update(_messages) -def add_precision(doctype, doclist): - type_precision_map = { - "Currency": 2, - "Float": cint(webnotes.conn.get_default("float_precision")) or 6 - } - for df in doclist.get({"doctype": "DocField", - "fieldtype": ["in", type_precision_map.keys()]}): - df.precision = type_precision_map[df.fieldtype] - class DocTypeDocList(webnotes.model.doclist.DocList): def get_field(self, fieldname, parent=None, parentfield=None): filters = {"doctype":"DocField"} @@ -412,19 +399,6 @@ class DocTypeDocList(webnotes.model.doclist.DocList): def get_table_fields(self): return self.get({"doctype": "DocField", "fieldtype": "Table"}) - def get_precision_map(self, parent=None, parentfield=None): - """get a map of fields of type 'currency' or 'float' with precision values""" - filters = {"doctype": "DocField", "fieldtype": ["in", ["Currency", "Float"]]} - if parentfield: - parent = self.get_options(parentfield) - if parent: - filters["parent"] = parent - else: - filters["parent"] = self[0].name - - from webnotes import _dict - return _dict((f.fieldname, f.precision) for f in self.get(filters)) - def get_parent_doclist(self): return webnotes.doclist([self[0]] + self.get({"parent": self[0].name})) diff --git a/webnotes/model/meta.py b/webnotes/model/meta.py index 970bfb206d..ed4f43345d 100644 --- a/webnotes/model/meta.py +++ b/webnotes/model/meta.py @@ -82,4 +82,33 @@ def has_field(doctype, fieldname, parent=None, parentfield=None): def get_field(doctype, fieldname, parent=None, parentfield=None): doclist = webnotes.get_doctype(doctype) - return doclist.get_field(fieldname, parent, parentfield) \ No newline at end of file + return doclist.get_field(fieldname, parent, parentfield) + +def get_field_currency(df, doc): + """get currency based on DocField options and fieldvalue in doc""" + currency = None + + if ":" in df.options: + split_opts = df.options.split(":") + if len(split_opts)==3: + currency = webnotes.conn.get_value(split_opts[0], doc.fields.get(split_opts[1]), + split_opts[2]) + else: + currency = doc.fields.get(df.options) + + return currency or webnotes.conn.get_default("currency") + +def get_field_precision(df, doc): + """get precision based on DocField options and fieldvalue in doc""" + from webnotes.utils import get_number_format_info + + number_format = None + currency = get_field_currency(df, doc) + + if currency: + number_format = webnotes.conn.get_value("Currency", currency, "number_format") + + decimal_str, comma_str, precision = get_number_format_info(number_format or \ + webnotes.conn.get_default("number_format") or "#,###.##") + + return precision \ No newline at end of file diff --git a/webnotes/model/utils.py b/webnotes/model/utils.py index bc33881fc2..aee746d834 100644 --- a/webnotes/model/utils.py +++ b/webnotes/model/utils.py @@ -225,11 +225,6 @@ def check_if_doc_is_linked(dt, dn, method="Delete"): (item.parent or item.name, item.parent and item.parenttype or link_dt), raise_exception=LinkExistsError) -def round_floats_in_doc(doc, precision_map): - from webnotes.utils import flt - for fieldname, precision in precision_map.items(): - doc.fields[fieldname] = flt(doc.fields.get(fieldname), precision) - def set_default(doc, key): if not doc.is_default: webnotes.conn.set(doc, "is_default", 1) @@ -237,5 +232,3 @@ def set_default(doc, key): webnotes.conn.sql("""update `tab%s` set `is_default`=0 where `%s`=%s and name!=%s""" % (doc.doctype, key, "%s", "%s"), (doc.fields.get(key), doc.name)) - - diff --git a/webnotes/utils/__init__.py b/webnotes/utils/__init__.py index fa31b9c502..7c2911c71f 100644 --- a/webnotes/utils/__init__.py +++ b/webnotes/utils/__init__.py @@ -321,7 +321,7 @@ def flt(s, precision=None): s = s.replace(',','') try: num = float(s) - if precision: + if precision is not None: num = round(num, precision) except Exception: num = 0 @@ -413,20 +413,19 @@ def fmt_money(amount, precision=None, currency=None): amount = symbol + " " + amount return amount - + +number_format_info = { + "#.###": ("", ".", 0), + "#,###": ("", ",", 0), + "#,###.##": (".", ",", 2), + "#,##,###.##": (".", ",", 2), + "#.###,##": (",", ".", 2), + "# ###.##": (".", " ", 2), + "#,###.###": (".", ",", 3), +} + 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 + return number_format_info.get(format) or (".", ",", 2) # # convet currency to words @@ -833,4 +832,4 @@ def compare(val1, condition, val2): if condition in operator_map: return operator_map[condition]((val1, val2)) - return False \ No newline at end of file + return False