diff --git a/frappe/__init__.py b/frappe/__init__.py
index 81371ad0f6..ddade9062c 100644
--- a/frappe/__init__.py
+++ b/frappe/__init__.py
@@ -48,9 +48,9 @@ def _(msg, lang=None):
# msg should always be unicode
msg = cstr(msg)
-
+
return get_full_dict(local.lang).get(msg) or msg
-
+
def get_lang_dict(fortype, name=None):
"""Returns the translated language dict for the given type and name.
@@ -836,7 +836,10 @@ def copy_doc(doc, ignore_no_copy=True):
if hasattr(d, df.fieldname):
d.set(df.fieldname, None)
- fields_to_clear = ['name', 'owner', 'creation', 'modified', 'modified_by', 'docstatus']
+ fields_to_clear = ['name', 'owner', 'creation', 'modified', 'modified_by']
+
+ if not local.flags.in_test:
+ fields_to_clear.append("docstatus")
if not isinstance(doc, dict):
d = doc.as_dict()
diff --git a/frappe/__version__.py b/frappe/__version__.py
index 14a6ceff3b..679f789661 100644
--- a/frappe/__version__.py
+++ b/frappe/__version__.py
@@ -1,2 +1,2 @@
from __future__ import unicode_literals
-__version__ = "6.27.2"
+__version__ = "6.27.3"
diff --git a/frappe/core/page/modules_setup/modules_setup.py b/frappe/core/page/modules_setup/modules_setup.py
index 83892bd4a5..d0956cd1e3 100644
--- a/frappe/core/page/modules_setup/modules_setup.py
+++ b/frappe/core/page/modules_setup/modules_setup.py
@@ -48,17 +48,21 @@ def get_user_icons(user):
icons = []
for icon in get_desktop_icons(user):
+ add = True
if icon.hidden_in_standard:
- continue
+ add = False
+
if not icon.custom:
- if icon.type=="page" and icon.link not in allowed_pages:
- continue
+ if icon.module_name=='Learn':
+ pass
+
+ elif icon.type=="page" and icon.link not in allowed_pages:
+ add = False
elif icon.type=="module" and icon.module_name not in user_perms.allow_modules:
- continue
+ add = False
- icons.append(icon)
+ if add:
+ icons.append(icon)
return icons
-
-
diff --git a/frappe/desk/doctype/desktop_icon/desktop_icon.py b/frappe/desk/doctype/desktop_icon/desktop_icon.py
index 35958c272a..35a2a4e703 100644
--- a/frappe/desk/doctype/desktop_icon/desktop_icon.py
+++ b/frappe/desk/doctype/desktop_icon/desktop_icon.py
@@ -97,7 +97,15 @@ def add_user_icon(label, link, type, _doctype):
frappe.session.user)[0][0] or \
frappe.db.sql('select count(*) from `tabDesktop Icon` where standard=1')[0][0]
- color = random.choice(palette)
+ module = frappe.db.get_value('DocType', _doctype, 'module')
+ module_icon = frappe.get_value('Desktop Icon', {'standard':1, 'module_name':module},
+ ['icon', 'color', 'reverse'], as_dict=True)
+
+ if not module_icon:
+ module_icon = frappe._dict()
+ opts = random.choice(palette)
+ module_icon.color = opts[0]
+ module_icon.reverse = 0 if (len(opts) > 1) else 1
try:
frappe.get_doc({
@@ -107,8 +115,9 @@ def add_user_icon(label, link, type, _doctype):
'link': link,
'type': type,
'_doctype': _doctype,
- 'color': color[0],
- 'reverse': 0 if (len(color) > 1) else 1,
+ 'icon': module_icon.icon,
+ 'color': module_icon.color,
+ 'reverse': module_icon.reverse,
'idx': idx + 1,
'custom': 1,
'standard': 0
@@ -128,8 +137,9 @@ def set_order(new_order):
if isinstance(new_order, basestring):
new_order = json.loads(new_order)
for i, module_name in enumerate(new_order):
- icon = get_user_copy(module_name, frappe.session.user)
- icon.db_set('idx', i)
+ if module_name not in ('Explore',):
+ icon = get_user_copy(module_name, frappe.session.user)
+ icon.db_set('idx', i)
clear_desktop_icons_cache()
diff --git a/frappe/desk/page/modules/modules_sidebar_item.html b/frappe/desk/page/modules/modules_sidebar_item.html
index 38fbe44df0..5dfe6aa8b6 100644
--- a/frappe/desk/page/modules/modules_sidebar_item.html
+++ b/frappe/desk/page/modules/modules_sidebar_item.html
@@ -1,7 +1,7 @@
-
diff --git a/frappe/hooks.py b/frappe/hooks.py
index b815781270..b1fd79e47a 100644
--- a/frappe/hooks.py
+++ b/frappe/hooks.py
@@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies"
app_description = "Full stack web framework with Python, Javascript, MariaDB, Redis, Node"
app_icon = "octicon octicon-circuit-board"
-app_version = "6.27.2"
+app_version = "6.27.3"
app_color = "orange"
source_link = "https://github.com/frappe/frappe"
app_license = "MIT"
diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py
index bb36a76bfd..a3b546ea40 100644
--- a/frappe/model/base_document.py
+++ b/frappe/model/base_document.py
@@ -201,6 +201,9 @@ class BaseDocument(object):
# unique empty field should be set to None
d[fieldname] = None
+ if isinstance(d[fieldname], list) and df.fieldtype != 'Table':
+ frappe.throw(_('Value for {0} cannot be a list').format(_(df.label)))
+
return d
def init_valid_columns(self):
diff --git a/frappe/model/document.py b/frappe/model/document.py
index e1f0509125..a61d6a065e 100644
--- a/frappe/model/document.py
+++ b/frappe/model/document.py
@@ -211,6 +211,10 @@ class Document(BaseDocument):
self.run_post_save_methods()
self.flags.in_insert = False
+ # delete __islocal
+ if hasattr(self, "__islocal"):
+ delattr(self, "__islocal")
+
return self
def save(self, ignore_permissions=None):
diff --git a/frappe/public/css/desk.css b/frappe/public/css/desk.css
index a7be95bad8..e9c6d3d65f 100644
--- a/frappe/public/css/desk.css
+++ b/frappe/public/css/desk.css
@@ -317,14 +317,9 @@ a.form-link {
textarea.form-control {
height: 120px;
}
-ul.linked-with-list {
- list-style: none;
- margin: 0 0 20px 0;
- padding: 0 0 0 0;
-}
-ul.linked-with-list li {
- padding: 5px 0px;
- border-bottom: 1px solid #d1d8dd;
+.link-select-row {
+ padding: 5px;
+ border-bottom: 1px solid #EBEFF2;
}
/* jquery ui */
.ui-datepicker .ui-datepicker-header {
diff --git a/frappe/public/js/frappe/form/control.js b/frappe/public/js/frappe/form/control.js
index f12843ce11..c344e2130d 100644
--- a/frappe/public/js/frappe/form/control.js
+++ b/frappe/public/js/frappe/form/control.js
@@ -1302,6 +1302,12 @@ frappe.ui.form.ControlDynamicLink = frappe.ui.form.ControlLink.extend({
if(this.df.get_options) {
return this.df.get_options();
}
+ if (this.docname==null && cur_dialog!=null){ //for dialog box
+ return cur_dialog.get_value(this.df.options)
+ }
+ if (cur_frm==null){//for list page
+ return $("input[data-fieldname*="+this.df.options+"]").val()
+ }
var options = frappe.model.get_value(this.df.parent, this.docname, this.df.options);
// if(!options) {
// msgprint(__("Please set {0} first",
diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js
index 48c3413b7e..b11864b03f 100644
--- a/frappe/public/js/frappe/form/grid.js
+++ b/frappe/public/js/frappe/form/grid.js
@@ -17,6 +17,7 @@ frappe.ui.form.Grid = Class.extend({
this.fieldinfo = {};
this.doctype = this.df.options;
this.template = null;
+ this.multiple_set = false;
if(this.frm.meta.__form_grid_templates
&& this.frm.meta.__form_grid_templates[this.df.fieldname]) {
this.template = this.frm.meta.__form_grid_templates[this.df.fieldname];
@@ -99,7 +100,21 @@ frappe.ui.form.Grid = Class.extend({
if(this.is_editable()) {
this.wrapper.find(".grid-footer").toggle(true);
- this.wrapper.find(".grid-add-row, .grid-add-multiple-rows").toggle(!this.cannot_add_rows);
+
+ // show, hide buttons to add rows
+ if(this.cannot_add_rows) {
+ // add 'hide' to buttons
+ this.wrapper.find(".grid-add-row, .grid-add-multiple-rows")
+ .addClass('hide');
+ } else {
+ // show buttons
+ this.wrapper.find(".grid-add-row").removeClass('hide');
+
+ if(this.multiple_set) {
+ this.wrapper.find(".grid-add-multiple-rows").removeClass('hide')
+ }
+ }
+
this.make_sortable($rows);
} else {
this.wrapper.find(".grid-footer").toggle(false);
@@ -213,18 +228,22 @@ frappe.ui.form.Grid = Class.extend({
if(this.multiple_set) return;
var me = this;
var link_field = frappe.meta.get_docfield(this.df.options, link);
- $(this.wrapper).find(".grid-add-multiple-rows")
- .removeClass("hide")
- .on("click", function() {
- new frappe.ui.form.LinkSelector({
- doctype: link_field.options,
- fieldname: link,
- qty_fieldname: qty,
- target: me,
- txt: ""
- });
- return false;
+ var btn = $(this.wrapper).find(".grid-add-multiple-rows");
+
+ // show button
+ btn.removeClass('hide');
+
+ // open link selector on click
+ btn.on("click", function() {
+ new frappe.ui.form.LinkSelector({
+ doctype: link_field.options,
+ fieldname: link,
+ qty_fieldname: qty,
+ target: me,
+ txt: ""
});
+ return false;
+ });
this.multiple_set = true;
},
setup_allow_bulk_edit: function() {
diff --git a/frappe/public/js/frappe/form/grid_body.html b/frappe/public/js/frappe/form/grid_body.html
index 55ebb86746..7b26b2a419 100644
--- a/frappe/public/js/frappe/form/grid_body.html
+++ b/frappe/public/js/frappe/form/grid_body.html
@@ -7,11 +7,11 @@