Skip to content

Commit

Permalink
Merge branch 'frappe:version-15' into version-15
Browse files Browse the repository at this point in the history
  • Loading branch information
metalmon authored Nov 5, 2024
2 parents 047eb04 + fc65921 commit 2b6bfbb
Show file tree
Hide file tree
Showing 28 changed files with 173 additions and 119 deletions.
2 changes: 1 addition & 1 deletion frappe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
)
from .utils.lazy_loader import lazy_import

__version__ = "15.46.0"
__version__ = "15.47.0"
__title__ = "Frappe Framework"

controllers = {}
Expand Down
3 changes: 2 additions & 1 deletion frappe/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from frappe import _
from frappe.apps import get_default_path
from frappe.core.doctype.activity_log.activity_log import add_authentication_log
from frappe.desk.utils import slug
from frappe.sessions import Session, clear_sessions, delete_session, get_expiry_in_seconds
from frappe.translate import get_language
from frappe.twofactor import (
Expand Down Expand Up @@ -185,7 +186,7 @@ def set_user_info(self, resume=False):
frappe.local.response["message"] = "Logged In"
default_workspace = frappe.boot.get_bootinfo().get("user").get("default_workspace")
if default_workspace:
frappe.local.response["home_page"] = "/app/" + default_workspace.get("name")
frappe.local.response["home_page"] = "/app/" + slug(default_workspace.get("name"))
else:
frappe.local.response["home_page"] = get_default_path() or "/app"

Expand Down
4 changes: 3 additions & 1 deletion frappe/automation/doctype/assignment_rule/assignment_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ def clear_cache(self):

def validate_document_types(self):
if self.document_type == "ToDo":
frappe.throw(_("Assignment Rule is not allowed on {0} document type").format(frappe.bold("ToDo")))
frappe.throw(
_("Assignment Rule is not allowed on document type {0}").format(frappe.bold(_("ToDo")))
)

def validate_assignment_days(self):
assignment_days = self.get_assignment_days()
Expand Down
8 changes: 6 additions & 2 deletions frappe/automation/doctype/auto_repeat/auto_repeat.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ def validate_reference_doctype(self):
def validate_submit_on_creation(self):
if self.submit_on_creation and not frappe.get_meta(self.reference_doctype).is_submittable:
frappe.throw(
_("Cannot enable {0} for a non-submittable doctype").format(frappe.bold("Submit on Creation"))
_("Cannot enable {0} for a non-submittable doctype").format(
frappe.bold(_("Submit on Creation"))
)
)

def validate_dates(self):
Expand All @@ -134,7 +136,9 @@ def validate_dates(self):

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"))
_("{0} should not be same as {1}").format(
frappe.bold(_("End Date")), frappe.bold(_("Start Date"))
)
)

def validate_email_id(self):
Expand Down
1 change: 1 addition & 0 deletions frappe/boot.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ def get_bootinfo():
bootinfo.update(get_email_accounts(user=frappe.session.user))
bootinfo.energy_points_enabled = is_energy_point_enabled()
bootinfo.website_tracking_enabled = is_tracking_enabled()
bootinfo.sms_gateway_enabled = bool(frappe.db.get_single_value("SMS Settings", "sms_gateway_url"))
bootinfo.points = get_energy_points(frappe.session.user)
bootinfo.frequently_visited_links = frequently_visited_links()
bootinfo.link_preview_doctypes = get_link_preview_doctypes()
Expand Down
2 changes: 1 addition & 1 deletion frappe/contacts/doctype/contact/contact.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def set_primary_email(self):
return

if len([email.email_id for email in self.email_ids if email.is_primary]) > 1:
frappe.throw(_("Only one {0} can be set as primary.").format(frappe.bold("Email ID")))
frappe.throw(_("Only one {0} can be set as primary.").format(frappe.bold(_("Email ID"))))

if len(self.email_ids) == 1:
self.email_ids[0].is_primary = 1
Expand Down
2 changes: 1 addition & 1 deletion frappe/core/doctype/doctype/doctype_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ frappe.listview_settings["DocType"] = {
let non_developer = frappe.session.user !== "Administrator" || !frappe.boot.developer_mode;
let fields = [
{
label: __("DocType Name"),
label: __("Name"),
fieldname: "name",
fieldtype: "Data",
reqd: 1,
Expand Down
10 changes: 9 additions & 1 deletion frappe/core/doctype/system_settings/system_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"language",
"column_break_3",
"time_zone",
"currency",
"enable_onboarding",
"setup_complete",
"disable_document_sharing",
Expand Down Expand Up @@ -684,12 +685,19 @@
"fieldname": "use_number_format_from_currency",
"fieldtype": "Check",
"label": "Use Number Format from Currency"
},
{
"description": "Default display currency",
"fieldname": "currency",
"fieldtype": "Link",
"label": "Currency",
"options": "Currency"
}
],
"icon": "fa fa-cog",
"issingle": 1,
"links": [],
"modified": "2024-09-26 16:20:59.417151",
"modified": "2024-11-04 15:51:39.954876",
"modified_by": "Administrator",
"module": "Core",
"name": "System Settings",
Expand Down
1 change: 1 addition & 0 deletions frappe/core/doctype/system_settings/system_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class SystemSettings(Document):
bypass_2fa_for_retricted_ip_users: DF.Check
bypass_restrict_ip_check_if_2fa_enabled: DF.Check
country: DF.Link | None
currency: DF.Link | None
currency_precision: DF.Literal["", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
date_format: DF.Literal[
"yyyy-mm-dd", "dd-mm-yyyy", "dd/mm/yyyy", "dd.mm.yyyy", "mm/dd/yyyy", "mm-dd-yyyy"
Expand Down
60 changes: 1 addition & 59 deletions frappe/core/doctype/user/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def validate(self):
if self.name not in STANDARD_USERS:
self.email = self.name
self.validate_email_type(self.name)
self.add_system_manager_role()

self.populate_role_profile_roles()
self.check_roles_added()
self.set_system_user()
Expand Down Expand Up @@ -262,48 +262,13 @@ def check_enable_disable(self):
if not cint(self.enabled) and self.name in STANDARD_USERS:
frappe.throw(_("User {0} cannot be disabled").format(self.name))

if not cint(self.enabled):
self.a_system_manager_should_exist()

# clear sessions if disabled
if not cint(self.enabled) and getattr(frappe.local, "login_manager", None):
frappe.local.login_manager.logout(user=self.name)

# toggle notifications based on the user's status
toggle_notifications(self.name, enable=cint(self.enabled))

def add_system_manager_role(self):
if self.is_system_manager_disabled():
return

# if adding system manager, do nothing
if not cint(self.enabled) or (
"System Manager" in [user_role.role for user_role in self.get("roles")]
):
return

if (
self.name not in STANDARD_USERS
and self.user_type == "System User"
and not self.get_other_system_managers()
and cint(frappe.db.get_single_value("System Settings", "setup_complete"))
):
msgprint(_("Adding System Manager to this User as there must be atleast one System Manager"))
self.append("roles", {"doctype": "Has Role", "role": "System Manager"})

if self.name == "Administrator":
# Administrator should always have System Manager Role
self.extend(
"roles",
[
{"doctype": "Has Role", "role": "System Manager"},
{"doctype": "Has Role", "role": "Administrator"},
],
)

def is_system_manager_disabled(self):
return frappe.db.get_value("Role", {"name": "System Manager"}, ["disabled"])

def email_new_password(self, new_password=None):
if new_password and not self.flags.in_insert:
_update_password(user=self.name, pwd=new_password, logout_all_sessions=self.logout_all_sessions)
Expand Down Expand Up @@ -417,20 +382,6 @@ def reset_password(self, send_email=False, password_expired=False):

return link

def get_other_system_managers(self):
user_doctype = DocType("User").as_("user")
user_role_doctype = DocType("Has Role").as_("user_role")
return (
frappe.qb.from_(user_doctype)
.from_(user_role_doctype)
.select(user_doctype.name)
.where(user_role_doctype.role == "System Manager")
.where(user_doctype.enabled == 1)
.where(user_role_doctype.parent == user_doctype.name)
.where(user_role_doctype.parent.notin(["Administrator", self.name]))
.limit(1)
).run()

def get_fullname(self):
"""get first_name space last_name"""
return (self.first_name or "") + (self.first_name and " " or "") + (self.last_name or "")
Expand Down Expand Up @@ -515,20 +466,11 @@ def send_login_mail(self, subject, template, add_args, now=None, custom_template
retry=3,
)

def a_system_manager_should_exist(self):
if self.is_system_manager_disabled():
return

if not self.get_other_system_managers():
throw(_("There should remain at least one System Manager"))

def on_trash(self):
frappe.clear_cache(user=self.name)
if self.name in STANDARD_USERS:
throw(_("User {0} cannot be deleted").format(self.name))

self.a_system_manager_should_exist()

# disable the user and log him/her out
self.enabled = 0
if getattr(frappe.local, "login_manager", None):
Expand Down
4 changes: 4 additions & 0 deletions frappe/desk/doctype/workspace/workspace.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ def before_export(self, doc):
if doc.title != doc.label and doc.label == doc.name:
self.name = doc.name = doc.label = doc.title

def on_trash(self):
if self.public and not is_workspace_manager():
frappe.throw(_("You need to be Workspace Manager to delete a public workspace."))

def after_delete(self):
if disable_saving_as_public():
return
Expand Down
2 changes: 2 additions & 0 deletions frappe/desk/page/setup_wizard/setup_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ def update_system_settings(args): # nosemgrep
"country": args.get("country"),
"language": get_language_code(args.get("language")) or "en",
"time_zone": args.get("timezone"),
"currency": args.get("currency"),
"float_precision": 3,
"rounding_method": "Banker's Rounding",
"date_format": frappe.db.get_value("Country", args.get("country"), "date_format"),
Expand Down Expand Up @@ -220,6 +221,7 @@ def create_or_update_user(args): # nosemgrep
}
)
user.append_roles(*_get_default_roles())
user.append_roles("System Manager")
user.flags.no_welcome_mail = True
user.insert()

Expand Down
22 changes: 21 additions & 1 deletion frappe/desk/query_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from frappe.model.utils import render_include
from frappe.modules import get_module_path, scrub
from frappe.monitor import add_data_to_monitor
from frappe.permissions import get_role_permissions
from frappe.permissions import get_role_permissions, has_permission
from frappe.utils import cint, cstr, flt, format_duration, get_html_format, sbool


Expand Down Expand Up @@ -195,6 +195,7 @@ def run(
parent_field=None,
are_default_filters=True,
):
validate_filters_permissions(report_name, filters, user)
report = get_report_doc(report_name)
if not user:
user = frappe.session.user
Expand Down Expand Up @@ -784,3 +785,22 @@ def get_user_match_filters(doctypes, user):
match_filters[dt] = filter_list

return match_filters


def validate_filters_permissions(report_name, filters=None, user=None):
if not filters:
return

if isinstance(filters, str):
filters = json.loads(filters)

report = frappe.get_doc("Report", report_name)
for field in report.filters:
if field.fieldname in filters and field.fieldtype == "Link":
linked_doctype = field.options
if not has_permission(doctype=linked_doctype, doc=filters[field.fieldname], user=user):
frappe.throw(
_("You do not have permission to access {0}: {1}.").format(
linked_doctype, filters[field.fieldname]
)
)
2 changes: 1 addition & 1 deletion frappe/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def check_write_permission(doctype: str | None = None, name: str | None = None):
if doctype and name:
try:
doc = frappe.get_doc(doctype, name)
doc.has_permission("write")
doc.check_permission("write")
except frappe.DoesNotExistError:
# doc has not been inserted yet, name is set to "new-some-doctype"
# If doc inserts fine then only this attachment will be linked see file/utils.py:relink_mismatched_files
Expand Down
4 changes: 2 additions & 2 deletions frappe/locale/es.po
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: [email protected]\n"
"POT-Creation-Date: 2024-10-08 17:02+0000\n"
"PO-Revision-Date: 2024-10-26 08:29\n"
"PO-Revision-Date: 2024-11-04 11:43\n"
"Last-Translator: [email protected]\n"
"Language-Team: Spanish\n"
"MIME-Version: 1.0\n"
Expand Down Expand Up @@ -12177,7 +12177,7 @@ msgstr "Importar / Exportar"
#. Label of a shortcut in the Tools Workspace
#: frappe/automation/workspace/tools/tools.json
msgid "Import Data"
msgstr "Datos de Importación"
msgstr "Importación de datos"

#: frappe/email/doctype/email_group/email_group.js:14
msgid "Import Email From"
Expand Down
12 changes: 6 additions & 6 deletions frappe/locale/sv.po
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: frappe\n"
"Report-Msgid-Bugs-To: [email protected]\n"
"POT-Creation-Date: 2024-10-08 17:02+0000\n"
"PO-Revision-Date: 2024-10-26 08:29\n"
"PO-Revision-Date: 2024-11-04 11:43\n"
"Last-Translator: [email protected]\n"
"Language-Team: Swedish\n"
"MIME-Version: 1.0\n"
Expand Down Expand Up @@ -1495,14 +1495,14 @@ msgstr "Adress"
#: frappe/contacts/doctype/address/address.json
#: frappe/website/doctype/contact_us_settings/contact_us_settings.json
msgid "Address Line 1"
msgstr "Co/Box"
msgstr "Adress Linje 1"

#. Label of a Data field in DocType 'Address'
#. Label of a Data field in DocType 'Contact Us Settings'
#: frappe/contacts/doctype/address/address.json
#: frappe/website/doctype/contact_us_settings/contact_us_settings.json
msgid "Address Line 2"
msgstr "Gata och Nummer"
msgstr "Adress Linje 2"

#. Name of a DocType
#: frappe/contacts/doctype/address_template/address_template.json
Expand Down Expand Up @@ -26226,7 +26226,7 @@ msgstr "Växla Diagram"
#. Type: Action
#: frappe/hooks.py
msgid "Toggle Full Width"
msgstr "Ändra Full Bredd"
msgstr "Växla Full Bredd"

#: frappe/public/js/frappe/views/file/file_view.js:33
msgid "Toggle Grid View"
Expand All @@ -26251,7 +26251,7 @@ msgstr "Växla Sidofält"
#. Type: Action
#: frappe/hooks.py
msgid "Toggle Theme"
msgstr "Ändra Tema"
msgstr "Växla Tema"

#. Option for the 'Response Type' (Select) field in DocType 'OAuth Client'
#: frappe/integrations/doctype/oauth_client/oauth_client.json
Expand Down Expand Up @@ -28971,7 +28971,7 @@ msgstr "Du kan ändra godkännda dokument genom att avbryta dem och sedan ändra

#: frappe/public/js/frappe/logtypes.js:21
msgid "You can change the retention policy from {0}."
msgstr "Du kan ändra lagring princip från {0}."
msgstr "Ändra lagring regel från {0}."

#: frappe/public/js/frappe/widgets/onboarding_widget.js:199
msgid "You can continue with the onboarding after exploring this page"
Expand Down
Loading

0 comments on commit 2b6bfbb

Please sign in to comment.