Merge branch 'version-12-hotfix' of https://github.com/frappe/frappe into events_ref
This commit is contained in:
commit
2dc1ffabff
13 changed files with 99 additions and 24 deletions
|
|
@ -23,7 +23,7 @@ if sys.version[0] == '2':
|
|||
reload(sys)
|
||||
sys.setdefaultencoding("utf-8")
|
||||
|
||||
__version__ = '12.0.0'
|
||||
__version__ = '12.0.1'
|
||||
__title__ = "Frappe Framework"
|
||||
|
||||
local = Local()
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class AutoRepeat(Document):
|
|||
def before_insert(self):
|
||||
if not frappe.flags.in_test:
|
||||
start_date = self.start_date
|
||||
today_date = today()
|
||||
today_date = getdate(today())
|
||||
if start_date <= today_date:
|
||||
start_date = today_date
|
||||
|
||||
|
|
@ -61,7 +61,8 @@ class AutoRepeat(Document):
|
|||
frappe.throw(_("Enable Allow Auto Repeat for the doctype {0} in Customize Form").format(self.reference_doctype))
|
||||
|
||||
def validate_dates(self):
|
||||
self.validate_from_to_dates('start_date', 'end_date')
|
||||
if self.end_date:
|
||||
self.validate_from_to_dates('start_date', 'end_date')
|
||||
|
||||
if self.end_date == self.start_date:
|
||||
frappe.throw(_('{0} should not be same as {1}').format(frappe.bold('End Date'), frappe.bold('Start Date')))
|
||||
|
|
@ -325,7 +326,9 @@ def set_auto_repeat_as_completed():
|
|||
doc.save()
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_auto_repeat(doctype, docname, frequency, start_date, end_date = None):
|
||||
def make_auto_repeat(doctype, docname, frequency = 'Daily', start_date = None, end_date = None):
|
||||
if not start_date:
|
||||
start_date = getdate(today())
|
||||
doc = frappe.new_doc('Auto Repeat')
|
||||
doc.reference_doctype = doctype
|
||||
doc.reference_document = docname
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ class File(NestedSet):
|
|||
return None
|
||||
|
||||
|
||||
def save_file(self, content=None, decode=False):
|
||||
def save_file(self, content=None, decode=False, ignore_existing_file_check=False):
|
||||
file_exists = False
|
||||
self.content = content
|
||||
if decode:
|
||||
|
|
@ -490,12 +490,15 @@ class File(NestedSet):
|
|||
self.content_hash = get_content_hash(self.content)
|
||||
self.content_type = mimetypes.guess_type(self.file_name)[0]
|
||||
|
||||
_file = False
|
||||
|
||||
# check if a file exists with the same content hash and is also in the same folder (public or private)
|
||||
_file = frappe.get_value("File", {
|
||||
"content_hash": self.content_hash,
|
||||
"is_private": self.is_private
|
||||
},
|
||||
["file_url"])
|
||||
if not ignore_existing_file_check:
|
||||
_file = frappe.get_value("File", {
|
||||
"content_hash": self.content_hash,
|
||||
"is_private": self.is_private
|
||||
},
|
||||
["file_url"])
|
||||
|
||||
if _file:
|
||||
self.file_url = _file
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
|
||||
frappe.ui.form.on('Session Default Settings', {
|
||||
refresh: function(frm) {
|
||||
frm.set_query('ref_doctype', 'session_defaults', function() {
|
||||
return {
|
||||
filters: {
|
||||
issingle: 0,
|
||||
istable: 0
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -45,7 +45,7 @@ def get(chart_name, from_date=None, to_date=None, refresh = None):
|
|||
'''.format(
|
||||
unit_function = get_unit_function(chart.based_on, timegrain),
|
||||
datefield = chart.based_on,
|
||||
aggregate_function = chart.chart_type,
|
||||
aggregate_function = get_aggregate_function(chart.chart_type),
|
||||
value_field = chart.value_based_on or '1',
|
||||
doctype = chart.document_type,
|
||||
conditions = conditions,
|
||||
|
|
@ -67,6 +67,13 @@ def get(chart_name, from_date=None, to_date=None, refresh = None):
|
|||
}]
|
||||
}
|
||||
|
||||
def get_aggregate_function(chart_type):
|
||||
return {
|
||||
"Sum": "SUM",
|
||||
"Count": "COUNT",
|
||||
"Average": "AVG"
|
||||
}[chart_type]
|
||||
|
||||
def convert_to_dates(data, timegrain):
|
||||
result = []
|
||||
for d in data:
|
||||
|
|
|
|||
|
|
@ -240,9 +240,6 @@ class DatabaseQuery(object):
|
|||
|
||||
_is_query(field)
|
||||
|
||||
invalid_characters_regex = r".*[^a-zA-Z0-9-_ ,`'\"\*\.\(\)].*"
|
||||
if re.match(invalid_characters_regex, field):
|
||||
frappe.throw(_("Illegal characters in SQL query"))
|
||||
|
||||
def extract_tables(self):
|
||||
"""extract tables from fields"""
|
||||
|
|
@ -691,9 +688,6 @@ class DatabaseQuery(object):
|
|||
if 'select' in _lower and ' from ' in _lower:
|
||||
frappe.throw(_('Cannot use sub-query in order by'))
|
||||
|
||||
invalid_characters_regex = r".*[^a-z0-9-_ ,`'\"\.\(\)].*"
|
||||
if re.match(invalid_characters_regex, _lower):
|
||||
frappe.throw(_("Illegal characters in SQL query"))
|
||||
|
||||
for field in parameters.split(","):
|
||||
if "." in field and field.strip().startswith("`tab"):
|
||||
|
|
|
|||
33
frappe/patches/v12_0/fix_public_private_files.py
Normal file
33
frappe/patches/v12_0/fix_public_private_files.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import frappe
|
||||
import os
|
||||
|
||||
def execute():
|
||||
files = frappe.get_all('File',
|
||||
fields=['is_private', 'file_url', 'name'],
|
||||
filters={'is_folder': 0})
|
||||
|
||||
for file in files:
|
||||
file_url = file.file_url
|
||||
if file.is_private:
|
||||
if not file_url.startswith('/private/files/'):
|
||||
generate_file(file.name)
|
||||
else:
|
||||
if file_url.startswith('/private/files/'):
|
||||
generate_file(file.name)
|
||||
|
||||
def generate_file(file_name):
|
||||
try:
|
||||
file_doc = frappe.get_doc('File', file_name)
|
||||
# private
|
||||
new_doc = frappe.new_doc('File')
|
||||
new_doc.is_private = file_doc.is_private
|
||||
new_doc.file_name = file_doc.file_name
|
||||
# to create copy of file in right location
|
||||
# if the file doc is private then the file will be created in /private folder
|
||||
# if the file doc is public then the file will be created in /files folder
|
||||
new_doc.save_file(content=file_doc.get_content(), ignore_existing_file_check=True)
|
||||
|
||||
file_doc.file_url = new_doc.file_url
|
||||
file_doc.save()
|
||||
except IOError:
|
||||
pass
|
||||
|
|
@ -300,6 +300,10 @@ frappe.ui.form.MultiSelectDialog = Class.extend({
|
|||
return a.parsed_date - b.parsed_date;
|
||||
});
|
||||
|
||||
// Preselect oldest entry
|
||||
if (me.start < 1 && r.values.length === 1) {
|
||||
results[0].checked = 1;
|
||||
}
|
||||
}
|
||||
me.render_result_list(results, more);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -598,7 +598,6 @@ class FilterArea {
|
|||
}
|
||||
|
||||
const doctype_fields = this.list_view.meta.fields;
|
||||
|
||||
fields = fields.concat(doctype_fields.filter(
|
||||
df => df.in_standard_filter &&
|
||||
frappe.model.is_value_type(df.fieldtype)
|
||||
|
|
@ -617,12 +616,17 @@ class FilterArea {
|
|||
options = options.join("\n");
|
||||
}
|
||||
}
|
||||
let default_value = (fieldtype === 'Link') ? frappe.defaults.get_user_default(options) : null;
|
||||
if (['__default', '__global'].includes(default_value)) {
|
||||
default_value = null;
|
||||
}
|
||||
return {
|
||||
fieldtype: fieldtype,
|
||||
label: __(df.label),
|
||||
options: options,
|
||||
fieldname: df.fieldname,
|
||||
condition: condition,
|
||||
default: default_value,
|
||||
onchange: () => this.refresh_list_view(),
|
||||
ignore_link_validation: fieldtype === 'Dynamic Link'
|
||||
};
|
||||
|
|
|
|||
|
|
@ -255,6 +255,12 @@ frappe.ui.toolbar.setup_session_defaults = function() {
|
|||
};
|
||||
}
|
||||
frappe.prompt(fields, function(values) {
|
||||
//if default is not set for a particular field in prompt
|
||||
fields.forEach(function(d) {
|
||||
if (!values[d.fieldname]) {
|
||||
values[d.fieldname] = "";
|
||||
}
|
||||
});
|
||||
frappe.call({
|
||||
method: 'frappe.core.doctype.session_default_settings.session_default_settings.set_session_default_values',
|
||||
args: {
|
||||
|
|
@ -266,7 +272,7 @@ frappe.ui.toolbar.setup_session_defaults = function() {
|
|||
'message': __('Session Defaults Saved'),
|
||||
'indicator': 'green'
|
||||
});
|
||||
frappe.clear_cache();
|
||||
frappe.ui.toolbar.clear_cache();
|
||||
} else {
|
||||
frappe.show_alert({
|
||||
'message': __('An error occurred while setting Session Defaults'),
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ export default class WebFormList {
|
|||
add_heading(row, "Sr.");
|
||||
this.columns.forEach(col => {
|
||||
let th = document.createElement("th");
|
||||
let text = document.createTextNode(col.label);
|
||||
let text = document.createTextNode(__(col.label));
|
||||
th.appendChild(text);
|
||||
row.appendChild(th);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -33,9 +33,15 @@
|
|||
{% for row in data %}
|
||||
<tr>
|
||||
{% for col in columns %}
|
||||
<td {{- get_alignment(col) }}>
|
||||
{{- frappe.format(row[col.fieldname], col, row) -}}
|
||||
</td>
|
||||
{% if row[col.fieldname] == 'Total' %}
|
||||
<td {{- get_alignment(col) }}>
|
||||
{{- row[col.fieldname] -}}
|
||||
</td>
|
||||
{% else %}
|
||||
<td {{- get_alignment(col) }}>
|
||||
{{- frappe.format(row[col.fieldname], col, row) -}}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ def render_template(template, context, is_path=None, safe_render=True):
|
|||
or (template.endswith('.html') and '\n' not in template)):
|
||||
return get_jenv().get_template(template).render(context)
|
||||
else:
|
||||
if safe_render and "__" in template:
|
||||
if safe_render and ".__" in template:
|
||||
throw("Illegal template")
|
||||
try:
|
||||
return get_jenv().from_string(template).render(context)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue