From 064ef5a15a5a7c3d85cfe7a794d38d5308474b7f Mon Sep 17 00:00:00 2001
From: Shariq Ansari
Date: Wed, 22 Mar 2023 19:41:41 +0530
Subject: [PATCH 01/14] fix: Avoid list update if user is doing some bulk
operation
---
frappe/public/js/frappe/list/list_view.js | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js
index 59784b853e..6b20282099 100644
--- a/frappe/public/js/frappe/list/list_view.js
+++ b/frappe/public/js/frappe/list/list_view.js
@@ -1339,6 +1339,11 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
return;
}
+ // if some bulk operation is happening by selecting list items, don't refresh
+ if (this.$checks && this.$checks.length) {
+ return;
+ }
+
if (!frappe.get_doc(data?.doctype, data?.name)?.__unsaved) {
frappe.model.remove_from_locals(data.doctype, data.name);
}
From 2036dd19b23dad7859235877e5f0ebbf5b81e95f Mon Sep 17 00:00:00 2001
From: Shariq Ansari
Date: Thu, 23 Mar 2023 12:30:50 +0530
Subject: [PATCH 02/14] fix: Get translated value for child tables in print
format
---
frappe/templates/print_formats/standard_macros.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/frappe/templates/print_formats/standard_macros.html b/frappe/templates/print_formats/standard_macros.html
index 5dcbaff7c5..2bfcf074ab 100644
--- a/frappe/templates/print_formats/standard_macros.html
+++ b/frappe/templates/print_formats/standard_macros.html
@@ -56,9 +56,9 @@
|
{% if doc.child_print_templates %}
{%- set child_templates = doc.child_print_templates.get(df.fieldname) -%}
- {{ print_value(tdf, d, doc, visible_columns, child_templates) }} |
+ {{ _(print_value(tdf, d, doc, visible_columns, child_templates)) }}
{% else %}
- {{ print_value(tdf, d, doc, visible_columns) }}
+ {{ _(print_value(tdf, d, doc, visible_columns)) }}
{% endif %}
{% endfor %}
From b39b2e7923c668105673e56467eb0087fe506b40 Mon Sep 17 00:00:00 2001
From: Ankush Menat
Date: Thu, 23 Mar 2023 15:54:23 +0530
Subject: [PATCH 03/14] fix: consider JSON as Data for filters
closes https://github.com/frappe/frappe/issues/20433
---
frappe/public/js/frappe/list/base_list.js | 1 +
frappe/public/js/frappe/ui/filters/filter.js | 1 +
2 files changed, 2 insertions(+)
diff --git a/frappe/public/js/frappe/list/base_list.js b/frappe/public/js/frappe/list/base_list.js
index 600db57dd1..8852a0df5d 100644
--- a/frappe/public/js/frappe/list/base_list.js
+++ b/frappe/public/js/frappe/list/base_list.js
@@ -774,6 +774,7 @@ class FilterArea {
"Data",
"Code",
"Phone",
+ "JSON",
"Read Only",
].includes(fieldtype)
) {
diff --git a/frappe/public/js/frappe/ui/filters/filter.js b/frappe/public/js/frappe/ui/filters/filter.js
index c2f795833c..5902c136bd 100644
--- a/frappe/public/js/frappe/ui/filters/filter.js
+++ b/frappe/public/js/frappe/ui/filters/filter.js
@@ -508,6 +508,7 @@ frappe.ui.filter_utils = {
"HTML Editor",
"Tag",
"Phone",
+ "JSON",
"Comments",
"Barcode",
"Dynamic Link",
From 5a91ac945cb5afcccd005b706254105db6a4294d Mon Sep 17 00:00:00 2001
From: Ankush Menat
Date: Thu, 23 Mar 2023 16:16:14 +0530
Subject: [PATCH 04/14] fix: doctype form - hide irrelevant fields
---
frappe/core/doctype/doctype/doctype.json | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/frappe/core/doctype/doctype/doctype.json b/frappe/core/doctype/doctype/doctype.json
index 671a6e86e6..b3196158f5 100644
--- a/frappe/core/doctype/doctype/doctype.json
+++ b/frappe/core/doctype/doctype/doctype.json
@@ -189,6 +189,7 @@
},
{
"default": "0",
+ "depends_on": "eval:!doc.istable",
"fieldname": "beta",
"fieldtype": "Check",
"label": "Beta"
@@ -463,6 +464,7 @@
},
{
"default": "0",
+ "depends_on": "eval:!doc.istable",
"description": "Tree structures are implemented using Nested Set",
"fieldname": "is_tree",
"fieldtype": "Check",
@@ -539,6 +541,7 @@
},
{
"default": "0",
+ "depends_on": "eval:!doc.istable",
"fieldname": "is_virtual",
"fieldtype": "Check",
"label": "Is Virtual"
@@ -622,6 +625,7 @@
},
{
"default": "0",
+ "depends_on": "eval:!doc.istable",
"description": "Enables Calendar and Gantt views.",
"fieldname": "is_calendar_and_gantt",
"fieldtype": "Check",
@@ -708,7 +712,7 @@
"link_fieldname": "reference_doctype"
}
],
- "modified": "2023-01-04 17:23:09.206018",
+ "modified": "2023-03-23 16:15:51.067267",
"modified_by": "Administrator",
"module": "Core",
"name": "DocType",
From 3f717f2fbdc13571d409a99f94df25c78aa5886b Mon Sep 17 00:00:00 2001
From: Ankush Menat
Date: Thu, 23 Mar 2023 16:55:09 +0530
Subject: [PATCH 05/14] perf: Don't re-initate sessions in realtime.py
Session is already created for all requests in app.py -> init_request -> HTTPRequest()
---
frappe/realtime.py | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/frappe/realtime.py b/frappe/realtime.py
index 6283b8eb80..4a7cce0f45 100644
--- a/frappe/realtime.py
+++ b/frappe/realtime.py
@@ -105,10 +105,8 @@ def get_redis_server():
@frappe.whitelist(allow_guest=True)
def can_subscribe_doc(doctype: str, docname: str) -> bool:
from frappe.exceptions import PermissionError
- from frappe.sessions import Session
- session = Session(None, resume=True).get_session_data()
- if not frappe.has_permission(user=session.user, doctype=doctype, doc=docname, ptype="read"):
+ if not frappe.has_permission(doctype=doctype, doc=docname, ptype="read"):
raise PermissionError()
return True
@@ -118,7 +116,7 @@ def can_subscribe_doc(doctype: str, docname: str) -> bool:
def can_subscribe_doctype(doctype: str) -> bool:
from frappe.exceptions import PermissionError
- if not frappe.has_permission(user=frappe.session.user, doctype=doctype, ptype="read"):
+ if not frappe.has_permission(doctype=doctype, ptype="read"):
raise PermissionError()
return True
@@ -126,13 +124,9 @@ def can_subscribe_doctype(doctype: str) -> bool:
@frappe.whitelist(allow_guest=True)
def get_user_info():
- from frappe.sessions import Session
-
- session = Session(None, resume=True).get_session_data()
-
return {
- "user": session.user,
- "user_type": session.user_type,
+ "user": frappe.session.user,
+ "user_type": frappe.session.user_type,
}
From 6e3ef3dc3d0c166e1a02fcba6556e4aae1327b8c Mon Sep 17 00:00:00 2001
From: Shariq Ansari
Date: Thu, 23 Mar 2023 17:53:18 +0530
Subject: [PATCH 06/14] test: fixed failing UI test
---
cypress/integration/list_view.js | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/cypress/integration/list_view.js b/cypress/integration/list_view.js
index 1fed62d678..3fa0758f0c 100644
--- a/cypress/integration/list_view.js
+++ b/cypress/integration/list_view.js
@@ -54,12 +54,8 @@ context("List View", () => {
method: "POST",
url: "api/method/frappe.model.workflow.bulk_workflow_approval",
}).as("bulk-approval");
- cy.intercept({
- method: "POST",
- url: "api/method/frappe.desk.reportview.get",
- }).as("real-time-update");
cy.wrap(elements).contains("Approve").click();
- cy.wait(["@bulk-approval", "@real-time-update"]);
+ cy.wait("@bulk-approval");
cy.wait(300);
cy.get_open_dialog().find(".btn-modal-close").click();
cy.reload();
From bd049a42a317b22d0c961ff0a12d26e123e41148 Mon Sep 17 00:00:00 2001
From: Leonard Goertz <49870752+uepselon@users.noreply.github.com>
Date: Fri, 24 Mar 2023 04:14:34 +0100
Subject: [PATCH 07/14] fix: fields are rendered empty after save (#20270)
Co-authored-by: Ankush Menat
---
frappe/public/js/frappe/list/list_view.js | 4 ----
1 file changed, 4 deletions(-)
diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js
index 6b20282099..38dc76ec80 100644
--- a/frappe/public/js/frappe/list/list_view.js
+++ b/frappe/public/js/frappe/list/list_view.js
@@ -1344,10 +1344,6 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
return;
}
- if (!frappe.get_doc(data?.doctype, data?.name)?.__unsaved) {
- frappe.model.remove_from_locals(data.doctype, data.name);
- }
-
if (this.avoid_realtime_update()) {
return;
}
From f7f575acbdfb48e086f1fcd39118ddd58c751fd3 Mon Sep 17 00:00:00 2001
From: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Date: Fri, 24 Mar 2023 04:23:34 +0100
Subject: [PATCH 08/14] ci: copy docs checker from erpnext (#20441)
[skip ci]
---
.github/helper/documentation.py | 97 ++++++++++++++++++++-------------
1 file changed, 60 insertions(+), 37 deletions(-)
diff --git a/.github/helper/documentation.py b/.github/helper/documentation.py
index 8156137e3f..b541583fd6 100644
--- a/.github/helper/documentation.py
+++ b/.github/helper/documentation.py
@@ -1,50 +1,73 @@
import sys
+import requests
from urllib.parse import urlparse
-import requests
-docs_repos = [
- "frappe_docs",
- "erpnext_documentation",
+WEBSITE_REPOS = [
"erpnext_com",
"frappe_io",
]
+DOCUMENTATION_DOMAINS = [
+ "docs.erpnext.com",
+ "frappeframework.com",
+]
-def uri_validator(x):
- result = urlparse(x)
- return all([result.scheme, result.netloc, result.path])
-def docs_link_exists(body):
- for line in body.splitlines():
- for word in line.split():
- if word.startswith('http') and uri_validator(word):
- parsed_url = urlparse(word)
- if parsed_url.netloc == "github.com":
- parts = parsed_url.path.split('/')
- if len(parts) == 5 and parts[1] == "frappe" and parts[2] in docs_repos:
- return True
- if parsed_url.netloc in ["docs.erpnext.com", "frappeframework.com"]:
- return True
+def is_valid_url(url: str) -> bool:
+ parts = urlparse(url)
+ return all((parts.scheme, parts.netloc, parts.path))
+
+
+def is_documentation_link(word: str) -> bool:
+ if not word.startswith("http") or not is_valid_url(word):
+ return False
+
+ parsed_url = urlparse(word)
+ if parsed_url.netloc in DOCUMENTATION_DOMAINS:
+ return True
+
+ if parsed_url.netloc == "github.com":
+ parts = parsed_url.path.split("/")
+ if len(parts) == 5 and parts[1] == "frappe" and parts[2] in WEBSITE_REPOS:
+ return True
+
+ return False
+
+
+def contains_documentation_link(body: str) -> bool:
+ return any(
+ is_documentation_link(word)
+ for line in body.splitlines()
+ for word in line.split()
+ )
+
+
+def check_pull_request(number: str) -> "tuple[int, str]":
+ response = requests.get(f"https://api.github.com/repos/frappe/frappe/pulls/{number}")
+ if not response.ok:
+ return 1, "Pull Request Not Found! ⚠️"
+
+ payload = response.json()
+ title = (payload.get("title") or "").lower().strip()
+ head_sha = (payload.get("head") or {}).get("sha")
+ body = (payload.get("body") or "").lower()
+
+ if (
+ not title.startswith("feat")
+ or not head_sha
+ or "no-docs" in body
+ or "backport" in body
+ ):
+ return 0, "Skipping documentation checks... 🏃"
+
+ if contains_documentation_link(body):
+ return 0, "Documentation Link Found. You're Awesome! 🎉"
+
+ return 1, "Documentation Link Not Found! ⚠️"
if __name__ == "__main__":
- pr = sys.argv[1]
- response = requests.get(f"https://api.github.com/repos/frappe/frappe/pulls/{pr}")
-
- if response.ok:
- payload = response.json()
- title = (payload.get("title") or "").lower()
- head_sha = (payload.get("head") or {}).get("sha")
- body = (payload.get("body") or "").lower()
-
- if title.startswith("feat") and head_sha and "no-docs" not in body:
- if docs_link_exists(body):
- print("Documentation Link Found. You're Awesome! 🎉")
-
- else:
- print("Documentation Link Not Found! ⚠️")
- sys.exit(1)
-
- else:
- print("Skipping documentation checks... 🏃")
+ exit_code, message = check_pull_request(sys.argv[1])
+ print(message)
+ sys.exit(exit_code)
From 6b3d283cf7ac7ce26907c67fe229fecf356388ef Mon Sep 17 00:00:00 2001
From: Ankush Menat
Date: Fri, 24 Mar 2023 09:58:19 +0530
Subject: [PATCH 09/14] fix: unsubscribe from list_update before resubbing
(#20450)
resubbing can result in multiple events being fired, so unsubscribe all
of them before re-subscribing.
missed in https://github.com/frappe/frappe/pull/20423
---
frappe/public/js/frappe/list/list_view.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js
index 38dc76ec80..a7cd09d76d 100644
--- a/frappe/public/js/frappe/list/list_view.js
+++ b/frappe/public/js/frappe/list/list_view.js
@@ -1334,6 +1334,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
return;
}
frappe.socketio.doctype_subscribe(this.doctype);
+ frappe.realtime.off("list_update");
frappe.realtime.on("list_update", (data) => {
if (data?.doctype !== this.doctype) {
return;
From 0374d37c624c0d4d406092f361641c9316d850f0 Mon Sep 17 00:00:00 2001
From: HarryPaulo
Date: Fri, 24 Mar 2023 04:13:09 -0300
Subject: [PATCH 10/14] feat: show if address is "Disabled" (#20446)
---
frappe/public/js/frappe/form/templates/address_list.html | 2 ++
1 file changed, 2 insertions(+)
diff --git a/frappe/public/js/frappe/form/templates/address_list.html b/frappe/public/js/frappe/form/templates/address_list.html
index a6b8bf1377..0e533ed2ea 100644
--- a/frappe/public/js/frappe/form/templates/address_list.html
+++ b/frappe/public/js/frappe/form/templates/address_list.html
@@ -8,6 +8,8 @@
({%= __("Primary") %}){% } %}
{% if(addr_list[i].is_shipping_address) { %}
({%= __("Shipping") %}){% } %}
+ {% if(addr_list[i].disabled) { %}
+ ({%= __("Disabled") %}){% } %}
From 0ec7ea45e9b3b291c84fb86026f31105b7df68b5 Mon Sep 17 00:00:00 2001
From: Himanshu Shivhare
Date: Fri, 24 Mar 2023 12:49:42 +0530
Subject: [PATCH 11/14] fix: Update social media links (#20400)
* YouTube channel addded in about section.
I have added ERPNext YouTube channel reference in the about section.
#Create an official Handle for YouTube Channel (Like @erpnext or erpnextofficial)
* chore: handle
[skip ci]
* Update about.js
YouTube channel name changed.
---------
[skip ci]
---
frappe/public/js/frappe/ui/toolbar/about.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frappe/public/js/frappe/ui/toolbar/about.js b/frappe/public/js/frappe/ui/toolbar/about.js
index 69cbbfaba0..699db266da 100644
--- a/frappe/public/js/frappe/ui/toolbar/about.js
+++ b/frappe/public/js/frappe/ui/toolbar/about.js
@@ -20,7 +20,7 @@ frappe.ui.misc.about = function () {
Twitter: https://twitter.com/erpnext
- YouTube: https://www.youtube.com/@erpnextofficial
+ YouTube: https://www.youtube.com/@frappetech
${__("Installed Apps")}
${__("Loading versions...")}
From 543a4c467bdcb91cd5d2e236208c673e7908d5fd Mon Sep 17 00:00:00 2001
From: Ankush Menat
Date: Fri, 24 Mar 2023 12:50:22 +0530
Subject: [PATCH 12/14] fix: social media links
[skip ci]
---
frappe/public/js/frappe/ui/toolbar/about.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frappe/public/js/frappe/ui/toolbar/about.js b/frappe/public/js/frappe/ui/toolbar/about.js
index 699db266da..b75f950d72 100644
--- a/frappe/public/js/frappe/ui/toolbar/about.js
+++ b/frappe/public/js/frappe/ui/toolbar/about.js
@@ -18,7 +18,7 @@ frappe.ui.misc.about = function () {
Facebook: https://facebook.com/erpnext
- Twitter: https://twitter.com/erpnext
+ Twitter: https://twitter.com/frappetech
YouTube: https://www.youtube.com/@frappetech
From d9383afae692bfaa83c333b12eef17868888e7e9 Mon Sep 17 00:00:00 2001
From: Ritwik Puri
Date: Fri, 24 Mar 2023 13:45:46 +0530
Subject: [PATCH 13/14] fix: exception handling for bulk email sending (#20451)
---
frappe/email/doctype/email_queue/email_queue.py | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/frappe/email/doctype/email_queue/email_queue.py b/frappe/email/doctype/email_queue/email_queue.py
index b474f37e8e..c10494b0d9 100644
--- a/frappe/email/doctype/email_queue/email_queue.py
+++ b/frappe/email/doctype/email_queue/email_queue.py
@@ -5,6 +5,7 @@ import json
import quopri
import smtplib
import traceback
+from contextlib import suppress
from email.parser import Parser
from email.policy import SMTPUTF8
@@ -706,7 +707,10 @@ class QueueBuilder:
if not smtp_server_instance:
email_account = q.get_email_account()
smtp_server_instance = email_account.get_smtp_server()
- q.send(smtp_server_instance=smtp_server_instance)
+
+ with suppress(Exception):
+ q.send(smtp_server_instance=smtp_server_instance)
+
smtp_server_instance.quit()
def as_dict(self, include_recipients=True):
From 86f72195251c5abfcacf5f9db0351fb0b54f8e1c Mon Sep 17 00:00:00 2001
From: gavin
Date: Fri, 24 Mar 2023 21:02:30 +0530
Subject: [PATCH 14/14] fix: Auto-Reload after changing time zone (#20456)
---
frappe/core/doctype/user/user.js | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/frappe/core/doctype/user/user.js b/frappe/core/doctype/user/user.js
index 18e8651819..413dd07dc4 100644
--- a/frappe/core/doctype/user/user.js
+++ b/frappe/core/doctype/user/user.js
@@ -114,12 +114,16 @@ frappe.ui.form.on("User", {
return;
}
+ function hasChanged(doc_attr, boot_attr) {
+ return (doc_attr || boot_attr) && doc_attr !== boot_attr;
+ }
+
if (
doc.name === frappe.session.user &&
!doc.__unsaved &&
frappe.all_timezones &&
- (doc.language || frappe.boot.user.language) &&
- doc.language !== frappe.boot.user.language
+ (hasChanged(doc.language, frappe.boot.user.language) ||
+ hasChanged(doc.time_zone, frappe.boot.time_zone.user))
) {
frappe.msgprint(__("Refreshing..."));
window.location.reload();