Creating Sales Invoices Programmatically

I am integrating ERPNext with a legacy sales hardware. Here is is my JSON

                "doctype": "Sales Invoice",
                "customer": customer['name'],
                "title": invoice['invoice_ref'],
                "contact_display": customer['name'],
                "posting_date": str(invoice['creation_date']),
                "company": "EBM Ltd",
                'currency': 'RWF',
                'debit_to': 'Debtors - EL',
                'conversion_rate': 1.0,
                'selling_price_list': 'Standard Selling',
                'price_list_currency': 'RWF',
                'plc_conversion_rate': 1.0,
                'naming_series': 'SINV-',
                'status': 'Draft',
                "items": [
                        'qty': 1,
                        'doctype': 'Sales Order Item',
                        'item_code': 'Water Consumption',
                        'item_name': 'Water Consumption',
                        'description': 'Water Consumption',
                        'income_accont': 'Sales - EL',
                        'cost_center': 'Main - EL',
                        'rate': 100,
                        'price_list_rate': 100,
                        'amount': 100


I have been trying the insert this for the past 2 days but get the error

File "/home/frappe/frappe-bench/apps/frappe/frappe/model/", line 932, in round_floats_in
    doc.set(fieldname, flt(doc.get(fieldname), self.precision(fieldname, doc.parentfield)))
  File "/home/frappe/frappe-bench/apps/frappe/frappe/model/", line 686, in precision
    if df.fieldtype in ("Currency", "Float", "Percent"):
AttributeError: 'NoneType' object has no attribute 'fieldtype'

ERPNext: v7.2.21

Frappe Framework: v7.2.17

Possibly you would want to check the precision set for the currency fields, please refer to the following link, based on what you have set up you might have to pass values like 100.000 or 100.00

I tried this but didn’t help. However you pointed me at looking at the precision method in File “/home/frappe/frappe-bench/apps/frappe/frappe/model/”, line 686, in precision

The method is looking for fields that don’t exist in Sales Invoice Item doctype. I added the fields on the doctype and the error deseappears for that particular field but the error keeps complaining about more missing fields. I have added the fields projected_qty, ordered_qty, returned_qty, billed_amt, valuation_rate. I am probably missing out something simple, I don’t think I really needed to add these fields

I was able to go past the error by manually adding missing fields. Overall I had to add the fields projected_qty, ordered_qty, returned_qty, billed_amt, valuation_rate, planned_qty, produced_qty and gross_profit. Now I am getting a new error:

file "/home/frappe/frappe-bench/apps/frappe/frappe/model/", line 650, in <lambda>
    fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
  File "/home/frappe/frappe-bench/apps/erpnext/erpnext/accounts/doctype/sales_invoice/", line 82, in validate
  File "/home/frappe/frappe-bench/apps/erpnext/erpnext/accounts/doctype/sales_invoice/", line 364, in set_against_income_account
    if d.income_account not in against_acc:
AttributeError: 'SalesOrderItem' object has no attribute 'income_account'

Creating an invoice through web form works well, the problem is in the way i am sending API request I can’t figure out

make sure the Item you are entering in the sales order has a default income account entered in ERPNext.

Either set default income account in Item master or provide income account while creating sales invoice via API.

I have tried both giving the same error.
I reverted to a workaround, I first created a sales order and called make_sales_invoice and it worked