diff --git a/.travis.yml b/.travis.yml
index 30eb882256..9fab56188b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -25,6 +25,7 @@ cache:
# https://docs.cypress.io/guides/guides/continuous-integration.html#Caching
- ~/.cache
+
matrix:
include:
- name: "Python 3.7 MariaDB"
@@ -46,7 +47,26 @@ matrix:
script: bench --site test_site run-ui-tests frappe --headless
before_install:
- # install wkhtmltopdf
+ # do we really want to run travis?
+ - |
+ ONLY_DOCS_CHANGES=$(git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '\.(md|png|jpg|jpeg)$|^.github|LICENSE' ; echo $?)
+ ONLY_JS_CHANGES=$(git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '\.js$' ; echo $?)
+ ONLY_PY_CHANGES=$(git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '\.py$' ; echo $?)
+
+ if [[ $ONLY_DOCS_CHANGES == "1" ]]; then
+ echo "Only docs were updated, stopping build process.";
+ exit;
+ fi
+ if [[ $ONLY_JS_CHANGES == "1" && $TYPE == "server" ]]; then
+ echo "Only JavaScript code was updated; Stopping Python build process.";
+ exit;
+ fi
+ if [[ $ONLY_PY_CHANGES == "1" && $TYPE == "ui" ]]; then
+ echo "Only Python code was updated, stopping Cypress build process.";
+ exit;
+ fi
+
+ # install wkhtmltopdf
- wget -O /tmp/wkhtmltox.tar.xz https://github.com/frappe/wkhtmltopdf/raw/master/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
- tar -xf /tmp/wkhtmltox.tar.xz -C /tmp
- sudo mv /tmp/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
diff --git a/frappe/__init__.py b/frappe/__init__.py
index f0b6bfe41b..d917458510 100644
--- a/frappe/__init__.py
+++ b/frappe/__init__.py
@@ -1559,10 +1559,10 @@ def get_doctype_app(doctype):
loggers = {}
log_level = None
-def logger(module=None, with_more_info=True):
+def logger(module=None, with_more_info=False):
'''Returns a python logger that uses StreamHandler'''
from frappe.utils.logger import get_logger
- return get_logger(module or 'default', with_more_info=with_more_info)
+ return get_logger(module=module, with_more_info=with_more_info)
def log_error(message=None, title=_("Error")):
'''Log error to Error Log'''
diff --git a/frappe/app.py b/frappe/app.py
index 3bb764149b..50d09177d6 100644
--- a/frappe/app.py
+++ b/frappe/app.py
@@ -99,6 +99,16 @@ def application(request):
frappe.monitor.stop(response)
frappe.recorder.dump()
+ frappe.logger("web").info({
+ "site": get_site_name(request.host),
+ "remote_addr": getattr(request, "remote_addr", "NOTFOUND"),
+ "base_url": getattr(request, "base_url", "NOTFOUND"),
+ "full_path": getattr(request, "full_path", "NOTFOUND"),
+ "method": getattr(request, "method", "NOTFOUND"),
+ "scheme": getattr(request, "scheme", "NOTFOUND"),
+ "http_status_code": getattr(response, "status_code", "NOTFOUND")
+ })
+
if response and hasattr(frappe.local, 'rate_limiter'):
response.headers.extend(frappe.local.rate_limiter.headers())
@@ -195,7 +205,6 @@ def handle_exception(e):
frappe.local.login_manager.clear_cookies()
if http_status_code >= 500:
- frappe.logger().error('Request Error', exc_info=True)
make_error_snapshot(e)
if return_as_message:
diff --git a/frappe/boot.py b/frappe/boot.py
index e615cc49fa..695a4d754b 100644
--- a/frappe/boot.py
+++ b/frappe/boot.py
@@ -19,6 +19,7 @@ from frappe.email.inbox import get_email_accounts
from frappe.social.doctype.energy_point_settings.energy_point_settings import is_energy_point_enabled
from frappe.website.doctype.web_page_view.web_page_view import is_tracking_enabled
from frappe.social.doctype.energy_point_log.energy_point_log import get_energy_points
+from frappe.model.base_document import get_controller
from frappe.social.doctype.post.post import frequently_visited_links
def get_bootinfo():
@@ -106,6 +107,7 @@ def load_desktop_data(bootinfo):
from frappe.desk.desktop import get_desk_sidebar_items
bootinfo.allowed_modules = get_modules_from_all_apps_for_user()
bootinfo.allowed_workspaces = get_desk_sidebar_items(True)
+ bootinfo.module_page_map = get_controller("Desk Page").get_module_page_map()
bootinfo.dashboards = frappe.get_all("Dashboard")
def get_allowed_pages(cache=False):
diff --git a/frappe/commands/site.py b/frappe/commands/site.py
index b0abe9e2e6..163d25f183 100755
--- a/frappe/commands/site.py
+++ b/frappe/commands/site.py
@@ -447,7 +447,7 @@ def _drop_site(site, root_login='root', root_password=None, archived_sites_path=
else:
click.echo("="*80)
click.echo("Error: The operation has stopped because backup of {s}'s database failed.".format(s=site))
- click.echo("Reason: {reason}{sep}".format(reason=err[1], sep="\n"))
+ click.echo("Reason: {reason}{sep}".format(reason=str(err), sep="\n"))
click.echo("Fix the issue and try again.")
click.echo(
"Hint: Use 'bench drop-site {s} --force' to force the removal of {s}".format(sep="\n", tab="\t", s=site)
diff --git a/frappe/core/doctype/access_log/test_access_log.py b/frappe/core/doctype/access_log/test_access_log.py
index 312f77c026..9830507423 100644
--- a/frappe/core/doctype/access_log/test_access_log.py
+++ b/frappe/core/doctype/access_log/test_access_log.py
@@ -158,11 +158,7 @@ class TestAccessLog(unittest.TestCase):
request = requests.post(private_file_link, headers=self.header)
last_doc = frappe.get_last_doc('Access Log')
- if request.status_code == 403:
- # if file is not accessible, access log wont be generated
- pass
-
- else:
+ if request.ok:
# check for the access log of downloaded file
self.assertEqual(new_private_file.doctype, last_doc.export_from)
self.assertEqual(new_private_file.name, last_doc.reference_document)
diff --git a/frappe/core/doctype/communication/communication.py b/frappe/core/doctype/communication/communication.py
index d8f3bf9e77..20e4774add 100644
--- a/frappe/core/doctype/communication/communication.py
+++ b/frappe/core/doctype/communication/communication.py
@@ -259,7 +259,12 @@ class Communication(Document):
# Timeline Links
def set_timeline_links(self):
- contacts = get_contacts([self.sender, self.recipients, self.cc, self.bcc])
+ contacts = []
+ if (self.email_account and frappe.db.get_value("Email Account", self.email_account, "create_contact")) or \
+ frappe.flags.in_test:
+
+ contacts = get_contacts([self.sender, self.recipients, self.cc, self.bcc])
+
for contact_name in contacts:
self.add_link('Contact', contact_name)
diff --git a/frappe/core/doctype/communication/test_communication.py b/frappe/core/doctype/communication/test_communication.py
index fb859586bb..6df90baaae 100644
--- a/frappe/core/doctype/communication/test_communication.py
+++ b/frappe/core/doctype/communication/test_communication.py
@@ -202,6 +202,8 @@ class TestCommunication(unittest.TestCase):
self.assertIn(("Note", note.name), doc_links)
def create_email_account():
+ frappe.delete_doc_if_exists("Email Account", "_Test Comm Account 1")
+
frappe.flags.mute_emails = False
frappe.flags.sent_mail = None
diff --git a/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py b/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py
index c179054550..765ae5fe93 100644
--- a/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py
+++ b/frappe/core/doctype/scheduled_job_type/scheduled_job_type.py
@@ -84,7 +84,7 @@ class ScheduledJobType(Document):
def log_status(self, status):
# log file
- frappe.logger(__name__).info('Scheduled Job {0}: {1} for {2}'.format(status, self.method, frappe.local.site))
+ frappe.logger("scheduler").info('Scheduled Job {0}: {1} for {2}'.format(status, self.method, frappe.local.site))
self.update_scheduler_log(status)
def update_scheduler_log(self, status):
diff --git a/frappe/custom/doctype/custom_field/custom_field.py b/frappe/custom/doctype/custom_field/custom_field.py
index 21679c5bc7..a24777a80a 100644
--- a/frappe/custom/doctype/custom_field/custom_field.py
+++ b/frappe/custom/doctype/custom_field/custom_field.py
@@ -46,6 +46,9 @@ class CustomField(Document):
if not self.fieldname:
frappe.throw(_("Fieldname not set for Custom Field"))
+ if self.fieldname in fieldnames:
+ frappe.throw(_("A field with the name '{}' already exists in doctype {}.").format(self.fieldname, self.dt))
+
if self.get('translatable', 0) and not supports_translation(self.fieldtype):
self.translatable = 0
diff --git a/frappe/desk/doctype/dashboard_chart/dashboard_chart.js b/frappe/desk/doctype/dashboard_chart/dashboard_chart.js
index 9053a9ab7f..a10d3d96f2 100644
--- a/frappe/desk/doctype/dashboard_chart/dashboard_chart.js
+++ b/frappe/desk/doctype/dashboard_chart/dashboard_chart.js
@@ -251,6 +251,7 @@ frappe.ui.form.on('Dashboard Chart', {
render_filters_table: function(frm) {
frm.set_df_property("filters_section", "hidden", 0);
let is_document_type = frm.doc.chart_type!== 'Report' && frm.doc.chart_type!=='Custom';
+ let is_dynamic_filter = f => ['Date', 'DateRange'].includes(f.fieldtype) && f.default;
let wrapper = $(frm.get_field('filters_json').wrapper).empty();
let table = $(`
@@ -268,6 +269,18 @@ frappe.ui.form.on('Dashboard Chart', {
let filters = JSON.parse(frm.doc.filters_json || '[]');
var filters_set = false;
+ // Set dynamic filters for reports
+ if (frm.doc.chart_type == 'Report') {
+ let set_filters = false;
+ frm.chart_filters.forEach(f => {
+ if (is_dynamic_filter(f)) {
+ filters[f.fieldname] = f.default;
+ set_filters = true;
+ }
+ });
+ set_filters && frm.set_value('filters_json', JSON.stringify(filters));
+ }
+
let fields;
if (is_document_type) {
fields = [
@@ -292,6 +305,7 @@ frappe.ui.form.on('Dashboard Chart', {
}
} else if (frm.chart_filters.length) {
fields = frm.chart_filters.filter(f => f.fieldname);
+
fields.map( f => {
if (filters[f.fieldname]) {
let condition = '=';
@@ -318,7 +332,7 @@ frappe.ui.form.on('Dashboard Chart', {
let dialog = new frappe.ui.Dialog({
title: __('Set Filters'),
- fields: fields,
+ fields: fields.filter(f => !is_dynamic_filter(f)),
primary_action: function() {
let values = this.get_values();
if (values) {
@@ -351,10 +365,15 @@ frappe.ui.form.on('Dashboard Chart', {
}
dialog.show();
- //Set query report object so that it can be used while fetching filter values in the report
- frappe.query_report = new frappe.views.QueryReport({'filters': dialog.fields_list});
- frappe.query_reports[frm.doc.report_name].onload
- && frappe.query_reports[frm.doc.report_name].onload(frappe.query_report);
+
+ if (frm.doc.chart_type == 'Report') {
+ //Set query report object so that it can be used while fetching filter values in the report
+ frappe.query_report = new frappe.views.QueryReport({'filters': dialog.fields_list});
+ frappe.query_reports[frm.doc.report_name]
+ && frappe.query_reports[frm.doc.report_name].onload
+ && frappe.query_reports[frm.doc.report_name].onload(frappe.query_report);
+ }
+
dialog.set_values(filters);
});
},
diff --git a/frappe/desk/doctype/desk_page/desk_page.py b/frappe/desk/doctype/desk_page/desk_page.py
index dd9cc0706a..f14535cb5f 100644
--- a/frappe/desk/doctype/desk_page/desk_page.py
+++ b/frappe/desk/doctype/desk_page/desk_page.py
@@ -20,6 +20,17 @@ class DeskPage(Document):
if frappe.conf.developer_mode and self.is_standard:
export_to_files(record_list=[['Desk Page', self.name]], record_module=self.module)
+ @staticmethod
+ def get_module_page_map():
+ filters = {
+ 'extends_another_page': 0,
+ 'for_user': '',
+ }
+
+ pages = frappe.get_all("Desk Page", fields=["name", "module"], filters=filters, as_list=1)
+
+ return { page[1]: page[0] for page in pages }
+
def disable_saving_as_standard():
return frappe.flags.in_install or \
frappe.flags.in_patch or \
diff --git a/frappe/desk/doctype/notification_log/notification_log.js b/frappe/desk/doctype/notification_log/notification_log.js
index 654b2b2b06..1f381d115b 100644
--- a/frappe/desk/doctype/notification_log/notification_log.js
+++ b/frappe/desk/doctype/notification_log/notification_log.js
@@ -3,10 +3,43 @@
frappe.ui.form.on('Notification Log', {
refresh: function(frm) {
- let dt = frm.doc.document_type;
- let dn = frm.doc.document_name;
- frm.fields_dict.document_name.$input_wrapper
- .find('.control-value')
- .wrapInner(``);
+ if (frm.doc.attached_file) {
+ frm.trigger('set_attachment');
+ } else {
+ frm.get_field('attachment_link').$wrapper.empty();
+ }
+ },
+
+ open_reference_document: function(frm) {
+ const dt = frm.doc.document_type;
+ const dn = frm.doc.document_name;
+ frappe.set_route('Form', dt, dn);
+ },
+
+ set_attachment: function(frm) {
+ const attachment = JSON.parse(frm.doc.attached_file);
+
+ const $wrapper = frm.get_field('attachment_link').$wrapper;
+ $wrapper.html(`
+
+ `);
+
+ $wrapper.find(".attached-file-link").click(() => {
+ const w = window.open(
+ frappe.urllib.get_full_url(`/api/method/frappe.utils.print_format.download_pdf?
+ doctype=${encodeURIComponent(attachment.doctype)}
+ &name=${encodeURIComponent(attachment.name)}
+ &format=${encodeURIComponent(attachment.print_format)}
+ &lang=${encodeURIComponent(attachment.lang)}`)
+ );
+ if (!w) {
+ frappe.msgprint(__("Please enable pop-ups"));
+ }
+ });
}
});
diff --git a/frappe/desk/doctype/notification_log/notification_log.json b/frappe/desk/doctype/notification_log/notification_log.json
index ecb746df64..050bf85ead 100644
--- a/frappe/desk/doctype/notification_log/notification_log.json
+++ b/frappe/desk/doctype/notification_log/notification_log.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"creation": "2019-08-26 13:37:34.165254",
"doctype": "DocType",
"editable_grid": 1,
@@ -8,10 +9,12 @@
"for_user",
"type",
"email_content",
- "column_break_4",
"document_type",
"read",
"document_name",
+ "attached_file",
+ "attachment_link",
+ "open_reference_document",
"from_user"
],
"fields": [
@@ -20,57 +23,65 @@
"fieldtype": "Text",
"in_list_view": 1,
"label": "Subject",
- "read_only": 1
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "for_user",
"fieldtype": "Link",
+ "hidden": 1,
"label": "For User",
"options": "User",
- "read_only": 1
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "type",
"fieldtype": "Select",
+ "hidden": 1,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Type",
- "options": "Mention\nEnergy Point\nAssignment\nShare",
- "read_only": 1,
- "search_index": 1
+ "options": "Mention\nEnergy Point\nAssignment\nShare\nAlert",
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "email_content",
- "fieldtype": "Text",
- "label": "Email Content",
- "read_only": 1
- },
- {
- "fieldname": "column_break_4",
- "fieldtype": "Column Break"
+ "fieldtype": "Text Editor",
+ "label": "Message",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "document_type",
"fieldtype": "Link",
+ "hidden": 1,
"label": "Document Type",
"options": "DocType",
- "read_only": 1,
- "search_index": 1
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "document_name",
"fieldtype": "Data",
- "label": "Document Name",
- "read_only": 1,
- "search_index": 1
+ "hidden": 1,
+ "label": "Document Link",
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "from_user",
"fieldtype": "Link",
+ "hidden": 1,
"label": "From User",
"options": "User",
- "read_only": 1,
- "search_index": 1
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
@@ -78,26 +89,51 @@
"fieldtype": "Check",
"hidden": 1,
"ignore_user_permissions": 1,
- "label": "Read"
+ "label": "Read",
+ "show_days": 1,
+ "show_seconds": 1
+ },
+ {
+ "fieldname": "open_reference_document",
+ "fieldtype": "Button",
+ "label": "Open Reference Document",
+ "show_days": 1,
+ "show_seconds": 1
+ },
+ {
+ "fieldname": "attached_file",
+ "fieldtype": "Code",
+ "hidden": 1,
+ "label": "Attached File",
+ "options": "JSON",
+ "show_days": 1,
+ "show_seconds": 1
+ },
+ {
+ "fieldname": "attachment_link",
+ "fieldtype": "HTML",
+ "label": "Attachment Link",
+ "show_days": 1,
+ "show_seconds": 1
}
],
+ "hide_toolbar": 1,
"in_create": 1,
- "modified": "2019-11-12 15:22:35.283678",
+ "links": [],
+ "modified": "2020-05-31 22:31:12.886950",
"modified_by": "umair@erpnext.com",
"module": "Desk",
"name": "Notification Log",
"owner": "Administrator",
"permissions": [
{
- "create": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "All",
- "share": 1,
- "write": 1
+ "share": 1
}
],
"sort_field": "modified",
diff --git a/frappe/desk/doctype/notification_log/notification_log.py b/frappe/desk/doctype/notification_log/notification_log.py
index 17eb6371b1..211b3ae5e6 100644
--- a/frappe/desk/doctype/notification_log/notification_log.py
+++ b/frappe/desk/doctype/notification_log/notification_log.py
@@ -48,6 +48,7 @@ def enqueue_create_notification(users, doc):
if isinstance(users, frappe.string_types):
users = [user.strip() for user in users.split(',') if user.strip()]
+ users = list(set(users))
frappe.enqueue(
'frappe.desk.doctype.notification_log.notification_log.make_notification_logs',
@@ -58,6 +59,7 @@ def enqueue_create_notification(users, doc):
def make_notification_logs(doc, users):
from frappe.social.doctype.energy_point_settings.energy_point_settings import is_energy_point_enabled
+
for user in users:
if frappe.db.exists('User', user):
if is_notifications_enabled(user):
@@ -68,7 +70,7 @@ def make_notification_logs(doc, users):
_doc.update(doc)
_doc.for_user = user
_doc.subject = _doc.subject.replace('', '').replace('
', '')
- if _doc.for_user != _doc.from_user or doc.type == 'Energy Point':
+ if _doc.for_user != _doc.from_user or doc.type == 'Energy Point' or doc.type == 'Alert':
_doc.insert(ignore_permissions=True)
def send_notification_email(doc):
diff --git a/frappe/desk/doctype/notification_settings/notification_settings.json b/frappe/desk/doctype/notification_settings/notification_settings.json
index 6af325507b..85f93e156e 100644
--- a/frappe/desk/doctype/notification_settings/notification_settings.json
+++ b/frappe/desk/doctype/notification_settings/notification_settings.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"autoname": "Prompt",
"creation": "2019-09-11 22:15:44.851526",
"doctype": "DocType",
@@ -21,52 +22,68 @@
"default": "1",
"fieldname": "enabled",
"fieldtype": "Check",
- "label": "Enabled"
+ "label": "Enabled",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "subscribed_documents",
"fieldtype": "Table MultiSelect",
"label": "Subscribed Documents",
- "options": "Notification Subscribed Document"
+ "options": "Notification Subscribed Document",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "column_break_3",
"fieldtype": "Section Break",
- "label": "Email Settings"
+ "label": "Email Settings",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "1",
"fieldname": "enable_email_notifications",
"fieldtype": "Check",
- "label": "Enable Email Notifications"
+ "label": "Enable Email Notifications",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "1",
"depends_on": "enable_email_notifications",
"fieldname": "enable_email_mention",
"fieldtype": "Check",
- "label": "Mentions"
+ "label": "Mentions",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "1",
"depends_on": "enable_email_notifications",
"fieldname": "enable_email_assignment",
"fieldtype": "Check",
- "label": "Assignments"
+ "label": "Assignments",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "1",
"depends_on": "enable_email_notifications",
"fieldname": "enable_email_energy_point",
"fieldtype": "Check",
- "label": "Energy Points"
+ "label": "Energy Points",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "1",
"depends_on": "enable_email_notifications",
"fieldname": "enable_email_share",
"fieldtype": "Check",
- "label": "Document Share"
+ "label": "Document Share",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "__user",
@@ -75,18 +92,23 @@
"hidden": 1,
"label": "User",
"options": "User",
- "read_only": 1
+ "read_only": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
"fieldname": "seen",
"fieldtype": "Check",
"hidden": 1,
- "label": "Seen"
+ "label": "Seen",
+ "show_days": 1,
+ "show_seconds": 1
}
],
"in_create": 1,
- "modified": "2019-11-19 12:57:59.356786",
+ "links": [],
+ "modified": "2020-05-31 22:16:40.798019",
"modified_by": "Administrator",
"module": "Desk",
"name": "Notification Settings",
diff --git a/frappe/desk/doctype/notification_settings/notification_settings.py b/frappe/desk/doctype/notification_settings/notification_settings.py
index 6b5a13ee27..9b124cd6f4 100644
--- a/frappe/desk/doctype/notification_settings/notification_settings.py
+++ b/frappe/desk/doctype/notification_settings/notification_settings.py
@@ -28,6 +28,9 @@ def is_email_notifications_enabled_for_type(user, notification_type):
if not is_email_notifications_enabled(user):
return False
+ if notification_type == 'Alert':
+ return False
+
fieldname = 'enable_email_' + frappe.scrub(notification_type)
enabled = frappe.db.get_value('Notification Settings', user, fieldname)
if enabled is None:
diff --git a/frappe/desk/page/user_profile/user_profile.js b/frappe/desk/page/user_profile/user_profile.js
index c43ff27ba3..646c31f7a1 100644
--- a/frappe/desk/page/user_profile/user_profile.js
+++ b/frappe/desk/page/user_profile/user_profile.js
@@ -110,7 +110,11 @@ class UserProfile {
render_line_chart() {
- this.line_chart_filters = [['Energy Point Log', 'user', '=', this.user_id, false]];
+ this.line_chart_filters = [
+ ['Energy Point Log', 'user', '=', this.user_id, false],
+ ['Energy Point Log', 'type', '!=', 'Review', false]
+ ];
+
this.line_chart_config = {
timespan: 'Last Month',
time_interval: 'Daily',
@@ -186,7 +190,10 @@ class UserProfile {
options: ['All', 'Auto', 'Criticism', 'Appreciation', 'Revert'],
action: (selected_item) => {
if (selected_item === 'All') {
- if (this.line_chart_filters.length > 1) this.line_chart_filters.pop();
+ this.line_chart_filters = [
+ ['Energy Point Log', 'user', '=', this.user_id, false],
+ ['Energy Point Log', 'type', '!=', 'Review', false]
+ ];
} else {
this.line_chart_filters[1] = ['Energy Point Log', 'type', '=', selected_item, false];
}
diff --git a/frappe/email/doctype/email_account/email_account.json b/frappe/email/doctype/email_account/email_account.json
index 6bde0291a0..057638697a 100644
--- a/frappe/email/doctype/email_account/email_account.json
+++ b/frappe/email/doctype/email_account/email_account.json
@@ -29,6 +29,7 @@
"default_incoming",
"email_sync_option",
"initial_sync_count",
+ "create_contact",
"section_break_12",
"enable_automatic_linking",
"section_break_13",
@@ -114,9 +115,9 @@
"depends_on": "eval:!doc.service",
"fieldname": "domain",
"fieldtype": "Link",
- "label": "Domain",
"in_list_view": 1,
"in_standard_filter": 1,
+ "label": "Domain",
"options": "Email Domain"
},
{
@@ -408,11 +409,17 @@
"fieldname": "use_ssl_for_outgoing",
"fieldtype": "Check",
"label": "Use SSL for Outgoing"
+ },
+ {
+ "default": "1",
+ "fieldname": "create_contact",
+ "fieldtype": "Check",
+ "label": "Create Contacts from Incoming Emails"
}
],
"icon": "fa fa-inbox",
"links": [],
- "modified": "2020-04-06 19:20:50.491146",
+ "modified": "2020-05-11 15:18:43.931499",
"modified_by": "Administrator",
"module": "Email",
"name": "Email Account",
@@ -427,11 +434,11 @@
"write": 1
},
{
- "read": 1,
- "role": "Inbox User"
+ "read": 1,
+ "role": "Inbox User"
}
],
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/frappe/email/doctype/notification/notification.js b/frappe/email/doctype/notification/notification.js
index 44056955f7..02fc8512ca 100644
--- a/frappe/email/doctype/notification/notification.js
+++ b/frappe/email/doctype/notification/notification.js
@@ -80,7 +80,6 @@ frappe.ui.form.on("Notification", {
});
},
refresh: function(frm) {
- frm.toggle_reqd("recipients", frm.doc.channel=="Email");
frappe.notification.setup_fieldname_select(frm);
frm.get_field("is_standard").toggle(frappe.boot.developer_mode);
frm.trigger('event');
diff --git a/frappe/email/doctype/notification/notification.json b/frappe/email/doctype/notification/notification.json
index 14eff2251a..d1526f5fe4 100644
--- a/frappe/email/doctype/notification/notification.json
+++ b/frappe/email/doctype/notification/notification.json
@@ -1,4 +1,5 @@
{
+ "actions": [],
"allow_rename": 1,
"autoname": "Prompt",
"creation": "2014-07-11 17:18:09.923399",
@@ -22,6 +23,7 @@
"days_in_advance",
"value_changed",
"sender",
+ "send_system_notification",
"sender_email",
"section_break_9",
"condition",
@@ -46,32 +48,43 @@
"default": "1",
"fieldname": "enabled",
"fieldtype": "Check",
- "label": "Enabled"
+ "label": "Enabled",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "column_break_2",
- "fieldtype": "Column Break"
+ "fieldtype": "Column Break",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "Email",
+ "depends_on": "eval: !doc.disable_channel",
"fieldname": "channel",
"fieldtype": "Select",
"label": "Channel",
- "options": "Email\nSlack",
+ "options": "Email\nSlack\nSystem Notification",
"reqd": 1,
- "set_only_once": 1
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "eval:doc.channel=='Slack'",
"fieldname": "slack_webhook_url",
"fieldtype": "Link",
"label": "Slack Channel",
- "options": "Slack Webhook URL"
+ "mandatory_depends_on": "eval:doc.channel=='Slack'",
+ "options": "Slack Webhook URL",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "filters",
"fieldtype": "Section Break",
- "label": "Filters"
+ "label": "Filters",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"description": "To add dynamic subject, use jinja tags like\n\n",
@@ -80,7 +93,9 @@
"ignore_xss_filter": 1,
"in_list_view": 1,
"label": "Subject",
- "reqd": 1
+ "reqd": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "document_type",
@@ -90,13 +105,17 @@
"label": "Document Type",
"options": "DocType",
"reqd": 1,
- "search_index": 1
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
"fieldname": "is_standard",
"fieldtype": "Check",
- "label": "Is Standard"
+ "label": "Is Standard",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "is_standard",
@@ -104,11 +123,15 @@
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Module",
- "options": "Module Def"
+ "options": "Module Def",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "col_break_1",
- "fieldtype": "Column Break"
+ "fieldtype": "Column Break",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "event",
@@ -117,21 +140,27 @@
"label": "Send Alert On",
"options": "\nNew\nSave\nSubmit\nCancel\nDays After\nDays Before\nValue Change\nMethod\nCustom",
"reqd": 1,
- "search_index": 1
+ "search_index": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "eval:doc.event=='Method'",
"description": "Trigger on valid methods like \"before_insert\", \"after_update\", etc (will depend on the DocType selected)",
"fieldname": "method",
"fieldtype": "Data",
- "label": "Trigger Method"
+ "label": "Trigger Method",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "eval:doc.event==\"Days After\" || doc.event==\"Days Before\"",
"description": "Send alert if date matches this field's value",
"fieldname": "date_changed",
"fieldtype": "Select",
- "label": "Reference Date"
+ "label": "Reference Date",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
@@ -139,31 +168,41 @@
"description": "Send days before or after the reference date",
"fieldname": "days_in_advance",
"fieldtype": "Int",
- "label": "Days Before or After"
+ "label": "Days Before or After",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "eval:doc.event==\"Value Change\"",
"description": "Send alert if this field's value changes",
"fieldname": "value_changed",
"fieldtype": "Select",
- "label": "Value Changed"
+ "label": "Value Changed",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "sender",
"fieldtype": "Link",
"label": "Sender",
- "options": "Email Account"
+ "options": "Email Account",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "sender_email",
"fieldtype": "Data",
"label": "Sender Email",
"options": "Email",
- "read_only": 1
+ "read_only": 1,
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "section_break_9",
- "fieldtype": "Section Break"
+ "fieldtype": "Section Break",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"description": "Optional: The alert will be sent if this expression is true",
@@ -171,99 +210,143 @@
"fieldtype": "Code",
"ignore_xss_filter": 1,
"in_list_view": 1,
- "label": "Condition"
+ "label": "Condition",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "column_break_6",
- "fieldtype": "Column Break"
+ "fieldtype": "Column Break",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "html_7",
"fieldtype": "HTML",
- "options": "Condition Examples:
\ndoc.status==\"Open\"
doc.due_date==nowdate()
doc.total > 40000\n
\n"
+ "options": "Condition Examples:
\ndoc.status==\"Open\"
doc.due_date==nowdate()
doc.total > 40000\n
\n",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"collapsible": 1,
"fieldname": "property_section",
"fieldtype": "Section Break",
- "label": "Set Property After Alert"
+ "label": "Set Property After Alert",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "set_property_after_alert",
"fieldtype": "Select",
- "label": "Set Property After Alert"
+ "label": "Set Property After Alert",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "property_value",
"fieldtype": "Data",
- "label": "Value To Be Set"
+ "label": "Value To Be Set",
+ "show_days": 1,
+ "show_seconds": 1
},
{
- "depends_on": "eval:doc.channel=='Email'",
+ "depends_on": "eval:doc.channel!=='Slack'",
"fieldname": "column_break_5",
"fieldtype": "Section Break",
- "label": "Recipients"
+ "label": "Recipients",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "recipients",
"fieldtype": "Table",
"label": "Recipients",
- "options": "Notification Recipient"
+ "mandatory_depends_on": "eval:doc.channel!=='Slack'",
+ "options": "Notification Recipient",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "message_sb",
"fieldtype": "Section Break",
- "label": "Message"
+ "label": "Message",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "Add your message here",
"fieldname": "message",
"fieldtype": "Code",
"ignore_xss_filter": 1,
- "label": "Message"
+ "label": "Message",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "eval:doc.channel=='Email'",
"fieldname": "message_examples",
"fieldtype": "HTML",
"label": "Message Examples",
- "options": "Message Example
\n\n<h3>Order Overdue</h3>\n\n<p>Transaction {{ doc.name }} has exceeded Due Date. Please take necessary action.</p>\n\n<!-- show last comment -->\n{% if comments %}\nLast comment: {{ comments[-1].comment }} by {{ comments[-1].by }}\n{% endif %}\n\n<h4>Details</h4>\n\n<ul>\n<li>Customer: {{ doc.customer }}\n<li>Amount: {{ doc.grand_total }}\n</ul>\n"
+ "options": "Message Example
\n\n<h3>Order Overdue</h3>\n\n<p>Transaction {{ doc.name }} has exceeded Due Date. Please take necessary action.</p>\n\n<!-- show last comment -->\n{% if comments %}\nLast comment: {{ comments[-1].comment }} by {{ comments[-1].by }}\n{% endif %}\n\n<h4>Details</h4>\n\n<ul>\n<li>Customer: {{ doc.customer }}\n<li>Amount: {{ doc.grand_total }}\n</ul>\n",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "eval:doc.channel=='Slack'",
"fieldname": "slack_message_examples",
"fieldtype": "HTML",
"label": "Message Examples",
- "options": "Message Example
\n\n*Order Overdue*\n\nTransaction {{ doc.name }} has exceeded Due Date. Please take necessary action.\n\n\n{% if comments %}\nLast comment: {{ comments[-1].comment }} by {{ comments[-1].by }}\n{% endif %}\n\n*Details*\n\n\u2022 Customer: {{ doc.customer }}\n\u2022 Amount: {{ doc.grand_total }}\n"
+ "options": "Message Example
\n\n*Order Overdue*\n\nTransaction {{ doc.name }} has exceeded Due Date. Please take necessary action.\n\n\n{% if comments %}\nLast comment: {{ comments[-1].comment }} by {{ comments[-1].by }}\n{% endif %}\n\n*Details*\n\n\u2022 Customer: {{ doc.customer }}\n\u2022 Amount: {{ doc.grand_total }}\n",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"fieldname": "view_properties",
"fieldtype": "Button",
- "label": "View Properties (via Customize Form)"
+ "label": "View Properties (via Customize Form)",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"collapsible": 1,
"collapsible_depends_on": "attach_print",
"fieldname": "column_break_25",
"fieldtype": "Section Break",
- "label": "Print Settings"
+ "label": "Print Settings",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"default": "0",
"fieldname": "attach_print",
"fieldtype": "Check",
- "label": "Attach Print"
+ "label": "Attach Print",
+ "show_days": 1,
+ "show_seconds": 1
},
{
"depends_on": "attach_print",
"fieldname": "print_format",
"fieldtype": "Link",
"label": "Print Format",
- "options": "Print Format"
+ "options": "Print Format",
+ "show_days": 1,
+ "show_seconds": 1
+ },
+ {
+ "default": "0",
+ "depends_on": "eval: doc.channel !== 'System Notification'",
+ "description": "If enabled, the notification will show up in the notifications dropdown on the top right corner of the navigation bar.",
+ "fieldname": "send_system_notification",
+ "fieldtype": "Check",
+ "label": "Send System Notification",
+ "show_days": 1,
+ "show_seconds": 1
}
],
"icon": "fa fa-envelope",
- "modified": "2019-07-15 13:17:02.585013",
+ "links": [],
+ "modified": "2020-05-29 16:03:10.914526",
"modified_by": "Administrator",
"module": "Email",
"name": "Notification",
diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py
index 8c011ade65..8e53b50fa2 100644
--- a/frappe/email/doctype/notification/notification.py
+++ b/frappe/email/doctype/notification/notification.py
@@ -13,6 +13,7 @@ from frappe.utils.jinja import validate_template
from frappe.modules.utils import export_module_json, get_doc_module
from six import string_types
from frappe.integrations.doctype.slack_webhook_url.slack_webhook_url import send_slack_message
+from frappe.desk.doctype.notification_log.notification_log import enqueue_create_notification
class Notification(Document):
def onload(self):
@@ -125,6 +126,9 @@ def get_context(context):
if self.channel == 'Slack':
self.send_a_slack_msg(doc, context)
+ if self.channel == 'System Notification' or self.send_system_notification:
+ self.create_system_notification(doc, context)
+
if self.set_property_after_alert:
allow_update = True
if doc.docstatus == 1 and not doc.meta.get_field(self.set_property_after_alert).allow_on_submit:
@@ -143,6 +147,25 @@ def get_context(context):
except Exception:
frappe.log_error(title='Document update failed', message=frappe.get_traceback())
+ def create_system_notification(self, doc, context):
+ subject = self.subject
+ if "{" in subject:
+ subject = frappe.render_template(self.subject, context)
+
+ attachments = self.get_attachment(doc)
+ recipients, cc, bcc = self.get_list_of_recipients(doc, context)
+ users = recipients + cc + bcc
+
+ notification_doc = {
+ 'type': 'Alert',
+ 'document_type': doc.doctype,
+ 'document_name': doc.name,
+ 'subject': subject,
+ 'email_content': frappe.render_template(self.message, context),
+ 'attached_file': attachments and json.dumps(attachments[0])
+ }
+ enqueue_create_notification(users, notification_doc)
+
def send_an_email(self, doc, context):
from email.utils import formataddr
subject = self.subject
@@ -228,8 +251,7 @@ def get_context(context):
# ignoring attachment as draft and cancelled documents are not allowed to print
status = "Draft" if doc.docstatus == 0 else "Cancelled"
- frappe.throw(_("""Not allowed to attach {0} document,
- please enable Allow Print For {0} in Print Settings""".format(status)),
+ frappe.throw(_("""Not allowed to attach {0} document, please enable Allow Print For {0} in Print Settings""").format(status),
title=_("Error in Notification"))
else:
return [{
diff --git a/frappe/installer.py b/frappe/installer.py
index 17e9bceed7..4fc19b282a 100755
--- a/frappe/installer.py
+++ b/frappe/installer.py
@@ -269,6 +269,7 @@ def make_site_dirs():
os.path.join(site_private_path, 'backups'),
os.path.join(site_public_path, 'files'),
os.path.join(site_private_path, 'files'),
+ os.path.join(frappe.local.site_path, 'logs'),
os.path.join(frappe.local.site_path, 'task-logs')):
if not os.path.exists(dir_path):
os.makedirs(dir_path)
diff --git a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py
index 2a036f4838..4b595b1abf 100644
--- a/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py
+++ b/frappe/integrations/doctype/dropbox_settings/dropbox_settings.py
@@ -90,7 +90,7 @@ def backup_to_dropbox(upload_db_backup=True):
dropbox_settings['access_token'] = access_token['oauth2_token']
set_dropbox_access_token(access_token['oauth2_token'])
- dropbox_client = dropbox.Dropbox(dropbox_settings['access_token'])
+ dropbox_client = dropbox.Dropbox(dropbox_settings['access_token'], timeout=None)
if upload_db_backup:
if frappe.flags.create_new_backup:
diff --git a/frappe/integrations/doctype/google_contacts/google_contacts.py b/frappe/integrations/doctype/google_contacts/google_contacts.py
index 5874c79108..6455623281 100644
--- a/frappe/integrations/doctype/google_contacts/google_contacts.py
+++ b/frappe/integrations/doctype/google_contacts/google_contacts.py
@@ -147,11 +147,14 @@ def sync_contacts_from_google_contacts(g_contact):
results = []
contacts_updated = 0
+ sync_token = account.get_password(fieldname="next_sync_token", raise_exception=False) or None
+ contacts = frappe._dict()
+
while True:
try:
- sync_token = account.get_password(fieldname="next_sync_token", raise_exception=False) or None
- contacts = google_contacts.people().connections().list(resourceName='people/me',syncToken=sync_token,
- personFields="names,emailAddresses,organizations,phoneNumbers").execute()
+ contacts = google_contacts.people().connections().list(resourceName='people/me', pageToken=contacts.get("nextPageToken"),
+ syncToken=sync_token, pageSize=2000, requestSyncToken=True, personFields="names,emailAddresses,organizations,phoneNumbers").execute()
+
except HttpError as err:
frappe.throw(_("Google Contacts - Could not sync contacts from Google Contacts {0}, error code {1}.").format(account.name, err.resp.status))
diff --git a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py
index 5e464d4882..1d2f7f9495 100644
--- a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py
+++ b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py
@@ -64,6 +64,8 @@ from __future__ import unicode_literals
import frappe
from frappe import _
import json
+import hmac
+import hashlib
from six.moves.urllib.parse import urlencode
from frappe.model.document import Document
from frappe.utils import get_url, call_hook_method, cint, get_timestamp
@@ -317,6 +319,20 @@ class RazorpaySettings(Document):
except Exception:
frappe.log_error(frappe.get_traceback())
+ def verify_signature(self, body, signature, key):
+ key = bytes(key, 'utf-8')
+ body = bytes(body, 'utf-8')
+
+ dig = hmac.new(key=key, msg=body, digestmod=hashlib.sha256)
+
+ generated_signature = dig.hexdigest()
+ result = hmac.compare_digest(generated_signature, signature)
+
+ if not result:
+ frappe.throw(_('Razorpay Signature Verification Failed'), exc=frappe.PermissionError)
+
+ return result
+
def capture_payment(is_sandbox=False, sanbox_response=None):
"""
Verifies the purchase as complete by the merchant.
diff --git a/frappe/model/base_document.py b/frappe/model/base_document.py
index feeb96898a..106d21eb51 100644
--- a/frappe/model/base_document.py
+++ b/frappe/model/base_document.py
@@ -693,7 +693,7 @@ class BaseDocument(object):
df = self.meta.get_field(fieldname)
sanitized_value = value
- if df and df.get("fieldtype") in ("Data", "Code", "Small Text") and df.get("options")=="Email":
+ if df and df.get("fieldtype") in ("Data", "Code", "Small Text", "Text") and df.get("options")=="Email":
sanitized_value = sanitize_email(value)
elif df and (df.get("ignore_xss_filter")
diff --git a/frappe/model/workflow.py b/frappe/model/workflow.py
index 4384e7c8f5..ea563dfc13 100644
--- a/frappe/model/workflow.py
+++ b/frappe/model/workflow.py
@@ -299,6 +299,7 @@ def set_workflow_state_on_action(doc, workflow_name, action):
return
action_map = {
+ 'update_after_submit': '1',
'submit': '1',
'cancel': '2'
}
diff --git a/frappe/patches.txt b/frappe/patches.txt
index 0a7d368ee2..d8923ca320 100644
--- a/frappe/patches.txt
+++ b/frappe/patches.txt
@@ -278,6 +278,7 @@ frappe.patches.v13_0.set_path_for_homepage_in_web_page_view
frappe.patches.v13_0.migrate_translation_column_data
frappe.patches.v13_0.set_read_times
frappe.patches.v13_0.remove_web_view
+frappe.patches.v13_0.site_wise_logging
frappe.patches.v13_0.set_unique_for_page_view
frappe.patches.v13_0.remove_tailwind_from_page_builder
frappe.patches.v13_0.rename_onboarding
@@ -285,4 +286,4 @@ frappe.patches.v13_0.email_unsubscribe
execute:frappe.delete_doc("Web Template", "Section with Left Image", force=1)
execute:frappe.delete_doc("DocType", "Onboarding Slide")
execute:frappe.delete_doc("DocType", "Onboarding Slide Field")
-execute:frappe.delete_doc("DocType", "Onboarding Slide Help Link")
\ No newline at end of file
+execute:frappe.delete_doc("DocType", "Onboarding Slide Help Link")
diff --git a/frappe/patches/v13_0/site_wise_logging.py b/frappe/patches/v13_0/site_wise_logging.py
new file mode 100644
index 0000000000..6f04e0c9dd
--- /dev/null
+++ b/frappe/patches/v13_0/site_wise_logging.py
@@ -0,0 +1,10 @@
+import os
+import frappe
+
+
+def execute():
+ site = frappe.local.site
+
+ log_folder = os.path.join(site, 'logs')
+ if not os.path.exists(log_folder):
+ os.mkdir(log_folder)
\ No newline at end of file
diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js
index bad7c877fc..369e4a56d4 100644
--- a/frappe/public/js/frappe/form/form.js
+++ b/frappe/public/js/frappe/form/form.js
@@ -650,13 +650,14 @@ frappe.ui.form.Form = class FrappeForm {
frappe.utils.play_sound("submit");
callback && callback();
me.script_manager.trigger("on_submit")
- .then(() => resolve(me));
- if (frappe.route_hooks.after_submit) {
- let route_callback = frappe.route_hooks.after_submit;
- delete frappe.route_hooks.after_submit;
-
- route_callback(me);
- }
+ .then(() => resolve(me))
+ .then(() => {
+ if (frappe.route_hooks.after_submit) {
+ let route_callback = frappe.route_hooks.after_submit;
+ delete frappe.route_hooks.after_submit;
+ route_callback(me);
+ }
+ });
}
}, btn, () => me.handle_save_fail(btn, on_error), resolve);
});
@@ -1586,7 +1587,7 @@ frappe.ui.form.Form = class FrappeForm {
let steps = frappe.tour[this.doctype].map(step => {
let field = this.get_docfield(step.fieldname);
return {
- element: `.frappe-control[title='${step.fieldname}']`,
+ element: `.frappe-control[data-fieldname='${step.fieldname}']`,
popover: {
title: step.title || field.label,
description: step.description
diff --git a/frappe/public/js/frappe/form/script_manager.js b/frappe/public/js/frappe/form/script_manager.js
index fd5b8d3856..1238bf141c 100644
--- a/frappe/public/js/frappe/form/script_manager.js
+++ b/frappe/public/js/frappe/form/script_manager.js
@@ -16,12 +16,22 @@ frappe.ui.form.get_event_handler_list = function(doctype, fieldname) {
frappe.ui.form.on = frappe.ui.form.on_change = function(doctype, fieldname, handler) {
var add_handler = function(fieldname, handler) {
var handler_list = frappe.ui.form.get_event_handler_list(doctype, fieldname);
- handler_list.push(handler);
+
+ let _handler = (...args) => {
+ try {
+ handler(...args);
+ } catch (error) {
+ console.error(handler);
+ throw error;
+ }
+ }
+
+ handler_list.push(_handler);
// add last handler to events so it can be called as
// frm.events.handler(frm)
if(cur_frm && cur_frm.doctype===doctype) {
- cur_frm.events[fieldname] = handler;
+ cur_frm.events[fieldname] = _handler;
}
}
diff --git a/frappe/public/js/frappe/socketio_client.js b/frappe/public/js/frappe/socketio_client.js
index 9983a35779..1411b6289d 100644
--- a/frappe/public/js/frappe/socketio_client.js
+++ b/frappe/public/js/frappe/socketio_client.js
@@ -287,7 +287,8 @@ frappe.socketio.SocketIOUploader = class SocketIOUploader {
}
function fallback_required() {
- return !frappe.boot.sysdefaults.use_socketio_to_upload_file || !frappe.socketio.socket.connected;
+ return !frappe.socketio.socket.connected
+ || !( !frappe.boot.sysdefaults || frappe.boot.sysdefaults.use_socketio_to_upload_file );
}
if (fallback_required()) {
diff --git a/frappe/public/js/frappe/ui/notifications/notifications.js b/frappe/public/js/frappe/ui/notifications/notifications.js
index 2420d6772e..64d19ce63f 100644
--- a/frappe/public/js/frappe/ui/notifications/notifications.js
+++ b/frappe/public/js/frappe/ui/notifications/notifications.js
@@ -304,10 +304,7 @@ frappe.ui.Notifications = class Notifications {
}
get_dropdown_item_html(field) {
- let doc_link = frappe.utils.get_form_link(
- field.document_type,
- field.document_name
- );
+ let doc_link = this.get_item_link(field);
let read_class = field.read ? '' : 'unread';
let mark_read_action = field.read ? '': 'data-action="mark_as_read"';
let message = field.subject;
@@ -336,6 +333,17 @@ frappe.ui.Notifications = class Notifications {
return item_html;
}
+ get_item_link(notification_doc) {
+ const link_doctype =
+ notification_doc.type == 'Alert' ? 'Notification Log': notification_doc.document_type;
+ const link_docname =
+ notification_doc.type == 'Alert' ? notification_doc.name: notification_doc.document_name;
+ return frappe.utils.get_form_link(
+ link_doctype,
+ link_docname
+ );
+ }
+
render_dropdown_headers() {
this.categories = [
{
diff --git a/frappe/public/js/frappe/utils/utils.js b/frappe/public/js/frappe/utils/utils.js
index f1677b5281..24fa946fc4 100644
--- a/frappe/public/js/frappe/utils/utils.js
+++ b/frappe/public/js/frappe/utils/utils.js
@@ -811,19 +811,19 @@ Object.assign(frappe.utils, {
let total_duration = frappe.utils.seconds_to_duration(value, duration_options);
if (total_duration.days) {
- duration += total_duration.days + 'd';
+ duration += total_duration.days + __('d', null, 'Days (Field: Duration)');
}
if (total_duration.hours) {
duration += (duration.length ? " " : "");
- duration += total_duration.hours + 'h';
+ duration += total_duration.hours + __('h', null, 'Hours (Field: Duration)');
}
if (total_duration.minutes) {
duration += (duration.length ? " " : "");
- duration += total_duration.minutes + 'm';
+ duration += total_duration.minutes + __('m', null, 'Minutes (Field: Duration)');
}
if (total_duration.seconds) {
duration += (duration.length ? " " : "");
- duration += total_duration.seconds + 's';
+ duration += total_duration.seconds + __('s', null, 'Seconds (Field: Duration)');
}
}
return duration;
@@ -998,4 +998,4 @@ String.prototype.plural = function(revert) {
}
return this;
-};
\ No newline at end of file
+};
diff --git a/frappe/public/js/frappe/utils/web_page_block.js b/frappe/public/js/frappe/utils/web_page_block.js
deleted file mode 100644
index db655df98b..0000000000
--- a/frappe/public/js/frappe/utils/web_page_block.js
+++ /dev/null
@@ -1,38 +0,0 @@
-frappe.ui.form.on("Web Page Block", {
- edit_values(frm, cdt, cdn) {
- let row = frm.selected_doc;
- frappe.model.with_doc("Web Template", row.web_template).then((doc) => {
- let d = new frappe.ui.Dialog({
- title: __("Edit Values"),
- fields: doc.fields.map((df) => {
- if (df.fieldtype == "Section Break") {
- df.collapsible = 1;
- }
- return df;
- }),
- primary_action(values) {
- frappe.model.set_value(
- cdt,
- cdn,
- "web_template_values",
- JSON.stringify(values)
- );
- d.hide();
- },
- });
- let values = JSON.parse(row.web_template_values || "{}");
- d.set_values(values);
- d.show();
-
- d.sections.forEach((sect) => {
- let fields_with_value = sect.fields_list.filter(
- (field) => values[field.df.fieldname]
- );
-
- if (fields_with_value.length) {
- sect.collapse(false);
- }
- });
- });
- },
-});
\ No newline at end of file
diff --git a/frappe/public/js/frappe/views/breadcrumbs.js b/frappe/public/js/frappe/views/breadcrumbs.js
index 1c1049391f..0058310e3f 100644
--- a/frappe/public/js/frappe/views/breadcrumbs.js
+++ b/frappe/public/js/frappe/views/breadcrumbs.js
@@ -89,16 +89,21 @@ frappe.breadcrumbs = {
breadcrumbs.module = frappe.breadcrumbs.module_map[breadcrumbs.module];
}
- if(frappe.get_module(breadcrumbs.module)) {
+ let current_module = breadcrumbs.module
+ // Check if a desk page exists
+ if (frappe.boot.module_page_map[breadcrumbs.module]) {
+ breadcrumbs.module = frappe.boot.module_page_map[breadcrumbs.module];
+ }
+
+ if(frappe.get_module(current_module)) {
// if module access exists
- var module_info = frappe.get_module(breadcrumbs.module),
+ var module_info = frappe.get_module(current_module),
icon = module_info && module_info.icon,
label = module_info ? module_info.label : breadcrumbs.module;
-
if(module_info && !module_info.blocked && frappe.visible_modules.includes(module_info.module_name)) {
$(repl('%(label)s',
- { module: breadcrumbs.module, label: __(label) }))
+ { module: breadcrumbs.module, label: __(breadcrumbs.module) }))
.appendTo($breadcrumbs);
}
}
diff --git a/frappe/public/js/frappe/widgets/chart_widget.js b/frappe/public/js/frappe/widgets/chart_widget.js
index d32ca6f4d8..8a0eca9eaf 100644
--- a/frappe/public/js/frappe/widgets/chart_widget.js
+++ b/frappe/public/js/frappe/widgets/chart_widget.js
@@ -97,7 +97,6 @@ export default class ChartWidget extends Widget {
this.chart_settings = {};
}
this.setup_container();
- this.prepare_chart_object();
if (!this.in_customize_mode) {
this.action_area.empty();
this.prepare_chart_actions();
@@ -110,7 +109,10 @@ export default class ChartWidget extends Widget {
this.render_time_series_filters();
}
}
- this.fetch_and_update_chart();
+ frappe.run_serially([
+ () => this.prepare_chart_object(),
+ () => this.fetch_and_update_chart(),
+ ]);
});
}
@@ -625,13 +627,41 @@ export default class ChartWidget extends Widget {
}
prepare_chart_object() {
- let saved_filters = this.chart_settings.filters || null;
- this.filters =
- saved_filters || this.filters || JSON.parse(this.chart_doc.filters_json || "[]");
-
if (this.chart_doc.type == 'Heatmap' && !this.chart_doc.heatmap_year) {
this.chart_doc.heatmap_year = frappe.dashboard_utils.get_year(frappe.datetime.now_date());
}
+
+ return this.set_chart_filters();
+ }
+
+ set_chart_filters() {
+ let user_saved_filters = this.chart_settings.filters || null;
+ let chart_saved_filters = JSON.parse(this.chart_doc.filters_json || "null");
+
+ if (this.chart_doc.chart_type == 'Report') {
+ return frappe.dashboard_utils
+ .get_filters_for_chart_type(this.chart_doc).then(filters => {
+ chart_saved_filters = this.update_default_date_filters(filters, chart_saved_filters);
+ this.filters =
+ user_saved_filters || this.filters || chart_saved_filters;
+ });
+ } else {
+ this.filters =
+ user_saved_filters || this.filters || chart_saved_filters;
+ return Promise.resolve();
+ }
+ }
+
+ update_default_date_filters(report_filters, chart_filters) {
+ report_filters.map(f => {
+ if (['Date', 'DateRange'].includes(f.fieldtype) && f.default) {
+ if (f.reqd || chart_filters[f.fieldname]) {
+ chart_filters[f.fieldname] = f.default;
+ }
+ }
+ });
+
+ return chart_filters;
}
get_settings() {
diff --git a/frappe/public/js/frappe/widgets/shortcut_widget.js b/frappe/public/js/frappe/widgets/shortcut_widget.js
index 572569839c..1de7e8bf75 100644
--- a/frappe/public/js/frappe/widgets/shortcut_widget.js
+++ b/frappe/public/js/frappe/widgets/shortcut_widget.js
@@ -29,9 +29,13 @@ export default class ShortcutWidget extends Widget {
name: this.link_to,
type: this.type,
is_query_report: this.is_query_report,
- doctype: this.ref_doctype
+ doctype: this.ref_doctype,
});
+ let filters = this.get_doctype_filter();
+ if (this.type == "DocType" && filters) {
+ frappe.route_options = filters;
+ }
frappe.set_route(route);
});
}
@@ -40,16 +44,26 @@ export default class ShortcutWidget extends Widget {
if (this.in_customize_mode) return;
this.widget.addClass("shortcut-widget-box");
- const get_filter = new Function(`return ${this.stats_filter}`);
- if (this.type == "DocType" && this.stats_filter) {
+
+ let filters = this.get_doctype_filter();
+ if (this.type == "DocType" && filters) {
frappe.db
.count(this.link_to, {
- filters: get_filter(),
+ filters: filters,
})
.then((count) => this.set_count(count));
}
}
+ get_doctype_filter() {
+ let count_filter = new Function(`return ${this.stats_filter}`)();
+ if (count_filter) {
+ return count_filter;
+ }
+
+ return null;
+ }
+
set_title() {
if (this.icon) {
this.title_field[0].innerHTML = `
@@ -82,4 +96,4 @@ export default class ShortcutWidget extends Widget {
buttons.appendTo(this.action_area);
}
-}
+}
\ No newline at end of file
diff --git a/frappe/public/js/frappe/widgets/widget_dialog.js b/frappe/public/js/frappe/widgets/widget_dialog.js
index 5c44533b37..d5cd6d9643 100644
--- a/frappe/public/js/frappe/widgets/widget_dialog.js
+++ b/frappe/public/js/frappe/widgets/widget_dialog.js
@@ -241,11 +241,14 @@ class ShortcutDialog extends WidgetDialog {
if (this.dialog.get_value("type") == "DocType" && this.filter_group) {
let filters = this.filter_group.get_filters();
- filters.forEach((arr) => {
- stats_filter[arr[1]] = [arr[2], arr[3]];
- });
- data.stats_filter = JSON.stringify(stats_filter);
+ if (filters.length) {
+ filters.forEach((arr) => {
+ stats_filter[arr[1]] = [arr[2], arr[3]];
+ });
+
+ data.stats_filter = JSON.stringify(stats_filter);
+ }
}
data.label = data.label
diff --git a/frappe/utils/__init__.py b/frappe/utils/__init__.py
index f2e2319802..60179e98b4 100644
--- a/frappe/utils/__init__.py
+++ b/frappe/utils/__init__.py
@@ -6,6 +6,7 @@
from __future__ import unicode_literals, print_function
from werkzeug.test import Client
import os, re, sys, json, hashlib, requests, traceback
+import functools
from .html_utils import sanitize_html
import frappe
from frappe.utils.identicon import Identicon
@@ -360,6 +361,7 @@ def decode_dict(d, encoding="utf-8"):
return d
+@functools.lru_cache()
def get_site_name(hostname):
return hostname.split(':')[0]
diff --git a/frappe/utils/dashboard.py b/frappe/utils/dashboard.py
index f06f9272b8..c1884d62fb 100644
--- a/frappe/utils/dashboard.py
+++ b/frappe/utils/dashboard.py
@@ -89,10 +89,14 @@ def sync_dashboards(app=None):
config = get_config(app_name, module_name)
if config:
frappe.flags.in_import = True
- make_records(config.charts, "Dashboard Chart")
- make_records(config.number_cards, "Number Card")
- make_records(config.dashboards, "Dashboard")
- frappe.flags.in_import = False
+ try:
+ make_records(config.charts, "Dashboard Chart")
+ make_records(config.number_cards, "Number Card")
+ make_records(config.dashboards, "Dashboard")
+ except Exception as e:
+ frappe.log_error(e, _("Dashboard Import Error"))
+ finally:
+ frappe.flags.in_import = False
def make_records(config, doctype):
if not config:
diff --git a/frappe/utils/error.py b/frappe/utils/error.py
index c124410a7f..af8c0952e8 100644
--- a/frappe/utils/error.py
+++ b/frappe/utils/error.py
@@ -21,7 +21,7 @@ def make_error_snapshot(exception):
if frappe.conf.disable_error_snapshot:
return
- logger = frappe.logger(__name__, with_more_info=False)
+ logger = frappe.logger(with_more_info=True)
try:
error_id = '{timestamp:s}-{ip:s}-{hash:s}'.format(
diff --git a/frappe/utils/logger.py b/frappe/utils/logger.py
index 5a77434cde..89e3711b0f 100755
--- a/frappe/utils/logger.py
+++ b/frappe/utils/logger.py
@@ -1,30 +1,53 @@
+# imports - compatibility imports
from __future__ import unicode_literals
-import frappe
+
+# imports - standard imports
import logging
+import os
from logging.handlers import RotatingFileHandler
+
+# imports - third party imports
from six import text_type
-default_log_level = logging.DEBUG
-LOG_FILENAME = '../logs/{}-frappe.log'.format(frappe.local.site)
+# imports - module imports
+import frappe
-def get_logger(module, with_more_info=True):
+
+default_log_level = logging.DEBUG
+site = getattr(frappe.local, 'site', None)
+
+
+def get_logger(module, with_more_info=False):
+ global site
if module in frappe.loggers:
return frappe.loggers[module]
- formatter = logging.Formatter('[%(levelname)s] %(asctime)s | %(pathname)s:\n%(message)s')
- # handler = logging.StreamHandler()
+ if not module:
+ module = "frappe"
+ with_more_info = True
- handler = RotatingFileHandler(
- LOG_FILENAME, maxBytes=100000, backupCount=20)
- handler.setFormatter(formatter)
+ logfile = module + '.log'
+ site = getattr(frappe.local, 'site', None)
+ LOG_FILENAME = os.path.join('..', 'logs', logfile)
+
+ logger = logging.getLogger(module)
+ logger.setLevel(frappe.log_level or default_log_level)
+ logger.propagate = False
+
+ formatter = logging.Formatter('%(asctime)s %(levelname)s %(name)s %(message)s')
+ handler = RotatingFileHandler(LOG_FILENAME, maxBytes=100_000, backupCount=20)
+ logger.addHandler(handler)
+#
+ if site:
+ SITELOG_FILENAME = os.path.join(site, 'logs', logfile)
+ site_handler = RotatingFileHandler(SITELOG_FILENAME, maxBytes=100_000, backupCount=20)
+ site_handler.setFormatter(formatter)
+ logger.addHandler(site_handler)
if with_more_info:
handler.addFilter(SiteContextFilter())
- logger = logging.getLogger(module)
- logger.setLevel(frappe.log_level or default_log_level)
- logger.addHandler(handler)
- logger.propagate = False
+ handler.setFormatter(formatter)
frappe.loggers[module] = logger
@@ -33,25 +56,9 @@ def get_logger(module, with_more_info=True):
class SiteContextFilter(logging.Filter):
"""This is a filter which injects request information (if available) into the log."""
def filter(self, record):
- record.msg = get_more_info_for_log() + text_type(record.msg)
- return True
-
-def get_more_info_for_log():
- '''Adds Site, Form Dict into log entry'''
- more_info = []
- site = getattr(frappe.local, 'site', None)
- if site:
- more_info.append('Site: {0}'.format(site))
-
- form_dict = getattr(frappe.local, 'form_dict', None)
- if form_dict:
- more_info.append('Form Dict: {0}'.format(frappe.as_json(form_dict)))
-
- if more_info:
- # to append a \n
- more_info = more_info + ['']
-
- return '\n'.join(more_info)
+ if "Form Dict" not in text_type(record.msg):
+ record.msg = text_type(record.msg) + "\nSite: {0}\nForm Dict: {1}".format(site, getattr(frappe.local, 'form_dict', None))
+ return True
def set_log_level(level):
'''Use this method to set log level to something other than the default DEBUG'''
diff --git a/frappe/utils/scheduler.py b/frappe/utils/scheduler.py
index 596595a160..749a41682f 100755
--- a/frappe/utils/scheduler.py
+++ b/frappe/utils/scheduler.py
@@ -7,17 +7,24 @@ Events:
monthly
weekly
"""
+# imports - compatibility imports
+from __future__ import print_function, unicode_literals
-from __future__ import unicode_literals, print_function
+# imports - standard imports
+import os
+import time
-import frappe, os, time
+# imports - third party imports
import schedule
-from frappe.utils import now_datetime, get_datetime
-from frappe.utils import get_sites
-from frappe.installer import update_site_config
+
+# imports - module imports
+import frappe
from frappe.core.doctype.user.user import STANDARD_USERS
+from frappe.installer import update_site_config
+from frappe.utils import get_sites, now_datetime
from frappe.utils.background_jobs import get_jobs
+
DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
def start_scheduler():
@@ -48,9 +55,8 @@ def enqueue_events_for_all_sites():
def enqueue_events_for_site(site):
def log_and_raise():
- frappe.logger(__name__).error('Exception in Enqueue Events for Site {0}'.format(site) +
- '\n' + frappe.get_traceback())
- raise # pylint: disable=misplaced-bare-raise
+ error_message = 'Exception in Enqueue Events for Site {0}\n{1}'.format(site, frappe.get_traceback())
+ frappe.logger("scheduler").error(error_message)
try:
frappe.init(site=site)
@@ -60,10 +66,10 @@ def enqueue_events_for_site(site):
enqueue_events(site=site)
- frappe.logger(__name__).debug('Queued events for site {0}'.format(site))
+ frappe.logger("scheduler").debug('Queued events for site {0}'.format(site))
except frappe.db.OperationalError as e:
if frappe.db.is_access_denied(e):
- frappe.logger(__name__).debug('Access denied for site {0}'.format(site))
+ frappe.logger("scheduler").debug('Access denied for site {0}'.format(site))
else:
log_and_raise()
except:
diff --git a/frappe/website/desk_page/website/website.json b/frappe/website/desk_page/website/website.json
index c42a17d404..9936f8d7e2 100644
--- a/frappe/website/desk_page/website/website.json
+++ b/frappe/website/desk_page/website/website.json
@@ -38,10 +38,11 @@
"docstatus": 0,
"doctype": "Desk Page",
"extends_another_page": 0,
+ "hide_custom": 0,
"idx": 0,
"is_standard": 1,
"label": "Website",
- "modified": "2020-05-05 18:17:13.232473",
+ "modified": "2020-05-28 13:53:10.736212",
"modified_by": "Administrator",
"module": "Website",
"name": "Website",
@@ -51,7 +52,7 @@
"pin_to_top": 0,
"shortcuts": [
{
- "color": "",
+ "color": "#cef6d1",
"format": "{} Published",
"label": "Blog Post",
"link_to": "Blog Post",
@@ -59,6 +60,7 @@
"type": "DocType"
},
{
+ "color": "#cef6d1",
"format": "{} Active",
"label": "Blogger",
"link_to": "Blogger",
@@ -66,8 +68,11 @@
"type": "DocType"
},
{
+ "color": "#cef6d1",
+ "format": "{} Published",
"label": "Web Page",
"link_to": "Web Page",
+ "stats_filter": "{ \"published\": 1 }",
"type": "DocType"
},
{
diff --git a/frappe/website/doctype/web_page/web_page.js b/frappe/website/doctype/web_page/web_page.js
index 437a86b5d0..b2e06efc79 100644
--- a/frappe/website/doctype/web_page/web_page.js
+++ b/frappe/website/doctype/web_page/web_page.js
@@ -2,9 +2,6 @@
// MIT License. See license.txt
frappe.ui.form.on('Web Page', {
- onload: function() {
- frappe.require('/assets/frappe/js/frappe/utils/web_page_block.js');
- },
title: function(frm) {
if (frm.doc.title && !frm.doc.route) {
frm.set_value('route', frappe.scrub(frm.doc.title, '-'));
@@ -49,6 +46,45 @@ frappe.ui.form.on('Web Page', {
}
});
+frappe.ui.form.on("Web Page Block", {
+ edit_values(frm, cdt, cdn) {
+ let row = frm.selected_doc;
+ frappe.model.with_doc("Web Template", row.web_template).then((doc) => {
+ let d = new frappe.ui.Dialog({
+ title: __("Edit Values"),
+ fields: doc.fields.map((df) => {
+ if (df.fieldtype == "Section Break") {
+ df.collapsible = 1;
+ }
+ return df;
+ }),
+ primary_action(values) {
+ frappe.model.set_value(
+ cdt,
+ cdn,
+ "web_template_values",
+ JSON.stringify(values)
+ );
+ d.hide();
+ },
+ });
+ let values = JSON.parse(row.web_template_values || "{}");
+ d.set_values(values);
+ d.show();
+
+ d.sections.forEach((sect) => {
+ let fields_with_value = sect.fields_list.filter(
+ (field) => values[field.df.fieldname]
+ );
+
+ if (fields_with_value.length) {
+ sect.collapse(false);
+ }
+ });
+ });
+ },
+});
+
frappe.tour['Web Page'] = [
{
fieldname: "title",
@@ -102,4 +138,4 @@ frappe.tour['Web Page'] = [
title: __("Meta Image"),
description: __("The meta image is unique image representing the content of the page. Images for this Card should be at least 280px in width, and at least 150px in height.")
},
-];
\ No newline at end of file
+];
diff --git a/frappe/website/doctype/website_theme/website_theme.js b/frappe/website/doctype/website_theme/website_theme.js
index 28b18a1bcd..75ecbe15e3 100644
--- a/frappe/website/doctype/website_theme/website_theme.js
+++ b/frappe/website/doctype/website_theme/website_theme.js
@@ -2,9 +2,6 @@
// MIT License. See license.txt
frappe.ui.form.on('Website Theme', {
- onload: function() {
- frappe.require('/assets/frappe/js/frappe/utils/web_page_block.js');
- },
refresh(frm) {
frm.clear_custom_buttons();
frm.toggle_display(["module", "custom"], !frappe.boot.developer_mode);
diff --git a/frappe/website/module_onboarding/website/website.json b/frappe/website/module_onboarding/website/website.json
index 606ef09811..c010d27eea 100644
--- a/frappe/website/module_onboarding/website/website.json
+++ b/frappe/website/module_onboarding/website/website.json
@@ -10,7 +10,7 @@
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/website",
"idx": 0,
"is_complete": 0,
- "modified": "2020-05-13 12:32:35.269025",
+ "modified": "2020-05-28 13:51:57.535269",
"modified_by": "Administrator",
"module": "Website",
"name": "Website",
diff --git a/frappe/website/onboarding_step/add_blog_category/add_blog_category.json b/frappe/website/onboarding_step/add_blog_category/add_blog_category.json
index 5936e78c68..71924f8848 100644
--- a/frappe/website/onboarding_step/add_blog_category/add_blog_category.json
+++ b/frappe/website/onboarding_step/add_blog_category/add_blog_category.json
@@ -8,10 +8,12 @@
"is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-04-30 19:06:10.750976",
+ "modified": "2020-05-28 13:51:53.157256",
"modified_by": "Administrator",
"name": "Add Blog Category",
"owner": "Administrator",
"reference_document": "Blog Category",
- "title": "Add Blog Category"
+ "show_full_form": 0,
+ "title": "Add Blog Category",
+ "validate_action": 0
}
\ No newline at end of file
diff --git a/frappe/website/onboarding_step/create_blogger/create_blogger.json b/frappe/website/onboarding_step/create_blogger/create_blogger.json
index 841325ca6a..48a0997025 100644
--- a/frappe/website/onboarding_step/create_blogger/create_blogger.json
+++ b/frappe/website/onboarding_step/create_blogger/create_blogger.json
@@ -13,5 +13,7 @@
"name": "Create Blogger",
"owner": "Administrator",
"reference_document": "Blogger",
- "title": "Create Blogger"
+ "show_full_form": 0,
+ "title": "Create Blogger",
+ "validate_action": 0
}
\ No newline at end of file
diff --git a/frappe/website/onboarding_step/enable_website_tracking/enable_website_tracking.json b/frappe/website/onboarding_step/enable_website_tracking/enable_website_tracking.json
index b37a704b1e..c445123243 100644
--- a/frappe/website/onboarding_step/enable_website_tracking/enable_website_tracking.json
+++ b/frappe/website/onboarding_step/enable_website_tracking/enable_website_tracking.json
@@ -14,6 +14,8 @@
"name": "Enable Website Tracking",
"owner": "Administrator",
"reference_document": "Website Settings",
+ "show_full_form": 0,
"title": "Enable Website Tracking",
+ "validate_action": 0,
"value_to_validate": "1"
}
\ No newline at end of file
diff --git a/frappe/website/onboarding_step/introduction_to_website/introduction_to_website.json b/frappe/website/onboarding_step/introduction_to_website/introduction_to_website.json
index f3c95657e8..29c1d8ff60 100644
--- a/frappe/website/onboarding_step/introduction_to_website/introduction_to_website.json
+++ b/frappe/website/onboarding_step/introduction_to_website/introduction_to_website.json
@@ -8,10 +8,12 @@
"is_mandatory": 1,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-04-30 19:06:10.578218",
+ "modified": "2020-05-28 13:51:51.485924",
"modified_by": "Administrator",
"name": "Introduction to Website",
"owner": "Administrator",
+ "show_full_form": 0,
"title": "Introduction to Website",
+ "validate_action": 0,
"video_url": "https://www.youtube.com/watch?v=lyW6mfFBSNw"
}
\ No newline at end of file
diff --git a/frappe/website/onboarding_step/web_page_tour/web_page_tour.json b/frappe/website/onboarding_step/web_page_tour/web_page_tour.json
index 1ee98d69ee..e73610d847 100644
--- a/frappe/website/onboarding_step/web_page_tour/web_page_tour.json
+++ b/frappe/website/onboarding_step/web_page_tour/web_page_tour.json
@@ -8,10 +8,12 @@
"is_mandatory": 0,
"is_single": 0,
"is_skipped": 0,
- "modified": "2020-05-13 12:32:15.966570",
+ "modified": "2020-05-28 13:51:54.264456",
"modified_by": "Administrator",
"name": "Web Page Tour",
"owner": "Administrator",
"reference_document": "Web Page",
- "title": "Learn about Web Pages"
+ "show_full_form": 0,
+ "title": "Learn about Web Pages",
+ "validate_action": 0
}
\ No newline at end of file
diff --git a/frappe/website/website_theme/standard/standard.json b/frappe/website/website_theme/standard/standard.json
index 11527a5229..62a5cc8d7b 100644
--- a/frappe/website/website_theme/standard/standard.json
+++ b/frappe/website/website_theme/standard/standard.json
@@ -7,9 +7,9 @@
"custom_overrides": "",
"docstatus": 0,
"doctype": "Website Theme",
- "font_properties": "wght:400;500;600;700;800",
- "idx": 28,
- "modified": "2020-05-19 00:33:58.011046",
+ "font_properties": "400,500,600,700,800",
+ "idx": 26,
+ "modified": "2020-05-20 14:47:12.938879",
"modified_by": "Administrator",
"module": "Website",
"name": "Standard",