Epicor functions are incredibly powerful and expose a lot of functionality without the baggage of having to do multiple requests to the REST API. But they also come with limitations one of which becomes very evident once you start trying to create complex functionality. Let’s take a look at the first time I tried to use them.
I needed to create a function that would fulfill (completely or partially) a customer order from a custom-made website but using the rest api proved to be far too because of the size of some of the orders. Some contained 50+ lines and that meant waiting for the pack num or ship-hed to be created as well as each of the lines and that goes with all the extra checks of inventory availability, part location checks and so epicor functions became the best option to avoid multiple http requests and to access the Epicor business objects directly. This meant that my request needed to include the site id, the order number as well as all the lines that I wished to fulfill from the order, so my request object needed to look something like this
{
"orderNum": 5392,
"plant": "EPIC06",
"orderLines": [
{
"part": "00C2A",
"lotNum": "",
"orderLine": 1,
"orderRelNum": 1,
"warehouse": "CHI",
"bin": "01-01-01",
"qty": 10,
"uom": "EA"
},
{
"part": "001MP",
"lotNum": "",
"orderLine": 2,
"orderRelNum": 1,
"warehouse": "CHI",
"bin": "00-00-09",
"qty": 10,
"uom": "EA"
},
{
"part": "00C1",
"lotNum": "",
"orderLine": 3,
"orderRelNum": 1,
"warehouse": "CHI",
"bin": "00-00-00",
"qty": 10,
"uom": "EA"
}
]
}
Epicor allows you to pick a method parameters (or signature like they call them) types from a list of C# primitives: int, float, string, decimal, bool, etc. or from a type in one of the assemblies within epicor. Finding a type to match the above request would be impossible so instead we will just pass all the primitives as part of the signature and the array of objects will just be a string

Once we escape the lines string. If you need a tool to quickly escape anything I recommend JSON Escaper. The request would look like:
{
"orderNum": 5392,
"plant": "EPIC06",
"orderLines": "[{\"part\": \"00C2A\", \"lotNum\" : \"\", \"orderLine\": 1, \"orderRelNum\": 1, \"warehouse\": \"CHI\", \"bin\": \"01-01-01\", \"qty\": 10, \"uom\": \"EA\"},{\"part\": \"001MP\", \"lotNum\" : \"\", \"orderLine\": 2, \"orderRelNum\": 1, \"warehouse\": \"CHI\", \"bin\": \"00-00-09\" , \"qty\": 10, \"uom\": \"EA\"},{\"part\": \"00C1\",\"lotNum\" : \"\", \"orderLine\": 3, \"orderRelNum\": 1, \"warehouse\": \"CHI\", \"bin\": \"00-00-00\" , \"qty\": 10, \"uom\": \"EA\"}]"
}
Once your Epicor function receives the request, we’ll need to deserialize and sanitize and type check. Luckily Epicor includes Newtonsoft’s Json library so we can use it to deserialize and to access the members of our complex object.
In your first custom code widget you’ll have all your parameters available your code will look something like this
Now we can access any of the line’s data in our function. I’ll go over the create shipment function in the next post