diff --git a/cypress/fixtures/child_table_doctype.js b/cypress/fixtures/child_table_doctype.js new file mode 100644 index 0000000000..f65e5d1765 --- /dev/null +++ b/cypress/fixtures/child_table_doctype.js @@ -0,0 +1,30 @@ +export default { + name: "Child Table Doctype", + actions: [], + custom: 1, + autoname: "field:title", + creation: "2022-02-09 20:15:21.242213", + doctype: "DocType", + editable_grid: 1, + engine: "InnoDB", + fields: [ + { + fieldname: "title", + fieldtype: "Data", + in_list_view: 1, + label: "Title", + unique: 1 + } + ], + links: [], + istable: 1, + modified: "2022-02-10 12:03:12.603763", + modified_by: "Administrator", + module: "Custom", + naming_rule: "By fieldname", + owner: "Administrator", + permissions: [], + sort_field: 'modified', + sort_order: 'ASC', + track_changes: 1 +}; \ No newline at end of file diff --git a/cypress/fixtures/doctype_to_link.js b/cypress/fixtures/doctype_to_link.js new file mode 100644 index 0000000000..f5335b1755 --- /dev/null +++ b/cypress/fixtures/doctype_to_link.js @@ -0,0 +1,45 @@ +export default { + name: "Doctype to Link", + actions: [], + custom: 1, + naming_rule: "By fieldname", + autoname: "field:title", + creation: "2022-02-09 20:15:21.242213", + doctype: "DocType", + editable_grid: 1, + engine: "InnoDB", + fields: [ + { + "fieldname": "title", + "fieldtype": "Data", + "label": "Title", + "unique": 1 + } + ], + links: [ + { + "group": "Child Doctype", + "link_doctype": "Doctype With Child Table", + "link_fieldname": "title" + } + ], + modified: "2022-02-10 12:03:12.603763", + modified_by: "Administrator", + module: "Custom", + owner: "Administrator", + permissions: [ + { + create: 1, + delete: 1, + email: 1, + print: 1, + read: 1, + role: 'System Manager', + share: 1, + write: 1 + } + ], + sort_field: 'modified', + sort_order: 'ASC', + track_changes: 1 +}; \ No newline at end of file diff --git a/cypress/fixtures/doctype_with_child_table.js b/cypress/fixtures/doctype_with_child_table.js new file mode 100644 index 0000000000..bbb2127448 --- /dev/null +++ b/cypress/fixtures/doctype_with_child_table.js @@ -0,0 +1,46 @@ +export default { + name: "Doctype With Child Table", + actions: [], + custom: 1, + autoname: "field:title", + creation: "2022-02-09 20:15:21.242213", + doctype: "DocType", + editable_grid: 1, + engine: "InnoDB", + fields: [ + { + fieldname: "title", + fieldtype: "Data", + label: "Title", + unique: 1 + }, + { + fieldname: "child_table", + fieldtype: "Table", + label: "Child Table", + options: "Child Table Doctype", + reqd: 1 + } + ], + links: [], + modified: "2022-02-10 12:03:12.603763", + modified_by: "Administrator", + module: "Custom", + naming_rule: "By fieldname", + owner: "Administrator", + permissions: [ + { + create: 1, + delete: 1, + email: 1, + print: 1, + read: 1, + role: 'System Manager', + share: 1, + write: 1 + } + ], + sort_field: 'modified', + sort_order: 'ASC', + track_changes: 1 +}; diff --git a/cypress/integration/dashboard_links.js b/cypress/integration/dashboard_links.js index 16ffd41cf4..93d10cf1fd 100644 --- a/cypress/integration/dashboard_links.js +++ b/cypress/integration/dashboard_links.js @@ -1,7 +1,21 @@ +import doctype_with_child_table from '../fixtures/doctype_with_child_table'; +import child_table_doctype from '../fixtures/child_table_doctype'; +import doctype_to_link from '../fixtures/doctype_to_link'; +const doctype_to_link_name = doctype_to_link.name; +const child_table_doctype_name = child_table_doctype.name; + context('Dashboard links', () => { before(() => { cy.visit('/login'); cy.login(); + cy.insert_doc('DocType', child_table_doctype, true); + cy.insert_doc('DocType', doctype_with_child_table, true); + cy.insert_doc('DocType', doctype_to_link, true); + return cy.window().its('frappe').then(frappe => { + return frappe.xcall("frappe.tests.ui_test_helpers.update_child_table", { + name: child_table_doctype_name + }); + }); }); it('Adding a new contact, checking for the counter on the dashboard and deleting the created contact', () => { @@ -62,4 +76,14 @@ context('Dashboard links', () => { cy.findByText('Website Analytics'); }); }); + + it('check if child table is populated with linked field on creation from dashboard link', () => { + cy.new_form(doctype_to_link_name); + cy.fill_field("title", "Test Linking"); + cy.findByRole("button", {name: "Save"}).click(); + + cy.get('.document-link .btn-new').click(); + cy.get('.frappe-control[data-fieldname="child_table"] .rows .data-row .col[data-fieldname="doctype_to_link"]') + .should('contain.text', 'Test Linking'); + }); }); diff --git a/frappe/public/js/frappe/form/form.js b/frappe/public/js/frappe/form/form.js index 53e86b9cde..409cf6890b 100644 --- a/frappe/public/js/frappe/form/form.js +++ b/frappe/public/js/frappe/form/form.js @@ -334,7 +334,7 @@ frappe.ui.form.Form = class FrappeForm { this.doc = frappe.get_doc(this.doctype, this.docname); // check permissions - if(!this.has_read_permission()) { + if (!this.has_read_permission()) { frappe.show_not_permitted(__(this.doctype) + " " + __(this.docname)); return; } @@ -1662,23 +1662,17 @@ frappe.ui.form.Form = class FrappeForm { // make new doctype from the current form // will handover to `make_methods` if defined // or will create and match link fields - var me = this; + let me = this; if(this.make_methods && this.make_methods[doctype]) { return this.make_methods[doctype](this); } else if(this.custom_make_buttons && this.custom_make_buttons[doctype]) { this.custom_buttons[__(this.custom_make_buttons[doctype])].trigger('click'); } else { frappe.model.with_doctype(doctype, function() { - var new_doc = frappe.model.get_new_doc(doctype); + let new_doc = frappe.model.get_new_doc(doctype, null, null, true); // set link fields (if found) - frappe.get_meta(doctype).fields.forEach(function(df) { - if(df.fieldtype==='Link' && df.options===me.doctype) { - new_doc[df.fieldname] = me.doc.name; - } else if (['Link', 'Dynamic Link'].includes(df.fieldtype) && me.doc[df.fieldname]) { - new_doc[df.fieldname] = me.doc[df.fieldname]; - } - }); + me.set_link_field(doctype, new_doc); frappe.ui.form.make_quick_entry(doctype, null, null, new_doc); // frappe.set_route('Form', doctype, new_doc.name); @@ -1686,6 +1680,20 @@ frappe.ui.form.Form = class FrappeForm { } } + set_link_field(doctype, new_doc) { + let me = this; + frappe.get_meta(doctype).fields.forEach(function(df) { + if (df.fieldtype === 'Link' && df.options === me.doctype) { + new_doc[df.fieldname] = me.doc.name; + } else if (['Link', 'Dynamic Link'].includes(df.fieldtype) && me.doc[df.fieldname]) { + new_doc[df.fieldname] = me.doc[df.fieldname]; + } else if (df.fieldtype === 'Table' && df.options && df.reqd) { + let row = new_doc[df.fieldname][0]; + me.set_link_field(df.options, row); + } + }); + } + update_in_all_rows(table_fieldname, fieldname, value) { // update the child value in all tables where it is missing if(!value) return; diff --git a/frappe/tests/ui_test_helpers.py b/frappe/tests/ui_test_helpers.py index 986494bfce..26c20f3d18 100644 --- a/frappe/tests/ui_test_helpers.py +++ b/frappe/tests/ui_test_helpers.py @@ -255,3 +255,17 @@ def update_webform_to_multistep(): _doc.route = "update-profile-duplicate" _doc.is_standard = False _doc.save() + +@frappe.whitelist() +def update_child_table(name): + doc = frappe.get_doc('DocType', name) + if len(doc.fields) == 1: + doc.append('fields', { + 'fieldname': 'doctype_to_link', + 'fieldtype': 'Link', + 'in_list_view': 1, + 'label': 'Doctype to Link', + 'options': 'Doctype to Link' + }) + + doc.save() \ No newline at end of file