Wednesday, May 11, 2011

Delete Rows in Epicor DeleteById Alternative

Epicor DeleteById vs. Update (RowMod="D")

In my experience, deleting rows from Epicor through the business objects works differently between objects.

For some objects, you can call .DeleteById, such as PartService.DeleteById and the row will be removed from Epicor database.

For other objects, .DeleteById fails (CustShipService.DeleteByID, SaleOrder.DeletedById, ...) sending to you check the AppServer log file, which states something like: "No ttOrderHead record is available", "Error attempting to push run time paramters onto the stack.".


In these cases, try deleting using the Update/RowMod option.
Call .Update (different from MasterUpdate, UpdateExt, etc.) passing in the appropriate dataset. You don't need the entire dataset returned by .GetById. Just pass in the element which has the unique ID for the business objects, and in that element, set RowMod="D".

For SalesOrder, my Service Connect trace looks like this:


<ext_UpdateRequest:UpdateRequest xmlns:ext_UpdateRequest="http://Epicor.com/SalesOrder/UpdateRequest">
<ext_UpdateRequest:loginOptions>EPIC03</ext_UpdateRequest:loginOptions>
<ext_UpdateRequest:ds>
<ext_UpdateRequest:OrderHed>
<ext_UpdateRequest:UpdExtSalesOrderDataSetTypeOrderHed>
<ext_UpdateRequest:OrderNum>2300091</ext_UpdateRequest:OrderNum>
<ext_UpdateRequest:RowMod>D</ext_UpdateRequest:RowMod>
</ext_UpdateRequest:UpdExtSalesOrderDataSetTypeOrderHed>
</ext_UpdateRequest:OrderHed>
</ext_UpdateRequest:ds>
</ext_UpdateRequest:UpdateRequest>

Friday, May 6, 2011

Service Connect Workflow Architecture Tips for Developers

I’ve recently started designing workflows for Epicor’s Service Connect. Previously I have used Microsoft DTS and SSIS. There is little information available on how to design the overall architecture for workflows. Here are the things I wish I knew when I started. Some knowledge of Service Connect is required before this will make any sense at all.

DTA and USR Elements

Inside the message envelope, the two elements you will use the most are the DTA and USR elements. Think of the data in DTA as parameters you need for the current step, and USR as the overall data you are processing. The structure of data in the DTA will change from step to step, depending on what operation you are performing. The structure of the data in USR does not change across the workflow, and is designed by you as either Process Variables, or Message Extensions. Process Variables are single value fields, and hold things like object IDs. Message Extensions are based on a .xsd schema, and hold datasets.

To maintain USR data across steps, you must map the USR section from input schema into the output schema. This link is usually automatically done for you when you create a new Conversion or Request step, but in some cases it must be manually done.

Suggested Architecture

For your workflow, you should create a Workflow Schema which serves two purposes:
1. It defines the initial DTA structure which will receive data from an Input Channel.
2. It will act as the intermediary schema between steps, making your workflow much more flexible.

In general my workflows look like:
1. Request Conversion from Workflow Schema to Request.xsd
2. Web Method / .NET Call
3. Save Response Conversion from Response.xsd to Workflow Schema
4. Repeat 1-3 for next Web Method / .NET Call

In my Request Conversion, I move data from the USR section to the DTA section of the request.

In my Save Response Conversion, I move data from the DTA section of the response into the USR section (usually as a Message Extension based on the Response.xsd.

This allows the easy insert or rearrangement of workflow items, as all conversions before a Web Method request take Workflow Schema as their input. It also makes it easier to maintain the data through the workflow, as I know it always comes from the USR section.

Other Tips

Don’t Pass Entire Dataset

Just because a business object methods takes a dataset, it does not mean you must pass the entire dataset.

For instance, SalesOrder.ChangePartMaster takes a SalesOrderDataSet, but you really only have to pass in OrderHed, OrderDtl, OrderRepComm, and TaxConnectStatus. Passing in the entire dataset is less efficient. How do you know what elements a method actually needs? Perform the operation through Epicor Client, and see what element it passes.

Methods Were Developed for Epicor Client, not General Programming

I think the methods exposed by Epicor were really developed first to support the Epicor Client. This means, the methods often expect certain data in the dataset to exist, even if it seems unnecessary to the current method you are calling. If you having trouble getting a method to work, trace the same method call in Epicor Client, and look for any previous calls which modify the dataset you are passing in. You may have to call them first.