Ejemplo n.º 1
0
def upload(select_doctype=None, rows=None):
	from frappe.utils.datautils import read_csv_content_from_uploaded_file
	from frappe.model.rename_doc import rename_doc

	if not select_doctype:
		select_doctype = frappe.form_dict.select_doctype

	if not frappe.has_permission(select_doctype, "write"):
		raise frappe.PermissionError

	if not rows:
		rows = read_csv_content_from_uploaded_file()
	if not rows:
		frappe.throw(_("Please select a valid csv file with data"))

	max_rows = 500
	if len(rows) > max_rows:
		frappe.throw(_("Maximum {0} rows allowed").format(max_rows))

	rename_log = []
	for row in rows:
		# if row has some content
		if len(row) > 1 and row[0] and row[1]:
			try:
				if rename_doc(select_doctype, row[0], row[1]):
					rename_log.append(_("Successful: ") + row[0] + " -> " + row[1])
					frappe.db.commit()
				else:
					rename_log.append(_("Ignored: ") + row[0] + " -> " + row[1])
			except Exception, e:
				rename_log.append("<span style='color: RED'>" + \
					_("Failed: ") + row[0] + " -> " + row[1] + "</span>")
				rename_log.append("<span style='margin-left: 20px;'>" + repr(e) + "</span>")
Ejemplo n.º 2
0
def upload():
	if not frappe.has_permission("Attendance", "create"):
		raise frappe.PermissionError

	from frappe.utils.datautils import read_csv_content_from_uploaded_file
	from frappe.modules import scrub

	rows = read_csv_content_from_uploaded_file()
	if not rows:
		msg = [_("Please select a csv file")]
		return {"messages": msg, "error": msg}
	columns = [scrub(f) for f in rows[4]]
	columns[0] = "name"
	columns[3] = "att_date"
	ret = []
	error = False

	from frappe.utils.datautils import check_record, import_doc

	for i, row in enumerate(rows[5:]):
		if not row: continue
		row_idx = i + 5
		d = frappe._dict(zip(columns, row))
		d["doctype"] = "Attendance"
		if d.name:
			d["docstatus"] = frappe.db.get_value("Attendance", d.name, "docstatus")

		try:
			check_record(d)
			ret.append(import_doc(d, "Attendance", 1, row_idx, submit=True))
		except Exception, e:
			error = True
			ret.append('Error for row (#%d) %s : %s' % (row_idx,
				len(row)>1 and row[1] or "", cstr(e)))
			frappe.errprint(frappe.get_traceback())
Ejemplo n.º 3
0
def import_user_permissions():
	frappe.only_for("System Manager")
	rows = read_csv_content_from_uploaded_file(ignore_encoding=True)
	clear_default(parenttype="User Permission")

	if rows[0][0]!="User Permissions" and rows[1][0] != "User":
		frappe.throw(frappe._("Please upload using the same template as download."))

	for row in rows[2:]:
		frappe.permissions.add_user_permission(row[1], row[2], row[0])
Ejemplo n.º 4
0
def upload(select_doctype=None, rows=None):
    from frappe.utils.datautils import read_csv_content_from_uploaded_file
    from frappe.modules import scrub
    from frappe.model.rename_doc import rename_doc

    if not select_doctype:
        select_doctype = frappe.form_dict.select_doctype

    if not frappe.has_permission(select_doctype, "write"):
        raise frappe.PermissionError

    if not rows:
        rows = read_csv_content_from_uploaded_file()
    if not rows:
        frappe.msgprint(_("Please select a valid csv file with data."))
        raise Exception

    if len(rows) > 500:
        frappe.msgprint(_("Max 500 rows only."))
        raise Exception

    rename_log = []
    for row in rows:
        # if row has some content
        if len(row) > 1 and row[0] and row[1]:
            try:
                if rename_doc(select_doctype, row[0], row[1]):
                    rename_log.append(
                        _("Successful: ") + row[0] + " -> " + row[1])
                    frappe.db.commit()
                else:
                    rename_log.append(
                        _("Ignored: ") + row[0] + " -> " + row[1])
            except Exception, e:
                rename_log.append("<span style='color: RED'>" + \
                 _("Failed: ") + row[0] + " -> " + row[1] + "</span>")
                rename_log.append("<span style='margin-left: 20px;'>" +
                                  repr(e) + "</span>")
Ejemplo n.º 5
0
def upload():
    if not frappe.has_permission("Attendance", "create"):
        raise frappe.PermissionError

    from frappe.utils.datautils import read_csv_content_from_uploaded_file
    from frappe.modules import scrub

    rows = read_csv_content_from_uploaded_file()
    if not rows:
        msg = [_("Please select a csv file")]
        return {"messages": msg, "error": msg}
    columns = [scrub(f) for f in rows[4]]
    columns[0] = "name"
    columns[3] = "att_date"
    ret = []
    error = False

    from frappe.utils.datautils import check_record, import_doc

    for i, row in enumerate(rows[5:]):
        if not row: continue
        row_idx = i + 5
        d = frappe._dict(zip(columns, row))
        d["doctype"] = "Attendance"
        if d.name:
            d["docstatus"] = frappe.db.get_value("Attendance", d.name,
                                                 "docstatus")

        try:
            check_record(d)
            ret.append(import_doc(d, "Attendance", 1, row_idx, submit=True))
        except Exception, e:
            error = True
            ret.append('Error for row (#%d) %s : %s' %
                       (row_idx, len(row) > 1 and row[1] or "", cstr(e)))
            frappe.errprint(frappe.get_traceback())
Ejemplo n.º 6
0
def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, overwrite=None, ignore_links=False):
	"""upload data"""
	frappe.flags.mute_emails = True
	# extra input params
	params = json.loads(frappe.form_dict.get("params") or '{}')

	if params.get("_submit"):
		submit_after_import = True
	if params.get("ignore_encoding_errors"):
		ignore_encoding_errors = True

	from frappe.utils.datautils import read_csv_content_from_uploaded_file

	def bad_template():
		frappe.throw(_("Please do not change the rows above {0}").format(data_keys.data_separator))

	def check_data_length():
		max_rows = 5000
		if not data:
			frappe.throw(_("No data found"))
		elif len(data) > max_rows:
			frappe.throw(_("Only allowed {0} rows in one import").format(max_rows))

	def get_start_row():
		for i, row in enumerate(rows):
			if row and row[0]==data_keys.data_separator:
				return i+1
		bad_template()

	def get_header_row(key):
		return get_header_row_and_idx(key)[0]

	def get_header_row_and_idx(key):
		for i, row in enumerate(header):
			if row and row[0]==key:
				return row, i
		return [], -1

	def filter_empty_columns(columns):
		empty_cols = filter(lambda x: x in ("", None), columns)

		if empty_cols:
			if columns[-1*len(empty_cols):] == empty_cols:
				# filter empty columns if they exist at the end
				columns = columns[:-1*len(empty_cols)]
			else:
				frappe.msgprint(_("Please make sure that there are no empty columns in the file."),
					raise_exception=1)

		return columns

	def make_column_map():
		doctype_row, row_idx = get_header_row_and_idx(data_keys.doctype)
		if row_idx == -1: # old style
			return

		dt = None
		for i, d in enumerate(doctype_row[1:]):
			if d not in ("~", "-"):
				if d: # value in doctype_row
					if doctype_row[i]==dt:
						# prev column is doctype (in case of parentfield)
						doctype_parentfield[dt] = doctype_row[i+1]
					else:
						dt = d
						doctypes.append(d)
						column_idx_to_fieldname[dt] = {}
						column_idx_to_fieldtype[dt] = {}
				if dt:
					column_idx_to_fieldname[dt][i+1] = rows[row_idx + 2][i+1]
					column_idx_to_fieldtype[dt][i+1] = rows[row_idx + 4][i+1]

	def get_doc(start_idx):
		if doctypes:
			doc = {}
			for idx in xrange(start_idx, len(rows)):
				if (not doc) or main_doc_empty(rows[idx]):
					for dt in doctypes:
						d = {}
						for column_idx in column_idx_to_fieldname[dt]:
							try:
								fieldname = column_idx_to_fieldname[dt][column_idx]
								fieldtype = column_idx_to_fieldtype[dt][column_idx]

								d[fieldname] = rows[idx][column_idx]
								if fieldtype in ("Int", "Check"):
									d[fieldname] = cint(d[fieldname])
								elif fieldtype in ("Float", "Currency"):
									d[fieldname] = flt(d[fieldname])
								elif fieldtype == "Date":
									d[fieldname] = parse_date(d[fieldname]) if d[fieldname] else None
							except IndexError:
								pass

						# scrub quotes from name and modified
						if d.get("name") and d["name"].startswith('"'):
							d["name"] = d["name"][1:-1]

						if sum([0 if not val else 1 for val in d.values()]):
							d['doctype'] = dt
							if dt == doctype:
								doc.update(d)
							else:
								if not overwrite:
									d['parent'] = doc["name"]
								d['parenttype'] = doctype
								d['parentfield'] = doctype_parentfield[dt]
								doc.setdefault(d['parentfield'], []).append(d)
				else:
					break

			return doc
		else:
			doc = frappe._dict(zip(columns, rows[start_idx][1:]))
			doc['doctype'] = doctype
			return doc

	def main_doc_empty(row):
		return not (row and ((len(row) > 1 and row[1]) or (len(row) > 2 and row[2])))

	# header
	if not rows:
		rows = read_csv_content_from_uploaded_file(ignore_encoding_errors)
	start_row = get_start_row()
	header = rows[:start_row]
	data = rows[start_row:]
	doctype = get_header_row(data_keys.main_table)[1]
	columns = filter_empty_columns(get_header_row(data_keys.columns)[1:])
	doctypes = []
	doctype_parentfield = {}
	column_idx_to_fieldname = {}
	column_idx_to_fieldtype = {}

	if submit_after_import and not cint(frappe.db.get_value("DocType",
			doctype, "is_submittable")):
		submit_after_import = False

	parenttype = get_header_row(data_keys.parent_table)

	if len(parenttype) > 1:
		parenttype = parenttype[1]

	# check permissions
	if not frappe.permissions.can_import(parenttype or doctype):
		frappe.flags.mute_emails = False
		return {"messages": [_("Not allowed to Import") + ": " + _(doctype)], "error": True}

	# allow limit rows to be uploaded
	check_data_length()
	make_column_map()

	frappe.db.begin()
	if overwrite==None:
		overwrite = params.get('overwrite')

	# delete child rows (if parenttype)
	if parenttype and overwrite:
		delete_child_rows(data, doctype)

	ret = []
	error = False
	for i, row in enumerate(data):
		# bypass empty rows
		if main_doc_empty(row):
			continue

		row_idx = i + start_row
		doc = None

		doc = get_doc(row_idx)
		if doc.get("name"):
			doc["_new_name_set"] = True

		try:
			frappe.local.message_log = []
			if doc.get("parentfield"):
				parent = frappe.get_doc(doc["parenttype"], doc["parentfield"])
				parent.append(doc)
				parent.save()
				ret.append('Inserted row for %s at #%s' % (getlink(parenttype,
					doc.parent), unicode(doc.idx)))

			else:
				if overwrite and frappe.db.exists(doctype, doc["name"]):
					original = frappe.get_doc(doctype, doc["name"])
					original.update(doc)
					original.ignore_links = ignore_links
					original.save()
					ret.append('Updated row (#%d) %s' % (row_idx + 1, getlink(original.doctype, original.name)))
				else:
					doc = frappe.get_doc(doc)
					doc.ignore_links = ignore_links
					doc.insert()
					ret.append('Inserted row (#%d) %s' % (row_idx + 1, getlink(doc.doctype, doc.name)))
				if submit_after_import:
					doc.submit()
					ret.append('Submitted row (#%d) %s' % (row_idx + 1, getlink(doc.doctype, doc.name)))
		except Exception, e:
			error = True
			if doc:
				frappe.errprint(doc if isinstance(doc, dict) else doc.as_dict())
			err_msg = frappe.local.message_log and "<br>".join(frappe.local.message_log) or cstr(e)
			ret.append('Error for row (#%d) %s : %s' % (row_idx + 1,
				len(row)>1 and row[1] or "", err_msg))
			frappe.errprint(frappe.get_traceback())
Ejemplo n.º 7
0
def upload():
	from frappe.utils.datautils import read_csv_content_from_uploaded_file
	return read_csv_content_from_uploaded_file()
Ejemplo n.º 8
0
def upload(rows=None,
           submit_after_import=None,
           ignore_encoding_errors=False,
           overwrite=None,
           ignore_links=False):
    """upload data"""
    frappe.flags.mute_emails = True
    # extra input params
    params = json.loads(frappe.form_dict.get("params") or '{}')

    if params.get("_submit"):
        submit_after_import = True
    if params.get("ignore_encoding_errors"):
        ignore_encoding_errors = True

    from frappe.utils.datautils import read_csv_content_from_uploaded_file

    def bad_template():
        frappe.throw(
            _("Please do not change the rows above {0}").format(
                data_keys.data_separator))

    def check_data_length():
        max_rows = 5000
        if not data:
            frappe.throw(_("No data found"))
        elif len(data) > max_rows:
            frappe.throw(
                _("Only allowed {0} rows in one import").format(max_rows))

    def get_start_row():
        for i, row in enumerate(rows):
            if row and row[0] == data_keys.data_separator:
                return i + 1
        bad_template()

    def get_header_row(key):
        return get_header_row_and_idx(key)[0]

    def get_header_row_and_idx(key):
        for i, row in enumerate(header):
            if row and row[0] == key:
                return row, i
        return [], -1

    def filter_empty_columns(columns):
        empty_cols = filter(lambda x: x in ("", None), columns)

        if empty_cols:
            if columns[-1 * len(empty_cols):] == empty_cols:
                # filter empty columns if they exist at the end
                columns = columns[:-1 * len(empty_cols)]
            else:
                frappe.msgprint(_(
                    "Please make sure that there are no empty columns in the file."
                ),
                                raise_exception=1)

        return columns

    def make_column_map():
        doctype_row, row_idx = get_header_row_and_idx(data_keys.doctype)
        if row_idx == -1:  # old style
            return

        dt = None
        for i, d in enumerate(doctype_row[1:]):
            if d not in ("~", "-"):
                if d:  # value in doctype_row
                    if doctype_row[i] == dt:
                        # prev column is doctype (in case of parentfield)
                        doctype_parentfield[dt] = doctype_row[i + 1]
                    else:
                        dt = d
                        doctypes.append(d)
                        column_idx_to_fieldname[dt] = {}
                        column_idx_to_fieldtype[dt] = {}
                if dt:
                    column_idx_to_fieldname[dt][i + 1] = rows[row_idx + 2][i +
                                                                           1]
                    column_idx_to_fieldtype[dt][i + 1] = rows[row_idx + 4][i +
                                                                           1]

    def get_doc(start_idx):
        if doctypes:
            doc = {}
            for idx in xrange(start_idx, len(rows)):
                if (not doc) or main_doc_empty(rows[idx]):
                    for dt in doctypes:
                        d = {}
                        for column_idx in column_idx_to_fieldname[dt]:
                            try:
                                fieldname = column_idx_to_fieldname[dt][
                                    column_idx]
                                fieldtype = column_idx_to_fieldtype[dt][
                                    column_idx]

                                d[fieldname] = rows[idx][column_idx]
                                if fieldtype in ("Int", "Check"):
                                    d[fieldname] = cint(d[fieldname])
                                elif fieldtype in ("Float", "Currency"):
                                    d[fieldname] = flt(d[fieldname])
                                elif fieldtype == "Date":
                                    d[fieldname] = parse_date(
                                        d[fieldname]) if d[fieldname] else None
                            except IndexError:
                                pass

                        # scrub quotes from name and modified
                        if d.get("name") and d["name"].startswith('"'):
                            d["name"] = d["name"][1:-1]

                        if sum([0 if not val else 1 for val in d.values()]):
                            d['doctype'] = dt
                            if dt == doctype:
                                doc.update(d)
                            else:
                                if not overwrite:
                                    d['parent'] = doc["name"]
                                d['parenttype'] = doctype
                                d['parentfield'] = doctype_parentfield[dt]
                                doc.setdefault(d['parentfield'], []).append(d)
                else:
                    break

            return doc
        else:
            doc = frappe._dict(zip(columns, rows[start_idx][1:]))
            doc['doctype'] = doctype
            return doc

    def main_doc_empty(row):
        return not (row and ((len(row) > 1 and row[1]) or
                             (len(row) > 2 and row[2])))

    # header
    if not rows:
        rows = read_csv_content_from_uploaded_file(ignore_encoding_errors)
    start_row = get_start_row()
    header = rows[:start_row]
    data = rows[start_row:]
    doctype = get_header_row(data_keys.main_table)[1]
    columns = filter_empty_columns(get_header_row(data_keys.columns)[1:])
    doctypes = []
    doctype_parentfield = {}
    column_idx_to_fieldname = {}
    column_idx_to_fieldtype = {}

    if submit_after_import and not cint(
            frappe.db.get_value("DocType", doctype, "is_submittable")):
        submit_after_import = False

    parenttype = get_header_row(data_keys.parent_table)

    if len(parenttype) > 1:
        parenttype = parenttype[1]

    # check permissions
    if not frappe.permissions.can_import(parenttype or doctype):
        frappe.flags.mute_emails = False
        return {
            "messages": [_("Not allowed to Import") + ": " + _(doctype)],
            "error": True
        }

    # allow limit rows to be uploaded
    check_data_length()
    make_column_map()

    frappe.db.begin()
    if overwrite == None:
        overwrite = params.get('overwrite')

    # delete child rows (if parenttype)
    if parenttype and overwrite:
        delete_child_rows(data, doctype)

    ret = []
    error = False
    for i, row in enumerate(data):
        # bypass empty rows
        if main_doc_empty(row):
            continue

        row_idx = i + start_row
        doc = None

        doc = get_doc(row_idx)
        try:
            frappe.local.message_log = []
            if doc.get("parentfield"):
                parent = frappe.get_doc(doc["parenttype"], doc["parentfield"])
                parent.append(doc)
                parent.save()
                ret.append('Inserted row for %s at #%s' %
                           (getlink(parenttype, doc.parent), unicode(doc.idx)))

            else:
                if overwrite and frappe.db.exists(doctype, doc["name"]):
                    original = frappe.get_doc(doctype, doc["name"])
                    original.update(doc)
                    original.ignore_links = ignore_links
                    original.save()
                    ret.append('Updated row (#%d) %s' %
                               (row_idx + 1,
                                getlink(original.doctype, original.name)))
                else:
                    doc = frappe.get_doc(doc)
                    doc.ignore_links = ignore_links
                    doc.insert()
                    ret.append('Inserted row (#%d) %s' %
                               (row_idx + 1, getlink(doc.doctype, doc.name)))
                if submit_after_import:
                    doc.submit()
                    ret.append('Submitted row (#%d) %s' %
                               (row_idx + 1, getlink(doc.doctype, doc.name)))
        except Exception, e:
            error = True
            if doc:
                frappe.errprint(
                    doc if isinstance(doc, dict) else doc.as_dict())
            err_msg = frappe.local.message_log and "<br>".join(
                frappe.local.message_log) or cstr(e)
            ret.append('Error for row (#%d) %s : %s' %
                       (row_idx + 1, len(row) > 1 and row[1] or "", err_msg))
            frappe.errprint(frappe.get_traceback())
Ejemplo n.º 9
0
                else:
                    break

            return doclist
        else:
            d = frappe._dict(zip(columns, rows[start_idx][1:]))
            d['doctype'] = doctype
            return [d]

    def main_doc_empty(row):
        return not (row and ((len(row) > 1 and row[1]) or
                             (len(row) > 2 and row[2])))

    # header
    if not rows:
        rows = read_csv_content_from_uploaded_file(ignore_encoding_errors)
    start_row = get_start_row()
    header = rows[:start_row]
    data = rows[start_row:]
    doctype = get_header_row(data_keys.main_table)[1]
    columns = filter_empty_columns(get_header_row(data_keys.columns)[1:])
    doctypes = []
    doctype_parentfield = {}
    column_idx_to_fieldname = {}
    column_idx_to_fieldtype = {}

    if submit_after_import and not cint(
            frappe.db.get_value("DocType", doctype, "is_submittable")):
        submit_after_import = False

    parenttype = get_header_row(data_keys.parent_table)