Work order from Sales Order using API

I’ve posted a similar question recently. But I still feel I’m missing something pertaining to a whitelisted function in erpnext/selling/doctype/sales_order/sales_order.py.

The function definition is: def make_work_orders(items, sales_order, company, project=None)

Tracing the code… It looks like ERPNext internally gets the first parameter, items, from a call to a method on the Python sales_order object with the following definition: def get_work_order_items(self, for_raw_material_request=0):
But since this is a method on a Python object I can’t access it through the API.

I’m wondering how the developers expected someone to use the make_work_orders function using the API? I can call various other functions and stitch together the ‘items’ array, but it seems that if the function was whitelisted… it should do what it says it does without me having to dive under the covers to hack together the parameters. Seems the white listed function could easily have instantiated a sales_order object given a sales order name and then called the get_work_order_items method internally.

What am I missing? Is there some other function I can call to get this information and feed it into the make_work_orders function?

Am I misunderstanding what the reason for whitelisting a function is? I currently believe it is so that it can be called by a REST API.

Is the function written the way it is in order to allow creating work orders for only some of the items on the sales order? If so wouldn’t it make sense for the first parameter to be an array of dicts with partnumber and quantity to create the work orders from.?

True, you cannot use this the way you would expect.

ERPNext still needs to whitelist the method to be able to call it from JavaScript. Whitelisting is mostly used for internal purposes.

Thank you. That clears some things up for me. I’ve created a Github issue for this to add a whitelisted function to get workOrderItems. I’ll see if that picks up any traction. But in the meantime I’ll just customize my local code.

Came across a really cool feature of Frappe. Server side scripts. Which allow you to add custom scripts in a couple of ways. I was able to just add a simple function to the API. The documentation for server side scripts is here: https://docs.erpnext.com/docs/user/manual/en/customize-erpnext/server-script

And just incase anyone can be helped by this… My script is:

so = frappe.get_doc("Sales Order", frappe.form_dict.sales_order)
woi = {'items':so.get_work_order_items()}
frappe.response['message'] = woi

Since I’m a noob to the ERPNext world, it took me a minute to figure out how to make this function work. In a custom script you don’t need to supply the function signature. That’s handled by the frame work. You just supply the body of the function. You can pass parameters to the function and retrieve them using the frappe.form_dict object, which is just a dictionary of parameters or form fields. and you return your value using frappe.response object in the message field.

This is a very nice way to allow developers to extend the functionality of ERPNext while isolating the code changes so future upgrades won’t cause merge conflicts!

1 Like

Try if /api/method/runserverobj works.