From ab8b4304ae83687d5fc21fb7e3bff2ef6a057dc9 Mon Sep 17 00:00:00 2001 From: nathando Date: Tue, 21 Oct 2014 13:56:46 +0800 Subject: [PATCH 01/33] Convert dict to object before formatting - According to this discussion, https://discuss.frappe.io/t/print-format-currency-utils/3480/3 --- frappe/utils/formatters.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frappe/utils/formatters.py b/frappe/utils/formatters.py index e97560b6c7..b202f1912b 100644 --- a/frappe/utils/formatters.py +++ b/frappe/utils/formatters.py @@ -8,6 +8,9 @@ from frappe.model.meta import get_field_currency, get_field_precision import re def format_value(value, df, doc=None, currency=None): + # Convert dict to object if necessary + df = frappe._dict(df) + if df.get("fieldtype")=="Date": return formatdate(value) From 84aa6d370d242871bbe839dcf4adb4c47de5fe84 Mon Sep 17 00:00:00 2001 From: nathando Date: Tue, 21 Oct 2014 14:15:03 +0800 Subject: [PATCH 02/33] Safe check for dict --- frappe/utils/formatters.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/utils/formatters.py b/frappe/utils/formatters.py index b202f1912b..9e08db60f6 100644 --- a/frappe/utils/formatters.py +++ b/frappe/utils/formatters.py @@ -9,7 +9,8 @@ import re def format_value(value, df, doc=None, currency=None): # Convert dict to object if necessary - df = frappe._dict(df) + if (isinstance(df, dict)): + df = frappe._dict(df) if df.get("fieldtype")=="Date": return formatdate(value) From 0eb5bdc167ac805f225f7ac7098e66f8f9d8451d Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Mon, 10 Nov 2014 13:07:44 +0600 Subject: [PATCH 03/33] bumped to version 4.5.4 --- frappe/__version__.py | 2 +- frappe/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/__version__.py b/frappe/__version__.py index 5b43808f60..bb160d0353 100644 --- a/frappe/__version__.py +++ b/frappe/__version__.py @@ -1 +1 @@ -__version__ = "4.5.3" +__version__ = "4.5.4" diff --git a/frappe/hooks.py b/frappe/hooks.py index ae5ef2ac71..18c892439f 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -3,7 +3,7 @@ app_title = "Frappe Framework" app_publisher = "Web Notes Technologies Pvt. Ltd." app_description = "Full Stack Web Application Framework in Python" app_icon = "assets/frappe/images/frappe.svg" -app_version = "4.5.3" +app_version = "4.5.4" app_color = "#3498db" app_email = "support@frappe.io" diff --git a/setup.py b/setup.py index 3ff6b857a7..a626c51a90 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.5.3" +version = "4.5.4" with open("requirements.txt", "r") as f: install_requires = f.readlines() From 1ba7837e979abc92e7f97266db1ed9876c912b01 Mon Sep 17 00:00:00 2001 From: jorxzpagta Date: Wed, 12 Nov 2014 16:42:26 +0800 Subject: [PATCH 04/33] Update event.py Calendar Bug: When you create an event and repeat it to a certain date, it repeats the event from the start date to the last day of the calendar on the page. Fix: it gets the repeat_till data from the database and limits the event to the proposed date. --- frappe/core/doctype/event/event.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/frappe/core/doctype/event/event.py b/frappe/core/doctype/event/event.py index b154256c23..a9511a9f2f 100644 --- a/frappe/core/doctype/event/event.py +++ b/frappe/core/doctype/event/event.py @@ -14,6 +14,9 @@ class Event(Document): def validate(self): if self.starts_on and self.ends_on and self.starts_on > self.ends_on: frappe.msgprint(frappe._("Event end must be after start"), raise_exception=True) + if self.starts_on and self.ends_on and int(date_diff(self.ends_on.split(" ")[0], self.starts_on.split(" ")[0])) > 0 \ + and self.repeat_on == "Every Day": + frappe.msgprint(frappe._("Every day events should finish on the same day."), raise_exception=True) def get_permission_query_conditions(user): if not user: user = frappe.session.user @@ -72,7 +75,7 @@ def get_events(start, end, user=None, for_reminder=False): user = frappe.session.user roles = frappe.get_roles(user) events = frappe.db.sql("""select name, subject, description, - starts_on, ends_on, owner, all_day, event_type, repeat_this_event, repeat_on, + starts_on, ends_on, owner, all_day, event_type, repeat_this_event, repeat_on,repeat_till, monday, tuesday, wednesday, thursday, friday, saturday, sunday from tabEvent where (( (date(starts_on) between date('%(start)s') and date('%(end)s')) @@ -105,14 +108,19 @@ def get_events(start, end, user=None, for_reminder=False): def add_event(e, date): new_event = e.copy() + enddate = add_days(date,int(date_diff(e.ends_on.split(" ")[0], e.starts_on.split(" ")[0]))) new_event.starts_on = date + " " + e.starts_on.split(" ")[1] if e.ends_on: - new_event.ends_on = date + " " + e.ends_on.split(" ")[1] + new_event.ends_on = enddate + " " + e.ends_on.split(" ")[1] add_events.append(new_event) for e in events: if e.repeat_this_event: event_start, time_str = e.starts_on.split(" ") + if e.repeat_till == None or "": + repeat = "3000-01-01" + else: + repeat = e.repeat_till if e.repeat_on=="Every Year": start_year = cint(start.split("-")[0]) end_year = cint(end.split("-")[0]) @@ -121,7 +129,7 @@ def get_events(start, end, user=None, for_reminder=False): # repeat for all years in period for year in range(start_year, end_year+1): date = str(year) + "-" + event_start - if date >= start and date <= end: + if date >= start and date <= repeat: add_event(e, date) remove_events.append(e) @@ -138,7 +146,7 @@ def get_events(start, end, user=None, for_reminder=False): start_from = date for i in xrange(int(date_diff(end, start) / 30) + 3): - if date >= start and date <= end and date >= event_start: + if date >= start and date <= repeat and date >= event_start: add_event(e, date) date = add_months(start_from, i+1) @@ -153,7 +161,7 @@ def get_events(start, end, user=None, for_reminder=False): date = add_days(start, weekday - start_weekday) for cnt in xrange(int(date_diff(end, start) / 7) + 3): - if date >= start and date <= end and date >= event_start: + if date >= start and date <= repeat and date >= event_start: add_event(e, date) date = add_days(date, 7) @@ -163,7 +171,7 @@ def get_events(start, end, user=None, for_reminder=False): if e.repeat_on=="Every Day": for cnt in xrange(date_diff(end, start) + 1): date = add_days(start, cnt) - if date >= event_start and date <= end \ + if date >= event_start and date <= repeat \ and e[weekdays[getdate(date).weekday()]]: add_event(e, date) remove_events.append(e) From 71a3cf1dfc65ff83b48a6458c4a2126016c59a24 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 12 Nov 2014 17:11:01 +0530 Subject: [PATCH 05/33] link for website view in email --- .../core/doctype/communication/communication.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py index 47546c221b..af98c0f076 100644 --- a/frappe/core/doctype/communication/communication.py +++ b/frappe/core/doctype/communication/communication.py @@ -167,14 +167,12 @@ def set_portal_link(sent_via, comm): footer = "" - if is_signup_enabled() and hasattr(sent_via, "get_portal_page"): - portal_page = sent_via.get_portal_page() - if portal_page: - is_valid_recipient = cstr(sent_via.get("email") or sent_via.get("email_id") or - sent_via.get("contact_email")) in comm.recipients - if is_valid_recipient: - url = "%s/%s?name=%s" % (get_url(), portal_page, urllib.quote(sent_via.name)) - footer = """ -

View this on our website

""" % url + if is_signup_enabled(): + is_valid_recipient = cstr(sent_via.get("email") or sent_via.get("email_id") or + sent_via.get("contact_email")) in comm.recipients + if is_valid_recipient: + url = "%s/%s/%s" % (get_url(), urllib.quote(sent_via.doctype), urllib.quote(sent_via.name)) + footer = """ +

View this on our website

""" % url return footer From 3e18bfded9fd9ea453669c2a0849df47efb95093 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Wed, 12 Nov 2014 17:27:40 +0530 Subject: [PATCH 06/33] Minor fix --- frappe/model/db_query.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 6658a792bf..83ec5b1fa6 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -317,13 +317,14 @@ class DatabaseQuery(object): ) and not self.group_by) if not group_function_without_group_by: - - args.order_by = "`tab{0}`.`{1}` {2}".format(self.doctype, - meta.sort_field or "modified", meta.sort_order or "desc") + if args.get("sort_field") and args.get("sort_order"): + args.order_by = "`tab{0}`.`{1}` {2}".format(self.doctype, + meta.sort_field or "modified", meta.sort_order or "desc") # draft docs always on top if meta.is_submittable: - args.order_by = "`tab{0}`.docstatus asc, ".format(self.doctype) + args.order_by + args.order_by = "`tab{0}`.docstatus asc {1}"\ + .format(self.doctype, (", " + args.order_by if args.order_by else "")) def check_sort_by_table(self, order_by): if "." in order_by: From 27c23dccac72bef01e596e736ab63a40f1a86569 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 13 Nov 2014 11:19:26 +0530 Subject: [PATCH 07/33] Block parallel ajax while saving --- frappe/public/js/frappe/form/save.js | 10 ++++++++++ frappe/public/js/frappe/request.js | 2 ++ 2 files changed, 12 insertions(+) diff --git a/frappe/public/js/frappe/form/save.js b/frappe/public/js/frappe/form/save.js index a788ed79c7..fabfe4c0ef 100644 --- a/frappe/public/js/frappe/form/save.js +++ b/frappe/public/js/frappe/form/save.js @@ -114,6 +114,13 @@ frappe.ui.form.save = function(frm, action, callback, btn) { // btn: btn // } $(opts.btn).prop("disabled", true); + + if(frappe.ui.form.is_saving) { + msgprint(__("Already saving. Please wait a few moments.")); + throw "saving"; + } + frappe.ui.form.is_saving = true; + return frappe.call({ freeze: true, method: opts.method, @@ -121,6 +128,9 @@ frappe.ui.form.save = function(frm, action, callback, btn) { callback: function(r) { $(opts.btn).prop("disabled", false); opts.callback && opts.callback(r); + }, + always: function() { + frappe.ui.form.is_saving = false; } }) }; diff --git a/frappe/public/js/frappe/request.js b/frappe/public/js/frappe/request.js index 87aee102f5..1618d213e5 100644 --- a/frappe/public/js/frappe/request.js +++ b/frappe/public/js/frappe/request.js @@ -29,6 +29,7 @@ frappe.call = function(opts) { args: args, success: opts.callback, error: opts.error, + always: opts.always, btn: opts.btn, freeze: opts.freeze, show_spinner: !opts.no_spinner, @@ -124,6 +125,7 @@ frappe.request.call = function(opts) { data = JSON.parse(data.responseText); } frappe.request.cleanup(opts, data); + if(opts.always) opts.always(data); }) .done(function(data, textStatus, xhr) { var status_code_handler = statusCode[xhr.statusCode().status]; From 4eb6cdb1576be00e693545da2d9c6ae5249e5520 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Thu, 13 Nov 2014 14:42:41 +0530 Subject: [PATCH 08/33] fix: query order by --- frappe/model/db_query.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index 83ec5b1fa6..a5c2f7b723 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -317,14 +317,12 @@ class DatabaseQuery(object): ) and not self.group_by) if not group_function_without_group_by: - if args.get("sort_field") and args.get("sort_order"): - args.order_by = "`tab{0}`.`{1}` {2}".format(self.doctype, - meta.sort_field or "modified", meta.sort_order or "desc") + args.order_by = "`tab{0}`.`{1}` {2}".format(self.doctype, + meta.get("sort_field") or "modified", meta.get("sort_order") or "desc") # draft docs always on top if meta.is_submittable: - args.order_by = "`tab{0}`.docstatus asc {1}"\ - .format(self.doctype, (", " + args.order_by if args.order_by else "")) + args.order_by = "`tab{0}`.docstatus asc, {1}".format(self.doctype, args.order_by) def check_sort_by_table(self, order_by): if "." in order_by: From 43aeb93608014bbdaf37e589d4cd8171db9c3845 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 12 Nov 2014 16:12:34 +0530 Subject: [PATCH 09/33] [minor] encode filename to utf-8 and filepath before saving --- frappe/utils/file_manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/utils/file_manager.py b/frappe/utils/file_manager.py index 2fbbb5ab4d..0da0052a67 100644 --- a/frappe/utils/file_manager.py +++ b/frappe/utils/file_manager.py @@ -170,7 +170,7 @@ def write_file(content, file_path, fname): # create directory (if not exists) frappe.create_folder(get_files_path()) # write the file - with open(os.path.join(file_path, fname), 'w+') as f: + with open(os.path.join(file_path.encode('utf-8'), fname.encode('utf-8')), 'w+') as f: f.write(content) return get_files_path(fname) @@ -251,7 +251,7 @@ def get_content_hash(content): def get_file_name(fname, optional_suffix): n_records = frappe.db.sql("select name from `tabFile Data` where file_name=%s", fname) - if len(n_records) > 0 or os.path.exists(get_files_path(fname)): + if len(n_records) > 0 or os.path.exists(get_files_path(fname.encode('utf-8'))): f = fname.rsplit('.', 1) if len(f) == 1: partial, extn = f[0], "" From eec17701b3700d8afeb079080f4a9418413e40af Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 12 Nov 2014 18:35:42 +0530 Subject: [PATCH 10/33] [minor] fix website route drop table --- frappe/patches/v4_2/refactor_website_routing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/patches/v4_2/refactor_website_routing.py b/frappe/patches/v4_2/refactor_website_routing.py index b3ad5c8761..9cb39beaf0 100644 --- a/frappe/patches/v4_2/refactor_website_routing.py +++ b/frappe/patches/v4_2/refactor_website_routing.py @@ -4,4 +4,4 @@ def execute(): # clear all static web pages frappe.delete_doc("DocType", "Website Route", force=1) frappe.delete_doc("Page", "sitemap-browser", force=1) - frappe.db.sql("drop table `tabWebsite Route`") + frappe.db.sql("drop table if exists `tabWebsite Route`") From edc8ed43a5a1731cd9f79729202d105e3b1ee1e1 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Fri, 14 Nov 2014 10:35:01 +0530 Subject: [PATCH 11/33] fix event test case --- frappe/core/doctype/event/test_event.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/core/doctype/event/test_event.py b/frappe/core/doctype/event/test_event.py index ab9260b0c5..0da305d482 100644 --- a/frappe/core/doctype/event/test_event.py +++ b/frappe/core/doctype/event/test_event.py @@ -80,7 +80,7 @@ class TestEvent(unittest.TestCase): ev = frappe.get_doc("Event", ev.name) - self.assertEquals(ev._assign, json.dumps(["test@example.com", "test1@example.com"])) + self.assertEquals(set(json.loads(ev._assign)), set(["test@example.com", "test1@example.com"])) # close an assignment todo = frappe.get_doc("ToDo", {"reference_type": ev.doctype, "reference_name": ev.name, From 6b324f451b126f39de29cde1c8c4881fd3db8728 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Fri, 14 Nov 2014 15:57:00 +0600 Subject: [PATCH 12/33] bumped to version 4.5.5 --- frappe/__version__.py | 2 +- frappe/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/__version__.py b/frappe/__version__.py index bb160d0353..1277a42759 100644 --- a/frappe/__version__.py +++ b/frappe/__version__.py @@ -1 +1 @@ -__version__ = "4.5.4" +__version__ = "4.5.5" diff --git a/frappe/hooks.py b/frappe/hooks.py index 18c892439f..685ef8495c 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -3,7 +3,7 @@ app_title = "Frappe Framework" app_publisher = "Web Notes Technologies Pvt. Ltd." app_description = "Full Stack Web Application Framework in Python" app_icon = "assets/frappe/images/frappe.svg" -app_version = "4.5.4" +app_version = "4.5.5" app_color = "#3498db" app_email = "support@frappe.io" diff --git a/setup.py b/setup.py index a626c51a90..517f19c057 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.5.4" +version = "4.5.5" with open("requirements.txt", "r") as f: install_requires = f.readlines() From 66f42121a5680b9b29c9f2b1e7d2b7b7f6579a5c Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 14 Nov 2014 15:59:24 +0530 Subject: [PATCH 13/33] hotfix in event --- frappe/core/doctype/event/event.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frappe/core/doctype/event/event.py b/frappe/core/doctype/event/event.py index a9511a9f2f..a834a06a01 100644 --- a/frappe/core/doctype/event/event.py +++ b/frappe/core/doctype/event/event.py @@ -108,7 +108,9 @@ def get_events(start, end, user=None, for_reminder=False): def add_event(e, date): new_event = e.copy() - enddate = add_days(date,int(date_diff(e.ends_on.split(" ")[0], e.starts_on.split(" ")[0]))) + + enddate = add_days(date,int(date_diff(e.ends_on.split(" ")[0], e.starts_on.split(" ")[0]))) \ + if (e.starts_on and e.ends_on) else date new_event.starts_on = date + " " + e.starts_on.split(" ")[1] if e.ends_on: new_event.ends_on = enddate + " " + e.ends_on.split(" ")[1] From 85e6f4090944536b8b01367d5494395e46e21550 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Fri, 14 Nov 2014 16:31:21 +0600 Subject: [PATCH 14/33] bumped to version 4.5.6 --- frappe/__version__.py | 2 +- frappe/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/__version__.py b/frappe/__version__.py index 1277a42759..933cd02a88 100644 --- a/frappe/__version__.py +++ b/frappe/__version__.py @@ -1 +1 @@ -__version__ = "4.5.5" +__version__ = "4.5.6" diff --git a/frappe/hooks.py b/frappe/hooks.py index 685ef8495c..e25d44d914 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -3,7 +3,7 @@ app_title = "Frappe Framework" app_publisher = "Web Notes Technologies Pvt. Ltd." app_description = "Full Stack Web Application Framework in Python" app_icon = "assets/frappe/images/frappe.svg" -app_version = "4.5.5" +app_version = "4.5.6" app_color = "#3498db" app_email = "support@frappe.io" diff --git a/setup.py b/setup.py index 517f19c057..6cbf9fe70f 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.5.5" +version = "4.5.6" with open("requirements.txt", "r") as f: install_requires = f.readlines() From c152f3ead341137d9475d04200aaa807e25d3664 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Fri, 14 Nov 2014 16:45:04 +0530 Subject: [PATCH 15/33] fix for negative value in money_in_words --- frappe/utils/data.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frappe/utils/data.py b/frappe/utils/data.py index 80de3ddab5..7d69f2bef4 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -325,6 +325,9 @@ def money_in_words(number, main_currency = None, fraction_currency=None): """ from frappe.utils import get_defaults + if not number or flt(number) < 0: + return "" + d = get_defaults() if not main_currency: main_currency = d.get('currency', 'INR') From 4fb0700dc07a009bc5ef0394ebe04300433f1a9d Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Fri, 14 Nov 2014 17:55:32 +0530 Subject: [PATCH 16/33] [minor] fix msgprint from duplicate name --- frappe/model/base_document.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py index c8c264354a..f335e843f4 100644 --- a/frappe/model/base_document.py +++ b/frappe/model/base_document.py @@ -203,7 +203,7 @@ class BaseDocument(object): except Exception, e: if e.args[0]==1062: type, value, traceback = sys.exc_info() - frappe.msgprint(_("Duplicate name {0} {1}".format(self.doctype, self.name))) + frappe.msgprint(_("Duplicate name {0} {1}").format(self.doctype, self.name)) raise frappe.NameError, (self.doctype, self.name, e), traceback else: raise From 08317b8e0e195c0f78f689cb292ecf52e6c1ea65 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Mon, 17 Nov 2014 12:05:13 +0600 Subject: [PATCH 17/33] bumped to version 4.5.7 --- frappe/__version__.py | 2 +- frappe/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/__version__.py b/frappe/__version__.py index 933cd02a88..39be6071fd 100644 --- a/frappe/__version__.py +++ b/frappe/__version__.py @@ -1 +1 @@ -__version__ = "4.5.6" +__version__ = "4.5.7" diff --git a/frappe/hooks.py b/frappe/hooks.py index e25d44d914..f3d3218de8 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -3,7 +3,7 @@ app_title = "Frappe Framework" app_publisher = "Web Notes Technologies Pvt. Ltd." app_description = "Full Stack Web Application Framework in Python" app_icon = "assets/frappe/images/frappe.svg" -app_version = "4.5.6" +app_version = "4.5.7" app_color = "#3498db" app_email = "support@frappe.io" diff --git a/setup.py b/setup.py index 6cbf9fe70f..a3508f40a9 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.5.6" +version = "4.5.7" with open("requirements.txt", "r") as f: install_requires = f.readlines() From 9de77b59de742b2ffc171959debecc8991a09d7c Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 17 Nov 2014 11:30:11 +0530 Subject: [PATCH 18/33] [fix] [hot] birthdays --- frappe/cli.py | 5 +++-- frappe/core/doctype/event/event.py | 8 ++++---- frappe/core/doctype/event/test_event.py | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/frappe/cli.py b/frappe/cli.py index 8868725f03..b4cc5813f2 100755 --- a/frappe/cli.py +++ b/frappe/cli.py @@ -792,7 +792,7 @@ def run_tests(app=None, module=None, doctype=None, verbose=False, tests=(), driv import frappe.test_runner from frappe.utils import sel - sel.start(verbose, driver) + # sel.start(verbose, driver) ret = 1 try: @@ -801,7 +801,8 @@ def run_tests(app=None, module=None, doctype=None, verbose=False, tests=(), driv if len(ret.failures) == 0 and len(ret.errors) == 0: ret = 0 finally: - sel.close() + pass + # sel.close() return ret diff --git a/frappe/core/doctype/event/event.py b/frappe/core/doctype/event/event.py index a834a06a01..ed93839f2e 100644 --- a/frappe/core/doctype/event/event.py +++ b/frappe/core/doctype/event/event.py @@ -131,7 +131,7 @@ def get_events(start, end, user=None, for_reminder=False): # repeat for all years in period for year in range(start_year, end_year+1): date = str(year) + "-" + event_start - if date >= start and date <= repeat: + if date >= start and date <= end and date <= repeat: add_event(e, date) remove_events.append(e) @@ -148,7 +148,7 @@ def get_events(start, end, user=None, for_reminder=False): start_from = date for i in xrange(int(date_diff(end, start) / 30) + 3): - if date >= start and date <= repeat and date >= event_start: + if date >= start and date <= end and date <= repeat and date >= event_start: add_event(e, date) date = add_months(start_from, i+1) @@ -163,7 +163,7 @@ def get_events(start, end, user=None, for_reminder=False): date = add_days(start, weekday - start_weekday) for cnt in xrange(int(date_diff(end, start) / 7) + 3): - if date >= start and date <= repeat and date >= event_start: + if date >= start and date <= end and date <= repeat and date >= event_start: add_event(e, date) date = add_days(date, 7) @@ -173,7 +173,7 @@ def get_events(start, end, user=None, for_reminder=False): if e.repeat_on=="Every Day": for cnt in xrange(date_diff(end, start) + 1): date = add_days(start, cnt) - if date >= event_start and date <= repeat \ + if date >= event_start and date <= end and date <= repeat \ and e[weekdays[getdate(date).weekday()]]: add_event(e, date) remove_events.append(e) diff --git a/frappe/core/doctype/event/test_event.py b/frappe/core/doctype/event/test_event.py index 0da305d482..ba2ee14ecf 100644 --- a/frappe/core/doctype/event/test_event.py +++ b/frappe/core/doctype/event/test_event.py @@ -8,6 +8,8 @@ import frappe.defaults import unittest import json +from frappe.core.doctype.event.event import get_events + test_records = frappe.get_test_records('Event') class TestEvent(unittest.TestCase): @@ -94,3 +96,26 @@ class TestEvent(unittest.TestCase): # cleanup ev.delete() + def test_recurring(self): + ev = frappe.get_doc({ + "doctype":"Event", + "subject": "_Test Event", + "starts_on": "2014-02-01", + "event_type": "Public", + "repeat_this_event": 1, + "repeat_on": "Every Year" + }) + ev.insert() + + ev_list = get_events("2014-02-01", "2014-02-01", "Administrator", for_reminder=True) + self.assertTrue(filter(lambda e: e.name==ev.name, ev_list)) + + ev_list1 = get_events("2015-01-20", "2015-01-20", "Administrator", for_reminder=True) + self.assertFalse(filter(lambda e: e.name==ev.name, ev_list1)) + + ev_list2 = get_events("2014-02-20", "2014-02-20", "Administrator", for_reminder=True) + self.assertFalse(filter(lambda e: e.name==ev.name, ev_list2)) + + ev_list3 = get_events("2015-02-01", "2015-02-01", "Administrator", for_reminder=True) + self.assertTrue(filter(lambda e: e.name==ev.name, ev_list3)) + From 1349402648f060ffa243ba00d74fc28ec48e3b57 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Mon, 17 Nov 2014 13:22:32 +0600 Subject: [PATCH 19/33] bumped to version 4.5.8 --- frappe/__version__.py | 2 +- frappe/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/__version__.py b/frappe/__version__.py index 39be6071fd..9f9f645091 100644 --- a/frappe/__version__.py +++ b/frappe/__version__.py @@ -1 +1 @@ -__version__ = "4.5.7" +__version__ = "4.5.8" diff --git a/frappe/hooks.py b/frappe/hooks.py index f3d3218de8..704053f337 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -3,7 +3,7 @@ app_title = "Frappe Framework" app_publisher = "Web Notes Technologies Pvt. Ltd." app_description = "Full Stack Web Application Framework in Python" app_icon = "assets/frappe/images/frappe.svg" -app_version = "4.5.7" +app_version = "4.5.8" app_color = "#3498db" app_email = "support@frappe.io" diff --git a/setup.py b/setup.py index a3508f40a9..72b4637a12 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.5.7" +version = "4.5.8" with open("requirements.txt", "r") as f: install_requires = f.readlines() From 766d4540b96f7d07f3cd97838afde988ba29241d Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Tue, 18 Nov 2014 15:23:49 +0530 Subject: [PATCH 20/33] [fixes] [minor] based on error reports --- .../core/doctype/custom_field/custom_field.py | 7 +++--- .../doctype/custom_field/test_custom_field.py | 23 ++++++++++++++++++- frappe/database.py | 4 +++- frappe/model/db_schema.py | 4 +++- frappe/tests/test_db.py | 5 ++++ frappe/utils/data.py | 9 +++++--- 6 files changed, 42 insertions(+), 10 deletions(-) diff --git a/frappe/core/doctype/custom_field/custom_field.py b/frappe/core/doctype/custom_field/custom_field.py index 2c2adb92bf..e848481a6d 100644 --- a/frappe/core/doctype/custom_field/custom_field.py +++ b/frappe/core/doctype/custom_field/custom_field.py @@ -9,7 +9,6 @@ from frappe import _ from frappe.model.document import Document class CustomField(Document): - def autoname(self): self.set_fieldname() self.name = self.dt + "-" + self.fieldname @@ -40,9 +39,9 @@ class CustomField(Document): self.create_property_setter() # update the schema - if not frappe.flags.in_test: - from frappe.model.db_schema import updatedb - updatedb(self.dt) + # if not frappe.flags.in_test: + from frappe.model.db_schema import updatedb + updatedb(self.dt) def on_trash(self): # delete property setter entries diff --git a/frappe/core/doctype/custom_field/test_custom_field.py b/frappe/core/doctype/custom_field/test_custom_field.py index ad4def6175..9ddacbe294 100644 --- a/frappe/core/doctype/custom_field/test_custom_field.py +++ b/frappe/core/doctype/custom_field/test_custom_field.py @@ -1,10 +1,31 @@ +# -*- coding: utf-8 -*- + # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # See license.txt +from __future__ import unicode_literals + import frappe import unittest test_records = frappe.get_test_records('Custom Field') +from frappe.model.db_schema import InvalidColumnName + class TestCustomField(unittest.TestCase): - pass + def test_non_ascii(self): + cf = frappe.get_doc({ + "doctype":"Custom Field", + "dt": "ToDo", + "fieldtype": "Data", + "fieldname": "δου" + }) + + self.assertRaises(InvalidColumnName, cf.insert) + + # todo = frappe.get_doc({ + # "doctype": "ToDo", + # "description": "test", + # "δου": "greek" + # }) + # todo.insert() diff --git a/frappe/database.py b/frappe/database.py index d40bf90cb8..bb3085c038 100644 --- a/frappe/database.py +++ b/frappe/database.py @@ -556,4 +556,6 @@ class Database: self._conn = None def escape(self, s): - return unicode(MySQLdb.escape_string((s or "").encode("utf-8")), "utf-8") + if isinstance(s, unicode): + s = (s or "").encode("utf-8") + return unicode(MySQLdb.escape_string(s), "utf-8") diff --git a/frappe/model/db_schema.py b/frappe/model/db_schema.py index 5c11f6f742..e4e370f4ab 100644 --- a/frappe/model/db_schema.py +++ b/frappe/model/db_schema.py @@ -13,6 +13,8 @@ import frappe from frappe import _ from frappe.utils import cstr, cint +class InvalidColumnName(frappe.ValidationError): pass + type_map = { 'Currency': ('decimal', '18,6') ,'Int': ('int', '11') @@ -373,7 +375,7 @@ def validate_column_name(n): n = n.replace(' ','_').strip().lower() import re if re.search("[\W]", n): - frappe.throw(_("Fieldname {0} cannot contain letters, numbers or spaces").format(n)) + frappe.throw(_("Fieldname {0} cannot contain letters, numbers or spaces").format(n), InvalidColumnName) return n diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index f7de01066e..be0e5fcca6 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + # Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors # MIT License. See license.txt @@ -14,3 +16,6 @@ class TestDB(unittest.TestCase): self.assertEquals(frappe.db.get_value("User", {"name": ["<=", "Administrator"]}), "Administrator") self.assertEquals("test1@example.com", frappe.db.get_value("User", {"name": [">", "s"]})) self.assertEquals("test1@example.com", frappe.db.get_value("User", {"name": [">=", "t"]})) + + def test_escape(self): + frappe.db.escape("香港濟生堂製藥有限公司 - IT".encode("utf-8")) diff --git a/frappe/utils/data.py b/frappe/utils/data.py index 7d69f2bef4..952c6bf900 100644 --- a/frappe/utils/data.py +++ b/frappe/utils/data.py @@ -165,9 +165,12 @@ def formatdate(string_date=None, format_string=None): out = frappe.local.user_format or "yyyy-mm-dd" - return out.replace("dd", date.strftime("%d"))\ - .replace("mm", date.strftime("%m"))\ - .replace("yyyy", date.strftime("%Y")) + try: + return out.replace("dd", date.strftime("%d"))\ + .replace("mm", date.strftime("%m"))\ + .replace("yyyy", date.strftime("%Y")) + except ValueError, e: + raise frappe.ValidationError, str(e) def global_date_format(date): """returns date as 1 January 2012""" From 53edaa23fa229fd617d04693dca5ccae49226911 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Wed, 19 Nov 2014 11:48:11 +0530 Subject: [PATCH 21/33] [fix] reportview.js, SUP10183 --- frappe/public/js/frappe/views/reportview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/views/reportview.js b/frappe/public/js/frappe/views/reportview.js index 3e34258249..a849cf1e34 100644 --- a/frappe/public/js/frappe/views/reportview.js +++ b/frappe/public/js/frappe/views/reportview.js @@ -197,7 +197,7 @@ frappe.views.ReportView = frappe.ui.Listing.extend({ // get table_name.column_name get_full_column_name: function(v) { if(!v) return; - return (v[1] ? ('`tab' + v[1] + '`') : this.tab_name) + '.' + v[0]; + return (v[1] ? ('`tab' + v[1] + '`') : this.tab_name) + '.`' + v[0] + '`'; }, // build columns for slickgrid From 9051e56d94375ec1a488e0200debbac09ba15729 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 19 Nov 2014 14:26:40 +0530 Subject: [PATCH 22/33] remove test for custom field --- .../doctype/custom_field/test_custom_field.py | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/frappe/core/doctype/custom_field/test_custom_field.py b/frappe/core/doctype/custom_field/test_custom_field.py index 9ddacbe294..41b0ac3a30 100644 --- a/frappe/core/doctype/custom_field/test_custom_field.py +++ b/frappe/core/doctype/custom_field/test_custom_field.py @@ -13,19 +13,4 @@ test_records = frappe.get_test_records('Custom Field') from frappe.model.db_schema import InvalidColumnName class TestCustomField(unittest.TestCase): - def test_non_ascii(self): - cf = frappe.get_doc({ - "doctype":"Custom Field", - "dt": "ToDo", - "fieldtype": "Data", - "fieldname": "δου" - }) - - self.assertRaises(InvalidColumnName, cf.insert) - - # todo = frappe.get_doc({ - # "doctype": "ToDo", - # "description": "test", - # "δου": "greek" - # }) - # todo.insert() + pass From 06e7c67c155031372a544cbebce0e71b6a70a3b4 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 19 Nov 2014 15:03:44 +0600 Subject: [PATCH 23/33] bumped to version 4.5.9 --- frappe/__version__.py | 2 +- frappe/hooks.py | 2 +- setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frappe/__version__.py b/frappe/__version__.py index 9f9f645091..12cf0f14d4 100644 --- a/frappe/__version__.py +++ b/frappe/__version__.py @@ -1 +1 @@ -__version__ = "4.5.8" +__version__ = "4.5.9" diff --git a/frappe/hooks.py b/frappe/hooks.py index 704053f337..f632099952 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -3,7 +3,7 @@ app_title = "Frappe Framework" app_publisher = "Web Notes Technologies Pvt. Ltd." app_description = "Full Stack Web Application Framework in Python" app_icon = "assets/frappe/images/frappe.svg" -app_version = "4.5.8" +app_version = "4.5.9" app_color = "#3498db" app_email = "support@frappe.io" diff --git a/setup.py b/setup.py index 72b4637a12..c8184c1a8e 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages import os -version = "4.5.8" +version = "4.5.9" with open("requirements.txt", "r") as f: install_requires = f.readlines() From 79ce25d44a2d055a4f98c1b0cbf1d67140f0ba62 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 19 Nov 2014 15:29:28 +0530 Subject: [PATCH 24/33] Validate jinja2 syntax before saving print format --- frappe/core/doctype/print_format/print_format.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/frappe/core/doctype/print_format/print_format.py b/frappe/core/doctype/print_format/print_format.py index a770062147..4d414c50e5 100644 --- a/frappe/core/doctype/print_format/print_format.py +++ b/frappe/core/doctype/print_format/print_format.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals import frappe import frappe.utils +from jinja2 import TemplateSyntaxError from frappe.model.document import Document @@ -16,6 +17,12 @@ class PrintFormat(Document): self.old_doc_type = frappe.db.get_value('Print Format', self.name, 'doc_type') + jenv = frappe.get_jenv() + try: + jenv.from_string(self.html) + except TemplateSyntaxError: + frappe.throw(frappe._("Syntax error in Jinja template")) + def on_update(self): if hasattr(self, 'old_doc_type') and self.old_doc_type: frappe.clear_cache(doctype=self.old_doc_type) From 3e07c1937e7eec8985d2f9feade7067f7e376cd3 Mon Sep 17 00:00:00 2001 From: Pratik Vyas Date: Wed, 19 Nov 2014 16:54:34 +0530 Subject: [PATCH 25/33] fix print format test case --- frappe/core/doctype/print_format/test_records.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/core/doctype/print_format/test_records.json b/frappe/core/doctype/print_format/test_records.json index aab3b96884..b0fac3c7ab 100644 --- a/frappe/core/doctype/print_format/test_records.json +++ b/frappe/core/doctype/print_format/test_records.json @@ -3,6 +3,7 @@ "doctype": "Print Format", "name": "_Test Print Format 1", "module": "core", - "doc_type": "User" + "doc_type": "User", + "html": "" } ] From cab28788a0304c6344e0f96873d705049bf538fa Mon Sep 17 00:00:00 2001 From: nikess Date: Sat, 22 Nov 2014 14:39:13 +0000 Subject: [PATCH 26/33] Fixed missing attribute closing inverted commas --- frappe/public/js/frappe/views/communication.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 79b0352b6e..97e0067a79 100644 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -96,7 +96,7 @@ frappe.views.CommunicationList = Class.extend({ "SMS": "icon-mobile-phone", }[doc.communication_medium] || "icon-envelope"; doc.avatar = frappe.get_gravatar(doc._sender_id); - var comm = $(repl('
\
\ \
\ From 1f0690b05ddd8f9b639e3f2ad1fd01f81d48260f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 24 Nov 2014 13:20:31 +0530 Subject: [PATCH 27/33] [security] [fix] stop client side queries in reportview.py --- frappe/model/db_query.py | 5 +++- frappe/public/js/frappe/views/listview.js | 28 ----------------------- frappe/widgets/reportview.py | 4 ++++ 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/frappe/model/db_query.py b/frappe/model/db_query.py index a5c2f7b723..79ef0e63d4 100644 --- a/frappe/model/db_query.py +++ b/frappe/model/db_query.py @@ -90,7 +90,10 @@ class DatabaseQuery(object): if isinstance(self.filters, basestring): self.filters = json.loads(self.filters) if isinstance(self.fields, basestring): - self.fields = json.loads(self.fields) + if self.fields == "*": + self.fields = ["*"] + else: + self.fields = json.loads(self.fields) if isinstance(self.filters, dict): fdict = self.filters self.filters = [] diff --git a/frappe/public/js/frappe/views/listview.js b/frappe/public/js/frappe/views/listview.js index e80ca5ab98..e9e958aa19 100644 --- a/frappe/public/js/frappe/views/listview.js +++ b/frappe/public/js/frappe/views/listview.js @@ -514,31 +514,3 @@ frappe.views.ListView = Class.extend({ $(parent).append(repl(icon_html, {icon_class: icon_class, label: __(label) || ''})); } }); - -// embeddable -frappe.provide('frappe.views.RecordListView'); -frappe.views.RecordListView = frappe.views.DocListView.extend({ - init: function(doctype, wrapper, ListView) { - this.doctype = doctype; - this.wrapper = wrapper; - this.listview = new ListView(this, doctype); - this.listview.parent = this; - this.setup(); - }, - - setup: function() { - var me = this; - me.page_length = 10; - $(me.wrapper).empty(); - me.init_list(); - }, - - get_args: function() { - var args = this._super(); - $.each((this.default_filters || []), function(i, f) { - args.filters.push(f); - }); - args.docstatus = args.docstatus.concat((this.default_docstatus || [])); - return args; - }, -}); diff --git a/frappe/widgets/reportview.py b/frappe/widgets/reportview.py index 304b874f21..7f339e03c7 100644 --- a/frappe/widgets/reportview.py +++ b/frappe/widgets/reportview.py @@ -20,6 +20,7 @@ def execute(doctype, query=None, filters=None, fields=None, or_filters=None, doc order_by, limit_start, limit_page_length, as_list, with_childnames, debug) def get_form_params(): + """Stringify GET request parameters.""" data = frappe._dict(frappe.local.form_dict) del data["cmd"] @@ -31,6 +32,9 @@ def get_form_params(): if isinstance(data.get("docstatus"), basestring): data["docstatus"] = json.loads(data["docstatus"]) + # queries must always be server side + data.query = None + return data def compress(data): From 5de44ed2b8ef19622b5fab14b3b598d9e9b76ba8 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 24 Nov 2014 13:10:11 +0530 Subject: [PATCH 28/33] Validate naming series . missing --- frappe/model/naming.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frappe/model/naming.py b/frappe/model/naming.py index 4f1f827758..804dcc368a 100644 --- a/frappe/model/naming.py +++ b/frappe/model/naming.py @@ -84,6 +84,8 @@ def make_autoname(key, doctype=''): if not "#" in key: key = key + ".#####" + elif not "." in key: + frappe.throw(_("Invalid naming series (. missing)") + (_(" for {0}").format(doctype) if doctype else "")) n = '' l = key.split('.') From 08efd4b412b46bf186d896bfefcd113585f75d1f Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 24 Nov 2014 16:28:25 +0530 Subject: [PATCH 29/33] [translations] updated via frappe.io/translator --- frappe/translate.py | 1 + frappe/translations/ar.csv | 6 +- frappe/translations/de.csv | 400 +++--- frappe/translations/el.csv | 18 +- frappe/translations/es.csv | 386 +++--- frappe/translations/fr.csv | 32 +- frappe/translations/hi.csv | 4 +- frappe/translations/hr.csv | 4 +- frappe/translations/id.csv | 24 +- frappe/translations/it.csv | 4 +- frappe/translations/ja.csv | 239 ++-- frappe/translations/kn.csv | 16 +- frappe/translations/ko.csv | 18 +- frappe/translations/nl.csv | 4 +- frappe/translations/pl.csv | 2336 ++++++++++++++++++------------------ frappe/translations/pt.csv | 48 +- frappe/translations/ro.csv | 24 +- frappe/translations/ru.csv | 16 +- frappe/translations/sr.csv | 4 +- frappe/translations/ta.csv | 4 +- frappe/translations/th.csv | 4 +- frappe/translations/tr.csv | 756 ++++++------ frappe/translations/vi.csv | 16 +- 23 files changed, 2182 insertions(+), 2182 deletions(-) diff --git a/frappe/translate.py b/frappe/translate.py index 1ac0a0ccb1..bfa34d92bd 100644 --- a/frappe/translate.py +++ b/frappe/translate.py @@ -298,6 +298,7 @@ def read_csv_file(path): from csv import reader with codecs.open(path, 'r', 'utf-8') as msgfile: data = msgfile.read() + data = data.replace(chr(28), "").replace(chr(29), "") data = reader([r.encode('utf-8') for r in data.splitlines()]) newdata = [[unicode(val, 'utf-8') for val in row] for row in data] return newdata diff --git a/frappe/translations/ar.csv b/frappe/translations/ar.csv index 87abadafa7..fbe83ea0b5 100644 --- a/frappe/translations/ar.csv +++ b/frappe/translations/ar.csv @@ -948,7 +948,7 @@ Select Type,حدد نوع Select User or DocType to start.,حدد العضو أو DOCTYPE للبدء. Select a Banner Image first.,تحديد صورة بانر الأول. Select an image of approx width 150px with a transparent background for best results.,اختر صورة من تقريبا عرض 150px مع خلفية شفافة للحصول على أفضل النتائج. -Select dates to create a new , +Select dates to create a new ,Select dates to create a new "Select modules to be shown (based on permission). If hidden, they will be hidden for all users.",حدد وحدات ليتم عرضها (على أساس إذن ) . إذا مخفي ، وسوف تكون مخفية لجميع المستخدمين. Select or drag across time slots to create a new event.,حدد أو اسحب عبر فتحات الوقت لإنشاء حدث جديد. "Select target = ""_blank"" to open in a new page.","حدد الهدف = "" _blank "" لفتح صفحة جديدة في ." @@ -1070,7 +1070,7 @@ Table,جدول Table {0} cannot be empty,الجدول {0} لا يمكن أن تكون فارغة Tag,بطاقة Tag Name,علامة الاسم -Tags,به +Tags,علامات Tahoma,تاهوما Target,الهدف Tasks,المهام @@ -1169,7 +1169,7 @@ User Permissions Manager,مدير ضوابط المستخدم User Roles,أدوار المستخدم User Tags,الكلمات المستخدم User Type,نوع المستخدم -"User Type ""System User"" can access Desktop. ""Website User"" can only be logged into the website and portal pages. ", +"User Type ""System User"" can access Desktop. ""Website User"" can only be logged into the website and portal pages. ","User Type ""System User"" can access Desktop. ""Website User"" can only be logged into the website and portal pages. " User Vote,تصويت المستخدم User not allowed to delete {0}: {1},المستخدم لا يسمح لحذف {0}: {1} User permissions should not apply for this Link,لا ينبغي تطبيق أذونات المستخدم لهذا الرابط diff --git a/frappe/translations/de.csv b/frappe/translations/de.csv index 0dad89ed68..26081a12b9 100644 --- a/frappe/translations/de.csv +++ b/frappe/translations/de.csv @@ -8,16 +8,16 @@ "000 is black, fff is white","000 ist schwarz, fff ist weiß" 2 days ago,vor 2 Tagen "[?]"," [?] " -"\
  • field:[fieldname] - By Field\
  • naming_series: - By Naming Series (field called naming_series must be present\
  • Prompt - Prompt user for a name\
  • [series] - Series by prefix (separated by a dot); for example PRE.#####\')"">Naming Options", +"\
  • field:[fieldname] - By Field\
  • naming_series: - By Naming Series (field called naming_series must be present\
  • Prompt - Prompt user for a name\
  • [series] - Series by prefix (separated by a dot); for example PRE.#####\')"">Naming Options","\
  • field:[fieldname] - By Field\
  • naming_series: - By Naming Series (field called naming_series must be present\
  • Prompt - Prompt user for a name\
  • [series] - Series by prefix (separated by a dot); for example PRE.#####\')"">Naming Options" new type of document, neue Art von Dokument "document type..., e.g. customer"," Dokumententyp ... , z. B. Kunden " e.g. (55 + 434) / 4 or =Math.sin(Math.PI/2)..., zB (55 + 434) / 4 oder = Math.sin (Math.PI / 2) ... module name..., Modulnamen ... text in document type, Text in Dokumenttyp A user can be permitted to multiple records of the same DocType.,Ein Benutzer kann die Genehmigung für mehrere Datensätze des gleichen DocType haben. -About,Info -About Us Settings,Über uns Einstellungen -About Us Team Member,Über uns Teammitglied +About,Information +About Us Settings,"""Über uns"" Einstellungen" +About Us Team Member,"""Über uns"" Teammitglied" Action,Aktion "Actions for workflow (e.g. Approve, Cancel).","Aktionen für Workflows (z. B. genehmigen , Abbruch) ." Add,Hinzufügen @@ -27,45 +27,45 @@ Add Attachments,Anhänge hinzufügen Add Bookmark,Lesezeichen hinzufügen Add CSS,CSS hinzufügen Add Column,Spalte hinzufügen -Add Filter, +Add Filter,Filter hinzufügen Add Google Analytics ID: eg. UA-89XXX57-1. Please search help on Google Analytics for more information.,Google Analytics-ID hinzufügen: z. B. UA-89XXX57-1. Weitere Informationen finden Sie bei Google Analytics. Add Message,Nachricht hinzufügen Add New Permission Rule,Neue Berechtigungsregel hinzufügen Add Reply,Antwort hinzufügen -Add Tag, -Add Total Row,Gesamtzeile hinzufügen +Add Tag,Stichwort hinzufügen +Add Total Row,Summenzeile hinzufügen Add a New Role,Neue Rolle hinzufügen Add a banner to the site. (small banners are usually good),Der Website ein Werbebanner hinzufügen. (kleine Banner sind in der Regel gut) Add all roles,Alle Rollen hinzufügen Add attachment,Anhang hinzufügen -Add code as <script>,Code als