Just did a hot-swap on the code to use some of Joses old recommendations on the same post. I get the following error:
Server Side Exception
BPM runtime caught an unexpected exception of ‘EntityException’ type.
See more info in the Inner Exception section of Exception Details.
Exception caught in: Epicor.ServiceModel
Error Detail
Correlation ID: 752e7d57-0fd4-4758-b5a6-733e6c159a3e
Description: BPM runtime caught an unexpected exception of ‘EntityException’ type.
See more info in the Inner Exception section of Exception Details.
Inner Exception: The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)
The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)
Program: EntityFramework.dll
Method: EnlistTransaction
Original Exception Type: EntityException
Framework Method: SaveChanges
Framework Line Number: 352
Framework Column Number: 17
Framework Source: SaveChanges at offset 404 in file:line:column C:_Releases\ICE\ICE4.1.100.0\Source\Server\Framework\Epicor.System\Data\IceDataContext.cs:352:17
I went ahead and added the keys and made a change where the orderhed table would use sessionID company as part of the where statement, I get same message.
using (var txScope = IceContext.CreateDefaultTransactionScope())
{
foreach(var UD01 in (from row in Db.UD01 select row))
{
Db.UD01.Delete(UD01);
}
Db.Validate();
txScope.Complete();
}
/* Find current record in dataset */
using(var UD01svc = Ice.Assemblies.ServiceRenderer.GetService<Ice.Contracts.UD01SvcContract>(Db))
{
foreach (var recOrderHed in (from row in Db.OrderHed where row.Company == Session.CompanyID && row.OpenOrder == true select row))
{
/* Find all lines for Order */
foreach (var recOrdDetail in (from row in Db.OrderDtl where row.Company == Session.CompanyID && row.OrderNum == recOrderHed.OrderNum && row.OpenLine == true select row))
{
foreach (var recOrdRel in (from row in Db.OrderRel where row.Company == Session.CompanyID && row.OrderNum == recOrdDetail.OrderNum && row.OrderLine == recOrdDetail.OrderLine && row.OpenRelease == true select row))
{
/* Update UD Record */
UD01Tableset ds = new UD01Tableset();
UD01svc.GetaNewUD01(ref ds);
ds.UD01[0].Key1 = recOrdRel.OrderNum.ToString();
ds.UD01[0].Key2 = recOrdRel.OrderLine.ToString();
ds.UD01[0].Key3 = recOrdRel.OrderRelNum.ToString();
ds.UD01[0].Company = Session.CompanyID;
ds.UD01[0].Number01 = recOrdRel.OrderNum;
ds.UD01[0].Number02 = recOrdRel.OrderLine;
ds.UD01[0].Number03 = recOrdRel.OrderRelNum;
ds.UD01[0].Date01 = recOrdRel.ReqDate;
UD01svc.Update(ref ds);
}
}
}
}
Server Side Exception
BPM runtime caught an unexpected exception of ‘EntityException’ type.
See more info in the Inner Exception section of Exception Details.
Exception caught in: Epicor.ServiceModel
Error Detail
Correlation ID: 46b45444-c73f-4a7c-9669-8dafcde49c22
Description: BPM runtime caught an unexpected exception of ‘EntityException’ type.
See more info in the Inner Exception section of Exception Details.
Inner Exception: The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)
The partner transaction manager has disabled its support for remote/network transactions. (Exception from HRESULT: 0x8004D025)
Program: EntityFramework.dll
Method: EnlistTransaction
Original Exception Type: EntityException
Framework Method: SaveChanges
Framework Line Number: 352
Framework Column Number: 17
Framework Source: SaveChanges at offset 404 in file:line:column C:_Releases\ICE\ICE4.1.100.0\Source\Server\Framework\Epicor.System\Data\IceDataContext.cs:352:17
Now for the fun part of the project, functions. The way that the integrator decided to delete out our sales order releases was to do it one line at a time. This means that there will be multiple UpdateExt Calls by their user account with RowMods = “D”. I want to push the data from OrderRel to UD01 only once when they initialize the first Delete call, not ever one they make. The way I though this could be done would be to make a scheduled program that toggles a little before their program is scheduled to run. This can then be called on a condition statement allowing for the data push to be run. After the data push I want that toggle to be set to false and only tick back to true three to four hours later. This will ensure that their program is done running its delete calls before toggling back. Does anyone have any expertise on this?
Delete all SO Releases? Seems awfully aggressive, and they might run into an issue with that since I didn’t think Epicor would allow all Releases to be deleted. Anyways, sounds like a ‘nuclear option.’
A few thoughts:
Demand Management instead, this would mean the PO data would feed into Epicor through Demand Management and then someone can mass manage the updates to the Sales Orders… might not be as ‘integrated’ but it might be safer and more elegant.
You could manage the whole thing with PowerShell and DMT. Before the Update (or bomb and rebuild) comes through, your can have a PowerShell run that will call a BAQ for all the current state Releases with the relevant data (OrderNum, LineNum, Rel, Promise Date, etc). That will put the BAQ results in a CSV. You can then use PowerShell to manipulate the CSV if needed. Then after the Rest Update, have the PowerShell run a SalesOrder Release Update with the CSV to update the Promise Dates back. Might be easier than trying to pick up on the right trigger in a BPM.
As you stated REST goes both ways, I would push a solution that will just Update the data that needs to be updated somehow.
Might be better to ‘capture’ the Load into a CSV and then use PowerShell DMT to to just update what is needed.
I like the idea of doing that. Before our company decided to implement with the integrator, at one of our customers’ request, I had an excel sheet with a couple of rest calls and a lot of macros that did almost exactly what you call for in step 2. Unfortunately, my hands are tied for the most part on this integration. Their system blows up our sales order releases then calculates new sales orders by looking at what is in the customers portal and then forces over new releases based on the sales order and line number. From what I’ve seen they have to have their system to work this way as they also handle asn’s and a plethora of other things that I’m not well versed in. and with go live first thing next week I have little time to come up with an automated process. I do agree with you though. I wish I had more of a say in how this thing was put together and how it handles my system.
Does anyone have experience with Functions and would be willing to give me a quick rundown on how they work?
Back to the bpm, I have an issue with how I’m detecting a change. I need to be able to grab the data before it is deleted hence why I chose a preprocess. However, I have not come to the realization that I cannot use the ChangedBy field as it won’t grab the user of the person initiating the change, but the user of whoever worked on it last. I need a way of saying if user x is deleting a row then grab everything before it is deleted. Does anyone have a quick trick to accomplish this?
Found an old post by @ckrusen that answered my question. Turns out there is a "Method Called By ______ option in the condition statement selection. Credit do here:
Next problem. I have noticed that the dates being captured in UD01 are not the dates that should be going in. In my manual tests the table populated the OrderRel.ReqDates into UD01.Date01. When we let the program run it seems to be catching dates after they have been deleted and new ones are uploaded by the integrator.
According to their process they are supposed to close all shipped/partially shipped order releases, then delete all other releases with no shipping data. Once that is done they do their calculations based on our customers portal and place those results back in as new releases.
My program runs off of a trigger with two trips. The first trip happens on their first deletion call, and simply writes all open sales orders,open lines, open releases, and OrderRel.ReqDate to UD01. The second trigger trips on their first upload resetting the trigger for next deletion from that user and allows for my other program to begin shuffling in dates from UD01 to OrderRel if they existed.
My best guess is that there is some cross talk somewhere on the first trip. I can confirm that while the integrators process is running that the first and second trip happen at least once as the dates in UD01 do not match the ones that I force in on my manual process. Does anyone have any ideas on what could be causing this to trigger more than once and how it would choose to overwrite with dates that werent capable of being in OrderRel until after the last deletion call was made?
Found the issue I was accidentally creating an infinite loop with my toggle. Does anyone know how Epicor determines when a user is to be timed out? Or what specifically triggers the time out event?