Using rest api saving order

hi i am trying to insert sales invoice using rest api

using https://frappe.github.io/erpnext/current/models/accounts/sales_invoice
as guidelines

the data i am sending is
data{
“selling_price_list”:“Standard Selling”,
“source”:“Existing Customer”,
“posting_date”:“2016-09-26”,
“due_date”:“2016-10-21”,
“items”:{
“qty”:1,
“stock_uom”:“Nos”,
“warehouse”:“Finished Goods - PSM”,
“item_name”:“product name”,
“rate”:“100”,
“amount”:100,
“base_rate”:“100”,
“item_code”:“sero-2469”
},
“is_pos”:0,
“conversion_rate”:1,
“customer_name”:“Chinmay Sekhri”,
“commission_rate”:0,
“company”:“PSM”,
“naming_series”:“SINV-”,
“paid_amount”:0,
“remarks”:“No Remarks”,
“debit_to”:“Debtors - PSM”,
“plc_conversion_rate”:1
}

geting responce of
Traceback (most recent call last):
File “/home/ubuntu/frappe-bench/apps/frappe/frappe/app.py”, line 60, in application
response = frappe.api.handle()
File “/home/ubuntu/frappe-bench/apps/frappe/frappe/api.py”, line 115, in handle
“data”: frappe.get_doc(data).insert().as_dict()
File “/home/ubuntu/frappe-bench/apps/frappe/frappe/model/document.py”, line 212, in insert
self.run_before_save_methods()
File “/home/ubuntu/frappe-bench/apps/frappe/frappe/model/document.py”, line 703, in run_before_save_methods
self.set_title_field()
File “/home/ubuntu/frappe-bench/apps/frappe/frappe/model/document.py”, line 347, in set_title_field
self.set(df.fieldname, df.default.format(**get_values()))
File “/home/ubuntu/frappe-bench/apps/frappe/frappe/model/document.py”, line 333, in get_values
values = self.as_dict()
File “/home/ubuntu/frappe-bench/apps/frappe/frappe/model/base_document.py”, line 243, in as_dict
doc[df.fieldname] = [d.as_dict(no_nulls=no_nulls) for d in children]
AttributeError: ‘unicode’ object has no attribute ‘as_dict’

Your items should be in a list, like this

data={“customer”: “YYY Inc”,“items”: [{“name”:“Premium Delivery Service”}]}

1 Like

after correcting it is now giving error

File “/home/ubuntu/frappe-bench/apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py”, line 80, in validate
self.set_against_income_account()

File “/home/ubuntu/frappe-bench/apps/erpnext/erpnext/accounts/doctype/sales_invoice/sales_invoice.py”, line 324, in set_against_income_account
self.against_income_account = ‘,’.join(against_acc)
TypeError: sequence item 0: expected string or Unicode, NoneType found

do we have some sample that we can reffer to for api for importing orders from api.
this is even when i have set “against_income_account”:“Sales - PSM”
please help me enter order with minimum variables so as to sucessfully save without manual intervention.
minimum i want to send is product code and product price and qty . rest all is extra for me .
eagerly waiting for your reply.

Have you made changes on the default chart of account? If yes, to make sure the API works I would advise to first test it on the default CoA then do you changes after. Also can you make sale invoices directly from the web interface.

You should also check you have not forgotten any mandatory field.
If it can be of any help, below is a python script I used to import supplier invoices from OpenERP for reference:

def supplier_invoice():
    cur2 = conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
    cur.execute("select account_invoice.id,account_invoice.type,date_invoice, res_partner.name as partner_name,amount_untaxed,amount_tax,amount_total,account_invoice.name,state from account_invoice, res_partner where res_partner.id=account_invoice.partner_id LIMIT 1000")
    count = 1
    failed = []


    for invoice in cur:
        if invoice['type']=="in_invoice":
            doc = {
                "doctype": "Purchase Invoice",
                "supplier": invoice['partner_name'],
                "title": invoice['name'],
                "contact_display": invoice['name'],
                "transaction_date": str(invoice['date_invoice']),
                "company": "XXXXXXXXXXXX",
                'currency': 'RWF',
                'conversion_rate': 1.0,
                'price_list_currency': 'RWF',
                'plc_conversion_rate': 1.0,
                'naming_series': 'PINV-',
                'status': 'Draft',
                'credit_to': '522-Non exempted sales - A',
                "items":[]
            }

            query = """
            select * from account_invoice_line where invoice_id=%i
            """ % int(invoice['id'])
            cur2.execute(query)
            for invoice_item in cur2:
                print invoice_item
                item = client.get_doc('Item',
                        filters=[["Item", "openerp_id", "=", int(invoice_item['product_id'])]],
                        fields=["name", "item_name", "item_code"])
                print item
                doc['items'].append({
                    'qty': float(invoice_item['quantity']),
                    'doctype':'Purchase Invoice Item',
                    'item_code':item[0]['item_code'],
                    'item_name':item[0]['item_name'],
                    'description':item[0]['item_name'],
                    'rate': float(invoice_item['price_unit']),
                    'amount': 5000
                    })
                print doc
            try:
                client.insert(doc)
            except:
               traceback.print_exc()
            count += 1
        else:
            pass
1 Like

i have updated json to below now
Sales incoice is generated but saving as draft.
please help me save it as confirmed / delivered or to deliver

{“naming_series”:“SINV-”,“customer”:“Chinmay
Sekhri”,“customer_name”:“Chinmay
Sekhri”,“posting_date”:“26-09-2016”,“company”:“PT Seroya
Mandiri”,“conversion_rate”:“1”,“selling_price_list”:“Standard
Selling”,“price_list_currency”:“IDR”,“plc_conversion_rate”:“1”,“items”:[{“qty”:1,“stock_uom”:“Nos”,“rate”:“81600”,“amount”:81600,“base_rate”:“81600”,“item_code”:“sero-2469”}],“base_net_total”:81600,“base_grand_total”:81600,“grand_total”:81600,“debit_to”:"Debtors

  • PSM",“total_advance”:81600,“source”:“Existing
    Customer”,“due_date”:“30-09-2016”,“update_stock”:“1”,“is_pos”:“1”,“submit_on_creation”:“1”,“against_income_account”:"Sales
  • PSM"}

Are you able to manually submit the invoice (i.e. if you log in)?

yes once i login into system i can save the sales invoice .

first it saves it as draft then it asks for confirmation.

once confirmed it saves it and reduces stock .

on api i am able to import sales invoice . i am stuck at saving as
draft. i want to be able to save as confirmed and reduce stock.

Ok, interesting, was just trying to confirm that there wasn’t an error preventing submission.

I’ve had success with sales orders but haven’t tried sales invoices, my configuration looked about the same as yours as well. Not sure how to proceed, sorry :S

EDIT: Try sending with docstatus: 1 as referenced here -> Submit_on_creation has no effect

@alec_ruizramon1

if i do sales order then will it reduce stock once gentrated by api?

as main reason i am using erp is as inventory management.and not gentrating/managing sales

i just want admin to enter new inventory rest all new item addition and sales generated by api.

if you gave an alternate please provide so.

Sales order won’t reduce stock, either delivery note or sales invoice will.

I only have experience using delivery note to reduce stock, not sales invoices, so I’m not familiar there.

1 Like

@alec_ruizramon1
can u share delivery note and sales order code so can cross check things and get it done asap. preferred using rest api

Sorry, should have been more clear - I don’t use the functionality through the API for that, just the desk UI.

@chinmay

Try adding

doc.submit()

after you insert

can u explain how to do doc.submit() on rest api.
if possible an example as well.

@chinmay did you found any solution for how to submit doc on rest api

@rmehta This is an issue for me too where we have written our App for selling to customers but all the Invoices are getting saved as Draft instead of Paid & inventory is not being deducted.
My code :-

    String requiredBody = "https://tooracart.erpnext.com/api/resource/Sales%20Invoice";
    String data = "{" +
            Utility.setdoubleQuote("naming_series") + ":" + Utility.setdoubleQuote(SalesInvoiceSeries) + "," +
            Utility.setdoubleQuote("customer") + ":" + Utility.setdoubleQuote(cstmr) + "," +
            Utility.setdoubleQuote("customer_name") + ":" + Utility.setdoubleQuote(cstmr) + "," +
            Utility.setdoubleQuote("is_pos") + ":" + Utility.setdoubleQuote("1") + "," +
            Utility.setdoubleQuote("company") + ":" + Utility.setdoubleQuote(company) + "," +
            Utility.setdoubleQuote("posting_date") + ":" + Utility.setdoubleQuote(Utility.getCurrentDate()) + "," +
            Utility.setdoubleQuote("due_date") + ":" + Utility.setdoubleQuote(Utility.getCurrentDate()) + "," +

// Utility.setdoubleQuote(“is_return”) + “:” + Utility.setdoubleQuote(“0”) + “,” +
Utility.setdoubleQuote(“currency”) + “:” + Utility.setdoubleQuote(“INR”) + “,” +
Utility.setdoubleQuote(“selling_price_list”) + “:” + Utility.setdoubleQuote(sellingPricelist) + “,” +
Utility.setdoubleQuote(“price_list_currency”) + “:” + Utility.setdoubleQuote(“INR”) + “,” +
Utility.setdoubleQuote(“update_stock”) + “:” + Utility.setdoubleQuote(“1”) + “,” +
Utility.setdoubleQuote(“discount_amount”) + “:” + getDiscountAmount() + “,” +
Utility.setdoubleQuote(“apply_discount_on”) + “:” + Utility.setdoubleQuote(“Grand Total”) + “,” +
Utility.setdoubleQuote(“cash_bank_account”) + “:” + Utility.setdoubleQuote(CashAccount) + “,” +
Utility.setdoubleQuote(“write_off_amount”) + “:” + “0.0” + “,” +
Utility.setdoubleQuote(“debit_to”) + “:” + Utility.setdoubleQuote(DebitedTo) + “,” +
// Utility.setdoubleQuote(“party_account_currency”) + “:” + Utility.setdoubleQuote(“INR”) + “,” +
Utility.setdoubleQuote(“remarks”) + “:” + Utility.setdoubleQuote(“via b2b mobile app”) + “,” +
Utility.setdoubleQuote(“customer_group”) + “:” + Utility.setdoubleQuote(“Individual”) + “,” +
Utility.setdoubleQuote(“submit_on_creation”) + “:” + Utility.setdoubleQuote(“1”) + “,” +
Utility.setdoubleQuote(“against_income_account”) + “:” + Utility.setdoubleQuote(IncomeAccount) + “,” +
Utility.setdoubleQuote(“paid_amount”) + “:” + total_amount.getText().toString() + “,” +
Utility.setdoubleQuote(“mode_of_payment”) + “:” + Utility.setdoubleQuote(“Cash”) + “,” +
Utility.setdoubleQuote(“is_opening”) + “:” + Utility.setdoubleQuote(“No”) + “,” +
Utility.setdoubleQuote(“status”) + “:” + Utility.setdoubleQuote(“Paid”) + “,” +
Utility.setdoubleQuote(“amount_received”) + “:” + Utility.setdoubleQuote(amountReceived.getText().toString()) + “,” +
Utility.setdoubleQuote(“amount_returned”) + “:” + Utility.setdoubleQuote(amountReturn.getText().toString()) + “,” +
Utility.setdoubleQuote(“items”) + “:[”;

    String ItemBody = "{" +
            Utility.setdoubleQuote("item_code") + ":" + Utility.setdoubleQuote(tempdb.getallCheckout(client).get(0).getProductCode()) + "," +
            Utility.setdoubleQuote("item_name") + ":" + Utility.setdoubleQuote(tempdb.getallCheckout(client).get(0).getProductName()) + "," +
            Utility.setdoubleQuote("qty") + ":" + Utility.setdoubleQuote(tempdb.getallCheckout(client).get(0).getProductQuantity().replace(" kg", "")) + "," +
            Utility.setdoubleQuote("rate") + ":" + Utility.setdoubleQuote(tempdb.getallCheckout(client).get(0).getProductPrice()) + "," +

// Utility.setdoubleQuote(“income_account”) + “:” + Utility.setdoubleQuote(IncomeAccount) + “,” +
Utility.setdoubleQuote(“expense_account”) + “:” + Utility.setdoubleQuote(ExpenseAccount) + “,” +
Utility.setdoubleQuote(“cost_center”) + “:” + Utility.setdoubleQuote(costCenter) + “,” +
Utility.setdoubleQuote(“warehouse”) + “:” + Utility.setdoubleQuote(warehouse) + “,” +
Utility.setdoubleQuote(“parenttype”) + “:” + Utility.setdoubleQuote(“Sales%20Invoice”) + “,” +
Utility.setdoubleQuote(“parentfield”) + “:” + Utility.setdoubleQuote(“items”) + “}”;

    String PaymentBody = "]," +
            Utility.setdoubleQuote("payments") + ":[{" +
            Utility.setdoubleQuote("mode_of_payment") + ":" + Utility.setdoubleQuote("Cash") + "," +
            Utility.setdoubleQuote("amount") + ":" + amount.getText().toString() + "," +
            Utility.setdoubleQuote("account") + ":" + Utility.setdoubleQuote(CashAccount) +
            "}]";


    String ClosingBody = "}";

For those facing this issue

call the after_insert method in your doctype
then self.submit()

def after_insert(self):
      self.submit()

this solved the issues for me

1 Like