From bdc5ec32df64de20ddd002bad52158e2b1c992e1 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Sat, 10 Aug 2019 21:33:53 +0530 Subject: [PATCH] feat: New Doctype - Data Import Beta - Import Preview using DataTable --- .../data_import_beta/data_import_beta.js | 41 ++++++++++ .../data_import_beta/data_import_beta.json | 79 +++++++++++++++++++ .../data_import_beta/data_import_beta.py | 44 +++++++++++ frappe/public/build.json | 3 + .../js/frappe/data_import/import_preview.js | 58 ++++++++++++++ frappe/public/js/frappe/data_import/index.js | 2 + 6 files changed, 227 insertions(+) create mode 100644 frappe/core/doctype/data_import_beta/data_import_beta.js create mode 100644 frappe/core/doctype/data_import_beta/data_import_beta.json create mode 100644 frappe/core/doctype/data_import_beta/data_import_beta.py create mode 100644 frappe/public/js/frappe/data_import/import_preview.js create mode 100644 frappe/public/js/frappe/data_import/index.js diff --git a/frappe/core/doctype/data_import_beta/data_import_beta.js b/frappe/core/doctype/data_import_beta/data_import_beta.js new file mode 100644 index 0000000000..be9d315dd3 --- /dev/null +++ b/frappe/core/doctype/data_import_beta/data_import_beta.js @@ -0,0 +1,41 @@ +// Copyright (c) 2019, Frappe Technologies and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Data Import Beta', { + refresh(frm) { + frm.trigger('import_file'); + frm.trigger('reference_doctype'); + }, + + reference_doctype(frm) { + // + }, + + download_sample_file(frm) { + frappe.require('/assets/js/data_import_tools.min.js', () => { + new frappe.data_import.DataExporter(frm.doc.reference_doctype); + }); + }, + + import_file(frm) { + if (frm.doc.import_file) { + $('') + .html(__('Loading import file...')) + .appendTo(frm.get_field('import_preview').$wrapper); + + frm.call('get_preview_from_template').then(r => { + let csv_array = r.message; + + frappe.require('/assets/js/data_import_tools.min.js', () => { + new frappe.data_import.ImportPreview( + frm.get_field('import_preview').$wrapper, + csv_array + ); + }); + }); + } else { + frm.get_field('import_preview').$wrapper.empty(); + } + frm.toggle_display('section_import_preview', frm.doc.import_file); + } +}); diff --git a/frappe/core/doctype/data_import_beta/data_import_beta.json b/frappe/core/doctype/data_import_beta/data_import_beta.json new file mode 100644 index 0000000000..8ae8315b33 --- /dev/null +++ b/frappe/core/doctype/data_import_beta/data_import_beta.json @@ -0,0 +1,79 @@ +{ + "beta": 1, + "creation": "2019-08-04 14:16:08.318714", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "reference_doctype", + "download_sample_file", + "import_type", + "import_file", + "section_import_preview", + "import_preview" + ], + "fields": [ + { + "fieldname": "reference_doctype", + "fieldtype": "Link", + "in_list_view": 1, + "label": "Document Type", + "options": "DocType", + "reqd": 1 + }, + { + "fieldname": "import_type", + "fieldtype": "Select", + "in_list_view": 1, + "label": "Import Type", + "options": "Insert new records\nUpdate existing records", + "reqd": 1 + }, + { + "depends_on": "eval:!doc.__islocal", + "fieldname": "import_file", + "fieldtype": "Attach", + "in_list_view": 1, + "label": "Import File" + }, + { + "fieldname": "import_preview", + "fieldtype": "HTML", + "label": "Import Preview" + }, + { + "fieldname": "section_import_preview", + "fieldtype": "Section Break", + "label": "Import Preview" + }, + { + "depends_on": "reference_doctype", + "fieldname": "download_sample_file", + "fieldtype": "Button", + "label": "Download Sample File" + } + ], + "hide_toolbar": 1, + "modified": "2019-08-10 02:08:33.133016", + "modified_by": "Administrator", + "module": "Core", + "name": "Data Import Beta", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/frappe/core/doctype/data_import_beta/data_import_beta.py b/frappe/core/doctype/data_import_beta/data_import_beta.py new file mode 100644 index 0000000000..b4514c2dc9 --- /dev/null +++ b/frappe/core/doctype/data_import_beta/data_import_beta.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2019, Frappe Technologies and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document +from frappe.utils.csvutils import read_csv_content +from frappe.core.doctype.data_import.exporter_new import Exporter + +class DataImportBeta(Document): + + def get_preview_from_template(self): + if not self.import_file: + return + + f = frappe.get_doc('File', { 'file_url': self.import_file }) + file_content = f.get_content() + csv_content = read_csv_content(file_content) + + return csv_content[:100] + + +@frappe.whitelist() +def download_template(doctype, export_fields=None, export_records=None, export_filters=None, file_type='CSV'): + """ + Download template from Exporter + :param doctype: Document Type + :param export_fields=None: Fields to export as dict {'Sales Invoice': ['name', 'customer'], 'Sales Invoice Item': ['item_code']} + :param export_records=None: One of 'all', 'last_10_records', 'by_filter' + :param export_filters: Filter dict + :param file_type: File type to export into + """ + + export_fields = frappe.parse_json(export_fields) + export_filters = frappe.parse_json(export_filters) + + e = Exporter(doctype, + export_fields=export_fields, + export_data=True, + export_filters=export_filters, + file_type=file_type + ) + e.build_csv_response() diff --git a/frappe/public/build.json b/frappe/public/build.json index 2c502c5f72..a88e0f5d54 100755 --- a/frappe/public/build.json +++ b/frappe/public/build.json @@ -325,5 +325,8 @@ ], "js/barcode_scanner.min.js": [ "public/js/frappe/barcode_scanner/quagga.js" + ], + "js/data_import_tools.min.js": [ + "public/js/frappe/data_import/index.js" ] } diff --git a/frappe/public/js/frappe/data_import/import_preview.js b/frappe/public/js/frappe/data_import/import_preview.js new file mode 100644 index 0000000000..eeca9deb3a --- /dev/null +++ b/frappe/public/js/frappe/data_import/import_preview.js @@ -0,0 +1,58 @@ +import DataTable from 'frappe-datatable'; + +frappe.provide('frappe.data_import'); + +frappe.data_import.ImportPreview = class ImportPreview { + constructor(wrapper, csv_array) { + frappe.import_preview = this; + this.wrapper = wrapper; + this.csv_array = csv_array; + + this.prepare_csv_array(); + this.render_datatable(); + } + + prepare_csv_array() { + this.csv_array = this.csv_array.map(row => { + return row.map(cell => { + if (cell == null) { + return ''; + } + return cell; + }); + }); + } + + render_datatable() { + let columns = this.csv_array[0].map(col => { + return { + id: col, + name: col + }; + }); + let data = this.csv_array.slice(1); + this.datatable = new DataTable(this.wrapper.get(0), { + data, + columns, + layout: 'fixed', + cellHeight: 35, + headerDropdown: [ + { + label: __('Change column mapping'), + action: console.log + }, + { + label: __("Don't Import"), + action: console.log + } + ] + }); + + this.datatable.style.setStyle( + '.dt-dropdown__list-item:nth-child(-n+4)', + { + display: 'none' + } + ); + } +}; diff --git a/frappe/public/js/frappe/data_import/index.js b/frappe/public/js/frappe/data_import/index.js new file mode 100644 index 0000000000..626d17c85d --- /dev/null +++ b/frappe/public/js/frappe/data_import/index.js @@ -0,0 +1,2 @@ +import './import_preview'; +import './data_exporter';