Custom Button Error

I want to create Sales Invoice from the Quotation. For the same, I have added Custom Script Button has appeared fine, but when I click on that button, getting an error message.

Custom Script:

frappe.ui.form.on("Quotation", "refresh", function(frm){
    if(cur_frm.doc.docstatus == 1 && cur_frm.doc.status!=='Lost' && cur_frm.doc.quotation_to == 'Customer') {
      frm.add_custom_button(__("Create Sales Invoice"), function() {
        frappe.model.open_mapped_doc({
                        method : "erpnext.selling.doctype.quotation.quotation._make_sales_invoice",
                        frm : cur_frm
                })
         })
    }
});

Error Message:

Traceback (most recent call last):
  File "/home/frappe/benches/bench-2017-01-27/apps/frappe/frappe/app.py", line 55, in application
    response = frappe.handler.handle()
  File "/home/frappe/benches/bench-2017-01-27/apps/frappe/frappe/handler.py", line 19, in handle
    execute_cmd(cmd)
  File "/home/frappe/benches/bench-2017-01-27/apps/frappe/frappe/handler.py", line 40, in execute_cmd
    ret = frappe.call(method, **frappe.form_dict)
  File "/home/frappe/benches/bench-2017-01-27/apps/frappe/frappe/__init__.py", line 897, in call
    return fn(*args, **newargs)
  File "/home/frappe/benches/bench-2017-01-27/apps/frappe/frappe/model/mapper.py", line 16, in make_mapped_doc
    method = frappe.get_attr(method)
  File "/home/frappe/benches/bench-2017-01-27/apps/frappe/frappe/__init__.py", line 877, in get_attr
    return getattr(get_module(modulename), methodname)
AttributeError: 'module' object has no attribute '_make_sales_invoice'

Help will be highly appreciated.

@haitham,

Please check if you have _make_sales_invoice method in quotation.py file.

Thanks,
Makarand

No. It is in an account hosted with ERPNext.

@haitham,

Can you share the use case? Currently _make_sales_invoice method is not available in the quotation.py. In order to create the Sales Invoice from the quotation, you will need to create the custom app and write a method to create an invoice from Quotation.

You will need to write a similar method to make_sales_order then call your custom app method instead.

Thanks,
Makarand

My use case is that, once I receive confirmation from the Customer on Quotation, I need to create Sales Invoice from Quotation itself.

Since my ERPNext account is hosted on erpnext.com, I cannot create custom application. Any other approach to cater to this requirement in the hosted account?

@haitham,

Can you please raise a github issue here?

Thanks,
Makarand

@haitham
you can also try this.
#1. add below code in you quotation.py file

@frappe.whitelist()
def make_sales_invoice(source_name, target_doc=None):
	return _make_sales_invoice(source_name, target_doc)

def _make_sales_invoice(source_name, target_doc=None, ignore_permissions=False):
	customer = _make_customer(source_name, ignore_permissions)

	def set_missing_values(source, target):
		if customer:
			target.customer = customer.name
			target.customer_name = customer.customer_name
		target.ignore_pricing_rule = 1
		target.flags.ignore_permissions = ignore_permissions
		target.run_method("set_missing_values")
		target.run_method("calculate_taxes_and_totals")

	doclist = get_mapped_doc("Quotation", source_name, {
			"Quotation": {
				"doctype": "Sales Invoice",
				"validation": {
					"docstatus": ["=", 1]
				}
			},
			"Quotation Item": {
				"doctype": "Sales Invoice Item",
				"field_map": {
					"parent": "prevdoc_docname"
				}
			},
			"Sales Taxes and Charges": {
				"doctype": "Sales Taxes and Charges",
				"add_if_empty": True
			},
			"Sales Team": {
				"doctype": "Sales Team",
				"add_if_empty": True
			}
		}, target_doc, set_missing_values, ignore_permissions=ignore_permissions)

	# postprocess: fetch shipping address, set missing values

	return doclist

#2. chege in quotation.js file

From

frappe.ui.form.on("Quotation", "refresh", function(frm){
    if(cur_frm.doc.docstatus == 1 && cur_frm.doc.status!=='Lost' && cur_frm.doc.quotation_to == 'Customer') {
      frm.add_custom_button(__("Create Sales Invoice"), function() {
        frappe.model.open_mapped_doc({
                        method : "erpnext.selling.doctype.quotation.quotation._make_sales_invoice",
                        frm : cur_frm
                })
         })
    }
});

to

frappe.ui.form.on("Quotation", "refresh", function(frm){
    if(cur_frm.doc.docstatus == 1 && cur_frm.doc.status!=='Lost' && cur_frm.doc.quotation_to == 'Customer') {
      frm.add_custom_button(__("Create Sales Invoice"), function() {
        frappe.model.open_mapped_doc({
                        method : "erpnext.selling.doctype.quotation.quotation.make_sales_invoice",
                        frm : cur_frm
                })
         })
    }
});

Thanks

1 Like

Thanks mate. But since my account is hosted with ERPNext, I cannot edit .py files.