Error after creating Sales Order

I have the function which creates List of Sales Order Item:

def get_sales_orders_items(plot_of_lands, docname):
    list_of_sales_order_items = []
    for plot in plot_of_lands:
        sales_order = frappe.new_doc("Sales Order Item")
        sales_order.item_code = plot.item_code
        sales_order.qty = 1.0
        sales_order.delivery_date = datetime.datetime.now().date()
        sales_order.amount = 0.0
        sales_order.base_amount = 0.0
        sales_order.rate = 0.0
        sales_order.item_name = plot.item_code
        sales_order.description = "qwer"
        sales_order.uom = "Nos"
        sales_order.conversion_factor = 1
        sales_order.parent = docname + " Order" #"LND-SAL-201900043"
        sales_order.parenttype = "Sales Order"
        sales_order.insert()
        sales_order.save()
        list_of_sales_order_items.append(sales_order)
    return list_of_sales_order_items

I create the Sales Order:

sales_order = frappe.new_doc("Sales Order")  # сŠ¾Š·Š“Š°ŠµŠ¼ sales Order Š±ŠµŠ· Item
    sales_order.name = docname + " Order"
    sales_order.items = get_sales_orders_items(land_sales.plot_of_lands, docname)

And take the exception:

Traceback (most recent call last):
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/app.py", line 61, in application
    response = frappe.handler.handle()
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/handler.py", line 21, in handle
    data = execute_cmd(cmd)
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/handler.py", line 56, in execute_cmd
    return frappe.call(method, **frappe.form_dict)
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/__init__.py", line 1036, in call
    return fn(*args, **newargs)
  File "/home/emil/Desktop/frappe-bench/apps/erpnext_safer/erpnext_safer/customizations/Land_Sales/land_sales_controller.py", line 46, in generate_sales_order
    sales_order.save()
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 260, in save
    return self._save(*args, **kwargs)
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 283, in _save
    self.insert()
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 222, in insert
    self.run_before_save_methods()
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 876, in run_before_save_methods
    self.run_method("validate")
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 772, in run_method
    out = Document.hook(fn)(self, *args, **kwargs)
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 1048, in composer
    return composed(self, method, *args, **kwargs)
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 1031, in runner
    add_to_return_value(self, fn(self, *args, **kwargs))
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 766, in <lambda>
    fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/selling/doctype/sales_order/sales_order.py", line 34, in validate
    super(SalesOrder, self).validate()
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/controllers/selling_controller.py", line 39, in validate
    super(SellingController, self).validate()
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/controllers/stock_controller.py", line 21, in validate
    super(StockController, self).validate()
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/controllers/accounts_controller.py", line 72, in validate
    self.calculate_taxes_and_totals()
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/controllers/accounts_controller.py", line 160, in calculate_taxes_and_totals
    calculate_taxes_and_totals(self)
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/controllers/taxes_and_totals.py", line 15, in __init__
    self.calculate()
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/controllers/taxes_and_totals.py", line 22, in calculate
    self._calculate()
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/controllers/taxes_and_totals.py", line 36, in _calculate
    self.calculate_item_values()
  File "/home/emil/Desktop/frappe-bench/apps/erpnext/erpnext/controllers/taxes_and_totals.py", line 61, in calculate_item_values
    self.doc.round_floats_in(item)
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/document.py", line 1103, in round_floats_in
    doc.set(fieldname, flt(doc.get(fieldname), self.precision(fieldname, doc.parentfield)))
  File "/home/emil/Desktop/frappe-bench/apps/frappe/frappe/model/base_document.py", line 690, in precision
    if df.fieldtype in ("Currency", "Float", "Percent"):
AttributeError: 'NoneType' object has no attribute 'fieldtype'

I understood, that this exception threw after when i set in ā€œSales Order Itemā€ qty = 1. But if I remove this field validation will threw me, that it is necessary field. It is possible to create ā€œSales Orderā€ on backend?

i did not try it in your way before, by creating child table then link many of them to one table field
i think it should be one child table linked with doctype field table type ā€¦
i would do something like this :

let get_sales_orders_items return list of each row what it contains with
sales_order.item_code = plot.item_code
sales_order.qty = 1.0
sales_order.delivery_date = datetime.datetime.now().date()
sales_order.amount = 0.0
sales_order.base_amount = 0.0
sales_order.rate = 0.0
sales_order.item_name = plot.item_code
sales_order.description = ā€œqwerā€
sales_order.uom = ā€œNosā€
sales_order.conversion_factor = 1

then sales_order.items will be done by new for loop on the returning array
// this add new row to child table
row = sales_order.append(ā€˜child table field nameā€™, {})
row.rate = i.rate
row.amount = value_from_list_itreatation ect i.amount

after that you save the sales order ā€¦

1 Like