diff --git a/frappe/__init__.py b/frappe/__init__.py
index ee8f544f18..f1633d21b6 100644
--- a/frappe/__init__.py
+++ b/frappe/__init__.py
@@ -14,7 +14,7 @@ import os, sys, importlib, inspect, json
from .exceptions import *
from .utils.jinja import get_jenv, get_template, render_template
-__version__ = '8.1.2'
+__version__ = '8.1.3'
__title__ = "Frappe Framework"
local = Local()
@@ -139,6 +139,7 @@ def init(site, sites_path=None, new_site=False):
local.module_app = None
local.app_modules = None
local.system_settings = None
+ local.system_country = None
local.user = None
local.user_perms = None
@@ -946,6 +947,7 @@ def make_property_setter(args, ignore_validate=False, validate_fields_for_doctyp
})
ps.flags.ignore_validate = ignore_validate
ps.flags.validate_fields_for_doctype = validate_fields_for_doctype
+ ps.validate_fieldtype_change()
ps.insert()
def import_doc(path, ignore_links=False, ignore_insert=False, insert=False):
@@ -1360,4 +1362,9 @@ def get_active_domains():
active_domains.append("")
cache().hset("domains", "active_domains", active_domains)
- return active_domains
\ No newline at end of file
+ return active_domains
+
+def get_system_country():
+ if local.system_country is None:
+ local.system_country = db.get_single_value('System Settings', 'country') or ''
+ return local.system_country
diff --git a/frappe/contacts/doctype/address/address.json b/frappe/contacts/doctype/address/address.json
index a3c8bd57d4..c3b655cec5 100644
--- a/frappe/contacts/doctype/address/address.json
+++ b/frappe/contacts/doctype/address/address.json
@@ -12,6 +12,7 @@
"editable_grid": 0,
"fields": [
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -41,11 +42,12 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
- "description": "Name of person or organization that this address belongs to.",
+ "description": "",
"fieldname": "address_title",
"fieldtype": "Data",
"hidden": 0,
@@ -70,6 +72,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -99,6 +102,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -127,6 +131,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -155,6 +160,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -183,6 +189,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -212,6 +219,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -240,6 +248,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -269,6 +278,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -297,6 +307,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -325,6 +336,7 @@
"width": "50%"
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -353,6 +365,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -381,6 +394,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -409,6 +423,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -439,6 +454,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -469,6 +485,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -498,6 +515,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -528,6 +546,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -569,7 +588,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-04-10 13:09:45.030542",
+ "modified": "2017-06-21 11:30:20.719590",
"modified_by": "Administrator",
"module": "Contacts",
"name": "Address",
diff --git a/frappe/contacts/doctype/contact/contact.json b/frappe/contacts/doctype/contact/contact.json
index a9948e00d9..d40866b290 100644
--- a/frappe/contacts/doctype/contact/contact.json
+++ b/frappe/contacts/doctype/contact/contact.json
@@ -13,6 +13,7 @@
"engine": "InnoDB",
"fields": [
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -42,36 +43,7 @@
"unique": 0
},
{
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "salutation",
- "fieldtype": "Link",
- "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": "Salutation",
- "length": 0,
- "no_copy": 0,
- "options": "Salutation",
- "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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -102,6 +74,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -132,6 +105,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -163,6 +137,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -193,6 +168,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -220,6 +196,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -250,6 +227,38 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "salutation",
+ "fieldtype": "Link",
+ "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": "Salutation",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Salutation",
+ "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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -280,6 +289,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -310,6 +320,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 1,
"collapsible": 0,
@@ -340,6 +351,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -369,6 +381,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -398,6 +411,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -430,6 +444,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -460,6 +475,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -489,6 +505,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -518,6 +535,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -547,6 +565,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -575,6 +594,7 @@
"unique": 0
},
{
+ "allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
@@ -615,7 +635,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2017-04-10 13:09:27.880530",
+ "modified": "2017-06-21 17:17:44.694188",
"modified_by": "Administrator",
"module": "Contacts",
"name": "Contact",
diff --git a/frappe/core/doctype/custom_role/custom_role.py b/frappe/core/doctype/custom_role/custom_role.py
index 2e183bc205..25257e1a23 100644
--- a/frappe/core/doctype/custom_role/custom_role.py
+++ b/frappe/core/doctype/custom_role/custom_role.py
@@ -7,7 +7,9 @@ import frappe
from frappe.model.document import Document
class CustomRole(Document):
- pass
+ def validate(self):
+ if self.report and not self.ref_doctype:
+ self.ref_doctype = frappe.db.get_value('Report', self.report, 'ref_doctype')
def get_custom_allowed_roles(field, name):
allowed_roles = []
diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py
index ea7d87b986..60cf53ef22 100644
--- a/frappe/core/doctype/doctype/doctype.py
+++ b/frappe/core/doctype/doctype/doctype.py
@@ -623,10 +623,24 @@ def validate_permissions_for_doctype(doctype, for_remove=False):
for perm in doctype.get("permissions"):
perm.db_update()
+ clear_permissions_cache(doctype.name)
+
+def clear_permissions_cache(doctype):
+ frappe.clear_cache(doctype=doctype)
+ delete_notification_count_for(doctype)
+ for user in frappe.db.sql_list("""select
+ distinct `tabHas Role`.parent
+ from
+ `tabHas Role`,
+ tabDocPerm
+ where tabDocPerm.parent = %s
+ and tabDocPerm.role = `tabHas Role`.role""", doctype):
+ frappe.clear_cache(user=user)
+
def validate_permissions(doctype, for_remove=False):
permissions = doctype.get("permissions")
if not permissions:
- frappe.throw(_('Enter at least one permission row'), frappe.MandatoryError)
+ frappe.msgprint(_('No Permissions Specified'), alert=True, indicator='orange')
issingle = issubmittable = isimportable = False
if doctype:
issingle = cint(doctype.issingle)
diff --git a/frappe/core/doctype/report/report.py b/frappe/core/doctype/report/report.py
index 143a0cf6b9..6151890183 100644
--- a/frappe/core/doctype/report/report.py
+++ b/frappe/core/doctype/report/report.py
@@ -39,6 +39,7 @@ class Report(Document):
if self.report_type == "Report Builder":
self.update_report_json()
+ def before_insert(self):
self.set_doctype_roles()
def on_update(self):
@@ -48,11 +49,10 @@ class Report(Document):
delete_custom_role('report', self.name)
def set_doctype_roles(self):
- if self.get('roles'): return
-
- doc = frappe.get_meta(self.ref_doctype)
- roles = [{'role': d.role} for d in doc.permissions if d.permlevel==0]
- self.set('roles', roles)
+ if not self.get('roles'):
+ meta = frappe.get_meta(self.ref_doctype)
+ roles = [{'role': d.role} for d in meta.permissions if d.permlevel==0]
+ self.set('roles', roles)
def is_permitted(self):
"""Returns true if Has Role is not set or the user is allowed."""
@@ -153,7 +153,7 @@ class Report(Document):
for c in columns]
out = out + [list(d) for d in result]
-
+
if as_dict:
data = []
for row in out:
diff --git a/frappe/core/page/permission_manager/permission_manager.py b/frappe/core/page/permission_manager/permission_manager.py
index 3f787a42fc..626bb1c20d 100644
--- a/frappe/core/page/permission_manager/permission_manager.py
+++ b/frappe/core/page/permission_manager/permission_manager.py
@@ -6,8 +6,10 @@ import frappe
import frappe.defaults
from frappe.modules.import_file import get_file_path, read_doc_from_file
from frappe.translate import send_translations
-from frappe.desk.notifications import delete_notification_count_for
-from frappe.permissions import reset_perms, get_linked_doctypes, get_all_perms, setup_custom_perms
+from frappe.permissions import (reset_perms, get_linked_doctypes, get_all_perms,
+ setup_custom_perms, add_permission)
+from frappe.core.doctype.doctype.doctype import (clear_permissions_cache,
+ validate_permissions_for_doctype)
from frappe import _
@frappe.whitelist()
@@ -61,20 +63,7 @@ def get_permissions(doctype=None, role=None):
@frappe.whitelist()
def add(parent, role, permlevel):
frappe.only_for("System Manager")
- setup_custom_perms(parent)
-
- frappe.get_doc({
- "doctype":"Custom DocPerm",
- "__islocal": 1,
- "parent": parent,
- "parenttype": "DocType",
- "parentfield": "permissions",
- "role": role,
- "permlevel": permlevel,
- "read": 1
- }).save()
-
- validate_and_reset(parent)
+ add_permission(parent, role, permlevel)
@frappe.whitelist()
def update(doctype, role, permlevel, ptype, value=None):
@@ -88,7 +77,7 @@ def update(doctype, role, permlevel, ptype, value=None):
frappe.db.sql("""update `tabCustom DocPerm` set `%s`=%s where name=%s"""\
% (frappe.db.escape(ptype), '%s', '%s'), (value, name))
- validate_and_reset(doctype)
+ validate_permissions_for_doctype(doctype)
return out
@@ -103,27 +92,14 @@ def remove(doctype, role, permlevel):
if not frappe.get_all('Custom DocPerm', dict(parent=doctype)):
frappe.throw(_('There must be atleast one permission rule.'), title=_('Cannot Remove'))
- validate_and_reset(doctype, for_remove=True)
-
-def validate_and_reset(doctype, for_remove=False):
- from frappe.core.doctype.doctype.doctype import validate_permissions_for_doctype
- validate_permissions_for_doctype(doctype, for_remove)
- clear_doctype_cache(doctype)
+ validate_permissions_for_doctype(doctype, for_remove=True)
@frappe.whitelist()
def reset(doctype):
frappe.only_for("System Manager")
reset_perms(doctype)
- clear_doctype_cache(doctype)
-
-def clear_doctype_cache(doctype):
- frappe.clear_cache(doctype=doctype)
- delete_notification_count_for(doctype)
- for user in frappe.db.sql_list("""select distinct `tabHas Role`.parent from `tabHas Role`,
- tabDocPerm
- where tabDocPerm.parent = %s
- and tabDocPerm.role = `tabHas Role`.role""", doctype):
- frappe.clear_cache(user=user)
+ clear_permissions_cache(doctype)
+
@frappe.whitelist()
def get_users_with_role(role):
diff --git a/frappe/core/report/todo/__init__.py b/frappe/core/report/todo/__init__.py
deleted file mode 100644
index 0e57cb68c3..0000000000
--- a/frappe/core/report/todo/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
-# MIT License. See license.txt
-
diff --git a/frappe/custom/doctype/custom_field/custom_field.py b/frappe/custom/doctype/custom_field/custom_field.py
index 7265cee8a6..57ea7a2b0b 100644
--- a/frappe/custom/doctype/custom_field/custom_field.py
+++ b/frappe/custom/doctype/custom_field/custom_field.py
@@ -73,7 +73,8 @@ class CustomField(Document):
@frappe.whitelist()
def get_fields_label(doctype=None):
- return [{"value": df.fieldname or "", "label": _(df.label or "")} for df in frappe.get_meta(doctype).get("fields")]
+ return [{"value": df.fieldname or "", "label": _(df.label or "")}
+ for df in frappe.get_meta(doctype).get("fields")]
def create_custom_field_if_values_exist(doctype, df):
df = frappe._dict(df)
diff --git a/frappe/custom/doctype/property_setter/property_setter.py b/frappe/custom/doctype/property_setter/property_setter.py
index 997d8443a1..070001fe02 100644
--- a/frappe/custom/doctype/property_setter/property_setter.py
+++ b/frappe/custom/doctype/property_setter/property_setter.py
@@ -3,9 +3,12 @@
from __future__ import unicode_literals
import frappe
+from frappe import _
from frappe.model.document import Document
+not_allowed_fieldtype_change = ['naming_series']
+
class PropertySetter(Document):
def autoname(self):
self.name = self.doc_type + "-" \
@@ -13,6 +16,18 @@ class PropertySetter(Document):
+ self.property
def validate(self):
+ self.validate_fieldtype_change()
+ self.delete_property_setter()
+
+ # clear cache
+ frappe.clear_cache(doctype = self.doc_type)
+
+ def validate_fieldtype_change(self):
+ if self.field_name in not_allowed_fieldtype_change and \
+ self.property == 'fieldtype':
+ frappe.throw(_("Field type cannot be changed for {0}").format(self.field_name))
+
+ def delete_property_setter(self):
"""delete other property setters on this, if this is new"""
if self.get('__islocal'):
frappe.db.sql("""delete from `tabProperty Setter` where
@@ -21,9 +36,6 @@ class PropertySetter(Document):
and ifnull(field_name,'') = ifnull(%(field_name)s, '')
and property = %(property)s""", self.get_valid_dict())
- # clear cache
- frappe.clear_cache(doctype = self.doc_type)
-
def get_property_list(self, dt):
return frappe.db.sql("""select fieldname, label, fieldtype
from tabDocField
diff --git a/frappe/desk/form/meta.py b/frappe/desk/form/meta.py
index 310193c5f8..48cacab3f6 100644
--- a/frappe/desk/form/meta.py
+++ b/frappe/desk/form/meta.py
@@ -65,7 +65,11 @@ class FormMeta(Meta):
def _get_path(fname):
return os.path.join(path, scrub(fname))
+ system_country = frappe.get_system_country()
+
self._add_code(_get_path(self.name + '.js'), '__js')
+ if system_country:
+ self._add_code(_get_path(os.path.join('regional', system_country + '.js')), '__js')
self._add_code(_get_path(self.name + '.css'), "__css")
self._add_code(_get_path(self.name + '_list.js'), '__list_js')
self._add_code(_get_path(self.name + '_calendar.js'), '__calendar_js')
diff --git a/frappe/desk/page/setup_wizard/setup_wizard.py b/frappe/desk/page/setup_wizard/setup_wizard.py
index dcc9e2bcd8..9a11894ce0 100755
--- a/frappe/desk/page/setup_wizard/setup_wizard.py
+++ b/frappe/desk/page/setup_wizard/setup_wizard.py
@@ -86,6 +86,11 @@ def update_user_name(args):
first_name, last_name = first_name.split(' ', 1)
if args.get("email"):
+ if frappe.db.exists('User', args.get('email')):
+ # running again
+ return
+
+
args['name'] = args.get("email")
_mute_emails, frappe.flags.mute_emails = frappe.flags.mute_emails, True
diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py
index cecd1bdbd9..3d743f77da 100644
--- a/frappe/desk/query_report.py
+++ b/frappe/desk/query_report.py
@@ -9,6 +9,7 @@ import os, json
from frappe import _
from frappe.modules import scrub, get_module_path
from frappe.utils import flt, cint, get_html_format, cstr
+from frappe.model.utils import render_include
from frappe.translate import send_translations
import frappe.desk.reportview
from frappe.permissions import get_role_permissions
@@ -55,7 +56,7 @@ def get_script(report_name):
send_translations(frappe.get_lang_dict("report", report_name))
return {
- "script": script,
+ "script": render_include(script),
"html_format": html_format
}
@@ -104,7 +105,7 @@ def run(report_name, filters=None, user=None):
if cint(report.add_total_row) and result:
result = add_total_row(result, columns)
-
+
return {
"result": result,
"columns": columns,
@@ -145,7 +146,7 @@ def export_query():
# add column headings
for idx in range(len(data.columns)):
result[0].append(columns[idx]["label"])
-
+
# build table from dict
if isinstance(data.result[0], dict):
for i,row in enumerate(data.result):
@@ -381,4 +382,4 @@ def get_user_match_filters(doctypes, ref_doctype):
if filter_list:
match_filters[dt] = filter_list
- return match_filters
+ return match_filters
\ No newline at end of file
diff --git a/frappe/desk/report/__init__.py b/frappe/desk/report/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frappe/desk/report/todo/__init__.py b/frappe/desk/report/todo/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/frappe/core/report/todo/todo.js b/frappe/desk/report/todo/todo.js
similarity index 88%
rename from frappe/core/report/todo/todo.js
rename to frappe/desk/report/todo/todo.js
index 805991cc40..bb2e0f7846 100644
--- a/frappe/core/report/todo/todo.js
+++ b/frappe/desk/report/todo/todo.js
@@ -1,5 +1,6 @@
// Copyright (c) 2016, Frappe Technologies and contributors
// For license information, please see license.txt
+/* eslint-disable */
frappe.query_reports["ToDo"] = {
"filters": [
diff --git a/frappe/core/report/todo/todo.json b/frappe/desk/report/todo/todo.json
similarity index 86%
rename from frappe/core/report/todo/todo.json
rename to frappe/desk/report/todo/todo.json
index 18ff072c23..b42c4c9c67 100644
--- a/frappe/core/report/todo/todo.json
+++ b/frappe/desk/report/todo/todo.json
@@ -7,9 +7,9 @@
"doctype": "Report",
"idx": 3,
"is_standard": "Yes",
- "modified": "2017-02-24 20:13:12.217943",
+ "modified": "2017-06-21 18:18:50.748793",
"modified_by": "Administrator",
- "module": "Core",
+ "module": "Desk",
"name": "ToDo",
"owner": "Administrator",
"ref_doctype": "ToDo",
diff --git a/frappe/core/report/todo/todo.py b/frappe/desk/report/todo/todo.py
similarity index 98%
rename from frappe/core/report/todo/todo.py
rename to frappe/desk/report/todo/todo.py
index 8757c05d05..a51d44fe08 100644
--- a/frappe/core/report/todo/todo.py
+++ b/frappe/desk/report/todo/todo.py
@@ -31,5 +31,4 @@ def execute(filters=None):
result.append([todo.name, todo.priority, todo.date, todo.description,
todo.owner, todo.assigned_by, todo.reference])
- return columns, result
-
+ return columns, result
\ No newline at end of file
diff --git a/frappe/docs/index.html b/frappe/docs/index.html
index 73d69f96ea..a70cba3109 100644
--- a/frappe/docs/index.html
+++ b/frappe/docs/index.html
@@ -32,8 +32,8 @@
Javascript, HTML/CSS with MySQL as the backend. It was built for ERPNext
but is pretty generic and can be used to build database driven apps.
-The key difference in Frappe compared to other frameworks is that in Frappe,
-metadata is also treated as data and it can be used to build frontend
+
The key differece in Frappe compared to other frameworks is that Frappe
+is that meta-data is also treated as data and is used to build front-ends
very easily. Frappe comes with a full blown admin UI called the Desk
that handles forms, navigation, lists, menus, permissions, file attachment
and much more out of the box.
diff --git a/frappe/model/document.py b/frappe/model/document.py
index 74f6ab0680..3e8db22802 100644
--- a/frappe/model/document.py
+++ b/frappe/model/document.py
@@ -4,7 +4,6 @@
from __future__ import unicode_literals, print_function
import frappe
import time
-import redis
from frappe import _, msgprint
from frappe.utils import flt, cstr, now, get_datetime_str, file_lock
from frappe.utils.background_jobs import enqueue
diff --git a/frappe/model/naming.py b/frappe/model/naming.py
index ef431adfda..3f0b1b7228 100644
--- a/frappe/model/naming.py
+++ b/frappe/model/naming.py
@@ -8,17 +8,16 @@ from frappe.utils import now_datetime, cint
import re
def set_new_name(doc):
- """Sets the `name`` property for the document based on various rules.
-
- 1. If amened doc, set suffix.
- 3. If `autoname` method is declared, then call it.
- 4. If `autoname` property is set in the DocType (`meta`), then build it using the `autoname` property.
- 2. If `name` is already defined, use that name
- 5. If no rule defined, use hash.
+ """
+ Sets the `name` property for the document based on various rules.
- #### Note:
+ 1. If amended doc, set suffix.
+ 2. If `autoname` method is declared, then call it.
+ 3. If `autoname` property is set in the DocType (`meta`), then build it using the `autoname` property.
+ 4. If no rule defined, use hash.
- :param doc: Document to be named."""
+ :param doc: Document to be named.
+ """
doc.run_method("before_naming")
diff --git a/frappe/model/utils/__init__.py b/frappe/model/utils/__init__.py
index 217ad47a54..c795ae2159 100644
--- a/frappe/model/utils/__init__.py
+++ b/frappe/model/utils/__init__.py
@@ -61,3 +61,20 @@ def render_include(content):
break
return content
+
+def get_fetch_values(doctype, fieldname, value):
+ '''Returns fetch value dict for the given object
+
+ :param doctype: Target doctype
+ :param fieldname: Link fieldname selected
+ :param value: Value selected
+ '''
+ out = {}
+ meta = frappe.get_meta(doctype)
+ link_df = meta.get_field(fieldname)
+ for df in meta.get_fields_to_fetch(fieldname):
+ # example shipping_address.gistin
+ link_field, source_fieldname = df.options.split('.', 1)
+ out[df.fieldname] = frappe.db.get_value(link_df.options, value, source_fieldname)
+
+ return out
diff --git a/frappe/model/utils/user_settings.py b/frappe/model/utils/user_settings.py
index 86498fc507..1034334049 100644
--- a/frappe/model/utils/user_settings.py
+++ b/frappe/model/utils/user_settings.py
@@ -16,7 +16,7 @@ def get_user_settings(doctype, for_update=False):
if not for_update:
update_user_settings(doctype, user_settings, True)
-
+
return user_settings or '{}'
def update_user_settings(doctype, user_settings, for_update=False):
diff --git a/frappe/modules/import_file.py b/frappe/modules/import_file.py
index 5f7c04c7f5..57c671b407 100644
--- a/frappe/modules/import_file.py
+++ b/frappe/modules/import_file.py
@@ -34,7 +34,6 @@ def get_file_path(module, dt, dn):
def import_file_by_path(path, force=False, data_import=False, pre_process=None, ignore_version=None,
reset_permissions=False):
- frappe.flags.in_import = True
try:
docs = read_doc_from_file(path)
except IOError:
@@ -54,8 +53,10 @@ def import_file_by_path(path, force=False, data_import=False, pre_process=None,
original_modified = doc.get("modified")
+ frappe.flags.in_import = True
import_doc(doc, force=force, data_import=data_import, pre_process=pre_process,
ignore_version=ignore_version, reset_permissions=reset_permissions)
+ frappe.flags.in_import = False
if original_modified:
# since there is a new timestamp on the file, update timestamp in
@@ -67,7 +68,6 @@ def import_file_by_path(path, force=False, data_import=False, pre_process=None,
(doc['doctype'], '%s', '%s'),
(original_modified, doc['name']))
- frappe.flags.in_import = False
return True
def read_doc_from_file(path):
diff --git a/frappe/patches.txt b/frappe/patches.txt
index 9fb0206557..74ffc5315c 100644
--- a/frappe/patches.txt
+++ b/frappe/patches.txt
@@ -183,4 +183,5 @@ frappe.patches.v8_0.set_currency_field_precision # 2017-05-09
frappe.patches.v8_0.rename_print_to_printing
frappe.patches.v7_1.disabled_print_settings_for_custom_print_format
frappe.patches.v8_0.update_desktop_icons
-frappe.patches.v8_0.update_gender_and_salutation
\ No newline at end of file
+frappe.patches.v8_0.update_gender_and_salutation
+execute:frappe.db.sql('update tabReport set module="Desk" where name="ToDo"')
\ No newline at end of file
diff --git a/frappe/permissions.py b/frappe/permissions.py
index 22342d9811..13da62d366 100644
--- a/frappe/permissions.py
+++ b/frappe/permissions.py
@@ -330,7 +330,7 @@ def get_all_perms(role):
'''Returns valid permissions for a given role'''
perms = frappe.get_all('DocPerm', fields='*', filters=dict(role=role))
custom_perms = frappe.get_all('Custom DocPerm', fields='*', filters=dict(role=role))
- doctypes_with_custom_perms = frappe.db.sql_list("""select distinct parent
+ doctypes_with_custom_perms = frappe.db.sql_list("""select distinct parent
from `tabCustom DocPerm`""")
for p in perms:
@@ -458,6 +458,31 @@ def setup_custom_perms(parent):
copy_perms(parent)
return True
+def add_permission(doctype, role, permlevel=0):
+ '''Add a new permission rule to the given doctype
+ for the given Role and Permission Level'''
+ from frappe.core.doctype.doctype.doctype import validate_permissions_for_doctype
+ setup_custom_perms(doctype)
+
+ if frappe.db.get_value('Custom DocPerm', dict(parent=doctype, role=role,
+ permlevel=permlevel)):
+ return
+
+ custom_docperm = frappe.get_doc({
+ "doctype":"Custom DocPerm",
+ "__islocal": 1,
+ "parent": doctype,
+ "parenttype": "DocType",
+ "parentfield": "permissions",
+ "role": role,
+ 'read': 1,
+ "permlevel": permlevel,
+ })
+
+ custom_docperm.save()
+
+ validate_permissions_for_doctype(doctype)
+
def copy_perms(parent):
'''Copy all DocPerm in to Custom DocPerm for the given document'''
for d in frappe.get_all('DocPerm', fields='*', filters=dict(parent=parent)):
@@ -480,3 +505,4 @@ def get_linked_doctypes(dt):
"options": ("!=", "[Select]")
})
]))
+
diff --git a/frappe/public/css/form.css b/frappe/public/css/form.css
index 64d2056de9..1272485515 100644
--- a/frappe/public/css/form.css
+++ b/frappe/public/css/form.css
@@ -223,6 +223,14 @@ h6.uppercase,
.badge-important {
background-color: #e74c3c;
}
+.address-box {
+ background-color: #fafbfc;
+ padding: 0px 15px;
+ margin: 15px 0px;
+ border: 1px solid #d1d8dd;
+ border-radius: 3px;
+ font-size: 12px;
+}
.timeline {
margin: 30px 0px;
}
@@ -272,7 +280,7 @@ h6.uppercase,
}
.timeline-item.user-content .media-body {
border: 1px solid #d1d8dd;
- border-radius: 2px;
+ border-radius: 3px;
margin-left: -7px;
position: relative;
overflow: visible;
@@ -386,7 +394,7 @@ h6.uppercase,
.timeline-head {
background-color: white;
border: 1px solid #d1d8dd;
- border-radius: 2px;
+ border-radius: 3px;
position: relative;
z-index: 1;
}
diff --git a/frappe/public/css/website.css b/frappe/public/css/website.css
index e0f122ba4d..a02316f7b9 100644
--- a/frappe/public/css/website.css
+++ b/frappe/public/css/website.css
@@ -290,6 +290,14 @@ a.no-decoration:active {
.avatar-large .standard-image {
font-size: 36px;
}
+.avatar-xl {
+ margin-right: 10px;
+ width: 108px;
+ height: 108px;
+}
+.avatar-xl .standard-image {
+ font-size: 72px;
+}
.avatar-xs {
margin-right: 3px;
margin-top: -2px;
@@ -980,3 +988,8 @@ li.footer-child-item {
.page-card .btn {
margin-top: 30px;
}
+.bordered {
+ border: 1px solid #d1d8dd;
+ padding: 10px;
+ border-radius: 4px;
+}
diff --git a/frappe/public/js/frappe/form/control.js b/frappe/public/js/frappe/form/control.js
index d25b4616ca..38aa00c401 100755
--- a/frappe/public/js/frappe/form/control.js
+++ b/frappe/public/js/frappe/form/control.js
@@ -609,6 +609,7 @@ frappe.ui.form.ControlDate = frappe.ui.form.ControlData.extend({
this.set_t_for_today();
},
set_formatted_input: function(value) {
+ this._super(value);
if(value
&& ((this.last_value && this.last_value !== value)
|| (!this.datepicker.selectedDates.length))) {
@@ -1289,7 +1290,14 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
frappe._from_link = this;
frappe._from_link_scrollY = $(document).scrollTop();
- frappe.ui.form.quick_entry(doctype, function(doc) {
+ var trimmed_doctype = doctype.replace(/ /g, '');
+ var controller_name = "QuickEntryForm";
+
+ if(frappe.ui.form[trimmed_doctype + "QuickEntryForm"]){
+ controller_name = trimmed_doctype + "QuickEntryForm";
+ }
+
+ new frappe.ui.form[controller_name](doctype, function(doc) {
if(me.frm) {
me.parse_validate_and_set_in_model(doc.name);
} else {
@@ -1530,7 +1538,7 @@ frappe.ui.form.ControlLink = frappe.ui.form.ControlData.extend({
// validate the value just entered
var me = this;
- if(this.df.options=="[Select]") {
+ if(this.df.options=="[Select]" || this.df.ignore_link_validation) {
callback(value);
return;
}
diff --git a/frappe/public/js/frappe/form/quick_entry.js b/frappe/public/js/frappe/form/quick_entry.js
index a267839884..ec48b3b1da 100644
--- a/frappe/public/js/frappe/form/quick_entry.js
+++ b/frappe/public/js/frappe/form/quick_entry.js
@@ -1,129 +1,178 @@
frappe.provide('frappe.ui.form');
-frappe.ui.form.quick_entry = function(doctype, success) {
- frappe.model.with_doctype(doctype, function() {
- var mandatory = $.map(frappe.get_meta(doctype).fields,
- function(d) { return (d.reqd || d.bold && !d.read_only) ? d : null });
- var meta = frappe.get_meta(doctype);
-
- var doc = frappe.model.get_new_doc(doctype, null, null, true);
+frappe.ui.form.QuickEntryForm = Class.extend({
+ init: function(doctype, success_function){
+ this.doctype = doctype;
+ this.success_function = success_function;
+ this.setup();
+ },
+
+ setup: function(){
+ var me = this;
+ frappe.model.with_doctype(this.doctype, function() {
+ me.set_meta_and_mandatory_fields();
+ var validate_flag = me.validate_quick_entry();
+ if(!validate_flag){
+ me.render_dialog();
+ }
+ });
+ },
+
+ set_meta_and_mandatory_fields: function(){
+ this.mandatory = $.map(frappe.get_meta(this.doctype).fields,
+ function(d) { return (d.reqd || d.bold && !d.read_only) ? d : null; });
+ this.meta = frappe.get_meta(this.doctype);
+ this.doc = frappe.model.get_new_doc(this.doctype, null, null, true);
+ },
+
+ validate_quick_entry: function(){
+ if(this.meta.quick_entry != 1) {
+ frappe.set_route('Form', this.doctype, this.doc.name);
+ return true;
+ }
+ var mandatory_flag = this.validate_mandatory_length();
+ var child_table_flag = this.validate_for_child_table();
- if(meta.quick_entry != 1) {
- frappe.set_route('Form', doctype, doc.name);
- return;
+ if (mandatory_flag || child_table_flag){
+ return true;
}
+ this.validate_for_prompt_autoname();
+ },
- if(mandatory.length > 7) {
+ validate_mandatory_length: function(){
+ if(this.mandatory.length > 7) {
// too many fields, show form
- frappe.set_route('Form', doctype, doc.name);
- return;
+ frappe.set_route('Form', this.doctype, this.doc.name);
+ return true;
}
+ },
- if($.map(mandatory, function(d) { return d.fieldtype==='Table' ? d : null }).length) {
+ validate_for_child_table: function(){
+ if($.map(this.mandatory, function(d) { return d.fieldtype==='Table' ? d : null; }).length) {
// has mandatory table, quit!
- frappe.set_route('Form', doctype, doc.name);
- return;
+ frappe.set_route('Form', this.doctype, this.doc.name);
+ return true;
}
+ },
- if(meta.autoname && meta.autoname.toLowerCase()==='prompt') {
- mandatory = [{fieldname:'__name', label:__('{0} Name', [meta.name]),
- reqd: 1, fieldtype:'Data'}].concat(mandatory);
+ validate_for_prompt_autoname: function(){
+ if(this.meta.autoname && this.meta.autoname.toLowerCase()==='prompt') {
+ this.mandatory = [{fieldname:'__name', label:__('{0} Name', [this.meta.name]),
+ reqd: 1, fieldtype:'Data'}].concat(this.mandatory);
}
+ },
- var dialog = new frappe.ui.Dialog({
- title: __("New {0}", [__(doctype)]),
- fields: mandatory,
+ render_dialog: function(){
+ var me = this;
+ this.dialog = new frappe.ui.Dialog({
+ title: __("New {0}", [__(this.doctype)]),
+ fields: this.mandatory,
});
+ this.dialog.doc = this.doc;
+ // refresh dependencies etc
+ this.dialog.refresh();
- var update_doc = function() {
- var data = dialog.get_values(true);
- $.each(data, function(key, value) {
- if(key==='__name') {
- dialog.doc.name = value;
- } else {
- if(!is_null(value)) {
- dialog.doc[key] = value;
- }
+ this.register_primary_action();
+ this.render_edit_in_full_page_link();
+ // ctrl+enter to save
+ this.dialog.wrapper.keydown(function(e) {
+ if((e.ctrlKey || e.metaKey) && e.which==13) {
+ if(!frappe.request.ajax_count) {
+ // not already working -- double entry
+ me.dialog.get_primary_btn().trigger("click");
+ e.preventDefault();
+ return false;
}
- });
- return dialog.doc;
- }
-
- var open_doc = function() {
- dialog.hide();
- update_doc();
- frappe.set_route('Form', doctype, doc.name);
- }
-
- dialog.doc = doc;
+ }
+ });
- // refresh dependencies etc
- dialog.refresh();
+ this.dialog.show();
+ this.set_defaults();
+ },
- dialog.set_primary_action(__('Save'), function() {
- if(dialog.working) return;
- var data = dialog.get_values();
+ register_primary_action: function(){
+ var me = this;
+ this.dialog.set_primary_action(__('Save'), function() {
+ if(me.dialog.working) return;
+ var data = me.dialog.get_values();
if(data) {
- dialog.working = true;
- var values = update_doc();
- frappe.call({
- method: "frappe.client.insert",
- args: {
- doc: values
- },
- callback: function(r) {
- dialog.hide();
- // delete the old doc
- frappe.model.clear_doc(dialog.doc.doctype, dialog.doc.name);
- var doc = r.message;
- if(success) {
- success(doc);
- }
- frappe.ui.form.update_calling_link(doc.name);
- },
- error: function() {
- open_doc();
- },
- always: function() {
- dialog.working = false;
- },
- freeze: true
- });
+ me.dialog.working = true;
+ var values = me.update_doc();
+ me.insert_document(values);
}
});
+ },
+
+ insert_document: function(values){
+ var me = this;
+ frappe.call({
+ method: "frappe.client.insert",
+ args: {
+ doc: values
+ },
+ callback: function(r) {
+ me.dialog.hide();
+ // delete the old doc
+ frappe.model.clear_doc(me.dialog.doc.doctype, me.dialog.doc.name);
+ var doc = r.message;
+ if(me.success_function) {
+ me.success_function(doc);
+ }
+ frappe.ui.form.update_calling_link(doc.name);
+ },
+ error: function() {
+ me.open_doc();
+ },
+ always: function() {
+ me.dialog.working = false;
+ },
+ freeze: true
+ });
+ },
+
+ update_doc: function(){
+ var me = this;
+ var data = this.dialog.get_values(true);
+ $.each(data, function(key, value) {
+ if(key==='__name') {
+ me.dialog.doc.name = value;
+ } else {
+ if(!is_null(value)) {
+ me.dialog.doc[key] = value;
+ }
+ }
+ });
+ return this.dialog.doc;
+ },
+ open_doc: function(){
+ this.dialog.hide();
+ this.update_doc();
+ frappe.set_route('Form', this.doctype, this.doc.name);
+ },
+
+ render_edit_in_full_page_link: function(){
+ var me = this;
var $link = $('' +
- __("Ctrl+enter to save") + ' |
' + __("Edit in full page") + ' ').appendTo(dialog.body);
+ __("Ctrl+enter to save") + ' | ' + __("Edit in full page") + ' ').appendTo(this.dialog.body);
$link.find('.edit-full').on('click', function() {
// edit in form
- open_doc();
- });
-
- // ctrl+enter to save
- dialog.wrapper.keydown(function(e) {
- if((e.ctrlKey || e.metaKey) && e.which==13) {
- if(!frappe.request.ajax_count) {
- // not already working -- double entry
- dialog.get_primary_btn().trigger("click");
- e.preventDefault();
- return false;
- }
- }
+ me.open_doc();
});
+ },
- dialog.show();
-
+ set_defaults: function(){
+ var me = this;
// set defaults
- $.each(dialog.fields_dict, function(fieldname, field) {
- field.doctype = doc.doctype;
- field.docname = doc.name;
+ $.each(this.dialog.fields_dict, function(fieldname, field) {
+ field.doctype = me.doc.doctype;
+ field.docname = me.doc.name;
- if(!is_null(doc[fieldname])) {
- field.set_input(doc[fieldname]);
+ if(!is_null(me.doc[fieldname])) {
+ field.set_input(me.doc[fieldname]);
}
});
-
- });
-}
+ }
+});
diff --git a/frappe/public/js/frappe/model/create_new.js b/frappe/public/js/frappe/model/create_new.js
index 2448734dbe..79d9ab44ef 100644
--- a/frappe/public/js/frappe/model/create_new.js
+++ b/frappe/public/js/frappe/model/create_new.js
@@ -318,7 +318,14 @@ frappe.new_doc = function (doctype, opts) {
if(frappe.create_routes[doctype]) {
frappe.set_route(frappe.create_routes[doctype]);
} else {
- frappe.ui.form.quick_entry(doctype, function(doc) {
+ var trimmed_doctype = doctype.replace(/ /g, '');
+ var controller_name = "QuickEntryForm";
+
+ if(frappe.ui.form[trimmed_doctype + "QuickEntryForm"]){
+ controller_name = trimmed_doctype + "QuickEntryForm";
+ }
+
+ new frappe.ui.form[controller_name](doctype, function(doc) {
//frappe.set_route('List', doctype);
var title = doc.name;
var title_field = frappe.get_meta(doc.doctype).title_field;
diff --git a/frappe/public/js/frappe/ui/page.js b/frappe/public/js/frappe/ui/page.js
index f6ac7e241e..5a08f2ad34 100644
--- a/frappe/public/js/frappe/ui/page.js
+++ b/frappe/public/js/frappe/ui/page.js
@@ -251,12 +251,22 @@ frappe.ui.Page = Class.extend({
},
add_inner_button: function(label, action, group) {
+ let _action = function() {
+ let btn = $(this);
+ let promise = action();
+ if (promise && promise.then) {
+ btn.attr('disabled', true);
+ promise.then(() => {
+ btn.attr('disabled', false);
+ })
+ }
+ }
if(group) {
var $group = this.get_inner_group_button(group);
- return $(''+label+' ').on('click', action).appendTo($group.find(".dropdown-menu"));
+ return $(''+label+' ').on('click', _action).appendTo($group.find(".dropdown-menu"));
} else {
return $(''+__(label)+'')
- .on("click", action).appendTo(this.inner_toolbar.removeClass("hide"))
+ .on("click", _action).appendTo(this.inner_toolbar.removeClass("hide"))
}
},
diff --git a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js
index e54833f846..60a41d9b88 100644
--- a/frappe/public/js/frappe/ui/toolbar/awesome_bar.js
+++ b/frappe/public/js/frappe/ui/toolbar/awesome_bar.js
@@ -18,7 +18,6 @@ frappe.search.AwesomeBar = Class.extend({
autoFirst: true,
list: [],
filter: function (text, term) {
- this.get_item(text.value).boo = "foo";
return true;
},
data: function (item, input) {
@@ -194,6 +193,7 @@ frappe.search.AwesomeBar = Class.extend({
}
} else {
out.push(option);
+ routes.push("");
}
});
return out;
diff --git a/frappe/public/js/frappe/ui/toolbar/toolbar.js b/frappe/public/js/frappe/ui/toolbar/toolbar.js
index 24fe005afb..41a22ccd8c 100644
--- a/frappe/public/js/frappe/ui/toolbar/toolbar.js
+++ b/frappe/public/js/frappe/ui/toolbar/toolbar.js
@@ -218,12 +218,15 @@ $.extend(frappe.ui.toolbar, {
frappe.ui.toolbar.clear_cache = function() {
frappe.assets.clear_local_storage();
- $c('frappe.sessions.clear',{},function(r,rt){
- if(!r.exc) {
- frappe.show_alert(r.message);
- location.reload(true);
+ frappe.call({
+ method: 'frappe.sessions.clear',
+ callback: function(r) {
+ if(!r.exc) {
+ frappe.show_alert({message:r.message, indicator:'green'});
+ location.reload(true);
+ }
}
- });
+ })
return false;
}
diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js
index 2d7a1e7a3e..789923d752 100644
--- a/frappe/public/js/frappe/views/reports/query_report.js
+++ b/frappe/public/js/frappe/views/reports/query_report.js
@@ -306,6 +306,7 @@ frappe.views.QueryReport = Class.extend({
var f = me.page.add_field(df);
$(f.wrapper).addClass("filters pull-left");
me.filters.push(f);
+
if(df["default"]) {
f.set_input(df["default"]);
}
@@ -327,6 +328,7 @@ frappe.views.QueryReport = Class.extend({
}
f.set_mandatory && f.set_mandatory(f.$input.val());
}
+ df.ignore_link_validation = true;
}
});
diff --git a/frappe/public/js/legacy/clientscriptAPI.js b/frappe/public/js/legacy/clientscriptAPI.js
index 326f4e075f..a57362bd63 100644
--- a/frappe/public/js/legacy/clientscriptAPI.js
+++ b/frappe/public/js/legacy/clientscriptAPI.js
@@ -248,7 +248,17 @@ _f.Frm.prototype.clear_table = function(fieldname) {
_f.Frm.prototype.add_child = function(fieldname, values) {
var doc = frappe.model.add_child(this.doc, frappe.meta.get_docfield(this.doctype, fieldname).options, fieldname);
if(values) {
- $.extend(doc, values);
+ // Values of unique keys should not be overridden
+ var d = {};
+ var unique_keys = ["idx", "name"];
+
+ Object.keys(values).map((key) => {
+ if(!unique_keys.includes(key)) {
+ d[key] = values[key];
+ }
+ });
+
+ $.extend(doc, d);
}
return doc;
}
diff --git a/frappe/public/less/form.less b/frappe/public/less/form.less
index 033addb629..036790d9a2 100644
--- a/frappe/public/less/form.less
+++ b/frappe/public/less/form.less
@@ -293,6 +293,15 @@ h6.uppercase, .h6.uppercase {
background-color: #e74c3c;
}
+.address-box {
+ background-color: @light-bg;
+ padding: 0px 15px;
+ margin: 15px 0px;
+ border: 1px solid @border-color;
+ border-radius: 3px;
+ font-size: 12px;
+}
+
.timeline {
margin: 30px 0px;
@@ -356,7 +365,7 @@ h6.uppercase, .h6.uppercase {
.media-body {
border: 1px solid @border-color;
- border-radius: 2px;
+ border-radius: 3px;
margin-left: -7px;
position: relative;
@@ -502,7 +511,7 @@ h6.uppercase, .h6.uppercase {
background-color: white;
// padding: 15px 30px;
border: 1px solid @border-color;
- border-radius: 2px;
+ border-radius: 3px;
position: relative;
z-index: 1;
diff --git a/frappe/public/less/website.less b/frappe/public/less/website.less
index 8eb0e37b5d..6158fee65e 100644
--- a/frappe/public/less/website.less
+++ b/frappe/public/less/website.less
@@ -720,3 +720,9 @@ li.footer-child-item {
margin-top: 30px;
}
}
+
+.bordered {
+ border: 1px solid @border-color;
+ padding: 10px;
+ border-radius: 4px;
+}
\ No newline at end of file
diff --git a/frappe/translations/de.csv b/frappe/translations/de.csv
index f785ca82fa..37e6ff9050 100644
--- a/frappe/translations/de.csv
+++ b/frappe/translations/de.csv
@@ -319,7 +319,7 @@ DocType: Event,Repeat Till,Wiederholen bis
apps/frappe/frappe/core/doctype/communication/communication_list.js +26,New,Neu
apps/frappe/frappe/public/js/frappe/form/share.js +74,Loading...,Laden ...
DocType: DocField,Password,Passwort
-apps/frappe/frappe/utils/response.py +175,Your system is being updated. Please refresh again after a few moments,Ihr System wird aktualisiert. Bitte aktualisieren Sie die Seite in ein paar Momenten
+apps/frappe/frappe/utils/response.py +175,Your system is being updated. Please refresh again after a few moments,Ihr System wird aktualisiert. Bitte aktualisieren Sie die Seite in einer kurzen Weile erneut
DocType: Blogger,Will be used in url (usually first name).,Wird in URL verwendet (in der Regel Vorname).
DocType: Auto Email Report,Day of Week,Tag der Woche
DocType: Note,Expire Notification On,Ablaufen Mitteilung On
@@ -412,7 +412,7 @@ DocType: Workflow State,exclamation-sign,Ausrufezeichen
apps/frappe/frappe/core/report/permitted_documents_for_user/permitted_documents_for_user.js +30,Show Permissions,Berechtigungen anzeigen
apps/frappe/frappe/core/doctype/doctype/doctype.py +554,Timeline field must be a Link or Dynamic Link,Timeline-Bereich muss einen Link oder Dynamic Link sein
apps/frappe/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py +36,Please install dropbox python module,Bitte das Dropbox-Python-Modul installieren
-apps/frappe/frappe/public/js/frappe/form/multi_select_dialog.js +53,Date Range,Datumsbereich
+apps/frappe/frappe/public/js/frappe/form/multi_select_dialog.js +53,Date Range,Datumspanne
apps/frappe/frappe/public/js/frappe/views/gantt/gantt_view.js +20,Gantt,Gantt-Diagramm
apps/frappe/frappe/public/html/print_template.html +27,Page {0} of {1},Seite {0} von {1}
DocType: About Us Settings,Introduce your company to the website visitor.,Vorstellung des Unternehmens für Besucher der Webseite.
@@ -1218,7 +1218,7 @@ apps/frappe/frappe/core/page/usage_info/usage_info.html +51,Max Emails,Max E-Mai
apps/frappe/frappe/public/js/frappe/form/footer/timeline.js +575,Delete comment?,Kommentar löschen?
DocType: Address Template,This format is used if country specific format is not found,"Dieses Format wird verwendet, wenn ein länderspezifisches Format nicht gefunden werden kann"
DocType: System Settings,Allow Login using Mobile Number,Login mit Mobilnummer zulassen
-apps/frappe/frappe/public/js/frappe/request.js +104,You do not have enough permissions to access this resource. Please contact your manager to get access.,"Sie haben nicht genügend Rechte, um auf diese Ressource zuzugreifen. Bitte kontaktieren Sie Ihren Manager um Zugang zu bekommen."
+apps/frappe/frappe/public/js/frappe/request.js +104,You do not have enough permissions to access this resource. Please contact your manager to get access.,"Sie haben nicht genügend Rechte, um auf diese Ressource zuzugreifen. Bitte kontaktieren Sie Ihren Manager um Zugang zu erhalten."
DocType: Custom Field,Custom,Benutzerdefiniert
apps/frappe/frappe/config/setup.py +150,Setup Email Alert based on various criteria.,E-Mail-Benachrichtigung einrichten auf der Grundlage verschiedener Kriterien.
apps/frappe/frappe/website/doctype/blog_post/blog_post.py +98,Posts filed under {0},Beiträge abgelegt unter {0}
@@ -1367,7 +1367,7 @@ apps/frappe/frappe/core/doctype/user/user.py +715,"Too many users signed up rece
apps/frappe/frappe/core/page/permission_manager/permission_manager.js +375,Add New Permission Rule,Neue Berechtigungsregel anlegen
apps/frappe/frappe/public/js/frappe/form/link_selector.js +26,You can use wildcard %,"Sie können den Platzhalter ""%"" verwenden"
apps/frappe/frappe/public/js/frappe/upload.js +270,"Only image extensions (.gif, .jpg, .jpeg, .tiff, .png, .svg) allowed","Nur Bild-Datenformate (.gif, .jpg, .jpeg, .tiff, .png, .svg) erlaubt"
-DocType: DocType,Database Engine,Database Engine
+DocType: DocType,Database Engine,Datenbank-Engine
DocType: Customize Form,"Fields separated by comma (,) will be included in the ""Search By"" list of Search dialog box","Felder, die durch Komma (,) getrennt sind, sind in der ""Suchen nach""-Liste des Suche-Dialogfeldes enthalten."
apps/frappe/frappe/website/doctype/website_theme/website_theme.py +35,Please Duplicate this Website Theme to customize.,Bitte dieses Webseiten-Thema duplizieren um es anzupassen.
DocType: DocField,Text Editor,Text Bearbeiter
@@ -1428,7 +1428,7 @@ apps/frappe/frappe/model/base_document.py +466,Options not set for link field {0
DocType: Customize Form,"Must be of type ""Attach Image""",Muss vom Typ sein "Bild anhängen"
apps/frappe/frappe/core/page/data_import_tool/data_import_main.html +25,Unselect All,Alles wiederufen
apps/frappe/frappe/custom/doctype/customize_form/customize_form.py +197,You cannot unset 'Read Only' for field {0},"""Nur lesen"" kann für das Feld {0} nicht rückgängig gemacht werden"
-DocType: Auto Email Report,Zero means send records updated at anytime,Zero bedeutet Sendeaufzeichnungen jederzeit aktualisiert
+DocType: Auto Email Report,Zero means send records updated at anytime,"Null bedeutet dass, Sendeaufzeichnungen jederzeit aktualisiert werden"
apps/frappe/frappe/desk/page/setup_wizard/setup_wizard_page.html +18,Complete Setup,Einrichtung abschliessen
DocType: Workflow State,asterisk,Sternchen
apps/frappe/frappe/core/page/data_import_tool/exporter.py +62,Please do not change the template headings.,Bitte nicht die Vorlagenköpfe ändern.
@@ -1757,7 +1757,7 @@ apps/frappe/frappe/core/page/desktop/desktop_help_message.html +5,You have made
DocType: OAuth Authorization Code,OAuth Authorization Code,OAuth-Autorisierungscode
apps/frappe/frappe/core/page/data_import_tool/importer.py +249,Not allowed to Import,Import nicht erlaubt
DocType: Social Login Keys,Frappe Client Secret,Frappe Client-Geheimnis
-DocType: Deleted Document,Deleted DocType,Gelöschte DocType
+DocType: Deleted Document,Deleted DocType,Gelöschtes DocType
apps/frappe/frappe/core/page/permission_manager/permission_manager_help.html +22,Permission Levels,Berechtigungsebenen
DocType: Workflow State,Warning,Warnung
DocType: Tag Category,Tag Category,Tag Kategorie
@@ -1778,7 +1778,7 @@ apps/frappe/frappe/core/page/usage_info/usage_info.html +22,Remaining,Verbleiben
apps/frappe/frappe/public/js/frappe/ui/toolbar/search.js +357,No results found for '
, Keine Ergebnisse für '
apps/frappe/frappe/public/js/legacy/form.js +139,Please save before attaching.,Bitte vor dem Anhängen speichern
apps/frappe/frappe/public/js/frappe/form/link_selector.js +124,Added {0} ({1}),{0} ({1}) hinzugefügt
-apps/frappe/frappe/website/doctype/website_theme/website_theme.js +20,Default theme is set in {0},Standard-Design wird in {0}
+apps/frappe/frappe/website/doctype/website_theme/website_theme.js +20,Default theme is set in {0},Standard-Design wird in {0} eingestellt
apps/frappe/frappe/custom/doctype/customize_form/customize_form.py +319,Fieldtype cannot be changed from {0} to {1} in row {2},Feldtyp kann nicht von {0} nach {1} in Zeile {2} geändert werden
apps/frappe/frappe/public/js/frappe/roles_editor.js +195,Role Permissions,Rollenberechtigungen
DocType: Help Article,Intermediate,Mittlere
@@ -1801,7 +1801,7 @@ apps/frappe/frappe/public/js/frappe/form/control.js +1407,Create a new {0},Neu e
DocType: Email Rule,Is Spam,ist Spam
apps/frappe/frappe/public/js/frappe/ui/toolbar/search_utils.js +192,Report {0},Bericht {0}
apps/frappe/frappe/public/js/frappe/form/templates/form_links.html +14,Open {0},{0} öffnen
-DocType: OAuth Client,Default Redirect URI,Standard Redirect URI
+DocType: OAuth Client,Default Redirect URI,Standard Weiterleitungs URI
DocType: Email Alert,Recipients,Empfänger
DocType: Workflow State,ok-sign,OK-Zeichen
apps/frappe/frappe/public/js/frappe/form/toolbar.js +141,Duplicate,Duplizieren
@@ -1914,9 +1914,9 @@ apps/frappe/frappe/public/js/frappe/ui/tags.js +20,Add a tag,Eine Markierung hin
apps/frappe/frappe/public/js/frappe/form/control.js +1207,Please attach a file first.,Bitte zuerst eine Datei anhängen.
apps/frappe/frappe/model/naming.py +169,"There were some errors setting the name, please contact the administrator",Beim Setzen des Namens hat es einige Fehler gegeben. Kontaktieren Sie bitte Ihren Administrator
apps/frappe/frappe/templates/includes/contact.js +17,"You seem to have written your name instead of your email. \
- Please enter a valid email address so that we can get back.","Du scheinst deinen Namen anstelle deiner E-Mail geschrieben zu haben. \ Bitte geben Sie eine gültige E-Mail-Adresse ein, damit wir zurückkommen können."
+ Please enter a valid email address so that we can get back.","Du scheinst deinen Namen anstelle deiner E-Mail geschrieben zu haben. \ Bitte geben Sie eine gültige E-Mail-Adresse ein, damit wir uns bei Ihnen melden können."
DocType: Website Slideshow Item,Website Slideshow Item,Webseiten-Diashow-Artikel
-DocType: Portal Settings,Default Role at Time of Signup,Standardrolle für Neuanmeldungen
+DocType: Portal Settings,Default Role at Time of Signup,Standardrolle bei Neuanmeldungen
DocType: DocType,Title Case,Bezeichnung in Großbuchstaben
DocType: DocType,"Naming Options:
field:[fieldname] - By Fieldnaming_series: - By Naming Series (field called naming_series must be presentPrompt - Prompt user for a name[series] - Series by prefix (separated by a dot); for example PRE.##### ",Namensoptionen: Feld: [Feldname] - Mit dem Feld naming_series: - Durch die Benennung der Serie (Feld namens naming_series muss vorhanden sein Prompt - Benutzer nach einem Namen [Serie] - Serie von Präfix (getrennt durch einen Punkt); zum Beispiel PRE. #####
@@ -2050,7 +2050,7 @@ DocType: DocType,Timeline Field,Timeline-Feld
DocType: Country,Time Zones,Zeitzonen
apps/frappe/frappe/core/page/permission_manager/permission_manager.py +87,There must be atleast one permission rule.,Es muss atleast eine Erlaubnis Regel sein.
apps/frappe/frappe/public/js/frappe/form/multi_select_dialog.js +67,Get Items,Artikel aufrufen
-apps/frappe/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py +96,You did not apporve Dropbox Access.,Sie haben den Dropbox-Zugriff nicht verifiziert.
+apps/frappe/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py +96,You did not apporve Dropbox Access.,Sie haben den Dropbox-Zugriff nicht freigegeben.
DocType: DocField,Image,Bild
DocType: Workflow State,remove-sign,Entfernen-Zeichen
apps/frappe/frappe/www/search.html +30,Type something in the search box to search,Geben Sie etwas in das Suchfeld zu suchen
@@ -2306,7 +2306,7 @@ apps/frappe/frappe/core/page/data_import_tool/data_import_tool.js +137,Importing
apps/frappe/frappe/core/doctype/file/file.js +27,Unzip,Dekomprimieren
apps/frappe/frappe/model/document.py +923,Incorrect value in row {0}: {1} must be {2} {3},Falscher Wert in Zeile {0}: {1} muss {2} {3} sein
apps/frappe/frappe/workflow/doctype/workflow/workflow.py +67,Submitted Document cannot be converted back to draft. Transition row {0},Buchung kann nicht in Entwurf umgewandelt werden. Zeile {0}
-apps/frappe/frappe/desk/reportview.py +217,Deleting {0},Löschen {0}
+apps/frappe/frappe/desk/reportview.py +217,Deleting {0},Löscht {0}
apps/frappe/frappe/printing/page/print_format_builder/print_format_builder_start.html +2,Select an existing format to edit or start a new format.,Vorhandenes Format zum Bearbeiten wählen oder neues Format erstellen.
apps/frappe/frappe/workflow/doctype/workflow/workflow.py +38,Created Custom Field {0} in {1},benutzerdefiniertes Feld {0} in {1} erstellt
DocType: System Settings,Time Zone,Zeitzone
diff --git a/frappe/translations/it.csv b/frappe/translations/it.csv
index 5b43e0ddf9..23c28b4a15 100644
--- a/frappe/translations/it.csv
+++ b/frappe/translations/it.csv
@@ -761,7 +761,7 @@ DocType: DocField,Section Break,Interruzione di sezione
DocType: Address,Warehouse,Deposito
,Messages,Messaggi
apps/frappe/frappe/desk/page/applications/applications.js +49,Portal,Portale
-DocType: Email Account,Use Different Email Login ID,Utilizzare diversi ID di accesso di posta elettronica
+DocType: Email Account,Use Different Email Login ID,Utilizzare un diverso ID di accesso alla posta elettronica
apps/frappe/frappe/desk/query_report.py +82,Must specify a Query to run,Necessario specificare una query per eseguire
apps/frappe/frappe/config/setup.py +78,"Language, Date and Time settings","Impostazioni di lingua , data e ora"
DocType: User Email,User Email,user-mail
@@ -1134,7 +1134,7 @@ DocType: Customize Form Field,Number of columns for a field in a Grid (Total Col
DocType: DocType,System,Sistema
DocType: Web Form,Max Attachment Size (in MB),Dimensione Max Allegato (in MB)
apps/frappe/frappe/www/login.html +93,Have an account? Login,Hai un account? Accedi
-apps/frappe/frappe/public/js/legacy/print_format.js +148,Unknown Print Format: {0},Formato Stampa Sconosciuto: {0}
+apps/frappe/frappe/public/js/legacy/print_format.js +148,Unknown Print Format: {0},Formato di Stampa Sconosciuto: {0}
DocType: Workflow State,arrow-down,freccia verso il basso
apps/frappe/frappe/public/js/frappe/ui/tree.js +130,Collapse,Collassa
apps/frappe/frappe/model/delete_doc.py +161,User not allowed to delete {0}: {1},L'utente non ha permesso di eliminare {0}: {1}
@@ -2325,7 +2325,7 @@ DocType: Email Account,Add Signature,Aggiungi Firma
apps/frappe/frappe/email/doctype/email_unsubscribe/email_unsubscribe.py +38,Left this conversation,Lasciato questa conversazione
apps/frappe/frappe/core/page/permission_manager/permission_manager.js +481,Did not set,Non impostato
,Background Jobs,Processi in background
-DocType: ToDo,ToDo,Cose da fare
+DocType: ToDo,ToDo,Da Fare
DocType: DocField,No Copy,Copia Assente
DocType: Workflow State,qrcode,QRCode
apps/frappe/frappe/www/login.html +34,Login with LDAP,Accesso con LDAP
diff --git a/frappe/translations/pt-BR.csv b/frappe/translations/pt-BR.csv
index 55ad4acafa..36c7bf0fe3 100644
--- a/frappe/translations/pt-BR.csv
+++ b/frappe/translations/pt-BR.csv
@@ -141,7 +141,6 @@ DocType: Kanban Board Column,purple,roxo
apps/frappe/frappe/public/js/frappe/upload.js +222,Please attach a file or set a URL,"Por favor, anexar um arquivo ou definir uma URL"
DocType: Async Task,System Manager,Administrador do Sistema
DocType: Dropbox Settings,Allow Dropbox Access,Permitir Acesso Dropbox
-apps/frappe/frappe/core/doctype/deleted_document/deleted_document.js +11,Restore,Restarurar
DocType: Workflow State,plus-sign,sinal de mais
apps/frappe/frappe/desk/page/setup_wizard/setup_wizard.py +23,Setup already complete,Configuração já está concluída
apps/frappe/frappe/__init__.py +883,App {0} is not installed,App {0} não está instalado
@@ -511,6 +510,7 @@ DocType: System Settings,Date and Number Format,Data e Formato de número
apps/frappe/frappe/model/document.py +906,one of,Um dos
apps/frappe/frappe/public/js/frappe/desk.js +151,Checking one moment,"Checando, um momento"
apps/frappe/frappe/public/js/frappe/list/list_sidebar.js +353,Show Tags,Mostrar Tags
+DocType: Address,Billing,Faturamento
DocType: Email Queue,Not Sent,Não Enviados
DocType: Workflow State,align-justify,Justificar
apps/frappe/frappe/public/js/frappe/ui/field_group.js +79,Following fields have missing values:,Os campos a seguir estão em branco:
diff --git a/frappe/translations/pt.csv b/frappe/translations/pt.csv
index 1b6c2f62f0..5331155dcc 100644
--- a/frappe/translations/pt.csv
+++ b/frappe/translations/pt.csv
@@ -920,7 +920,7 @@ apps/frappe/frappe/website/doctype/web_form/templates/web_form.html +169,Max att
apps/frappe/frappe/model/document.py +906,one of,um dos
apps/frappe/frappe/public/js/frappe/desk.js +151,Checking one moment,Verificando um momento
apps/frappe/frappe/public/js/frappe/list/list_sidebar.js +353,Show Tags,Mostrar as tags
-DocType: Address,Billing,Faturamento
+DocType: Address,Billing,Faturação
DocType: Email Queue,Not Sent,Não Enviado
DocType: Web Form,Actions,Ações
DocType: Workflow State,align-justify,alinhar justificado
@@ -2220,7 +2220,7 @@ DocType: Async Task,Core,Núcleo
apps/frappe/frappe/custom/doctype/customize_form/customize_form.js +78,Set Permissions,Definir permissões
DocType: DocField,Set non-standard precision for a Float or Currency field,Definir precisão não-padrão para um campo Float ou Moeda
DocType: Email Account,Ignore attachments over this size,Ignorar anexos acima deste tamanho
-DocType: Address,Preferred Billing Address,Endereço de Faturamento Preferido
+DocType: Address,Preferred Billing Address,Endereço de Faturação Preferido
apps/frappe/frappe/database.py +231,Too many writes in one request. Please send smaller requests,"Muitos escreve em um pedido. Por favor, enviar pedidos de menores"
apps/frappe/frappe/core/doctype/version/version_view.html +8,Values Changed,Os valores alterados
DocType: Workflow State,arrow-up,seta-para-cima
diff --git a/frappe/translations/uk.csv b/frappe/translations/uk.csv
index 94e748ef34..fd46657631 100644
--- a/frappe/translations/uk.csv
+++ b/frappe/translations/uk.csv
@@ -1179,7 +1179,7 @@ apps/frappe/frappe/public/js/frappe/model/meta.js +189,Last Modified By,Оста
DocType: Workflow State,hand-down,виносити
apps/frappe/frappe/core/doctype/doctype/doctype.py +661,{0}: Cannot set Cancel without Submit,{0}: Неможливо встановити Скасувати без Проведення
DocType: Website Theme,Theme,Тема
-apps/frappe/frappe/desk/page/setup_wizard/setup_wizard.js +158,There were errors.,Були помилки.
+apps/frappe/frappe/desk/page/setup_wizard/setup_wizard.js +158,There were errors.,Трапились помилки.
DocType: OAuth Authorization Code,Redirect URI Bound To Auth Code,"Перенаправлення URI, пов'язаного з Auth кодексу"
DocType: DocType,Is Submittable,Є Submittable
apps/frappe/frappe/custom/doctype/property_setter/property_setter.js +7,Value for a check field can be either 0 or 1,"Значення для поля реєстрації може бути або 0, або 1"
@@ -1296,7 +1296,7 @@ apps/frappe/frappe/model/document.py +526,Record does not exist,Запис не
apps/frappe/frappe/core/doctype/version/version_view.html +13,Original Value,первісна вартість
DocType: Help Category,Help Category,Довідка з категорій
apps/frappe/frappe/utils/oauth.py +288,User {0} is disabled,Користувач {0} відключена
-apps/frappe/frappe/www/404.html +8,Page missing or moved,Сторінка відсутній або переїхав
+apps/frappe/frappe/www/404.html +8,Page missing or moved,Сторінка відсутня або її було переміщено
apps/frappe/frappe/public/js/legacy/form.js +192,Edit {0} properties,Зміна {0} властивості
DocType: DocType,Route,маршрут
apps/frappe/frappe/config/integrations.py +23,Razorpay Payment gateway settings,Налаштування шлюзу оплати Razorpay
@@ -1414,7 +1414,7 @@ apps/frappe/frappe/email/doctype/email_group/email_group.js +13,Import Email Fro
apps/frappe/frappe/email/doctype/contact/contact.js +20,Invite as User,Запросити стати користувачем
apps/frappe/frappe/public/js/frappe/views/communication.js +83,Select Attachments,Виберіть Вкладення
apps/frappe/frappe/model/naming.py +95, for {0},для {0}
-apps/frappe/frappe/website/js/web_form.js +301,There were errors. Please report this.,"Були помилки. Будь ласка, повідомте про це."
+apps/frappe/frappe/website/js/web_form.js +301,There were errors. Please report this.,"Трапились помилки. Будь ласка, повідомте про це."
apps/frappe/frappe/public/js/legacy/form.js +176,You are not allowed to print this document,Ви не можете надрукувати цей документ
apps/frappe/frappe/email/doctype/auto_email_report/auto_email_report.py +103,Please set filters value in Report Filter table.,"Будь ласка, встановіть значення фільтрів в Report Filter таблиці."
apps/frappe/frappe/public/js/frappe/views/reports/query_report.js +375,Loading Report,Завантаження звіту
@@ -2192,7 +2192,7 @@ apps/frappe/frappe/public/js/frappe/form/save.js +15,Cancelling,Скасуван
DocType: DocType,Allow Rename,Дозволити Перейменувати
DocType: Authentication Log,Full Name,Повне ім'я
DocType: DocType,Child Tables are shown as a Grid in other DocTypes.,Дитячі Столики показані у вигляді сітки в інших DOCTYPES.
-apps/frappe/frappe/www/404.html +10,The page you are looking for is missing. This could be because it is moved or there is a typo in the link.,"Сторінка, яку ви шукаєте, відсутній. Це може бути тому, що вона переміщається або є помилка в засланні."
+apps/frappe/frappe/www/404.html +10,The page you are looking for is missing. This could be because it is moved or there is a typo in the link.,"Сторінка, яку ви шукаєте, відсутня. Можливо, вона була переміщена або у посиланні є помилка."
apps/frappe/frappe/www/404.html +13,Error Code: {0},Код помилки: {0}
DocType: Blog Post,"Description for listing page, in plain text, only a couple of lines. (max 140 characters)","Опис для перерахування сторінку, у вигляді звичайного тексту, тільки пару рядків. (макс 140 знаків)"
apps/frappe/frappe/core/page/user_permissions/user_permissions.js +304,Add A User Restriction,Додати A Обмеження користувача
diff --git a/frappe/translations/vi.csv b/frappe/translations/vi.csv
index 0feb2a95d9..8688dae62a 100644
--- a/frappe/translations/vi.csv
+++ b/frappe/translations/vi.csv
@@ -52,7 +52,7 @@ apps/frappe/frappe/core/page/data_import_tool/exporter.py +52,Data Import Templa
apps/frappe/frappe/public/js/frappe/model/model.js +31,Parent,Cha mẹ
DocType: System Settings,"If enabled, the password strength will be enforced based on the Minimum Password Score value. A value of 2 being medium strong and 4 being very strong.","Nếu được bật, mật khẩu sẽ được thi hành dựa trên giá trị Điểm Số Điểm Tối Thiểu. Một giá trị của 2 là trung bình mạnh và 4 là rất mạnh."
DocType: System Settings,"If enabled, the password strength will be enforced based on the Minimum Password Score value. A value of 2 being medium strong and 4 being very strong.","Nếu được bật, mật khẩu sẽ được thi hành dựa trên giá trị Điểm Số Điểm Tối Thiểu. Một giá trị của 2 là trung bình mạnh và 4 là rất mạnh."
-DocType: About Us Settings,"""Team Members"" or ""Management""","""Các Thành Viên Nhóm"" hay ""Ban Quản Lý"""
+DocType: About Us Settings,"""Team Members"" or ""Management""","""Các Thành Viên Nhóm"" hay ""Ban Quản Trị"""
apps/frappe/frappe/core/doctype/doctype/doctype.py +437,Default for 'Check' type of field must be either '0' or '1',Mặc định cho loại 'Kiểm tra' của trường phải là '0' hoặc '1'
apps/frappe/frappe/public/js/frappe/misc/pretty_date.js +50,Yesterday,Hôm qua
DocType: Contact,Designation,Chỉ định
@@ -97,7 +97,7 @@ apps/frappe/frappe/core/page/data_import_tool/data_import_main.html +4,"To impor
DocType: DocType,Default Print Format,Mặc định In Định dạng
DocType: Workflow State,Tags,tags
apps/frappe/frappe/public/js/frappe/form/workflow.js +33,None: End of Workflow,Không: Kết thúc quy trình làm việc
-apps/frappe/frappe/model/db_schema.py +346,"{0} field cannot be set as unique in {1}, as there are non-unique existing values","trường {0} không thể thiết lập là duy nhất trong {1}, vì đang chứa những giá trị không phải duy nhất"
+apps/frappe/frappe/model/db_schema.py +346,"{0} field cannot be set as unique in {1}, as there are non-unique existing values","{0}Lĩnh vực không thể thiết lập như kiểu duy nhất trong {1}, vì đang tồn tại những giá trị không phải duy nhất"
apps/frappe/frappe/core/page/permission_manager/permission_manager.js +47,Document Types,Các loại tài liệu
DocType: Workflow,Workflow State Field,Công việc nhà nước Dòng
apps/frappe/frappe/website/doctype/web_form/templates/web_form.html +54,Please sign-up or login to begin,Vui lòng đăng ký hoặc đăng nhập để bắt đầu
@@ -786,7 +786,7 @@ apps/frappe/frappe/desk/form/assign_to.py +137,"The task {0}, that you assigned
DocType: User,Modules Access,Modules truy cập
apps/frappe/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py +75,Please close this window,Hãy đóng cửa sổ này
DocType: Print Format,Print Format Type,Định dạng in Loại
-DocType: Newsletter,A Lead with this Email Address should exist,Một Chì với Địa chỉ Email này nên tồn tại
+DocType: Newsletter,A Lead with this Email Address should exist,Một Lead với Địa chỉ Email này nên tồn tại
apps/frappe/frappe/public/js/frappe/ui/toolbar/about.js +7,Open Source Applications for the Web,Ứng dụng mã nguồn mở cho Web
DocType: Website Theme,"Add the name of a ""Google Web Font"" e.g. ""Open Sans""",Thêm tên của một "Font Google Web" ví dụ "Open Sans"
apps/frappe/frappe/public/js/frappe/request.js +141,Request Timed Out,Yêu cầu Timed Out
@@ -1143,7 +1143,7 @@ apps/frappe/frappe/core/page/user_permissions/user_permissions.js +251,If Docume
apps/frappe/frappe/model/delete_doc.py +220,"Cannot delete or cancel because {0} {1} is linked with {2} {3} {4}","Không thể xóa hoặc hủy bỏ vì {0} {1} được liên kết với {2} {3} {4}"
apps/frappe/frappe/desk/page/applications/applications.py +109,Unknown app {0},Ứng dụng không rõ {0}
apps/frappe/frappe/email/doctype/auto_email_report/auto_email_report.py +48,"%s is not a valid report format. Report format should \
- one of the following %s",%s không phải là một định dạng báo cáo hợp lệ. Mẫu báo cáo nên \ một trong những %s sau
+ one of the following %s",%s không phải là một mẫu báo cáo hợp lệ. Mẫu báo cáo nên \ một trong những %s sau
DocType: Communication,Chat,Trò chuyện
apps/frappe/frappe/core/doctype/doctype/doctype.py +391,Fieldname {0} appears multiple times in rows {1},Fieldname {0} xuất hiện nhiều lần trong hàng {1}
apps/frappe/frappe/public/js/frappe/form/footer/timeline.js +460,{0} from {1} to {2} in row #{3},{0} từ {1} đến {2} trong hàng # {3}
@@ -1578,7 +1578,7 @@ apps/frappe/frappe/desk/page/applications/applications.js +77,Installed,Đã cà
apps/frappe/frappe/desk/page/applications/applications.js +47,Developer Tools,Những công cụ phát triển
DocType: Workflow State,fullscreen,toàn màn hình
apps/frappe/frappe/public/js/frappe/views/reports/query_report.js +214,You are not allowed to make PDF for this report,Bạn không được phép làm PDF cho báo cáo này
-apps/frappe/frappe/templates/emails/feedback_request_url.html +8,1 star being lowest & 5 stars being highest rating,1 sao là thấp nhất & 5 sao được đánh giá cao nhất
+apps/frappe/frappe/templates/emails/feedback_request_url.html +8,1 star being lowest & 5 stars being highest rating,1 sao là thấp nhất & 5 sao là đánh giá cao nhất
DocType: Event,Ref Name,Tài liệu tham khảo Tên
DocType: Web Page,Center,Trung tâm
apps/frappe/frappe/core/doctype/error_snapshot/error_snapshot_list.js +11,First Level,Đầu Cấp
@@ -1966,7 +1966,7 @@ DocType: Address Template,Template,Mẫu
apps/frappe/frappe/config/integrations.py +48,LDAP Settings,Cài đặt LDAP
apps/frappe/frappe/public/js/frappe/form/save.js +14,Amending,Sửa đổi
apps/frappe/frappe/config/integrations.py +18,PayPal payment gateway settings,thiết lập cổng thanh toán PayPal
-apps/frappe/frappe/model/base_document.py +580,"{0}: '{1}' ({3}) will get truncated, as max characters allowed is {2}","{0}: {1} '({3}) sẽ được cắt ngắn, số kí tự tối đa cho phép là {2}"
+apps/frappe/frappe/model/base_document.py +580,"{0}: '{1}' ({3}) will get truncated, as max characters allowed is {2}","{0}: {1} '({3}) sẽ được cắt ngắn, vì số kí tự tối đa cho phép là {2}"
DocType: OAuth Client,Resource Owner Password Credentials,Tài nguyên chủ Password Credentials
DocType: OAuth Client,Response Type,Loại phản ứng
apps/frappe/frappe/core/page/usage_info/usage_info.html +21,Max Users,người dùng Max
@@ -2246,7 +2246,7 @@ DocType: DocType,Quick Entry,Quick Entry
apps/frappe/frappe/core/doctype/file/file.py +224,No permission to write / remove.,Không có quyền viết / loại bỏ.
DocType: Web Form,Button Label,nút Label
DocType: Website Theme,UPPERCASE,in hoa
-apps/frappe/frappe/public/js/frappe/list/list_view.js +806,{0} items selected,Đã chọn {0} mục
+apps/frappe/frappe/public/js/frappe/list/list_view.js +806,{0} items selected,{0} mục đã được chọn
apps/frappe/frappe/email/doctype/email_queue/email_queue_list.js +16,Suspend Sending,đình chỉ Gửi
apps/frappe/frappe/printing/page/print_format_builder/print_format_builder_layout.html +3,Drag elements from the sidebar to add. Drag them back to trash.,Yếu tố kéo từ thanh bên để thêm. Kéo chúng trở lại vào thùng rác.
DocType: Workflow State,resize-small,thay đổi kích thước nhỏ
@@ -2374,7 +2374,7 @@ DocType: Web Page,Website Sidebar,website Sidebar
DocType: Web Form,Show Sidebar,Hiện Sidebar
apps/frappe/frappe/website/doctype/web_form/web_form.py +128,You need to be logged in to access this {0}.,Bạn cần phải đăng nhập để truy cập {0} này.
apps/frappe/frappe/public/js/frappe/form/footer/assign_to.js +142,Complete By,Hoàn chỉnh bởi
-apps/frappe/frappe/templates/includes/comments/comments.py +48,{0} by {1},{0} nhân {1}
+apps/frappe/frappe/templates/includes/comments/comments.py +48,{0} by {1},{0} bởi {1}
apps/frappe/frappe/utils/password_strength.py +171,All-uppercase is almost as easy to guess as all-lowercase.,All-hoa là gần như là dễ đoán như tất cả-chữ thường.
DocType: Feedback Trigger,Email Fieldname,Fieldname email
DocType: Website Settings,Top Bar Items,Top Bar mục
@@ -2692,7 +2692,7 @@ apps/frappe/frappe/public/js/frappe/views/treeview.js +297,View List,Xem danh s
apps/frappe/frappe/public/js/frappe/form/control.js +686,Date must be in format: {0},Ngày phải có định dạng: {0}
DocType: Workflow,Don't Override Status,Đừng Override Status
apps/frappe/frappe/www/feedback.html +90,Please give a rating.,Xin vui lòng cho một đánh giá.
-apps/frappe/frappe/public/js/frappe/feedback.js +47,{0} Feedback Request,{0} Phản hồi Yêu cầu
+apps/frappe/frappe/public/js/frappe/feedback.js +47,{0} Feedback Request,{0} Yêu cầu Phản Hồi
apps/frappe/frappe/public/js/frappe/form/multi_select_dialog.js +26,Search term,Thuật ngữ tìm kiếm
apps/frappe/frappe/desk/page/setup_wizard/setup_wizard.js +548,The First User: You,Những thành viên đầu tiên: Bạn
apps/frappe/frappe/printing/page/print_format_builder/print_format_builder_field.html +32,Select Columns,Select Columns
diff --git a/frappe/utils/bench_helper.py b/frappe/utils/bench_helper.py
index c1223dbb37..32a782a3dd 100644
--- a/frappe/utils/bench_helper.py
+++ b/frappe/utils/bench_helper.py
@@ -78,7 +78,7 @@ def get_frappe_commands():
if app_commands:
commands.extend(app_commands.keys())
- print(json.dumps(get_app_commands('frappe').keys()))
+ print(json.dumps(commands))
@click.command('get-frappe-help')
def get_frappe_help():
diff --git a/frappe/website/context.py b/frappe/website/context.py
index cee4c9a2c7..72227f3c41 100644
--- a/frappe/website/context.py
+++ b/frappe/website/context.py
@@ -48,7 +48,7 @@ def update_controller_context(context, controller):
context.update(ret)
except frappe.Redirect:
raise
- except frappe.PermissionError:
+ except (frappe.PermissionError, frappe.DoesNotExistError):
raise
except:
if not frappe.flags.in_migrate: