def get_template():
    args = webnotes.form_dict
    global doclist
    doclist = webnotes.model.doctype.get("Attendance")

    w = UnicodeWriter()
    w = add_header(w)

    w = add_data(w, args)

    # write out response as a type csv
    webnotes.response["result"] = cstr(w.getvalue())
    webnotes.response["type"] = "csv"
    webnotes.response["doctype"] = "Attendance"
Example #2
0
def get_template():
    args = webnotes.form_dict
    global doclist
    doclist = webnotes.model.doctype.get("Attendance")

    w = UnicodeWriter()
    w = add_header(w)

    w = add_data(w, args)

    # write out response as a type csv
    webnotes.response['result'] = cstr(w.getvalue())
    webnotes.response['type'] = 'csv'
    webnotes.response['doctype'] = "Attendance"
Example #3
0
def get_template():
	if not webnotes.has_permission("Attendance", "create"):
		raise webnotes.PermissionError
	
	args = webnotes.local.form_dict
	webnotes.local.uploadattendance_doclist = webnotes.model.doctype.get("Attendance")

	w = UnicodeWriter()
	w = add_header(w)
	
	w = add_data(w, args)

	# write out response as a type csv
	webnotes.response['result'] = cstr(w.getvalue())
	webnotes.response['type'] = 'csv'
	webnotes.response['doctype'] = "Attendance"
Example #4
0
def get_template():
    if not webnotes.has_permission("Attendance", "create"):
        raise webnotes.PermissionError

    args = webnotes.local.form_dict
    webnotes.local.uploadattendance_doclist = webnotes.model.doctype.get(
        "Attendance")

    w = UnicodeWriter()
    w = add_header(w)

    w = add_data(w, args)

    # write out response as a type csv
    webnotes.response['result'] = cstr(w.getvalue())
    webnotes.response['type'] = 'csv'
    webnotes.response['doctype'] = "Attendance"
def get_template(doctype=None, parent_doctype=None, all_doctypes="No", with_data="No"):
	import webnotes.permissions
	all_doctypes = all_doctypes=="Yes"
	if not parent_doctype:
		parent_doctype = doctype
	
	column_start_end = {}
	
	if all_doctypes:
		doctype_parentfield = {}
		child_doctypes = []
		for d in get_table_fields(doctype):
			child_doctypes.append(d[0])
			doctype_parentfield[d[0]] = d[1]
		
	def add_main_header():
		w.writerow(['Data Import Template'])
		w.writerow([data_keys.main_table, doctype])
		
		if parent_doctype != doctype:
			w.writerow([data_keys.parent_table, parent_doctype])
		else:
			w.writerow([''])

		w.writerow([''])
		w.writerow(['Notes:'])
		w.writerow(['Please do not change the template headings.'])
		w.writerow(['First data column must be blank.'])
		w.writerow(['If you are uploading new records, leave the "name" (ID) column blank.'])
		w.writerow(['If you are uploading new records, "Naming Series" becomes mandatory, if present.'])
		w.writerow(['Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.'])
		w.writerow(['For updating, you can update only selective columns.'])
		w.writerow(['You can only upload upto 5000 records in one go. (may be less in some cases)'])
		if key == "parent":
			w.writerow(['"Parent" signifies the parent table in which this row must be added'])
			w.writerow(['If you are updating, please select "Overwrite" else existing rows will not be deleted.'])

	def build_field_columns(dt):
		doctype_dl = webnotes.model.doctype.get(dt)

		tablecolumns = filter(None, 
			[doctype_dl.get_field(f[0]) for f in webnotes.conn.sql('desc `tab%s`' % dt)])

		tablecolumns.sort(lambda a, b: a.idx - b.idx)

		if dt==doctype:
			column_start_end[dt] = webnotes._dict({"start": 0})
		else:
			column_start_end[dt] = webnotes._dict({"start": len(columns)})
			
			append_field_column(webnotes._dict({
				"fieldname": "name",
				"label": "ID",
				"fieldtype": "Data",
				"reqd": 1,
				"idx": 0,
				"info": "Leave blank for new records"
			}), True)
			
		for docfield in tablecolumns:
			append_field_column(docfield, True)

		# all non mandatory fields
		for docfield in tablecolumns:
			append_field_column(docfield, False)

		# append DocType name
		tablerow[column_start_end[dt].start + 1] = dt
		if dt!=doctype:
			tablerow[column_start_end[dt].start + 2] = doctype_parentfield[dt]

		column_start_end[dt].end = len(columns) + 1
			
	def append_field_column(docfield, mandatory):
		if docfield and ((mandatory and docfield.reqd) or not (mandatory or docfield.reqd)) \
			and (docfield.fieldname not in ('parenttype', 'trash_reason')) and not docfield.hidden:
			tablerow.append("")
			fieldrow.append(docfield.fieldname)
			labelrow.append(docfield.label)
			mandatoryrow.append(docfield.reqd and 'Yes' or 'No')
			typerow.append(docfield.fieldtype)
			inforow.append(getinforow(docfield))
			columns.append(docfield.fieldname)
			
	def append_empty_field_column():
		tablerow.append("~")
		fieldrow.append("~")
		labelrow.append("")
		mandatoryrow.append("")
		typerow.append("")
		inforow.append("")
		columns.append("")

	def getinforow(docfield):
		"""make info comment for options, links etc."""
		if docfield.fieldtype == 'Select':
			if not docfield.options:
				return ''
			elif docfield.options.startswith('link:'):
				return 'Valid %s' % docfield.options[5:]
			else:
				return 'One of: %s' % ', '.join(filter(None, docfield.options.split('\n')))
		elif docfield.fieldtype == 'Link':
			return 'Valid %s' % docfield.options
		elif docfield.fieldtype in ('Int'):
			return 'Integer'
		elif docfield.fieldtype == "Check":
			return "0 or 1"
		elif docfield.info:
			return docfield.info
		else:
			return ''

	def add_field_headings():
		w.writerow(tablerow)
		w.writerow(labelrow)
		w.writerow(fieldrow)
		w.writerow(mandatoryrow)
		w.writerow(typerow)
		w.writerow(inforow)
		w.writerow([data_keys.data_separator])

	def add_data():
		def add_data_row(row_group, dt, doc, rowidx):
			d = doc.copy()
			if all_doctypes:
				d.name = '"'+ d.name+'"'

			if len(row_group) < rowidx + 1:
				row_group.append([""] * (len(columns) + 1))
			row = row_group[rowidx]
			for i, c in enumerate(columns[column_start_end[dt].start:column_start_end[dt].end]):
				row[column_start_end[dt].start + i + 1] = d.get(c, "")

		if with_data=='Yes':
			webnotes.permissions.can_export(parent_doctype, raise_exception=True)
			
			# get permitted data only
			data = reportview.execute(doctype, fields="*")
			for doc in data:
				# add main table
				row_group = []
					
				add_data_row(row_group, doctype, doc, 0)
				
				if all_doctypes:
					# add child tables
					for child_doctype in child_doctypes:
						for ci, child in enumerate(webnotes.conn.sql("""select * from `tab%s` 
							where parent=%s order by idx""" % (child_doctype, "%s"), doc.name, as_dict=1)):
							add_data_row(row_group, child_doctype, child, ci)
					
				for row in row_group:
					w.writerow(row)
	
	w = UnicodeWriter()
	key = 'parent' if parent_doctype != doctype else 'name'
	
	add_main_header()

	w.writerow([''])
	tablerow = [data_keys.doctype, ""]
	labelrow = ["Column Labels:", "ID"]
	fieldrow = [data_keys.columns, key]
	mandatoryrow = ['Mandatory:', 'Yes']
	typerow = ['Type:', 'Data (text)']
	inforow = ['Info:', '']
	columns = [key]

	build_field_columns(doctype)
	if all_doctypes:
		for d in child_doctypes:
			append_empty_field_column()
			build_field_columns(d)
	
	add_field_headings()
	add_data()
	
	# write out response as a type csv
	webnotes.response['result'] = cstr(w.getvalue())
	webnotes.response['type'] = 'csv'
	webnotes.response['doctype'] = doctype
Example #6
0
def get_template(doctype=None,
                 parent_doctype=None,
                 all_doctypes="No",
                 with_data="No"):
    webnotes.check_admin_or_system_manager()
    all_doctypes = all_doctypes == "Yes"
    if not parent_doctype:
        parent_doctype = doctype

    column_start_end = {}

    if all_doctypes:
        doctype_parentfield = {}
        child_doctypes = []
        for d in get_table_fields(doctype):
            child_doctypes.append(d[0])
            doctype_parentfield[d[0]] = d[1]

    def add_main_header():
        w.writerow(['Data Import Template'])
        w.writerow([data_keys.main_table, doctype])

        if parent_doctype != doctype:
            w.writerow([data_keys.parent_table, parent_doctype])
        else:
            w.writerow([''])

        w.writerow([''])
        w.writerow(['Notes:'])
        w.writerow(['Please do not change the template headings.'])
        w.writerow(['First data column must be blank.'])
        w.writerow([
            'If you are uploading new records, leave the "name" (ID) column blank.'
        ])
        w.writerow([
            'If you are uploading new records, "Naming Series" becomes mandatory, if present.'
        ])
        w.writerow([
            'Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.'
        ])
        w.writerow(['For updating, you can update only selective columns.'])
        w.writerow([
            'You can only upload upto 5000 records in one go. (may be less in some cases)'
        ])
        if key == "parent":
            w.writerow([
                '"Parent" signifies the parent table in which this row must be added'
            ])
            w.writerow([
                'If you are updating, please select "Overwrite" else existing rows will not be deleted.'
            ])

    def build_field_columns(dt):
        doctype_dl = webnotes.model.doctype.get(dt)

        tablecolumns = filter(None, [
            doctype_dl.get_field(f[0])
            for f in webnotes.conn.sql('desc `tab%s`' % dt)
        ])

        tablecolumns.sort(lambda a, b: a.idx - b.idx)

        if dt == doctype:
            column_start_end[dt] = webnotes._dict({"start": 0})
        else:
            column_start_end[dt] = webnotes._dict({"start": len(columns)})

            append_field_column(
                webnotes._dict({
                    "fieldname": "name",
                    "label": "ID",
                    "fieldtype": "Data",
                    "reqd": 1,
                    "idx": 0,
                    "info": "Leave blank for new records"
                }), True)

        for docfield in tablecolumns:
            append_field_column(docfield, True)

        # all non mandatory fields
        for docfield in tablecolumns:
            append_field_column(docfield, False)

        # append DocType name
        tablerow[column_start_end[dt].start + 1] = dt
        if dt != doctype:
            tablerow[column_start_end[dt].start + 2] = doctype_parentfield[dt]

        column_start_end[dt].end = len(columns) + 1

    def append_field_column(docfield, mandatory):
        if docfield and ((mandatory and docfield.reqd) or not (mandatory or docfield.reqd)) \
         and (docfield.fieldname not in ('parenttype', 'trash_reason')) and not docfield.hidden:
            tablerow.append("")
            fieldrow.append(docfield.fieldname)
            labelrow.append(docfield.label)
            mandatoryrow.append(docfield.reqd and 'Yes' or 'No')
            typerow.append(docfield.fieldtype)
            inforow.append(getinforow(docfield))
            columns.append(docfield.fieldname)

    def append_empty_field_column():
        tablerow.append("~")
        fieldrow.append("~")
        labelrow.append("")
        mandatoryrow.append("")
        typerow.append("")
        inforow.append("")
        columns.append("")

    def getinforow(docfield):
        """make info comment for options, links etc."""
        if docfield.fieldtype == 'Select':
            if not docfield.options:
                return ''
            elif docfield.options.startswith('link:'):
                return 'Valid %s' % docfield.options[5:]
            else:
                return 'One of: %s' % ', '.join(
                    filter(None, docfield.options.split('\n')))
        elif docfield.fieldtype == 'Link':
            return 'Valid %s' % docfield.options
        elif docfield.fieldtype in ('Int'):
            return 'Integer'
        elif docfield.fieldtype == "Check":
            return "0 or 1"
        elif docfield.info:
            return docfield.info
        else:
            return ''

    def add_field_headings():
        w.writerow(tablerow)
        w.writerow(labelrow)
        w.writerow(fieldrow)
        w.writerow(mandatoryrow)
        w.writerow(typerow)
        w.writerow(inforow)
        w.writerow([data_keys.data_separator])

    def add_data():
        def add_data_row(row_group, dt, doc, rowidx):
            d = doc.copy()
            if all_doctypes:
                d.name = '"' + d.name + '"'

            if len(row_group) < rowidx + 1:
                row_group.append([""] * (len(columns) + 1))
            row = row_group[rowidx]
            for i, c in enumerate(columns[column_start_end[dt].
                                          start:column_start_end[dt].end]):
                row[column_start_end[dt].start + i + 1] = d.get(c, "")

        if with_data == 'Yes':
            data = webnotes.conn.sql("""select * from `tab%s` where docstatus<2""" \
             % doctype, as_dict=1)
            for doc in data:
                # add main table
                row_group = []

                add_data_row(row_group, doctype, doc, 0)

                if all_doctypes:
                    # add child tables
                    for child_doctype in child_doctypes:
                        for ci, child in enumerate(
                                webnotes.conn.sql("""select * from `tab%s` 
							where parent=%s order by idx""" % (child_doctype, "%s"),
                                                  doc.name,
                                                  as_dict=1)):
                            add_data_row(row_group, child_doctype, child, ci)

                for row in row_group:
                    w.writerow(row)

    w = UnicodeWriter()
    key = 'parent' if parent_doctype != doctype else 'name'

    add_main_header()

    w.writerow([''])
    tablerow = [data_keys.doctype, ""]
    labelrow = ["Column Labels:", "ID"]
    fieldrow = [data_keys.columns, key]
    mandatoryrow = ['Mandatory:', 'Yes']
    typerow = ['Type:', 'Data (text)']
    inforow = ['Info:', '']
    columns = [key]

    build_field_columns(doctype)
    if all_doctypes:
        for d in child_doctypes:
            append_empty_field_column()
            build_field_columns(d)

    add_field_headings()
    add_data()

    # write out response as a type csv
    webnotes.response['result'] = cstr(w.getvalue())
    webnotes.response['type'] = 'csv'
    webnotes.response['doctype'] = doctype
Example #7
0
def get_template():
	doctype = webnotes.form_dict['doctype']
	parenttype = webnotes.form_dict.get('parent_doctype')
	
	doctype_dl = webnotes.model.doctype.get(doctype)
	tablecolumns = [f[0] for f in webnotes.conn.sql('desc `tab%s`' % doctype)]
	
	def getinforow(docfield):
		"""make info comment"""
		if docfield.fieldtype == 'Select':
			if not docfield.options:
				return ''
			elif docfield.options.startswith('link:'):
				return 'Valid %s' % docfield.options[5:]
			else:
				return 'One of: %s' % ', '.join(filter(None, docfield.options.split('\n')))
		if docfield.fieldtype == 'Link':
			return 'Valid %s' % docfield.options
		if docfield.fieldtype in ('Int'):
			return 'Integer'
		if docfield.fieldtype == "Check":
			return "0 or 1"
		else:
			return ''
			
	w = UnicodeWriter()
	key = 'name'

	w.writerow(['Data Import Template'])	
	w.writerow([data_keys.main_table, doctype])
	
	if parenttype != doctype:
		w.writerow([data_keys.parent_table, parenttype])
		key = 'parent'
	else:
		w.writerow([''])
	
	w.writerow([''])
	w.writerow(['Notes:'])
	w.writerow(['Please do not change the template headings.'])
	w.writerow(['First data column must be blank.'])
	w.writerow(['Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.'])
	w.writerow(['For updating, you can update only selective columns.'])
	w.writerow(['If you are uploading new records, leave the "name" (ID) column blank.'])
	w.writerow(['If you are uploading new records, "Naming Series" becomes mandatory, if present.'])
	w.writerow(['You can only upload upto 5000 records in one go. (may be less in some cases)'])
	if key == "parent":
		w.writerow(['"Parent" signifies the parent table in which this row must be added'])
		w.writerow(['If you are updating, please select "Overwrite" else existing rows will not be deleted.'])
	w.writerow([''])
	labelrow = ["Column Labels", "ID"]
	fieldrow = [data_keys.columns, key]
	mandatoryrow = ['Mandatory:', 'Yes']
	typerow = ['Type:', 'Data (text)']
	inforow = ['Info:', '']
	columns = [key]
	
	def append_row(t, mandatory):
		docfield = doctype_dl.get_field(t)
		
		if docfield and ((mandatory and docfield.reqd) or not (mandatory or docfield.reqd)) \
			and (t not in ('parenttype', 'trash_reason')) and not docfield.hidden:
			fieldrow.append(t)
			labelrow.append(docfield.label)
			mandatoryrow.append(docfield.reqd and 'Yes' or 'No')
			typerow.append(docfield.fieldtype)
			inforow.append(getinforow(docfield))
			columns.append(t)
	
	# get all mandatory fields
	for t in tablecolumns:
		append_row(t, True)

	# all non mandatory fields
	for t in tablecolumns:
		append_row(t, False)

	w.writerow(labelrow)
	w.writerow(fieldrow)
	w.writerow(mandatoryrow)
	w.writerow(typerow)
	w.writerow(inforow)
	
	w.writerow([data_keys.data_separator])

	if webnotes.form_dict.get('with_data')=='Yes':
		data = webnotes.conn.sql("""select * from `tab%s` where docstatus<2""" % doctype, as_dict=1)
		for d in data:
			row = [""]
			for c in columns:
				row.append(d.get(c, ""))
			w.writerow(row)

	# write out response as a type csv
	webnotes.response['result'] = cstr(w.getvalue())
	webnotes.response['type'] = 'csv'
	webnotes.response['doctype'] = doctype
Example #8
0
def get_template():
    doctype = webnotes.form_dict['doctype']
    parenttype = webnotes.form_dict.get('parent_doctype')

    doctype_dl = webnotes.model.doctype.get(doctype)
    tablecolumns = [f[0] for f in webnotes.conn.sql('desc `tab%s`' % doctype)]

    def getinforow(docfield):
        """make info comment"""
        if docfield.fieldtype == 'Select':
            if not docfield.options:
                return ''
            elif docfield.options.startswith('link:'):
                return 'Valid %s' % docfield.options[5:]
            else:
                return 'One of: %s' % ', '.join(
                    filter(None, docfield.options.split('\n')))
        if docfield.fieldtype == 'Link':
            return 'Valid %s' % docfield.options
        if docfield.fieldtype in ('Int'):
            return 'Integer'
        if docfield.fieldtype == "Check":
            return "0 or 1"
        else:
            return ''

    w = UnicodeWriter()
    key = 'name'

    w.writerow(['Data Import Template'])
    w.writerow([data_keys.main_table, doctype])

    if parenttype != doctype:
        w.writerow([data_keys.parent_table, parenttype])
        key = 'parent'
    else:
        w.writerow([''])

    w.writerow([''])
    w.writerow(['Notes:'])
    w.writerow(['Please do not change the template headings.'])
    w.writerow(['First data column must be blank.'])
    w.writerow([
        'Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish.'
    ])
    w.writerow(['For updating, you can update only selective columns.'])
    w.writerow([
        'If you are uploading new records, leave the "name" (ID) column blank.'
    ])
    w.writerow([
        'If you are uploading new records, "Naming Series" becomes mandatory, if present.'
    ])
    w.writerow([
        'You can only upload upto 5000 records in one go. (may be less in some cases)'
    ])
    if key == "parent":
        w.writerow([
            '"Parent" signifies the parent table in which this row must be added'
        ])
        w.writerow([
            'If you are updating, please select "Overwrite" else existing rows will not be deleted.'
        ])
    w.writerow([''])
    labelrow = ["Column Labels", "ID"]
    fieldrow = [data_keys.columns, key]
    mandatoryrow = ['Mandatory:', 'Yes']
    typerow = ['Type:', 'Data (text)']
    inforow = ['Info:', '']
    columns = [key]

    def append_row(t, mandatory):
        docfield = doctype_dl.get_field(t)

        if docfield and ((mandatory and docfield.reqd) or not (mandatory or docfield.reqd)) \
         and (t not in ('parenttype', 'trash_reason')) and not docfield.hidden:
            fieldrow.append(t)
            labelrow.append(docfield.label)
            mandatoryrow.append(docfield.reqd and 'Yes' or 'No')
            typerow.append(docfield.fieldtype)
            inforow.append(getinforow(docfield))
            columns.append(t)

    # get all mandatory fields
    for t in tablecolumns:
        append_row(t, True)

    # all non mandatory fields
    for t in tablecolumns:
        append_row(t, False)

    w.writerow(labelrow)
    w.writerow(fieldrow)
    w.writerow(mandatoryrow)
    w.writerow(typerow)
    w.writerow(inforow)

    w.writerow([data_keys.data_separator])

    if webnotes.form_dict.get('with_data') == 'Yes':
        data = webnotes.conn.sql(
            """select * from `tab%s` where docstatus<2""" % doctype, as_dict=1)
        for d in data:
            row = [""]
            for c in columns:
                row.append(d.get(c, ""))
            w.writerow(row)

    # write out response as a type csv
    webnotes.response['result'] = cstr(w.getvalue())
    webnotes.response['type'] = 'csv'
    webnotes.response['doctype'] = doctype
def get_template():
    webnotes.check_admin_or_system_manager()
    doctype = webnotes.form_dict.doctype
    parenttype = webnotes.form_dict.parent_doctype
    all_doctypes = webnotes.form_dict.all_doctypes == "Yes"
    with_data = webnotes.form_dict.with_data
    column_start_end = {}

    if all_doctypes:
        doctype_parentfield = {}
        child_doctypes = []
        for d in get_table_fields(doctype):
            child_doctypes.append(d[0])
            doctype_parentfield[d[0]] = d[1]

    def add_main_header():
        w.writerow(["Data Import Template"])
        w.writerow([data_keys.main_table, doctype])

        if parenttype != doctype:
            w.writerow([data_keys.parent_table, parenttype])
        else:
            w.writerow([""])

        w.writerow([""])
        w.writerow(["Notes:"])
        w.writerow(["Please do not change the template headings."])
        w.writerow(["First data column must be blank."])
        w.writerow(['If you are uploading new records, leave the "name" (ID) column blank.'])
        w.writerow(['If you are uploading new records, "Naming Series" becomes mandatory, if present.'])
        w.writerow(
            ["Only mandatory fields are necessary for new records. You can delete non-mandatory columns if you wish."]
        )
        w.writerow(["For updating, you can update only selective columns."])
        w.writerow(["You can only upload upto 5000 records in one go. (may be less in some cases)"])
        if key == "parent":
            w.writerow(['"Parent" signifies the parent table in which this row must be added'])
            w.writerow(['If you are updating, please select "Overwrite" else existing rows will not be deleted.'])

    def build_field_columns(dt):
        doctype_dl = webnotes.model.doctype.get(dt)

        tablecolumns = filter(None, [doctype_dl.get_field(f[0]) for f in webnotes.conn.sql("desc `tab%s`" % dt)])

        tablecolumns.sort(lambda a, b: a.idx - b.idx)

        if dt == doctype:
            column_start_end[dt] = webnotes._dict({"start": 0})

            if all_doctypes and with_data:
                append_field_column(
                    webnotes._dict(
                        {
                            "fieldname": "modified",
                            "label": "Last Updated On",
                            "fieldtype": "Data",
                            "reqd": 1,
                            "idx": 0,
                            "info": "Don't change!",
                        }
                    ),
                    True,
                )

        else:
            column_start_end[dt] = webnotes._dict({"start": len(columns)})

            append_field_column(
                webnotes._dict(
                    {
                        "fieldname": "name",
                        "label": "ID",
                        "fieldtype": "Data",
                        "reqd": 1,
                        "idx": 0,
                        "info": "Leave blank for new records",
                    }
                ),
                True,
            )

        for docfield in tablecolumns:
            append_field_column(docfield, True)

            # all non mandatory fields
        for docfield in tablecolumns:
            append_field_column(docfield, False)

            # append DocType name
        tablerow[column_start_end[dt].start + 1] = dt
        if dt != doctype:
            tablerow[column_start_end[dt].start + 2] = doctype_parentfield[dt]

        column_start_end[dt].end = len(columns) + 1

    def append_field_column(docfield, mandatory):
        if (
            docfield
            and ((mandatory and docfield.reqd) or not (mandatory or docfield.reqd))
            and (docfield.fieldname not in ("parenttype", "trash_reason"))
            and not docfield.hidden
        ):
            tablerow.append("")
            fieldrow.append(docfield.fieldname)
            labelrow.append(docfield.label)
            mandatoryrow.append(docfield.reqd and "Yes" or "No")
            typerow.append(docfield.fieldtype)
            inforow.append(getinforow(docfield))
            columns.append(docfield.fieldname)

    def append_empty_field_column():
        tablerow.append("~")
        fieldrow.append("~")
        labelrow.append("")
        mandatoryrow.append("")
        typerow.append("")
        inforow.append("")
        columns.append("")

    def getinforow(docfield):
        """make info comment for options, links etc."""
        if docfield.fieldtype == "Select":
            if not docfield.options:
                return ""
            elif docfield.options.startswith("link:"):
                return "Valid %s" % docfield.options[5:]
            else:
                return "One of: %s" % ", ".join(filter(None, docfield.options.split("\n")))
        elif docfield.fieldtype == "Link":
            return "Valid %s" % docfield.options
        elif docfield.fieldtype in ("Int"):
            return "Integer"
        elif docfield.fieldtype == "Check":
            return "0 or 1"
        elif docfield.info:
            return docfield.info
        else:
            return ""

    def add_field_headings():
        w.writerow(tablerow)
        w.writerow(labelrow)
        w.writerow(fieldrow)
        w.writerow(mandatoryrow)
        w.writerow(typerow)
        w.writerow(inforow)
        w.writerow([data_keys.data_separator])

    def add_data():
        def add_data_row(row_group, dt, d, rowidx):
            if len(row_group) < rowidx + 1:
                row_group.append([""] * (len(columns) + 1))
            row = row_group[rowidx]
            for i, c in enumerate(columns[column_start_end[dt].start : column_start_end[dt].end]):
                row[column_start_end[dt].start + i + 1] = d.get(c, "")

        if with_data == "Yes":
            data = webnotes.conn.sql("""select * from `tab%s` where docstatus<2""" % doctype, as_dict=1)
            for doc in data:
                # add main table
                row_group = []
                if all_doctypes:
                    doc.modified = '"' + doc.modified + '"'

                add_data_row(row_group, doctype, doc, 0)

                if all_doctypes:
                    # add child tables
                    for child_doctype in child_doctypes:
                        for ci, child in enumerate(
                            webnotes.conn.sql(
                                """select * from `tab%s` 
							where parent=%s order by idx"""
                                % (child_doctype, "%s"),
                                doc.name,
                                as_dict=1,
                            )
                        ):
                            add_data_row(row_group, child_doctype, child, ci)

                for row in row_group:
                    w.writerow(row)

    w = UnicodeWriter()
    key = "parent" if parenttype != doctype else "name"

    add_main_header()

    w.writerow([""])
    tablerow = [data_keys.doctype, ""]
    labelrow = ["Column Labels:", "ID"]
    fieldrow = [data_keys.columns, key]
    mandatoryrow = ["Mandatory:", "Yes"]
    typerow = ["Type:", "Data (text)"]
    inforow = ["Info:", ""]
    columns = [key]

    build_field_columns(doctype)
    if all_doctypes:
        for d in child_doctypes:
            append_empty_field_column()
            build_field_columns(d)

    add_field_headings()
    add_data()

    # write out response as a type csv
    webnotes.response["result"] = cstr(w.getvalue())
    webnotes.response["type"] = "csv"
    webnotes.response["doctype"] = doctype