Skip to content

Commit

Permalink
Merge pull request #24076 from frappe/version-14-hotfix
Browse files Browse the repository at this point in the history
chore: release v14
  • Loading branch information
ankush committed Jan 2, 2024
2 parents a2d7d43 + 0bf46ff commit 204101c
Show file tree
Hide file tree
Showing 31 changed files with 207 additions and 72 deletions.
3 changes: 3 additions & 0 deletions cypress/integration/control_date.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ context("Date Control", () => {
function get_dialog(date_field_options) {
return cy.dialog({
title: "Date",
animate: false,
fields: [
{
label: "Date",
Expand Down Expand Up @@ -75,6 +76,8 @@ context("Date Control", () => {

//Verifying if clicking on "Today" button matches today's date
cy.window().then((win) => {
// `expect` can not wait like `should`
cy.wait(500);
expect(win.cur_dialog.fields_dict.date.value).to.be.equal(
win.frappe.datetime.get_today()
);
Expand Down
10 changes: 8 additions & 2 deletions frappe/commands/site.py
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ def describe_database_table(context, doctype, column):


def _extract_table_stats(doctype: str, columns: list[str]) -> dict:
from frappe.utils import cstr, get_table_name
from frappe.utils import cint, cstr, get_table_name

def sql_bool(val):
return cstr(val).lower() in ("yes", "1", "true")
Expand Down Expand Up @@ -588,7 +588,13 @@ def update_cardinality(column, value):
if idx["Seq_in_index"] == 1:
update_cardinality(idx["Column_name"], idx["Cardinality"])

total_rows = frappe.db.count(doctype)
total_rows = cint(
frappe.db.sql(
f"""select table_rows
from information_schema.tables
where table_name = 'tab{doctype}'"""
)[0][0]
)

# fetch accurate cardinality for columns by query. WARN: This can take a lot of time.
for column in columns:
Expand Down
7 changes: 6 additions & 1 deletion frappe/core/doctype/data_import/data_import.js
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ frappe.ui.form.on("Data Import", {
}
} else {
let messages = JSON.parse(log.messages || "[]")
.map(JSON.parse)
.map((m) => {
let title = m.title ? `<strong>${m.title}</strong>` : "";
let message = m.message ? `<div>${m.message}</div>` : "";
Expand Down Expand Up @@ -507,7 +506,13 @@ frappe.ui.form.on("Data Import", {
},

show_import_log(frm) {
if (!frm.doc.show_failed_logs) {
frm.toggle_display("import_log_preview", false);
return;
}

frm.toggle_display("import_log_section", false);
frm.toggle_display("import_log_preview", true);

if (frm.import_in_progress) {
return;
Expand Down
5 changes: 4 additions & 1 deletion frappe/core/doctype/doctype/test_doctype.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,8 @@ def new_doctype(
unique: bool = False,
depends_on: str = "",
fields: list[dict] | None = None,
custom: bool = True,
default: str | None = None,
**kwargs,
):
if not name:
Expand All @@ -732,13 +734,14 @@ def new_doctype(
{
"doctype": "DocType",
"module": "Core",
"custom": 1,
"custom": custom,
"fields": [
{
"label": "Some Field",
"fieldname": "some_fieldname",
"fieldtype": "Data",
"unique": unique,
"default": default,
"depends_on": depends_on,
}
],
Expand Down
2 changes: 1 addition & 1 deletion frappe/core/doctype/user/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ def user_query(doctype, txt, searchfield, start, page_len, filters):
user_type_condition = "and user_type != 'Website User'"
if filters and filters.get("ignore_user_type") and frappe.session.data.user_type == "System User":
user_type_condition = ""
filters.pop("ignore_user_type")
filters and filters.pop("ignore_user_type", None)

txt = f"%{txt}%"
return frappe.db.sql(
Expand Down
2 changes: 1 addition & 1 deletion frappe/core/page/permission_manager/permission_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ frappe.PermissionEngine = class PermissionEngine {

this.rights.forEach((r) => {
if (!d.is_submittable && ["submit", "cancel", "amend"].includes(r)) return;
if (d.in_create && ["create", "write", "delete"].includes(r)) return;
if (d.in_create && ["create", "delete"].includes(r)) return;
this.add_check(perm_container, d, r);
});

Expand Down
9 changes: 4 additions & 5 deletions frappe/custom/doctype/customize_form/test_customize_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,9 @@ def test_save_customization_length_field_property(self):
# Using Notification Log doctype as it doesn't have any other custom fields
d = self.get_customize_form("Notification Log")

new_document_length = 255
document_name = d.get("fields", {"fieldname": "document_name"})[0]
document_name.length = 255
document_name.length = new_document_length
d.run_method("save_customization")

self.assertEqual(
Expand All @@ -250,19 +251,17 @@ def test_save_customization_length_field_property(self):
{"doc_type": "Notification Log", "property": "length", "field_name": "document_name"},
"value",
),
"255",
str(new_document_length),
)

self.assertTrue(d.flags.update_db)

length = frappe.db.sql(
"""SELECT character_maximum_length
FROM information_schema.columns
WHERE table_name = 'tabNotification Log'
AND column_name = 'document_name'"""
)[0][0]

self.assertEqual(length, 255)
self.assertEqual(length, new_document_length)

def test_custom_link(self):
try:
Expand Down
6 changes: 4 additions & 2 deletions frappe/desk/form/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from frappe.model.meta import Meta
from frappe.model.utils import render_include
from frappe.modules import get_module_path, load_doctype_module, scrub
from frappe.utils import get_html_format
from frappe.utils import get_bench_path, get_html_format
from frappe.utils.data import get_link_to_form

ASSET_KEYS = (
Expand Down Expand Up @@ -122,7 +122,9 @@ def _get_path(fname):
def _add_code(self, path, fieldname):
js = get_js(path)
if js:
comment = f"\n\n/* Adding {path} */\n\n"
bench_path = get_bench_path() + "/"
asset_path = path.replace(bench_path, "")
comment = f"\n\n/* Adding {asset_path} */\n\n"
sourceURL = f"\n\n//# sourceURL={scrub(self.name) + fieldname}"
self.set(fieldname, (self.get(fieldname) or "") + comment + js + sourceURL)

Expand Down
2 changes: 1 addition & 1 deletion frappe/desk/page/setup_wizard/setup_wizard.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ frappe.setup.SetupWizardSlide = class SetupWizardSlide extends frappe.ui.Slide {
let me = this;
this.fields.filter(frappe.model.is_value_type).forEach((field) => {
field.fieldname &&
me.get_input(field.fieldname)?.on("change", function () {
me.get_input(field.fieldname)?.on?.("change", function () {
frappe.telemetry.capture(`${field.fieldname}_set`, "setup");
if (
field.fieldname == "enable_telemetry" &&
Expand Down
11 changes: 10 additions & 1 deletion frappe/geo/country_info.json
Original file line number Diff line number Diff line change
Expand Up @@ -2089,8 +2089,17 @@
},
"Palestinian Territory, Occupied": {
"code": "ps",
"currency": "ILS",
"currency_fraction": "Agora",
"currency_fraction_units": 100,
"currency_name": "New Israeli Sheqel",
"currency_symbol": "\u20aa",
"number_format": "#,###.##",
"isd": "+970"
"isd": "+970",
"timezones": [
"Asia/Hebron",
"Asia/Jerusalem"
]
},
"Panama": {
"code": "pa",
Expand Down
9 changes: 6 additions & 3 deletions frappe/model/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ def _save(self, ignore_permissions=None, ignore_version=None) -> "Document":
if self.get("__islocal") or not self.get("name"):
return self.insert()

self._set_defaults()
self.check_permission("write", "save")

self.set_user_and_timestamp()
Expand Down Expand Up @@ -738,16 +739,18 @@ def _set_defaults(self):
if frappe.flags.in_import:
return

new_doc = frappe.new_doc(self.doctype, as_dict=True)
self.update_if_missing(new_doc)
if self.is_new():
new_doc = frappe.new_doc(self.doctype, as_dict=True)
self.update_if_missing(new_doc)

# children
for df in self.meta.get_table_fields():
new_doc = frappe.new_doc(df.options, parent_doc=self, parentfield=df.fieldname, as_dict=True)
value = self.get(df.fieldname)
if isinstance(value, list):
for d in value:
d.update_if_missing(new_doc)
if d.is_new():
d.update_if_missing(new_doc)

def check_if_latest(self):
"""Checks if `modified` timestamp provided by document being updated is same as the
Expand Down
3 changes: 3 additions & 0 deletions frappe/model/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ def get_mapped_doc(
True if target_doc.get(target_parentfield) else False
)

if table_map.get("ignore"):
continue

if table_map.get("add_if_empty") and row_exists_for_parentfield.get(target_parentfield):
continue

Expand Down
11 changes: 4 additions & 7 deletions frappe/model/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,15 +694,12 @@ def add_doctype_links(self, data):
dict(label=link.group, items=[link.parent_doctype or link.link_doctype])
)

if not data.fieldname and link.link_fieldname:
data.fieldname = link.link_fieldname

if not link.is_child_table:
if link.link_fieldname != data.fieldname:
if data.fieldname:
data.non_standard_fieldnames[link.link_doctype] = link.link_fieldname
else:
data.fieldname = link.link_fieldname
data.non_standard_fieldnames[link.link_doctype] = link.link_fieldname
elif link.is_child_table:
if not data.fieldname:
data.fieldname = link.link_fieldname
data.internal_links[link.parent_doctype] = [link.table_fieldname, link.link_fieldname]

def get_row_template(self):
Expand Down
8 changes: 4 additions & 4 deletions frappe/public/js/frappe/file_uploader/ImageCropper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,19 @@ export default {
aspect_ratio_buttons() {
return [
{
label: __("1:1"),
label: __("1:1", null, "Image Cropper"),
value: 1,
},
{
label: __("4:3"),
label: __("4:3", null, "Image Cropper"),
value: 4 / 3,
},
{
label: __("16:9"),
label: __("16:9", null, "Image Cropper"),
value: 16 / 9,
},
{
label: __("Free"),
label: __("Free", null, "Image Cropper"),
value: NaN,
},
];
Expand Down
18 changes: 10 additions & 8 deletions frappe/public/js/frappe/form/controls/multicheck.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,15 @@ frappe.ui.form.ControlMultiCheck = class ControlMultiCheck extends frappe.ui.for
make_checkboxes() {
this.$load_state.hide();
this.$checkbox_area.empty();
this.options.forEach((option) => {
let checkbox = this.get_checkbox_element(option).appendTo(this.$checkbox_area);
if (option.danger) {
checkbox.find(".label-area").addClass("text-danger");
}
option.$checkbox = checkbox;
});
this.options
.sort((a, b) => cstr(a.label).localeCompare(cstr(b.label)))
.forEach((option) => {
let checkbox = this.get_checkbox_element(option).appendTo(this.$checkbox_area);
if (option.danger) {
checkbox.find(".label-area").addClass("text-danger");
}
option.$checkbox = checkbox;
});
if (this.df.select_all) {
this.setup_select_all();
}
Expand Down Expand Up @@ -152,7 +154,7 @@ frappe.ui.form.ControlMultiCheck = class ControlMultiCheck extends frappe.ui.for
<div class="checkbox unit-checkbox">
<label title="${option.description || ""}">
<input type="checkbox" data-unit="${option.value}"></input>
<span class="label-area" data-unit="${option.value}">${__(option.label)}</span>
<span class="label-area" data-unit="${option.value}">${option.label}</span>
</label>
</div>
`);
Expand Down
2 changes: 1 addition & 1 deletion frappe/public/js/frappe/form/controls/rating.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
frappe.ui.form.ControlRating = class ControlRating extends frappe.ui.form.ControlInt {
frappe.ui.form.ControlRating = class ControlRating extends frappe.ui.form.ControlFloat {
make_input() {
super.make_input();
let stars = "";
Expand Down
2 changes: 1 addition & 1 deletion frappe/public/js/frappe/roles_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ frappe.RoleEditor = class {
this.frm = frm;
this.wrapper = wrapper;
this.disable = disable;
let user_roles = this.frm.doc.roles.map((a) => a.role);
let user_roles = this.frm.doc.roles ? this.frm.doc.roles.map((a) => a.role) : [];
this.multicheck = frappe.ui.form.make_control({
parent: wrapper,
df: {
Expand Down
1 change: 1 addition & 0 deletions frappe/public/js/frappe/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ frappe.router = {
layout_mapped: {},

is_app_route(path) {
if (!path) return;
// desk paths must begin with /app or doctype route
if (path.substr(0, 1) === "/") path = path.substr(1);
path = path.split("/");
Expand Down
2 changes: 1 addition & 1 deletion frappe/public/js/frappe/ui/capture.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ frappe.ui.Capture = class {

setup_remove_action() {
let me = this;
let elements = this.$template[0].getElementsByClassName("capture-remove-btn");
let elements = Array.from(this.$template[0].getElementsByClassName("capture-remove-btn"));

elements.forEach((el) => {
el.onclick = () => {
Expand Down
21 changes: 4 additions & 17 deletions frappe/public/js/frappe/ui/filters/filter_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,27 +249,15 @@ frappe.ui.FilterGroup = class {

filter_exists(filter_value) {
// filter_value of form: [doctype, fieldname, condition, value]
let exists = false;
this.filters
return this.filters
.filter((f) => f.field)
.map((f) => {
.some((f) => {
let f_value = f.get_value();
if (filter_value.length === 2) {
exists = filter_value[0] === f_value[0] && filter_value[1] === f_value[1];
return;
}

let value = filter_value[3];
let equal = frappe.utils.arrays_equal;

if (
equal(f_value.slice(0, 4), filter_value.slice(0, 4)) ||
(Array.isArray(value) && equal(value, f_value[3]))
) {
exists = true;
return filter_value[0] === f_value[0] && filter_value[1] === f_value[1];
}
return frappe.utils.arrays_equal(f_value.slice(0, 4), filter_value.slice(0, 4));
});
return exists;
}

get_filters() {
Expand All @@ -278,7 +266,6 @@ frappe.ui.FilterGroup = class {
.map((f) => {
return f.get_value();
});
// {}: this.list.update_standard_filters(values);
}

update_filters() {
Expand Down
6 changes: 5 additions & 1 deletion frappe/public/js/frappe/utils/diffview.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ frappe.ui.DiffView = class DiffView {
make_dialog() {
const get_query = () => ({
query: "frappe.utils.diff.version_query",
filters: { docname: this.docname, ref_doctype: this.doctype },
filters: {
docname: this.docname,
ref_doctype: this.doctype,
fieldname: this.fieldname,
},
});
const onchange = () => this.compute_diff();
let dialog = new frappe.ui.Dialog({
Expand Down
3 changes: 3 additions & 0 deletions frappe/public/js/frappe/utils/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,9 @@ Object.assign(frappe.utils, {
},

fetch_link_title(doctype, name) {
if (!doctype || !name) {
return;
}
try {
return frappe
.xcall("frappe.desk.search.get_link_title", {
Expand Down
Loading

0 comments on commit 204101c

Please sign in to comment.