Beispiel #1
0
def save_and_attach(content,
                    to_doctype,
                    to_name,
                    folder,
                    hashname=None,
                    is_private=1):
    """
    Save content to disk and create a File document.
    File document is linked to another document.
    """
    if not hashname:
        file_name = "{0}.pdf".format(
            to_name.replace(" ", "-").replace("/", "-"))
    else:
        # use a hased file name
        file_name = "{0}.pdf".format(
            hashlib.md5("{0}{1}".format(
                to_name, time.time()).encode('utf-8')).hexdigest())

    save_file(file_name,
              content,
              to_doctype,
              to_name,
              folder=folder,
              is_private=is_private)
    return
Beispiel #2
0
def create_communications_for_sync(erpnext_support_issue,
                                   subject,
                                   description,
                                   raised_by,
                                   recipients,
                                   attachments=None):

    comm = frappe.get_doc({
        "doctype": "Communication",
        "subject": subject,
        "content": description,
        "recipients": recipients,
        "sent_or_received": "Received",
        "reference_doctype": "ERPNext Support Issue",
        "communication_medium": "Email",
        "sender": raised_by,
        "reference_name": erpnext_support_issue,
        "has_attachment": 1 if attachments else 0
    }).insert(ignore_permissions=True)

    if attachments:
        attachments = json.loads(attachments)

        for d in attachments:
            save_file(d.get("filename"), base64.b64decode(d.get("content")),
                      "Communication", comm.name)
Beispiel #3
0
def create_reply_from_customer(erpnext_support_user,
                               subject,
                               description,
                               raised_by,
                               recipients,
                               bench_site,
                               frappe_issue_id,
                               attachments=None):
    authenticate_erpnext_support_user(erpnext_support_user)

    comm = frappe.get_doc({
        "doctype": "Communication",
        "subject": subject,
        "content": description,
        "sent_or_received": "Received",
        "reference_doctype": "Issue",
        "communication_medium": "Email",
        "sender": raised_by,
        "recipients": recipients,
        "reference_name": frappe_issue_id,
        "has_attachment": 1 if attachments else 0
    }).insert(ignore_permissions=True)

    if attachments:
        attachments = json.loads(attachments)

        for d in attachments:
            save_file(d.get("filename"), base64.b64decode(d.get("content")),
                      "Communication", comm.name)

    frappe.db.set_value("Issue", frappe_issue_id, "status", "Open")

    return json.dumps({"last_sync_on": get_datetime_str(now_datetime())})
    def payment_success(self):
        self.switch_to_frame('main_part')

        save_file(self.docname + ' Online Payment Screenshot.png',
                  self.br.get_screenshot_as_png(),
                  self.doctype,
                  self.docname,
                  is_private=1)

        ref_no = '-'
        if self.data.transfer_type == 'Transfer within the bank':
            ref_no = self.br.execute_script(
                "return $('table.transTable td:nth-child(3) > span').text();"
            ) or '-'
        elif self.data.transfer_type == 'Transfer to other bank (NEFT)':
            ref_no = (self.get_element(
                "//td[contains(text(),'Reference Number')]/following-sibling::td[last()]",
                'xpath').text or '-').strip()

        frappe.publish_realtime('payment_success', {
            'ref_no': ref_no,
            'uid': self.uid
        },
                                user=frappe.session.user,
                                doctype="Payment Entry",
                                docname=self.docname)

        frappe.db.commit()
        self.logout()
    def payment_success(self):
        self.switch_to_frame("main_part")

        save_file(
            self.docname + " Online Payment Screenshot.png",
            self.br.get_screenshot_as_png(),
            self.doctype,
            self.docname,
            is_private=1,
        )

        ref_no = "-"
        if self.data.transfer_type == "Transfer within the bank":
            ref_no = (self.br.execute_script(
                "return $('table.transTable td:nth-child(3) > span').text();")
                      or "-")
        elif self.data.transfer_type == "Transfer to other bank (NEFT)":
            ref_no = (self.get_element(
                "//td[contains(text(),'Reference Number')]/following-sibling::td[last()]",
                "xpath",
            ).text or "-").strip()

        frappe.publish_realtime(
            "payment_success",
            {
                "ref_no": ref_no,
                "uid": self.uid
            },
            user=frappe.session.user,
            doctype="Payment Entry",
            docname=self.docname,
        )

        frappe.db.commit()
        self.logout()
    def import_fints_transactions(self, fints_import):
        """Create payment entries by FinTS transactions.

        :param fints_import: fints_import doc name
        :type fints_import: str
        :return: List of max 10 transcations and all new payment entries
        """
        try:
            self.interactive.show_progress_realtime(
                _("Start transcation import"), 40, reload=False)
            curr_doc = frappe.get_doc("FinTS Import", fints_import)
            new_payments = None
            tansactions = self.get_fints_transactions(curr_doc.from_date,
                                                      curr_doc.to_date)
            try:
                save_file(fints_import + ".json",
                          json.dumps(tansactions, ensure_ascii=False).replace(
                              ",", ",\n").encode('utf8'),
                          'FinTS Import',
                          fints_import,
                          folder='Home/Attachments/FinTS',
                          decode=False,
                          is_private=1,
                          df=None)
            except Exception as e:
                frappe.throw(_("Failed to attach file"), e)

            if (len(tansactions) == 0):
                frappe.msgprint(_("No transcations found"))
            else:
                if (len(tansactions) == 1):
                    curr_doc.start_date = tansactions[0]["date"]
                    curr_doc.end_date = tansactions[0]["date"]
                else:
                    curr_doc.start_date = tansactions[0]["date"]
                    curr_doc.end_date = tansactions[-1]["date"]

                importer = ImportPaymentEntry(self.fints_login,
                                              self.interactive)
                importer.fints_import(tansactions)

                if len(importer.payment_entries) == 0:
                    frappe.msgprint(_("No new payments found"))
                else:
                    # Save payment entries
                    frappe.db.commit()

                    frappe.msgprint(
                        _("Found a total of '{0}' payments").format(
                            len(importer.payment_entries)))
                new_payments = importer.payment_entries

            curr_doc.submit()
            self.interactive.show_progress_realtime(
                _("Payment entry import completed"), 100, reload=False)
            return {"transactions": tansactions[:10], "payments": new_payments}
        except Exception as e:
            frappe.throw(
                _("Error parsing transactions<br>{0}").format(str(e)),
                frappe.get_traceback())
	def setUp(self):
		self.attached_to_doctype, self.attached_to_docname = make_test_doc()
		self.test_content1 = test_content1
		self.test_content2 = test_content2
		self.saved_file1 = save_file('hello.txt', self.test_content1, self.attached_to_doctype, self.attached_to_docname)
		self.saved_file2 = save_file('hello.txt', self.test_content2, self.attached_to_doctype, self.attached_to_docname)
		self.saved_filename1 = get_files_path(self.saved_file1.file_name)
		self.saved_filename2 = get_files_path(self.saved_file2.file_name)
Beispiel #8
0
def prepare_and_attach_invoice(doc):
	progressive_name, progressive_number = get_progressive_name_and_number(doc)

	invoice = prepare_invoice(doc, progressive_number)
	invoice_xml = frappe.render_template('erpnext/regional/italy/e-invoice.xml', context={"doc": invoice}, is_path=True)

	xml_filename = progressive_name + ".xml"
	save_file(xml_filename, invoice_xml, dt=doc.doctype, dn=doc.name, is_private=True)
Beispiel #9
0
def zip_attachments(document):
    zip_count = 1
    zip_size = 0
    document = json.loads(document)
    document2 = frappe._dict(document)

    fname = get_file_name(document2.name + " (zip 1).zip", random_string(7))

    import zipfile
    docZip = zipfile.ZipFile(fname, "w", zipfile.ZIP_DEFLATED)

    for file_url in frappe.db.sql(
            """select file_url, is_private from `tabFile` where attached_to_doctype = %(doctype)s and attached_to_name = %(docname)s""",
        {
            'doctype': document2.doctype,
            'docname': document2.name
        },
            as_dict=True):
        frappe.msgprint("Adding " + file_url.file_url)

        if file_url.file_url.startswith("/private/files/"):
            path = get_files_path(*file_url.file_url.split(
                "/private/files/", 1)[1].split("/"),
                                  is_private=1)

        elif file_url.file_url.startswith("/files/"):
            path = get_files_path(
                *file_url.file_url.split("/files/", 1)[1].split("/"))

        path = encode(path)
        if zip_size + os.path.getsize(path) > 10000000:
            zip_count = zip_count + 1
            zip_size = 0
            docZip.close()
            with open(encode(fname), 'r') as f:
                content = f.read()

            content = base64.b64encode(content)

            save_file(fname, content, document2.doctype, document2.name,
                      "Home/Attachments", 1)
            fname = get_file_name(
                document2.name + " (zip " + str(zip_count) + ").zip",
                random_string(7))
            docZip = zipfile.ZipFile(fname, "w", zipfile.ZIP_DEFLATED)
        docZip.write(path, os.path.basename(path))
        zip_size = zip_size + docZip.getinfo(
            os.path.basename(path)).compress_size

    docZip.close()
    with open(encode(fname), 'r') as f:
        content = f.read()

    content = base64.b64encode(content)

    save_file(fname, content, document2.doctype, document2.name,
              "Home/Attachments", 1)
Beispiel #10
0
def prepare_and_attach_invoice(doc):
	progressive_name, progressive_number = get_progressive_name_and_number(doc)

	invoice = prepare_invoice(doc, progressive_number)
	invoice_xml = frappe.render_template('erpnext/regional/italy/e-invoice.xml', context={"doc": invoice}, is_path=True)
	invoice_xml = invoice_xml.replace("&", "&amp;")

	xml_filename = progressive_name + ".xml"
	save_file(xml_filename, invoice_xml, dt=doc.doctype, dn=doc.name, is_private=True)
Beispiel #11
0
	def setUp(self):
		self.attached_to_doctype1, self.attached_to_docname1 = make_test_doc()
		self.attached_to_doctype2, self.attached_to_docname2 = make_test_doc()
		self.test_content1 = test_content1
		self.test_content2 = test_content1
		self.orig_filename = 'hello.txt'
		self.dup_filename = 'hello2.txt'
		self.saved_file1 = save_file(self.orig_filename, self.test_content1, self.attached_to_doctype1, self.attached_to_docname1)
		self.saved_file2 = save_file(self.dup_filename, self.test_content2, self.attached_to_doctype2, self.attached_to_docname2)
		self.saved_filename1 = get_files_path(self.saved_file1.file_name)
		self.saved_filename2 = get_files_path(self.saved_file2.file_name)
Beispiel #12
0
 def setUp(self):
     self.attached_to_doctype, self.attached_to_docname = make_test_doc()
     self.test_content1 = test_content1
     self.test_content2 = test_content2
     self.saved_file1 = save_file('hello.txt', self.test_content1,
                                  self.attached_to_doctype,
                                  self.attached_to_docname)
     self.saved_file2 = save_file('hello.txt', self.test_content2,
                                  self.attached_to_doctype,
                                  self.attached_to_docname)
     self.saved_filename1 = get_files_path(self.saved_file1.file_name)
     self.saved_filename2 = get_files_path(self.saved_file2.file_name)
Beispiel #13
0
def create_pdf(doctype, docname, printformat):
    # create html
    html = frappe.get_print(doctype, docname, print_format=printformat)
    # create pdf
    pdf = frappe.utils.pdf.get_pdf(html)
    # save and attach pdf
    now = datetime.now()
    ts = "{0:04d}-{1:02d}-{2:02d}".format(now.year, now.month, now.day)
    file_name = "{0}_{1}.pdf".format(
        ts,
        docname.replace(" ", "_").replace("/", "_"))
    save_file(file_name, pdf, doctype, docname, is_private=1)
    return
Beispiel #14
0
def save_and_attach(content, to_doctype, to_name, folder):
    """
    Save content to disk and create a File document.
    File document is linked to another document.
    """
    file_name = "{}.pdf".format(to_name.replace(" ", "-").replace("/", "-"))
    save_file(file_name,
              content,
              to_doctype,
              to_name,
              folder=folder,
              is_private=1)
    return
    def throw(self, message, screenshot=False):
        js = "frappe.hide_msgprint();"
        if screenshot:
            save_file('payment_error_{}.png'.format(self.uid), self.br.get_screenshot_as_png(),
                self.doctype, self.docname, is_private=1)

            frappe.db.commit()
            js += " if (cur_frm) cur_frm.reload_doc();"
            message += " (See attached screenshot)"

        frappe.emit_js(js)
        self.logout()
        frappe.throw(message)
Beispiel #16
0
	def save_attachments_in_doc(self, doc):
		"""Save email attachments in given document."""
		from frappe.utils.file_manager import save_file, MaxFileSizeReachedError
		for attachment in self.attachments:
			try:
				save_file(attachment['fname'], attachment['fcontent'],
					doc.doctype, doc.name)
			except MaxFileSizeReachedError:
				# WARNING: bypass max file size exception
				pass
			except frappe.DuplicateEntryError:
				# same file attached twice??
				pass
 def save_attachments_in_doc(self, doc):
     """Save email attachments in given document."""
     from frappe.utils.file_manager import save_file, MaxFileSizeReachedError
     for attachment in self.attachments:
         try:
             save_file(attachment['filename'], attachment['content'],
                       doc.doctype, doc.name)
         except MaxFileSizeReachedError:
             # WARNING: bypass max file size exception
             pass
         except frappe.DuplicateEntryError:
             # same file attached twice??
             pass
Beispiel #18
0
def create_flyer_pdf(name):
    block = frappe.get_doc("Block", name)
    # create html
    html = frappe.get_print("Block",
                            name,
                            print_format=block.flyer_print_format)
    # create pdf
    pdf = frappe.utils.pdf.get_pdf(html)
    # clear attached files
    remove_all("Block", name)
    # save and attach pdf
    file_name = "{0}.pdf".format(name.replace(" ", "_").replace("/", "_"))
    save_file(file_name, pdf, "Block", name, is_private=0)
    return
Beispiel #19
0
def build_long_fiscal_year_print(fiscal_year):
    fiscal_year = frappe.get_doc("Fiscal Year", fiscal_year)
    # clear attached files
    remove_all("Fiscal Year", fiscal_year.name)
    for c in fiscal_year.companies:
        # create html
        if not c.print_format:
            frappe.log_error( _("Please specify a print format for company {0}", _("Print Fiscal Year") ) )
        html = frappe.get_print("Fiscal Year", fiscal_year.name, print_format=c.print_format)
        # create pdf
        pdf = frappe.utils.pdf.get_pdf(html)
        # save and attach pdf
        file_name = ("{0}_{1}.pdf".format(fiscal_year.name, c.company)).replace(" ", "_").replace("/", "_")
        save_file(file_name, pdf, "Fiscal Year", fiscal_year.name, is_private=1)
    return
    def payment_success_action(self):
        # Get reference no. and screenshot << refno is the id
        save_file(self.docname + ' Online Payment Screenshot.png',
                  self.br.get_screenshot_as_png(), 'Payment Entry',
                  self.docname)

        if self.transfer_type == 'Transfer within the bank':
            ref_no = self.br.find_element_by_id('refno').text
        else:
            ref_no = self.br.find_element_by_class_name('clsreferenceno').text

        frappe.publish_realtime('payment_success', {'ref_no': ref_no},
                                user=frappe.session.user)

        self.logout()
Beispiel #21
0
 def setUp(self):
     self.attached_to_doctype1, self.attached_to_docname1 = make_test_doc()
     self.attached_to_doctype2, self.attached_to_docname2 = make_test_doc()
     self.test_content1 = test_content1
     self.test_content2 = test_content1
     self.orig_filename = 'hello.txt'
     self.dup_filename = 'hello2.txt'
     self.saved_file1 = save_file(self.orig_filename, self.test_content1,
                                  self.attached_to_doctype1,
                                  self.attached_to_docname1)
     self.saved_file2 = save_file(self.dup_filename, self.test_content2,
                                  self.attached_to_doctype2,
                                  self.attached_to_docname2)
     self.saved_filename1 = get_files_path(self.saved_file1.file_name)
     self.saved_filename2 = get_files_path(self.saved_file2.file_name)
Beispiel #22
0
def create_json_gz_file(data, dt, dn):
	# Storing data in CSV file causes information loss
	# Reports like P&L Statement were completely unsuable because of this
	json_filename = '{0}.json.gz'.format(frappe.utils.data.format_datetime(frappe.utils.now(), "Y-m-d-H:M"))
	encoded_content = frappe.safe_encode(frappe.as_json(data))

	# GZip compression seems to reduce storage requirements by 80-90%
	compressed_content = gzip_compress(encoded_content)
	save_file(
		fname=json_filename,
		content=compressed_content,
		dt=dt,
		dn=dn,
		folder=None,
		is_private=False)
def create_json_gz_file(data, dt, dn):
	# Storing data in CSV file causes information loss
	# Reports like P&L Statement were completely unsuable because of this
	json_filename = '{0}.json.gz'.format(frappe.utils.data.format_datetime(frappe.utils.now(), "Y-m-d-H:M"))
	encoded_content = frappe.safe_encode(frappe.as_json(data))

	# GZip compression seems to reduce storage requirements by 80-90%
	compressed_content = gzip_compress(encoded_content)
	save_file(
		fname=json_filename,
		content=compressed_content,
		dt=dt,
		dn=dn,
		folder=None,
		is_private=True)
Beispiel #24
0
def attach_file(filename=None, filedata=None, doctype=None, docname=None, folder=None, decode_base64=False, is_private=None, docfield=None):
	'''Attach a file to Document (POST)

	:param filename: filename e.g. test-file.txt
	:param filedata: base64 encode filedata which must be urlencoded
	:param doctype: Reference DocType to attach file to
	:param docname: Reference DocName to attach file to
	:param folder: Folder to add File into
	:param decode_base64: decode filedata from base64 encode, default is False
	:param is_private: Attach file as private file (1 or 0)
	:param docfield: file to attach to (optional)'''

	request_method = frappe.local.request.environ.get("REQUEST_METHOD")

	if request_method.upper() != "POST":
		frappe.throw(_("Invalid Request"))

	doc = frappe.get_doc(doctype, docname)

	if not doc.has_permission():
		frappe.throw(_("Not permitted"), frappe.PermissionError)

	f = save_file(filename, filedata, doctype, docname, folder, decode_base64, is_private, docfield)

	if docfield and doctype:
		doc.set(docfield, f.file_url)
		doc.save()

	return f.as_dict()
Beispiel #25
0
def create_items(args):
    for i in xrange(1, 6):
        item = args.get("item_" + str(i))
        if item:
            item_group = _(args.get("item_group_" + str(i)))
            is_sales_item = args.get("is_sales_item_" + str(i))
            is_purchase_item = args.get("is_purchase_item_" + str(i))
            is_stock_item = item_group != _("Services")
            default_warehouse = ""
            if is_stock_item:
                default_warehouse = frappe.db.get_value(
                    "Warehouse",
                    filters={
                        "warehouse_name":
                        _("Finished Goods") if is_sales_item else _("Stores"),
                        "company":
                        args.get("company_name")
                    })

            try:
                frappe.get_doc({
                    "doctype": "Item",
                    "item_code": item,
                    "item_name": item,
                    "description": item,
                    "show_in_website": 1,
                    "is_sales_item": is_sales_item,
                    "is_purchase_item": is_purchase_item,
                    "is_stock_item": is_stock_item and 1 or 0,
                    "item_group": item_group,
                    "stock_uom": _(args.get("item_uom_" + str(i))),
                    "default_warehouse": default_warehouse
                }).insert()

                if args.get("item_img_" + str(i)):
                    item_image = args.get("item_img_" + str(i)).split(",")
                    if len(item_image) == 3:
                        filename, filetype, content = item_image
                        fileurl = save_file(filename,
                                            content,
                                            "Item",
                                            item,
                                            decode=True).file_url
                        frappe.db.set_value("Item", item, "image", fileurl)

                if args.get("item_price_" + str(i)):
                    item_price = flt(args.get("item_price_" + str(i)))

                    if is_sales_item:
                        price_list_name = frappe.db.get_value(
                            "Price List", {"selling": 1})
                        make_item_price(item, price_list_name, item_price)

                    if is_purchase_item:
                        price_list_name = frappe.db.get_value(
                            "Price List", {"buying": 1})
                        make_item_price(item, price_list_name, item_price)

            except frappe.NameError:
                pass
Beispiel #26
0
def create_items(args):
	for i in xrange(1,6):
		item = args.get("item_" + str(i))
		if item:
			item_group = args.get("item_group_" + str(i))
			is_sales_item = args.get("is_sales_item_" + str(i))
			is_purchase_item = args.get("is_purchase_item_" + str(i))
			is_stock_item = item_group!=_("Services")
			default_warehouse = ""
			if is_stock_item:
				if is_sales_item:
					default_warehouse = _("Finished Goods") + " - " + args.get("company_abbr")
				else:
					default_warehouse = _("Stores") + " - " + args.get("company_abbr")

			frappe.get_doc({
				"doctype":"Item",
				"item_code": item,
				"item_name": item,
				"description": item,
				"is_sales_item": "Yes" if is_sales_item else "No",
				"is_purchase_item": "Yes" if is_purchase_item else "No",
				"show_in_website": 1,
				"is_stock_item": is_stock_item and "Yes" or "No",
				"item_group": item_group,
				"stock_uom": args.get("item_uom_" + str(i)),
				"default_warehouse": default_warehouse
			}).insert()

			if args.get("item_img_" + str(i)):
				item_image = args.get("item_img_" + str(i)).split(",")
				if len(item_image)==3:
					filename, filetype, content = item_image
					fileurl = save_file(filename, content, "Item", item, decode=True).file_url
					frappe.db.set_value("Item", item, "image", fileurl)
Beispiel #27
0
	def prepare_data_for_import(self, file_content, file_name, encoded_content):
		for line in file_content.find_all("DatiGeneraliDocumento"):
			invoices_args = {
				"company": self.company,
				"naming_series": self.invoice_series,
				"document_type": line.TipoDocumento.text,
				"bill_date": get_datetime_str(line.Data.text),
				"bill_no": line.Numero.text,
				"total_discount": 0,
				"items": [],
				"buying_price_list": self.default_buying_price_list
			}

			if not invoices_args.get("bill_no", ''):
				frappe.throw(_("Numero has not set in the XML file"))

			supp_dict = get_supplier_details(file_content)
			invoices_args["destination_code"] = get_destination_code_from_file(file_content)
			self.prepare_items_for_invoice(file_content, invoices_args)
			invoices_args["taxes"] = get_taxes_from_file(file_content, self.tax_account)
			invoices_args["terms"] = get_payment_terms_from_file(file_content)

			supplier_name = create_supplier(self.supplier_group, supp_dict)
			address = create_address(supplier_name, supp_dict)
			pi_name = create_purchase_invoice(supplier_name, file_name, invoices_args, self.name)

			self.file_count += 1
			if pi_name:
				self.purchase_invoices_count += 1
				file_save = save_file(file_name, encoded_content, "Purchase Invoice",
					pi_name, folder=None, decode=False, is_private=0, df=None)
Beispiel #28
0
 def setUp(self):
     self.attached_to_doctype, self.attached_to_docname = make_test_doc()
     self.test_content = test_content1
     self.saved_file = save_file('hello.txt', self.test_content,
                                 self.attached_to_doctype,
                                 self.attached_to_docname)
     self.saved_filename = get_files_path(self.saved_file.file_name)
Beispiel #29
0
def create_logo(args):
	if args.get("attach_logo"):
		filename, filetype, content = args.get("attach_logo").split(",")
		fileurl = save_file(filename, content, "Website Settings", "Website Settings",
			decode=True).file_url
		frappe.db.set_value("Website Settings", "Website Settings", "banner_html",
			"<img src='%s' style='max-width: 100%%;'>" % fileurl)
Beispiel #30
0
def attach_file(doctype, docname, filedata):
	if not filedata: return


	fd_json = json.loads(filedata)
	fd_list = list(fd_json["files_data"])

	for fd in fd_list:
		attach_type = frappe.get_value("Tipo de Adjunto", fd["attach_type"], 
			["allow_more_than_one", "max_attacthments"], as_dict=True)

		file_list = frappe.get_list("File", { "file_name": ["like", "{}%".format(fd["filename"].split(".pdf")[0])]})

		if file_list:
			if (not attach_type.allow_more_than_one and len(file_list))\
				or\
			(attach_type.allow_more_than_one and attach_type.max_attacthments 
				and flt(attach_type.max_attacthments) <= len(file_list)):
				frappe.throw("No puede agregar mas adjuntos de este tipo")

			fd["filename"] = fd["filename"].replace(".pdf", "-{}.pdf".format(len(file_list)))
			fd["filename"] = s_sanitize(fd["filename"], upper=False)
		
		filedoc = save_file(fd["filename"], fd["dataurl"], 
			doctype, docname, decode=True, is_private=True)
Beispiel #31
0
def create_logo(args):
	if args.get("attach_logo"):
		filename, filetype, content = args.get("attach_logo").split(",")
		fileurl = save_file(filename, content, "Website Settings", "Website Settings",
			decode=True).file_url
		frappe.db.set_value("Website Settings", "Website Settings", "banner_html",
			"<img src='%s' style='max-width: 100%%;'>" % fileurl)
Beispiel #32
0
def update_user_name(args):
	if args.get("email"):
		args['name'] = args.get("email")

		_mute_emails, frappe.flags.mute_emails = frappe.flags.mute_emails, True
		doc = frappe.get_doc({
			"doctype":"User",
			"email": args.get("email"),
			"first_name": args.get("first_name"),
			"last_name": args.get("last_name")
		})
		doc.flags.no_welcome_mail = True
		doc.insert()
		frappe.flags.mute_emails = _mute_emails
		from frappe.auth import _update_password
		_update_password(args.get("email"), args.get("password"))

	else:
		args['name'] = frappe.session.user

		# Update User
		if not args.get('last_name') or args.get('last_name')=='None':
				args['last_name'] = None
		frappe.db.sql("""update `tabUser` SET first_name=%(first_name)s,
			last_name=%(last_name)s WHERE name=%(name)s""", args)

	if args.get("attach_user"):
		attach_user = args.get("attach_user").split(",")
		if len(attach_user)==3:
			filename, filetype, content = attach_user
			fileurl = save_file(filename, content, "User", args.get("name"), decode=True).file_url
			frappe.db.set_value("User", args.get("name"), "user_image", fileurl)

	add_all_roles_to(args.get("name"))
Beispiel #33
0
def create_items(args):
	for i in xrange(1,6):
		item = args.get("item_" + str(i))
		if item:
			item_group = args.get("item_group_" + str(i))
			is_sales_item = args.get("is_sales_item_" + str(i))
			is_purchase_item = args.get("is_purchase_item_" + str(i))
			is_stock_item = item_group!=_("Services")
			default_warehouse = ""
			if is_stock_item:
				default_warehouse = frappe.db.get_value("Warehouse", filters={
					"warehouse_name": _("Finished Goods") if is_sales_item else _("Stores"),
					"company": args.get("company_name").strip()
				})

			frappe.get_doc({
				"doctype":"Item",
				"item_code": item,
				"item_name": item,
				"description": item,
				"is_sales_item": "Yes" if is_sales_item else "No",
				"is_purchase_item": "Yes" if is_purchase_item else "No",
				"show_in_website": 1,
				"is_stock_item": is_stock_item and "Yes" or "No",
				"item_group": item_group,
				"stock_uom": args.get("item_uom_" + str(i)),
				"default_warehouse": default_warehouse
			}).insert()

			if args.get("item_img_" + str(i)):
				item_image = args.get("item_img_" + str(i)).split(",")
				if len(item_image)==3:
					filename, filetype, content = item_image
					fileurl = save_file(filename, content, "Item", item, decode=True).file_url
					frappe.db.set_value("Item", item, "image", fileurl)
Beispiel #34
0
def update_profile_name(args):
    if args.get("email"):
        args['name'] = args.get("email")
        frappe.flags.mute_emails = True
        frappe.bean({
            "doctype": "Profile",
            "email": args.get("email"),
            "first_name": args.get("first_name"),
            "last_name": args.get("last_name")
        }).insert()
        frappe.flags.mute_emails = False
        from frappe.auth import _update_password
        _update_password(args.get("email"), args.get("password"))

    else:
        args['name'] = frappe.session.user

        # Update Profile
        if not args.get('last_name') or args.get('last_name') == 'None':
            args['last_name'] = None
        frappe.db.sql(
            """update `tabProfile` SET first_name=%(first_name)s,
			last_name=%(last_name)s WHERE name=%(name)s""", args)

    if args.get("attach_profile"):
        filename, filetype, content = args.get("attach_profile").split(",")
        fileurl = save_file(filename,
                            content,
                            "Profile",
                            args.get("name"),
                            decode=True).file_name
        frappe.db.set_value("Profile", args.get("name"), "user_image", fileurl)

    add_all_roles_to(args.get("name"))
Beispiel #35
0
def attach_all_boms(document):
	"""This function attaches drawings to the purchase order based on the items being ordered"""
	document = json.loads(document)
	document2 = frappe._dict(document)
	
	current_attachments = []
	
	for file_url in frappe.db.sql("""select file_name from `tabFile` where attached_to_doctype = %(doctype)s and attached_to_name = %(docname)s""", {'doctype': document2.doctype, 'docname': document2.name}, as_dict=True ):
		current_attachments.append(file_url.file_name)
	
	# add the directly linked drawings
	boms = []
	for item in document["items"]:
		#add the boms
		boms = get_bom_pdf(boms, item["item_code"])
	
	count = 0
	for bom_doc in boms:
		#frappe.msgprint(item_doc)
		bom = frappe.get_doc("BOM",bom_doc)
		
		# Check to see if this file is attached to the one we are looking for
		if not (bom.name + ".pdf") in current_attachments:
			count = count + 1
			my_attach = frappe.attach_print(bom.doctype, bom.name, doc=bom)
			myFile = save_file(my_attach['fname'], my_attach['fcontent'], document2.doctype, document2.name, "Home/Attachments", decode=False, is_private=1)
			myFile.file_name = my_attach['fname']
			myFile.save()
			current_attachments.append(my_attach['fname'])
				
	frappe.msgprint("Attached {0} boms".format(count))
Beispiel #36
0
def file_upload(data):
        dts=json.loads(data)
	#print dts
	#frappe.errprint(dts)
        qry="select user from __Auth where user='******'username'])+"' and password=password('"+cstr(dts['userpass'])+"') "
        valid=frappe.db.sql(qry)
        if not valid:
            return {
                "status":"401",
                "message":"User name or Password is incorrect"
            }
        from frappe.utils.file_manager import  save_file
        filedata=save_file(fname=dts['filename'],content=base64.b64decode(dts['fdata']),dt=dts['tbl'],dn=dts['name'])
        comment = frappe.get_doc(dts['tbl'], dts['name']).add_comment("Attachment",
            _("Added {0}").format("<a href='{file_url}' target='_blank'>{file_name}</a>".format(**filedata.as_dict())))

	if dts['tbl']=='Member':
             frappe.db.sql("update tabMember set image=%s where name=%s",(filedata.file_url,dts['name']))
	#frappe.errprint(filedata.name,filedata.file_name,filedata.file_url,comment.as_dict())
        return {
            "name": filedata.name,
            "file_name": filedata.file_name,
            "file_url": filedata.file_url,
            "comment": comment.as_dict()
        }
Beispiel #37
0
    def save_attachments_in_doc(self, doc):
        """Save email attachments in given document."""
        from frappe.utils.file_manager import save_file, MaxFileSizeReachedError
        saved_attachments = []

        for attachment in self.attachments:
            try:
                file_data = save_file(attachment['fname'],
                                      attachment['fcontent'],
                                      doc.doctype,
                                      doc.name,
                                      is_private=1)
                saved_attachments.append(file_data)

                if attachment['fname'] in self.cid_map:
                    self.cid_map[file_data.name] = self.cid_map[
                        attachment['fname']]

            except MaxFileSizeReachedError:
                # WARNING: bypass max file size exception
                pass
            except frappe.DuplicateEntryError:
                # same file attached twice??
                pass

        return saved_attachments
Beispiel #38
0
def zip_attachments(document):
	zip_count = 1
	zip_size = 0
	document = json.loads(document)
	document2 = frappe._dict(document)

	
	fname = get_file_name(document2.name + " (zip 1).zip", random_string(7))
	
	import zipfile
	docZip = zipfile.ZipFile(fname,"w", zipfile.ZIP_DEFLATED)
	
	
	for file_url in frappe.db.sql("""select file_url, is_private from `tabFile` where attached_to_doctype = %(doctype)s and attached_to_name = %(docname)s""", {'doctype': document2.doctype, 'docname': document2.name}, as_dict=True ):
		frappe.msgprint("Adding " + file_url.file_url)
		
		if file_url.file_url.startswith("/private/files/"):
			path = get_files_path(*file_url.file_url.split("/private/files/", 1)[1].split("/"), is_private=1)

		elif file_url.file_url.startswith("/files/"):
			path = get_files_path(*file_url.file_url.split("/files/", 1)[1].split("/"))
		
		path = encode(path)
		if zip_size + os.path.getsize(path) > 10000000:
			zip_count = zip_count + 1
			zip_size = 0
			docZip.close()
			with open(encode(fname), 'r') as f:
				content = f.read()
			
			content = base64.b64encode(content)
				
			save_file(fname, content, document2.doctype, document2.name, "Home/Attachments", 1)
			fname = get_file_name(document2.name + " (zip " + str(zip_count) + ").zip", random_string(7))
			docZip = zipfile.ZipFile(fname,"w", zipfile.ZIP_DEFLATED)
		docZip.write(path, os.path.basename(path))
		zip_size  = zip_size + docZip.getinfo(os.path.basename(path)).compress_size
		

	docZip.close()
	with open(encode(fname), 'r') as f:
		content = f.read()
	
	content = base64.b64encode(content)
		
	save_file(fname, content, document2.doctype, document2.name, "Home/Attachments", 1)
	def download_test(self):
		str_save_file = "A"
		str_save_file += frappe.db.get_value("Electronic Funds Transfer Bank Detail", self.bank_account, "originator_id").zfill(10)
		str_save_file += self.file_creation_number.zfill(4)

		today = datetime.date.today()

		str_save_file += "0" + today.strftime("%y%j")
		str_save_file += frappe.db.get_value("Electronic Funds Transfer Bank Detail", self.bank_account, "destination_data_centre_code").zfill(5)

		str_save_file += "\nXC430"
		str_save_file += "0" + today.strftime("%y%j")
		str_save_file += frappe.db.get_value("Electronic Funds Transfer Bank Detail", self.bank_account, "originators_short").ljust(15)
		str_save_file += frappe.db.get_value("Electronic Funds Transfer Bank Detail", self.bank_account, "originators_long").ljust(30)
		str_save_file += "0"
		str_save_file += frappe.db.get_value("Electronic Funds Transfer Bank Detail", self.bank_account, "institution_number").ljust(3)
		str_save_file += frappe.db.get_value("Electronic Funds Transfer Bank Detail", self.bank_account, "branch_number").ljust(5)
		str_save_file += frappe.db.get_value("Electronic Funds Transfer Bank Detail", self.bank_account, "account_number").ljust(12)

		count = 0
		total = 0.00

		for supplier, dict_invoice in self.create_dict_from_list(self.get('items_eft')).items():
			grand_total = 0.00
			for invoice_name, grand_total_invoice in dict_invoice.items():
				grand_total = grand_total + grand_total_invoice
			str_save_file += "\nC"
			str_save_file += "{:.2f}".format(grand_total).replace('.','').replace(',','').zfill(10)
			str_save_file += "0"
			str_save_file += frappe.db.get_value("Electronic Funds Transfer Supplier Information", {'supplier':supplier}, "institution_number").zfill(3)
			str_save_file += frappe.db.get_value("Electronic Funds Transfer Supplier Information", {'supplier':supplier}, "branch_number").zfill(5)
			str_save_file += frappe.db.get_value("Electronic Funds Transfer Supplier Information", {'supplier':supplier}, "account_number").ljust(12)
			supplier_without_accent = ''.join((c for c in unicodedata.normalize('NFD', supplier) if unicodedata.category(c) != 'Mn'))
			#supplier_without_accent = supplier
			str_save_file += supplier_without_accent.ljust(29)[:29]
			str_save_file += supplier_without_accent.ljust(19)[:19]
			count += 1
			total += grand_total

		str_save_file += "\nYC" + str(count).zfill(8) + "{:.2f}".format(total).replace('.','').replace(',','').zfill(14)
		var_zero = 0
		str_save_file += "\nZ" + str(var_zero).zfill(14) + str(var_zero).zfill(5) +  "{:.2f}".format(total).replace('.','').replace(',','').zfill(14) + str(count).zfill(5)

		save_file("file-bank-transfer.txt", str_save_file, self.doctype, self.name, is_private=True)
		frappe.db.set(self, 'is_file_generated', True)
Beispiel #40
0
def create_items(args):
    for i in xrange(1, 6):
        item = args.get("item_" + str(i))
        if item:
            item_group = args.get("item_group_" + str(i))
            is_sales_item = args.get("is_sales_item_" + str(i))
            is_purchase_item = args.get("is_purchase_item_" + str(i))
            is_stock_item = item_group != _("Services")
            is_pro_applicable = item_group != _("Services")
            default_warehouse = ""
            if is_stock_item:
                default_warehouse = frappe.db.get_value(
                    "Warehouse",
                    filters={
                        "warehouse_name": _("Finished Goods") if is_sales_item else _("Stores"),
                        "company": args.get("company_name").strip(),
                    },
                )

            try:
                frappe.get_doc(
                    {
                        "doctype": "Item",
                        "item_code": item,
                        "item_name": item,
                        "description": item,
                        "is_sales_item": 1 if is_sales_item else 0,
                        "is_purchase_item": 1 if is_purchase_item else 0,
                        "show_in_website": 1,
                        "is_stock_item": is_stock_item and 1 or 0,
                        "is_pro_applicable": is_pro_applicable and 1 or 0,
                        "item_group": item_group,
                        "stock_uom": args.get("item_uom_" + str(i)),
                        "default_warehouse": default_warehouse,
                    }
                ).insert()

                if args.get("item_img_" + str(i)):
                    item_image = args.get("item_img_" + str(i)).split(",")
                    if len(item_image) == 3:
                        filename, filetype, content = item_image
                        fileurl = save_file(filename, content, "Item", item, decode=True).file_url
                        frappe.db.set_value("Item", item, "image", fileurl)

                if args.get("item_price_" + str(i)):
                    item_price = flt(args.get("item_price_" + str(i)))

                    if is_sales_item:
                        price_list_name = frappe.db.get_value("Price List", {"selling": 1})
                        make_item_price(item, price_list_name, item_price)

                    if is_purchase_item:
                        price_list_name = frappe.db.get_value("Price List", {"buying": 1})
                        make_item_price(item, price_list_name, item_price)

            except frappe.NameError:
                pass
Beispiel #41
0
def create_logo(args):
	if args.get("attach_logo"):
		attach_logo = args.get("attach_logo").split(",")
		if len(attach_logo)==3:
			filename, filetype, content = attach_logo
			fileurl = save_file(filename, content, "Website Settings", "Website Settings",
				decode=True).file_url
			frappe.db.set_value("Website Settings", "Website Settings", "brand_html",
				"<img src='{0}' style='max-width: 40px; max-height: 25px;'> {1}".format(fileurl, args.get("company_name").strip()))
Beispiel #42
0
def create_logo(args):
	if args.get("attach_logo"):
		attach_logo = args.get("attach_logo").split(",")
		if len(attach_logo)==3:
			filename, filetype, content = attach_logo
			fileurl = save_file(filename, content, "Website Settings", "Website Settings",
				decode=True).file_url
			frappe.db.set_value("Website Settings", "Website Settings", "brand_html",
				"<img src='{0}' style='max-width: 40px; max-height: 25px;'> {1}".format(fileurl, args.get("company_name").strip()))
Beispiel #43
0
	def test_on_delete(self):
		file = frappe.get_doc("File", {"file_name":"file_copy.txt"})
		file.delete()

		self.assertEqual(frappe.db.get_value("File", _("Home/Test Folder 1"), "file_size"), 0)

		folder = self.get_folder("Test Folder 3", "Home/Test Folder 1")
		self.saved_file = save_file('folder_copy.txt', "Testing folder copy example.", "", "", folder.name)

		folder = frappe.get_doc("File", "Home/Test Folder 1/Test Folder 3")
		self.assertRaises(frappe.ValidationError, folder.delete)
Beispiel #44
0
def create_letter_head(args):
	if args.get("attach_letterhead"):
		frappe.get_doc({
			"doctype":"Letter Head",
			"letter_head_name": _("Standard"),
			"is_default": 1
		}).insert()

		filename, filetype, content = args.get("attach_letterhead").split(",")
		fileurl = save_file(filename, content, "Letter Head", _("Standard"), decode=True).file_url
		frappe.db.set_value("Letter Head", _("Standard"), "content", "<img src='%s' style='max-width: 100%%;'>" % fileurl)
Beispiel #45
0
def qrcode_as_png(user, totp_uri):
	'''Save temporary Qrcode to server.'''
	from frappe.utils.file_manager import save_file
	folder = create_barcode_folder()
	png_file_name = '{}.png'.format(frappe.generate_hash(length=20))
	file_obj = save_file(png_file_name, png_file_name, 'User', user, folder=folder)
	frappe.db.commit()
	file_url = get_url(file_obj.file_url)
	file_path = os.path.join(frappe.get_site_path('public', 'files'), file_obj.file_name)
	url = qrcreate(totp_uri)
	with open(file_path, 'w') as png_file:
		url.png(png_file, scale=8, module_color=[0, 0, 0, 180], background=[0xff, 0xff, 0xcc])
	return file_url
Beispiel #46
0
    def test_folder_copy(self):
        folder = self.get_folder("Test Folder 2", "Home")
        folder = self.get_folder("Test Folder 3", "Home/Test Folder 2")

        self.saved_file = save_file("folder_copy.txt", "Testing folder copy example.", "", "", folder.name)

        file_dict = [{"name": folder.name}]

        move_file(json.dumps(file_dict), "Home/Test Folder 1", folder.folder)

        file = frappe.get_doc("File", "/files/folder_copy.txt")

        self.assertEqual(_("Home/Test Folder 1/Test Folder 3"), file.folder)
        self.assertEqual(frappe.db.get_value("File", _("Home/Test Folder 1"), "file_size"), file.file_size)
        self.assertEqual(frappe.db.get_value("File", _("Home/Test Folder 2"), "file_size"), None)
Beispiel #47
0
	def test_folder_copy(self):
		folder = self.get_folder("Test Folder 2", "Home")
		folder = self.get_folder("Test Folder 3", "Home/Test Folder 2")

		self.saved_file = save_file('folder_copy.txt', "Testing folder copy example.", "", "", folder.name)

		move_file([{"name": folder.name}], 'Home/Test Folder 1', folder.folder)

		file = frappe.get_doc("File", {"file_name":"folder_copy.txt"})
		file_copy_txt = frappe.get_value("File", {"file_name":"file_copy.txt"})
		if file_copy_txt:
			frappe.get_doc("File", file_copy_txt).delete()

		self.assertEqual(_("Home/Test Folder 1/Test Folder 3"), file.folder)
		self.assertEqual(frappe.db.get_value("File", _("Home/Test Folder 1"), "file_size"), file.file_size)
		self.assertEqual(frappe.db.get_value("File", _("Home/Test Folder 2"), "file_size"), 0)
Beispiel #48
0
def update_user_name(args):
	first_name, last_name = args.get('full_name', ''), ''
	if ' ' in first_name:
		first_name, last_name = first_name.split(' ', 1)

	if args.get("email"):
		if frappe.db.exists('User', args.get('email')):
			# running again
			return


		args['name'] = args.get("email")

		_mute_emails, frappe.flags.mute_emails = frappe.flags.mute_emails, True
		doc = frappe.get_doc({
			"doctype":"User",
			"email": args.get("email"),
			"first_name": first_name,
			"last_name": last_name
		})
		doc.flags.no_welcome_mail = True
		doc.insert()
		frappe.flags.mute_emails = _mute_emails
		update_password(args.get("email"), args.get("password"))

	elif first_name:
		args.update({
			"name": frappe.session.user,
			"first_name": first_name,
			"last_name": last_name
		})

		frappe.db.sql("""update `tabUser` SET first_name=%(first_name)s,
			last_name=%(last_name)s WHERE name=%(name)s""", args)

	if args.get("attach_user"):
		attach_user = args.get("attach_user").split(",")
		if len(attach_user)==3:
			filename, filetype, content = attach_user
			fileurl = save_file(filename, content, "User", args.get("name"), decode=True).file_url
			frappe.db.set_value("User", args.get("name"), "user_image", fileurl)

	if args.get('name'):
		add_all_roles_to(args.get("name"))
Beispiel #49
0
    def save_attachments_in_doc(self, doc):
        """Save email attachments in given document."""
        from frappe.utils.file_manager import save_file, MaxFileSizeReachedError

        saved_attachments = []

        for attachment in self.attachments:
            try:
                file_data = save_file(attachment["fname"], attachment["fcontent"], doc.doctype, doc.name)
                saved_attachments.append(file_data.file_name)

                self.file_name_map[file_data.file_name] = file_data.file_url
            except MaxFileSizeReachedError:
                # WARNING: bypass max file size exception
                pass
            except frappe.DuplicateEntryError:
                # same file attached twice??
                pass

        return saved_attachments
Beispiel #50
0
	def save_attachments_in_doc(self, doc):
		"""Save email attachments in given document."""
		saved_attachments = []

		for attachment in self.attachments:
			try:
				file_data = save_file(attachment['fname'], attachment['fcontent'],
					doc.doctype, doc.name, is_private=1)
				saved_attachments.append(file_data)

				if attachment['fname'] in self.cid_map:
					self.cid_map[file_data.name] = self.cid_map[attachment['fname']]

			except MaxFileSizeReachedError:
				# WARNING: bypass max file size exception
				pass
			except frappe.DuplicateEntryError:
				# same file attached twice??
				pass

		return saved_attachments
Beispiel #51
0
def process_picture(post, picture_name, picture):
	from frappe.templates.generators.website_group import clear_cache

	post.picture_url = save_file(picture_name, picture, "Post", post.name, decode=True).file_url
	frappe.db.set_value("Post", post.name, "picture_url", post.picture_url)
	clear_cache(website_group=post.website_group)
Beispiel #52
0
def accept():
	args = frappe.form_dict
	files = []

	web_form = frappe.get_doc("Web Form", args.web_form)
	if args.doctype != web_form.doc_type:
		frappe.throw(_("Invalid Request"))

	elif args.name and not web_form.allow_edit:
		frappe.throw(_("You are not allowed to update this Web Form Document"))

	if args.name:
		# update
		doc = frappe.get_doc(args.doctype, args.name)
	else:
		# insert
		doc = frappe.new_doc(args.doctype)

	# set values
	for fieldname, value in args.iteritems():
		if fieldname not in ("web_form", "cmd", "owner"):
			if value and value.startswith("{"):
				try:
					filedata = json.loads(value)
					if "__file_attachment" in filedata:
						files.append((fieldname, filedata))
						continue

				except ValueError:
					pass

			doc.set(fieldname, value)

	if args.name:
		if has_web_form_permission(doc.doctype, doc.name, "write"):
			doc.save(ignore_permissions=True)
		else:
			# only if permissions are present
			doc.save()

	else:
		# insert
		if web_form.login_required and frappe.session.user=="Guest":
			frappe.throw(_("You must login to submit this form"))

		doc.insert(ignore_permissions = True)

	# add files
	if files:
		for f in files:
			fieldname, filedata = f

			# remove earlier attachmed file (if exists)
			if doc.get(fieldname):
				remove_file_by_url(doc.get(fieldname), doc.doctype, doc.name)

			# save new file
			filedoc = save_file(filedata["filename"], filedata["dataurl"],
				doc.doctype, doc.name, decode=True)

			# update values
			doc.set(fieldname, filedoc.file_url)

		doc.save()
Beispiel #53
0
def accept(web_form, data, for_payment=False):
	'''Save the web form'''
	data = frappe._dict(json.loads(data))
	files = []
	files_to_delete = []

	web_form = frappe.get_doc("Web Form", web_form)
	if data.doctype != web_form.doc_type:
		frappe.throw(_("Invalid Request"))

	elif data.name and not web_form.allow_edit:
		frappe.throw(_("You are not allowed to update this Web Form Document"))

	frappe.flags.in_web_form = True

	if data.name:
		# update
		doc = frappe.get_doc(data.doctype, data.name)
	else:
		# insert
		doc = frappe.new_doc(data.doctype)

	# set values
	for fieldname, value in iteritems(data):
		if value and isinstance(value, dict):
			try:
				if "__file_attachment" in value:
					files.append((fieldname, value))
					continue
				if '__no_attachment' in value:
					files_to_delete.append(doc.get(fieldname))
					value = ''

			except ValueError:
				pass

		doc.set(fieldname, value)

	if for_payment:
		web_form.validate_mandatory(doc)
		doc.run_method('validate_payment')

	if doc.name:
		if has_web_form_permission(doc.doctype, doc.name, "write"):
			doc.save(ignore_permissions=True)
		else:
			# only if permissions are present
			doc.save()

	else:
		# insert
		if web_form.login_required and frappe.session.user=="Guest":
			frappe.throw(_("You must login to submit this form"))

		doc.insert(ignore_permissions = True)

	# add files
	if files:
		for f in files:
			fieldname, filedata = f

			# remove earlier attached file (if exists)
			if doc.get(fieldname):
				remove_file_by_url(doc.get(fieldname), doc.doctype, doc.name)

			# save new file
			filedoc = save_file(filedata["filename"], filedata["dataurl"],
				doc.doctype, doc.name, decode=True)

			# update values
			doc.set(fieldname, filedoc.file_url)

		doc.save()

	if files_to_delete:
		for f in files_to_delete:
			if f:
				remove_file_by_url(f, doc.doctype, doc.name)

	frappe.flags.web_form_doc = doc

	if for_payment:
		return web_form.get_payment_gateway_url(doc)
	else:
		return doc.name
Beispiel #54
0
	def setUp(self):
		self.attached_to_doctype, self.attached_to_docname = make_test_doc()
		self.test_content = test_content1
		self.saved_file = save_file('hello.txt', self.test_content, self.attached_to_doctype, self.attached_to_docname)
		self.saved_filename = get_files_path(self.saved_file.file_name)
Beispiel #55
0
	def upload_file(self):
		self.saved_file = save_file('file_copy.txt', "Testing file copy example.",\
			 "", "", self.get_folder("Test Folder 1", "Home").name)
		self.saved_filename = get_files_path(self.saved_file.file_name)
	def store_file(file_name, image_data, ps_doctype, ps_name):
		frappe.msgprint(str(file_name))
		save_file(file_name, image_data, ps_doctype, ps_name, is_private=1)
Beispiel #57
0
def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, no_email=True, overwrite=None,
	update_only = None, ignore_links=False, pre_process=None, via_console=False, from_data_import="No",
	skip_errors = True, data_import_doc=None, validate_template=False, user=None):
	"""upload data"""

	# for translations
	if user:
		frappe.cache().hdel("lang", user)
		frappe.set_user_lang(user)

	if data_import_doc and isinstance(data_import_doc, string_types):
		data_import_doc = frappe.get_doc("Data Import", data_import_doc)
	if data_import_doc and from_data_import == "Yes":
		no_email = data_import_doc.no_email
		ignore_encoding_errors = data_import_doc.ignore_encoding_errors
		update_only = data_import_doc.only_update
		submit_after_import = data_import_doc.submit_after_import
		overwrite = data_import_doc.overwrite
		skip_errors = data_import_doc.skip_errors
	else:
		# extra input params
		params = json.loads(frappe.form_dict.get("params") or '{}')
		if params.get("submit_after_import"):
			submit_after_import = True
		if params.get("ignore_encoding_errors"):
			ignore_encoding_errors = True
		if not params.get("no_email"):
			no_email = False
		if params.get('update_only'):
			update_only = True
		if params.get('from_data_import'):
			from_data_import = params.get('from_data_import')
		if not params.get('skip_errors'):
			skip_errors = params.get('skip_errors')

	frappe.flags.in_import = True
	frappe.flags.mute_emails = no_email

	def get_data_keys_definition():
		return get_data_keys()

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

	def check_data_length():
		if not data:
			frappe.throw(_("No data found in the file. Please reattach the new file with data."))

	def get_start_row():
		for i, row in enumerate(rows):
			if row and row[0]==get_data_keys_definition().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 = list(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(get_data_keys_definition().doctype)
		if row_idx == -1: # old style
			return

		dt = None
		for i, d in enumerate(doctype_row[1:]):
			if d not in ("~", "-"):
				if d and doctype_row[i] in (None, '' ,'~', '-', _("DocType") + ":"):
					dt, parentfield = d, None
					# xls format truncates the row, so it may not have more columns
					if len(doctype_row) > i+2:
						parentfield = doctype_row[i+2]
					doctypes.append((dt, parentfield))
					column_idx_to_fieldname[(dt, parentfield)] = {}
					column_idx_to_fieldtype[(dt, parentfield)] = {}
				if dt:
					column_idx_to_fieldname[(dt, parentfield)][i+1] = rows[row_idx + 2][i+1]
					column_idx_to_fieldtype[(dt, parentfield)][i+1] = rows[row_idx + 4][i+1]

	def get_doc(start_idx):
		if doctypes:
			doc = {}
			attachments = []
			last_error_row_idx = None
			for idx in range(start_idx, len(rows)):
				last_error_row_idx = idx	# pylint: disable=W0612
				if (not doc) or main_doc_empty(rows[idx]):
					for dt, parentfield in doctypes:
						d = {}
						for column_idx in column_idx_to_fieldname[(dt, parentfield)]:
							try:
								fieldname = column_idx_to_fieldname[(dt, parentfield)][column_idx]
								fieldtype = column_idx_to_fieldtype[(dt, parentfield)][column_idx]

								if not fieldname or not rows[idx][column_idx]:
									continue

								d[fieldname] = rows[idx][column_idx]
								if fieldtype in ("Int", "Check"):
									d[fieldname] = cint(d[fieldname])
								elif fieldtype in ("Float", "Currency", "Percent"):
									d[fieldname] = flt(d[fieldname])
								elif fieldtype == "Date":
									if d[fieldname] and isinstance(d[fieldname], string_types):
										d[fieldname] = getdate(parse_date(d[fieldname]))
								elif fieldtype == "Datetime":
									if d[fieldname]:
										if " " in d[fieldname]:
											_date, _time = d[fieldname].split()
										else:
											_date, _time = d[fieldname], '00:00:00'
										_date = parse_date(d[fieldname])
										d[fieldname] = get_datetime(_date + " " + _time)
									else:
										d[fieldname] = None

								elif fieldtype in ("Image", "Attach Image", "Attach"):
									# added file to attachments list
									attachments.append(d[fieldname])

								elif fieldtype in ("Link", "Dynamic Link", "Data") and d[fieldname]:
									# as fields can be saved in the number format(long type) in data import template
									d[fieldname] = cstr(d[fieldname])

							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 and doc.get("name"):
									d['parent'] = doc["name"]
								d['parenttype'] = doctype
								d['parentfield'] = parentfield
								doc.setdefault(d['parentfield'], []).append(d)
				else:
					break

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

	# used in testing whether a row is empty or parent row or child row
	# checked only 3 first columns since first two columns can be blank for example the case of
	# importing the item variant where item code and item name will be blank.
	def main_doc_empty(row):
		if row:
			for i in range(3,0,-1):
				if len(row) > i and row[i]:
					return False
		return True

	def validate_naming(doc):
		autoname = frappe.get_meta(doctype).autoname
		if autoname:
			if autoname[0:5] == 'field':
				autoname = autoname[6:]
			elif autoname == 'naming_series:':
				autoname = 'naming_series'
			else:
				return True

			if (autoname not in doc) or (not doc[autoname]):
				from frappe.model.base_document import get_controller
				if not hasattr(get_controller(doctype), "autoname"):
					frappe.throw(_("{0} is a mandatory field".format(autoname)))
		return True

	users = frappe.db.sql_list("select name from tabUser")
	def prepare_for_insert(doc):
		# don't block data import if user is not set
		# migrating from another system
		if not doc.owner in users:
			doc.owner = frappe.session.user
		if not doc.modified_by in users:
			doc.modified_by = frappe.session.user

	def is_valid_url(url):
		is_valid = False
		if url.startswith("/files") or url.startswith("/private/files"):
			url = get_url(url)

		try:
			r = requests.get(url)
			is_valid = True if r.status_code == 200 else False
		except Exception:
			pass

		return is_valid

	def attach_file_to_doc(doctype, docname, file_url):
		# check if attachment is already available
		# check if the attachement link is relative or not
		if not file_url:
			return
		if not is_valid_url(file_url):
			return

		files = frappe.db.sql("""Select name from `tabFile` where attached_to_doctype='{doctype}' and
			attached_to_name='{docname}' and (file_url='{file_url}' or thumbnail_url='{file_url}')""".format(
				doctype=doctype,
				docname=docname,
				file_url=file_url
			))

		if files:
			# file is already attached
			return

		save_url(file_url, None, doctype, docname, "Home/Attachments", 0)

	# header
	filename, file_extension = ['','']
	if not rows:
		from frappe.utils.file_manager import get_file # get_file_doc
		fname, fcontent = get_file(data_import_doc.import_file)
		filename, file_extension = os.path.splitext(fname)

		if file_extension == '.xlsx' and from_data_import == 'Yes':
			from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file
			rows = read_xlsx_file_from_attached_file(file_id=data_import_doc.import_file)

		elif file_extension == '.csv':
			from frappe.utils.csvutils import read_csv_content
			rows = read_csv_content(fcontent, ignore_encoding_errors)

		else:
			frappe.throw(_("Unsupported File Format"))

	start_row = get_start_row()
	header = rows[:start_row]
	data = rows[start_row:]
	try:
		doctype = get_header_row(get_data_keys_definition().main_table)[1]
		columns = filter_empty_columns(get_header_row(get_data_keys_definition().columns)[1:])
	except:
		frappe.throw(_("Cannot change header content"))
	doctypes = []
	column_idx_to_fieldname = {}
	column_idx_to_fieldtype = {}

	if skip_errors:
		data_rows_with_error = header

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

	parenttype = get_header_row(get_data_keys_definition().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}

	# Throw expception in case of the empty data file
	check_data_length()
	make_column_map()
	total = len(data)

	if validate_template:
		if total:
			data_import_doc.total_rows = total
		return True

	if overwrite==None:
		overwrite = params.get('overwrite')

	# delete child rows (if parenttype)
	parentfield = None
	if parenttype:
		parentfield = get_parent_field(doctype, parenttype)

		if overwrite:
			delete_child_rows(data, doctype)

	import_log = []
	def log(**kwargs):
		if via_console:
			print((kwargs.get("title") + kwargs.get("message")).encode('utf-8'))
		else:
			import_log.append(kwargs)

	def as_link(doctype, name):
		if via_console:
			return "{0}: {1}".format(doctype, name)
		else:
			return getlink(doctype, name)

	# publish realtime task update
	def publish_progress(achieved, reload=False):
		if data_import_doc:
			frappe.publish_realtime("data_import_progress", {"progress": str(int(100.0*achieved/total)),
				"data_import": data_import_doc.name, "reload": reload}, user=frappe.session.user)


	error_flag = rollback_flag = False

	batch_size = frappe.conf.data_import_batch_size or 1000

	for batch_start in range(0, total, batch_size):
		batch = data[batch_start:batch_start + batch_size]

		for i, row in enumerate(batch):
			# bypass empty rows
			if main_doc_empty(row):
				continue

			row_idx = i + start_row
			doc = None

			publish_progress(i)

			try:
				doc, attachments, last_error_row_idx = get_doc(row_idx)
				validate_naming(doc)
				if pre_process:
					pre_process(doc)

				original = None
				if parentfield:
					parent = frappe.get_doc(parenttype, doc["parent"])
					doc = parent.append(parentfield, doc)
					parent.save()
				else:
					if overwrite and doc.get("name") and frappe.db.exists(doctype, doc["name"]):
						original = frappe.get_doc(doctype, doc["name"])
						original_name = original.name
						original.update(doc)
						# preserve original name for case sensitivity
						original.name = original_name
						original.flags.ignore_links = ignore_links
						original.save()
						doc = original
					else:
						if not update_only:
							doc = frappe.get_doc(doc)
							prepare_for_insert(doc)
							doc.flags.ignore_links = ignore_links
							doc.insert()
					if attachments:
						# check file url and create a File document
						for file_url in attachments:
							attach_file_to_doc(doc.doctype, doc.name, file_url)
					if submit_after_import:
						doc.submit()

				# log errors
				if parentfield:
					log(**{"row": doc.idx, "title": 'Inserted row for "%s"' % (as_link(parenttype, doc.parent)),
						"link": get_url_to_form(parenttype, doc.parent), "message": 'Document successfully saved', "indicator": "green"})
				elif submit_after_import:
					log(**{"row": row_idx + 1, "title":'Submitted row for "%s"' % (as_link(doc.doctype, doc.name)),
						"message": "Document successfully submitted", "link": get_url_to_form(doc.doctype, doc.name), "indicator": "blue"})
				elif original:
					log(**{"row": row_idx + 1,"title":'Updated row for "%s"' % (as_link(doc.doctype, doc.name)),
						"message": "Document successfully updated", "link": get_url_to_form(doc.doctype, doc.name), "indicator": "green"})
				elif not update_only:
					log(**{"row": row_idx + 1, "title":'Inserted row for "%s"' % (as_link(doc.doctype, doc.name)),
						"message": "Document successfully saved", "link": get_url_to_form(doc.doctype, doc.name), "indicator": "green"})
				else:
					log(**{"row": row_idx + 1, "title":'Ignored row for %s' % (row[1]), "link": None,
						"message": "Document updation ignored", "indicator": "orange"})

			except Exception as e:
				error_flag = True

				# build error message
				if frappe.local.message_log:
					err_msg = "\n".join(['<p class="border-bottom small">{}</p>'.format(json.loads(msg).get('message')) for msg in frappe.local.message_log])
				else:
					err_msg = '<p class="border-bottom small">{}</p>'.format(cstr(e))

				error_trace = frappe.get_traceback()
				if error_trace:
					error_log_doc = frappe.log_error(error_trace)
					error_link = get_url_to_form("Error Log", error_log_doc.name)
				else:
					error_link = None

				log(**{
					"row": row_idx + 1,
					"title": 'Error for row %s' % (len(row)>1 and frappe.safe_decode(row[1]) or ""),
					"message": err_msg,
					"indicator": "red",
					"link":error_link
				})

				# data with error to create a new file
				# include the errored data in the last row as last_error_row_idx will not be updated for the last row
				if skip_errors:
					if last_error_row_idx == len(rows)-1:
						last_error_row_idx = len(rows)
					data_rows_with_error += rows[row_idx:last_error_row_idx]
				else:
					rollback_flag = True
			finally:
				frappe.local.message_log = []

		start_row += batch_size
		if rollback_flag:
			frappe.db.rollback()
		else:
			frappe.db.commit()

	frappe.flags.mute_emails = False
	frappe.flags.in_import = False

	log_message = {"messages": import_log, "error": error_flag}
	if data_import_doc:
		data_import_doc.log_details = json.dumps(log_message)

		import_status = None
		if error_flag and data_import_doc.skip_errors and len(data) != len(data_rows_with_error):
			import_status = "Partially Successful"
			# write the file with the faulty row
			from frappe.utils.file_manager import save_file
			file_name = 'error_' + filename + file_extension
			if file_extension == '.xlsx':
				from frappe.utils.xlsxutils import make_xlsx
				xlsx_file = make_xlsx(data_rows_with_error, "Data Import Template")
				file_data = xlsx_file.getvalue()
			else:
				from frappe.utils.csvutils import to_csv
				file_data = to_csv(data_rows_with_error)
			error_data_file = save_file(file_name, file_data, "Data Import",
				data_import_doc.name,  "Home/Attachments")
			data_import_doc.error_file = error_data_file.file_url

		elif error_flag:
			import_status = "Failed"
		else:
			import_status = "Successful"

		data_import_doc.import_status = import_status
		data_import_doc.save()
		if data_import_doc.import_status in ["Successful", "Partially Successful"]:
			data_import_doc.submit()
			publish_progress(100, True)
		else:
			publish_progress(0, True)
		frappe.db.commit()
	else:
		return log_message