diff --git a/frappe/core/doctype/data_import/importer_new.py b/frappe/core/doctype/data_import/importer_new.py index 911d6a2501..f4cc8fbe94 100644 --- a/frappe/core/doctype/data_import/importer_new.py +++ b/frappe/core/doctype/data_import/importer_new.py @@ -305,21 +305,26 @@ class Importer: out = self.get_data_for_import_preview() fields = out["fields"] data = out["data"] + warnings = [] # validate link field values missing_link_values = self.get_missing_link_field_values(fields, data) - if missing_link_values: - return {"missing_link_values": missing_link_values} + for d in missing_link_values: + msg = _('The following linked values are missing for the Document Type {0}:').format(frappe.bold(_(d.doctype))) + msg += ' ' + ', '.join(d.missing_values) + warnings.append(msg) # parse import data payloads = self.get_payloads_for_import(fields, data) # collect warnings - warnings = [] for payload in payloads: warnings += payload.warnings + if warnings: - return {"warnings": warnings} + self.data_import.db_set("template_warnings", json.dumps(warnings)) + frappe.publish_realtime("data_import_refresh") + return # setup import log if self.data_import.import_log: @@ -424,6 +429,7 @@ class Importer: """ doc = {} warnings = [] + mandatory_fields = [] doctypes = set([df.parent for df in fields if df.parent]) # first row is included by default @@ -458,14 +464,12 @@ class Importer: if value in INVALID_VALUES: if df.reqd: - warnings.append( - _("Row {0}: {1} is a mandatory field").format(row_index, frappe.bold(df.label)) - ) + mandatory_fields.append(frappe._dict(row_number=row_number, df=df)) continue else: value = None - doc[df.fieldname] = value = self.parse_value(value, df) + doc[df.fieldname] = self.parse_value(value, df) return doc parsed_docs = {} @@ -476,6 +480,7 @@ class Importer: # then skip continue + row_number = row[0] column_indexes = get_column_indexes(doctype) values = [row[i] for i in column_indexes] @@ -484,7 +489,7 @@ class Importer: continue docfields = [fields[i] for i in column_indexes] - doc = parse_doc(doctype, docfields, values, row_index) + doc = parse_doc(doctype, docfields, values, row_number) parsed_docs[doctype] = parsed_docs.get(doctype, []) parsed_docs[doctype].append(doc) @@ -499,6 +504,23 @@ class Importer: table_field = table_dfs[0] doc[table_field.fieldname] = docs + if mandatory_fields: + df_by_row_number = {} + for d in mandatory_fields: + df_by_row_number.setdefault(d.row_number, []) + df_by_row_number[d.row_number].append(d.df) + + for row_number, fields in df_by_row_number.items(): + if len(fields) == 1: + warnings.append( + _("Row {0}: {1} is a mandatory field").format(row_number, fields[0].label) + ) + else: + fields_string = ', '.join([df.label for df in fields]) + warnings.append( + _("Row {0}: {1} are mandatory fields").format(row_number, fields_string) + ) + return doc, rows, data[len(rows) :], warnings def get_first_parent_column_index(self, fields): diff --git a/frappe/core/doctype/data_import_beta/data_import_beta.js b/frappe/core/doctype/data_import_beta/data_import_beta.js index a3b4b40133..a14820ce6f 100644 --- a/frappe/core/doctype/data_import_beta/data_import_beta.js +++ b/frappe/core/doctype/data_import_beta/data_import_beta.js @@ -157,11 +157,14 @@ frappe.ui.form.on('Data Import Beta', { show_import_preview(frm, preview_data) { let import_log = JSON.parse(frm.doc.import_log || '[]'); + let warnings = JSON.parse(frm.doc.template_warnings || '[]'); + warnings = warnings.concat(preview_data.warnings || []); if (frm.import_preview) { frm.import_preview.preview_data = preview_data; frm.import_preview.import_log = import_log; frm.import_preview.refresh(); + frm.import_preview.render_warnings(warnings); return; } @@ -171,6 +174,7 @@ frappe.ui.form.on('Data Import Beta', { doctype: frm.doc.reference_doctype, preview_data, import_log, + warnings, events: { remap_column(header_row_index, fieldname) { let template_options = JSON.parse(frm.doc.template_options || '{}'); diff --git a/frappe/core/doctype/data_import_beta/data_import_beta.json b/frappe/core/doctype/data_import_beta/data_import_beta.json index a54ccfbfcb..83e63d2e36 100644 --- a/frappe/core/doctype/data_import_beta/data_import_beta.json +++ b/frappe/core/doctype/data_import_beta/data_import_beta.json @@ -15,6 +15,7 @@ "section_break_7", "date_format", "template_options", + "template_warnings", "section_import_preview", "import_preview", "import_log_section", @@ -107,9 +108,17 @@ "default": "Pending", "fieldname": "status", "fieldtype": "Select", + "hidden": 1, "label": "Status", "options": "Pending\nSuccess\nPartial Success", "read_only": 1 + }, + { + "fieldname": "template_warnings", + "fieldtype": "Code", + "label": "Template Warnings", + "options": "JSON" + }, } ], "hide_toolbar": 1, diff --git a/frappe/public/js/frappe/data_import/import_preview.js b/frappe/public/js/frappe/data_import/import_preview.js index d007865a44..17dab0692c 100644 --- a/frappe/public/js/frappe/data_import/import_preview.js +++ b/frappe/public/js/frappe/data_import/import_preview.js @@ -14,12 +14,13 @@ const SVG_ICONS = { }; frappe.data_import.ImportPreview = class ImportPreview { - constructor({ wrapper, doctype, preview_data, import_log, events = {} }) { + constructor({ wrapper, doctype, preview_data, import_log, warnings, events = {} }) { frappe.import_preview = this; this.wrapper = wrapper; this.doctype = doctype; this.preview_data = preview_data; this.events = events; + this.warnings = warnings; this.import_log = import_log; frappe.model.with_doctype(doctype, () => { @@ -31,7 +32,6 @@ frappe.data_import.ImportPreview = class ImportPreview { this.header_row = this.preview_data.header_row; this.fields = this.preview_data.fields; this.data = this.preview_data.data; - this.warnings = this.preview_data.warnings; this.make_wrapper(); this.prepare_columns(); this.prepare_data(); @@ -73,7 +73,7 @@ frappe.data_import.ImportPreview = class ImportPreview { focusable: false, align: 'left', header_row_index, - width: column_width, + width: df.label === 'Sr. No' ? 60 : column_width, format: (value, row, column, data) => { let html = `
${value}
`; if (df.label === 'Sr. No' && this.is_row_imported(row)) { @@ -123,11 +123,11 @@ frappe.data_import.ImportPreview = class ImportPreview { if (warnings.length > 0) { let warning_html = warnings .map(warning => { - return `
${warning}
`; + return `
  • ${warning}
  • `; }) .join(''); - html = `
    ${warning_html}
    `; + html = ``; } this.$warnings.html(html); }