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
BohdanK-W32 authored Feb 14, 2024
2 parents 2dfbc74 + e61132a commit 4094261
Show file tree
Hide file tree
Showing 29 changed files with 103 additions and 93 deletions.
2 changes: 1 addition & 1 deletion frappe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
)
from .utils.lazy_loader import lazy_import

__version__ = "15.13.0"
__version__ = "15.14.0"
__title__ = "Frappe Framework"

controllers = {}
Expand Down
1 change: 1 addition & 0 deletions frappe/core/doctype/communication/communication.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ def get_contacts(email_strings: list[str], auto_create_contact=False) -> list[st
contact.insert(ignore_permissions=True)
contact_name = contact.name
except Exception:
contact_name = None
contact.log_error("Unable to add contact")

if contact_name:
Expand Down
2 changes: 0 additions & 2 deletions frappe/core/doctype/communication/communication_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ frappe.listview_settings["Communication"] = {
"communication_date",
],

filters: [["status", "=", "Open"]],

onload: function (list_view) {
let method = "frappe.email.inbox.create_email_flag_queue";

Expand Down
5 changes: 4 additions & 1 deletion frappe/core/doctype/file/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,10 @@ def unique_url(self) -> str:
"""Unique URL contains file ID in URL to speed up permisison checks."""
from urllib.parse import urlencode

return self.file_url + "?" + urlencode({"fid": self.name})
if self.is_private:
return self.file_url + "?" + urlencode({"fid": self.name})
else:
return self.file_url

@staticmethod
def zip_files(files):
Expand Down
2 changes: 1 addition & 1 deletion frappe/core/doctype/file/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ def _save_file(match):
}
)
_file.save(ignore_permissions=True)
file_url = _file.file_url
file_url = _file.unique_url
frappe.flags.has_dataurl = True

return f'<img src="{file_url}"'
Expand Down
1 change: 1 addition & 0 deletions frappe/core/doctype/user/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,7 @@ def test_password_strength(new_password: str, key=None, old_password=None, user_
password_policy_validation_passed = True

result["feedback"]["password_policy_validation_passed"] = password_policy_validation_passed
result.pop("password", None)
return result


Expand Down
7 changes: 5 additions & 2 deletions frappe/database/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,11 @@ def get_values(
skip_locked=skip_locked,
)
except Exception as e:
if ignore and (frappe.db.is_missing_column(e) or frappe.db.is_table_missing(e)):
# table or column not found, return None
if ignore and (
frappe.db.is_missing_column(e)
or frappe.db.is_table_missing(e)
or str(e).startswith("Invalid DocType")
):
out = None
elif (not ignore) and frappe.db.is_table_missing(e):
# table not found, look in singles
Expand Down
7 changes: 1 addition & 6 deletions frappe/database/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,8 @@ def get_definition(fieldtype, precision=None, length=None):


def add_column(doctype, column_name, fieldtype, precision=None, length=None, default=None, not_null=False):
if column_name in frappe.db.get_table_columns(doctype):
# already exists
return

frappe.db.commit()

query = "alter table `tab{}` add column {} {}".format(
query = "alter table `tab{}` add column if not exists {} {}".format(
doctype,
column_name,
get_definition(fieldtype, precision, length),
Expand Down
4 changes: 2 additions & 2 deletions frappe/email/doctype/email_template/email_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,12 @@
"fieldname": "response_html",
"fieldtype": "Code",
"label": "Response ",
"options": "HTML"
"options": "Jinja"
}
],
"icon": "fa fa-comment",
"links": [],
"modified": "2023-08-28 22:29:04.457992",
"modified": "2023-12-12 20:01:07.080625",
"modified_by": "Administrator",
"module": "Email",
"name": "Email Template",
Expand Down
1 change: 1 addition & 0 deletions frappe/email/doctype/email_template/email_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class EmailTemplate(Document):
use_html: DF.Check

# end: auto-generated types

@property
def response_(self):
return self.response_html if self.use_html else self.response
Expand Down
3 changes: 3 additions & 0 deletions frappe/geo/country_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -2648,6 +2648,9 @@
"currency": "TZS",
"currency_name": "Tanzanian Shilling",
"number_format": "#,###.##",
"timezones": [
"Africa/Dar_es_Salaam"
],
"isd": "+255"
},
"Thailand": {
Expand Down
4 changes: 4 additions & 0 deletions frappe/geo/languages.json
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,10 @@
"code": "ml",
"name": "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02"
},
{
"code": "mn",
"name": "\u041c\u043e\u043d\u0433\u043e\u043b (Mongolian)"
},
{
"code": "mr",
"name": "\u092e\u0930\u093e\u0920\u0940"
Expand Down
1 change: 1 addition & 0 deletions frappe/migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ def setUp(self):
"""Complete setup required for site migration"""
frappe.flags.touched_tables = set()
self.touched_tables_file = frappe.get_site_path("touched_tables.json")
frappe.clear_cache()
add_column(doctype="DocType", column_name="migration_hash", fieldtype="Data")
clear_global_cache()

Expand Down
22 changes: 11 additions & 11 deletions frappe/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,22 +134,22 @@
)

std_fields = [
{"fieldname": "name", "fieldtype": "Link", "label": _("ID")},
{"fieldname": "owner", "fieldtype": "Link", "label": _("Created By"), "options": "User"},
{"fieldname": "idx", "fieldtype": "Int", "label": _("Index")},
{"fieldname": "creation", "fieldtype": "Datetime", "label": _("Created On")},
{"fieldname": "modified", "fieldtype": "Datetime", "label": _("Last Updated On")},
{"fieldname": "name", "fieldtype": "Link", "label": "ID"},
{"fieldname": "owner", "fieldtype": "Link", "label": "Created By", "options": "User"},
{"fieldname": "idx", "fieldtype": "Int", "label": "Index"},
{"fieldname": "creation", "fieldtype": "Datetime", "label": "Created On"},
{"fieldname": "modified", "fieldtype": "Datetime", "label": "Last Updated On"},
{
"fieldname": "modified_by",
"fieldtype": "Link",
"label": _("Last Updated By"),
"label": "Last Updated By",
"options": "User",
},
{"fieldname": "_user_tags", "fieldtype": "Data", "label": _("Tags")},
{"fieldname": "_liked_by", "fieldtype": "Data", "label": _("Liked By")},
{"fieldname": "_comments", "fieldtype": "Text", "label": _("Comments")},
{"fieldname": "_assign", "fieldtype": "Text", "label": _("Assigned To")},
{"fieldname": "docstatus", "fieldtype": "Int", "label": _("Document Status")},
{"fieldname": "_user_tags", "fieldtype": "Data", "label": "Tags"},
{"fieldname": "_liked_by", "fieldtype": "Data", "label": "Liked By"},
{"fieldname": "_comments", "fieldtype": "Text", "label": "Comments"},
{"fieldname": "_assign", "fieldtype": "Text", "label": "Assigned To"},
{"fieldname": "docstatus", "fieldtype": "Int", "label": "Document Status"},
]


Expand Down
4 changes: 3 additions & 1 deletion frappe/model/db_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,9 @@ def prepare_filter_condition(self, f):
f.update(get_additional_filter_field(additional_filters_config, f, f.value))

meta = frappe.get_meta(f.doctype)
can_be_null = f.fieldname != "name" # primary key is never nullable

# primary key is never nullable, modified is usually indexed by default and always present
can_be_null = f.fieldname not in ("name", "modified")

# prepare in condition
if f.operator.lower() in NestedSetHierarchy:
Expand Down
7 changes: 4 additions & 3 deletions frappe/printing/doctype/print_format/print_format.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,15 @@
"label": "HTML",
"oldfieldname": "html",
"oldfieldtype": "Text Editor",
"options": "HTML"
"options": "Jinja"
},
{
"depends_on": "raw_printing",
"description": "Any string-based printer languages can be used. Writing raw commands requires knowledge of the printer's native language provided by the printer manufacturer. Please refer to the developer manual provided by the printer manufacturer on how to write their native commands. These commands are rendered on the server side using the Jinja Templating Language.",
"fieldname": "raw_commands",
"fieldtype": "Code",
"label": "Raw Commands"
"label": "Raw Commands",
"options": "Jinja"
},
{
"depends_on": "eval:!doc.custom_format",
Expand Down Expand Up @@ -259,7 +260,7 @@
"icon": "fa fa-print",
"idx": 1,
"links": [],
"modified": "2023-08-28 20:25:09.660073",
"modified": "2023-12-12 19:59:37.133301",
"modified_by": "Administrator",
"module": "Printing",
"name": "Print Format",
Expand Down
1 change: 1 addition & 0 deletions frappe/printing/doctype/print_format/print_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class PrintFormat(Document):
standard: DF.Literal["No", "Yes"]

# end: auto-generated types

def onload(self):
templates = frappe.get_all(
"Print Format Field Template",
Expand Down
1 change: 1 addition & 0 deletions frappe/public/js/frappe/form/controls/code.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ frappe.ui.form.ControlCode = class ControlCode extends frappe.ui.form.ControlTex
JSON: "ace/mode/json",
Golang: "ace/mode/golang",
Go: "ace/mode/golang",
Jinja: "ace/mode/django",
};
const language = this.df.options;

Expand Down
5 changes: 5 additions & 0 deletions frappe/public/js/frappe/model/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,11 @@ $.extend(frappe.model, {
return frappe.boot.user.can_delete.indexOf(doctype) !== -1;
},

can_submit: function (doctype) {
if (!doctype) return false;
return frappe.boot.user.can_submit.indexOf(doctype) !== -1;
},

can_cancel: function (doctype) {
if (!doctype) return false;
return frappe.boot.user.can_cancel.indexOf(doctype) !== -1;
Expand Down
1 change: 1 addition & 0 deletions frappe/public/js/frappe/utils/diffview.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ frappe.ui.DiffView = class DiffView {
docname: this.docname,
ref_doctype: this.doctype,
fieldname: this.fieldname,
page_len: 100,
},
});
const onchange = () => this.compute_diff();
Expand Down
19 changes: 14 additions & 5 deletions frappe/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -984,13 +984,22 @@ class TestTypingValidations(FrappeTestCase):
ERR_REGEX = f"^Argument '.*' should be of type '.*' but got '.*' instead.$"

def test_validate_whitelisted_api(self):
from inspect import signature
@frappe.whitelist()
def simple(string: str, number: int):
return

whitelisted_fn = next(x for x in frappe.whitelisted if x.__annotations__)
bad_params = (object(),) * len(signature(whitelisted_fn).parameters)
@frappe.whitelist()
def varkw(string: str, **kwargs):
return

with self.assertRaisesRegex(frappe.FrappeTypeError, self.ERR_REGEX):
whitelisted_fn(*bad_params)
test_cases = [
(simple, (object(), object()), {}),
(varkw, (object(),), {"xyz": object()}),
]

for fn, args, kwargs in test_cases:
with self.assertRaisesRegex(frappe.FrappeTypeError, self.ERR_REGEX):
fn(*args, **kwargs)

def test_validate_whitelisted_doc_method(self):
report = frappe.get_last_doc("Report")
Expand Down
2 changes: 1 addition & 1 deletion frappe/translate.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def get_language(lang_list: list = None) -> str:
if preferred_language_cookie in lang_set:
return preferred_language_cookie

parent_language = get_parent_language(language)
parent_language = get_parent_language(preferred_language_cookie)
if parent_language in lang_set:
return parent_language

Expand Down
4 changes: 2 additions & 2 deletions frappe/utils/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,10 @@ def version_query(doctype, txt, searchfield, start, page_len, filters):

results = frappe.get_list(
"Version",
fields=["name", "modified"],
fields=["name", "modified", "owner"],
filters=version_filters,
limit_start=start,
limit_page_length=page_len,
order_by="modified desc",
)
return [(d.name, pretty_date(d.modified), d.modified) for d in results]
return [(d.name, pretty_date(d.modified), d.modified, d.owner) for d in results]
5 changes: 5 additions & 0 deletions frappe/utils/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def __init__(self, name=""):
self.can_select = []
self.can_read = []
self.can_write = []
self.can_submit = []
self.can_cancel = []
self.can_delete = []
self.can_search = []
Expand Down Expand Up @@ -142,6 +143,9 @@ def build_permissions(self):
else:
self.can_read.append(dt)

if p.get("submit"):
self.can_submit.append(dt)

if p.get("cancel"):
self.can_cancel.append(dt)

Expand Down Expand Up @@ -238,6 +242,7 @@ def load_user(self):
"can_create",
"can_write",
"can_read",
"can_submit",
"can_cancel",
"can_delete",
"can_get_report",
Expand Down
5 changes: 3 additions & 2 deletions frappe/website/doctype/web_template/web_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"fieldname": "template",
"fieldtype": "Code",
"label": "Template",
"options": "HTML"
"options": "Jinja"
},
{
"fieldname": "fields",
Expand Down Expand Up @@ -54,7 +54,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-09-04 12:38:27.656042",
"modified": "2023-12-12 20:01:21.524022",
"modified_by": "Administrator",
"module": "Website",
"name": "Web Template",
Expand All @@ -76,5 +76,6 @@
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
1 change: 1 addition & 0 deletions frappe/website/doctype/web_template/web_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class WebTemplate(Document):
type: DF.Literal["Component", "Section", "Navbar", "Footer"]

# end: auto-generated types

def validate(self):
if self.standard and not (frappe.conf.developer_mode or frappe.flags.in_patch):
frappe.throw(_("Enable developer mode to create a standard Web Template"))
Expand Down
26 changes: 0 additions & 26 deletions frappe/workflow/doctype/workflow/test_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,35 +21,9 @@ def setUpClass(cls):
def setUp(self):
self.workflow = create_todo_workflow()
frappe.set_user("Administrator")
if self._testMethodName == "test_if_workflow_actions_were_processed_using_user":
if not frappe.db.has_column("Workflow Action", "user"):
# mariadb would raise this statement would create an implicit commit
# if we do not commit before alter statement
# nosemgrep
frappe.db.commit()
frappe.db.multisql(
{
"mariadb": "ALTER TABLE `tabWorkflow Action` ADD COLUMN user varchar(140)",
"postgres": 'ALTER TABLE "tabWorkflow Action" ADD COLUMN "user" varchar(140)',
}
)
frappe.cache.delete_value("table_columns")

def tearDown(self):
frappe.delete_doc("Workflow", "Test ToDo")
if self._testMethodName == "test_if_workflow_actions_were_processed_using_user":
if frappe.db.has_column("Workflow Action", "user"):
# mariadb would raise this statement would create an implicit commit
# if we do not commit before alter statement
# nosemgrep
frappe.db.commit()
frappe.db.multisql(
{
"mariadb": "ALTER TABLE `tabWorkflow Action` DROP COLUMN user",
"postgres": 'ALTER TABLE "tabWorkflow Action" DROP COLUMN "user"',
}
)
frappe.cache.delete_value("table_columns")

def test_default_condition(self):
"""test default condition is set"""
Expand Down
Loading

0 comments on commit 4094261

Please sign in to comment.