diff --git a/frappe/__init__.py b/frappe/__init__.py index f59a4c0be2..1a119a09d5 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -13,7 +13,7 @@ import os, sys, importlib, inspect, json from .exceptions import * from .utils.jinja import get_jenv, get_template, render_template -__version__ = '8.0.65' +__version__ = '8.0.66' __title__ = "Frappe Framework" local = Local() diff --git a/frappe/hooks.py b/frappe/hooks.py index e0bd2877d0..e1618b89d0 100755 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -149,10 +149,12 @@ scheduler_events = { "frappe.utils.scheduler.restrict_scheduler_events_if_dormant", "frappe.email.doctype.auto_email_report.auto_email_report.send_daily", "frappe.core.doctype.feedback_request.feedback_request.delete_feedback_request", - "frappe.core.doctype.authentication_log.authentication_log.clear_authentication_logs", + "frappe.core.doctype.authentication_log.authentication_log.clear_authentication_logs" + ], + "daily_long": [ "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_daily" ], - "weekly": [ + "weekly_long": [ "frappe.integrations.doctype.dropbox_settings.dropbox_settings.take_backups_weekly" ], "monthly": [ diff --git a/frappe/integrations/doctype/social_login_keys/social_login_keys.py b/frappe/integrations/doctype/social_login_keys/social_login_keys.py index 5a4f662a99..693bce679b 100644 --- a/frappe/integrations/doctype/social_login_keys/social_login_keys.py +++ b/frappe/integrations/doctype/social_login_keys/social_login_keys.py @@ -5,10 +5,17 @@ from __future__ import unicode_literals import frappe +import requests +import socket from frappe.model.document import Document from frappe import _ +try: + from urllib.parse import urlparse +except ImportError: + from urlparse import urlparse + class SocialLoginKeys(Document): def validate(self): self.validate_frappe_server_url() @@ -17,10 +24,16 @@ class SocialLoginKeys(Document): if self.frappe_server_url: if self.frappe_server_url.endswith('/'): self.frappe_server_url = self.frappe_server_url[:-1] - import requests + try: - r = requests.get(self.frappe_server_url + "/api/method/frappe.handler.version", timeout=5) + frappe_server_hostname = urlparse(self.frappe_server_url).netloc except: - frappe.throw(_("Unable to make request to the Frappe Server URL")) - if r.status_code != 200: frappe.throw(_("Check Frappe Server URL")) + + if socket.gethostname() != frappe_server_hostname or \ + (frappe.local.conf.domains is not None) and \ + (frappe_server_hostname not in frappe.local.conf.domains): + try: + requests.get(self.frappe_server_url + "/api/method/frappe.handler.version", timeout=5) + except: + frappe.throw(_("Unable to make request to the Frappe Server URL")) diff --git a/frappe/public/js/frappe/model/sync.js b/frappe/public/js/frappe/model/sync.js index 829ee5753d..6dd2433fc6 100644 --- a/frappe/public/js/frappe/model/sync.js +++ b/frappe/public/js/frappe/model/sync.js @@ -8,14 +8,14 @@ $.extend(frappe.model, { extract docs, docinfo (attachments, comments, assignments) from incoming request and set in `locals` and `frappe.model.docinfo` */ - + var isPlain; if(!r.docs && !r.docinfo) r = {docs:r}; - if($.isPlainObject(r.docs)) r.docs = [r.docs]; + isPlain = $.isPlainObject(r.docs); + if(isPlain) r.docs = [r.docs]; if(r.docs) { var last_parent_name = null; - var dirty = []; for(var i=0, l=r.docs.length; i', 10)})) self.assertFalse(evaluate_filters({'doctype': 'User', 'status': 'Open', 'age': 20}, {'status': 'Open', 'age': ('>', 30)})) + +class TestMoney(unittest.TestCase): + def test_money_in_words(self): + nums_bhd = [ + (5000, "BHD Five Thousand only."), (5000.0, "BHD Five Thousand only."), + (0.1, "One Hundred Fils only."), (0, "BHD Zero only."), ("Fail", "") + ] + + nums_ngn = [ + (5000, "NGN Five Thousand only."), (5000.0, "NGN Five Thousand only."), + (0.1, "Ten Kobo only."), (0, "NGN Zero only."), ("Fail", "") + ] + + for num in nums_bhd: + self.assertEqual( + money_in_words(num[0], "BHD"), num[1], "{0} is not the same as {1}". + format(money_in_words(num[0], "BHD"), num[1]) + ) + + for num in nums_ngn: + self.assertEqual( + money_in_words(num[0], "NGN"), num[1], "{0} is not the same as {1}". + format(money_in_words(num[0], "NGN"), num[1]) + ) \ No newline at end of file diff --git a/frappe/utils/data.py b/frappe/utils/data.py index 067d5a4650..f28c321f0b 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -419,7 +419,14 @@ def money_in_words(number, main_currency = None, fraction_currency=None): from frappe.utils import get_defaults _ = frappe._ - if not number or flt(number) < 0: + try: + # note: `flt` returns 0 for invalid input and we don't want that + number = float(number) + except ValueError: + return "" + + number = flt(number) + if number < 0: return "" d = get_defaults() @@ -428,20 +435,30 @@ def money_in_words(number, main_currency = None, fraction_currency=None): if not fraction_currency: fraction_currency = frappe.db.get_value("Currency", main_currency, "fraction") or _("Cent") - n = "%.2f" % flt(number) - main, fraction = n.split('.') - if len(fraction)==1: fraction += '0' - - number_format = frappe.db.get_value("Currency", main_currency, "number_format", cache=True) or \ frappe.db.get_default("number_format") or "#,###.##" + fraction_length = len(number_format.rsplit('.', 1)[-1]) + n = "%.{0}f".format(fraction_length) % number + main, fraction = n.split('.') + + if len(fraction) < fraction_length: + zeros = '0' * (fraction_length - len(fraction)) + fraction += zeros + in_million = True if number_format == "#,##,###.##": in_million = False - out = main_currency + ' ' + in_words(main, in_million).title() - if cint(fraction): - out = out + ' ' + _('and') + ' ' + in_words(fraction, in_million).title() + ' ' + fraction_currency + # 0.00 + if main == '0' and fraction in ['00', '000']: + out = "{0} {1}".format(main_currency, _('Zero')) + # 0.XX + elif main == '0': + out = _(in_words(fraction, in_million).title()) + ' ' + fraction_currency + else: + out = main_currency + ' ' + _(in_words(main, in_million).title()) + if cint(fraction): + out = out + ' ' + _('and') + ' ' + _(in_words(fraction, in_million).title()) + ' ' + fraction_currency return out + ' ' + _('only.')