So I had the need to un-release a Job using custom code in a BPM, I wrote the code and it threw an error “Update not allowed, Engineered and Prevent Changes.” the issue is that the same EXACT code works fine in a customization the only difference being how the BO is instanciated.
See the code below,
/****
Customization Code triggered from a button Click, works fine
Result: Job is Un-Released, no Errors
*/
JobEntryImpl svc = WCFServiceSupport.CreateImpl<JobEntryImpl>((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase<Erp.Contracts.JobEntrySvcContract>.UriPath); //Instanciated Client Side
var ds = svc.GetByID("CAN000076");
ds.JobHead[0].JobReleased = false;
ds.JobHead[0].RowMod="U";
svc.ChangeJobHeadJobReleased(ds);
svc.Update(ds);
/***
BPM Code triggered from ABCCode-> GetNew Preprocessing for testing purposes
Result: Error: Update not allowed, Engineered and Prevent Changes
*/
var svc = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.JobEntrySvcContract>(); //Instanciated Server Side
var ds = svc.GetByID("CAN000076");
ds.JobHead[0].JobReleased=false;
ds.JobHead[0].RowMod="U";
svc.ChangeJobHeadJobReleased(ref ds);
svc.Update(ref ds);
Theoretically speaking both pieces of code should run the same exact result… Anyone have any ideas? I’ve replicated this in 2 different instances of 500.8 with the same results so I know it is not just my DB.
Hi Ted,
Yes that is flagged but that is not the issue, that flag is supposed to be checked but you are still allowed to un-release / un-engineer a job. Furthermore it works fine in the customization, just not on the BPM… strange behavior
From what I understand when it comes to ServiceRenderer. I am sure Bart will correct me, might be off a bit.
When you use Ice.Assemblies.ServiceRenderer.GetService() you are creating a Assembly Instance without any args so i assume it will create its own context instance / transaction.
When you use Ice.Assemblies.ServiceRenderer.GetService(Db) you are calling GetService(IceDataContext context, bool ignoreFacade = false) which does an CreateInstance and passes the Db Context as an argument to the Assembly. Which is returned to you.
When you use Ice.Assemblies.ServiceRenderer.GetService(Db, true) you are also setting the ignoreFacade to true… What is a Facade in Epicor? Well if you use the ICE SDK and you create your own Business Objects you always create a SvcFacade.cs file which contains the required code for interacting with BPM… So by setting ignoreFacade to true you are basically saying… Do Not Trigger the “Update” BPM… perhaps you want it, but if you are in the Update already you would cause a loop.
I am wondering if it helps to pass through the Db Context. Perhaps there is a issue in how ServiceRenderer instantiates the Transaction, perhaps it does not pass the Client Context.
@Edge
Full stack trace below, BPM attached E10Test.bpm (11.8 KB) runs on ABC Code -> Get New only fails if Prevent Changes is Checked in Company Config -> Production -> Change Engineered Jobs
I haven’t tried it in the Training DB, but I will
Business Layer Exception
Update not allowed, Engineered and Prevent Changes.
Exception caught in: Epicor.ServiceModel
Error Detail
============
Description: Update not allowed, Engineered and Prevent Changes.
Program: Erp.Services.BO.JobEntry.dll
Method: valPreventChange
Line Number: 5954
Column Number: 29
Table: JobAsmbl
Server Trace Stack: at Erp.Services.BO.JobEntrySvc.valPreventChange() in C:\_Releases\ERP\UD10.1.500.8\Source\Server\Services\BO\JobEntry\JobEntry.cs:line 5954
at Erp.Services.BO.JobEntrySvc.BeforeUpdate() in C:\_Releases\ERP\UD10.1.500.8\Source\Server\Services\BO\JobEntry\JobEntry.cs:line 5965
at Erp.Services.BO.JobEntrySvc.OnTablesetEvent(DatasetEventType type) in C:\_Releases\ERP\UD10.1.500.8\Source\Server\Services\BO\JobEntry\JobEntry.Designer.cs:line 619
at Ice.Services.Trace.TablesetProfilingCollector.DoTablesetEventTrace(String tablesetName, String methodName, Action action) in C:\_Releases\ICE\3.1.500.8\Source\Framework\Epicor.Ice\Services\TablesetProfilingCollector.cs:line 200
at Ice.TablesetBound`3.InnerUpdate(IceDataContext dataContext, TFullTableset tableset) in C:\_Releases\ICE\3.1.500.8\Source\Framework\Epicor.Ice\Services\TablesetBound.cs:line 794
at Erp.Services.BO.JobEntrySvc.Update(JobEntryTableset& ds) in C:\_Releases\ERP\UD10.1.500.8\Source\Server\Services\BO\JobEntry\JobEntry.Designer.cs:line 7392
at Erp.Services.BO.JobEntrySvcFacade.Update(JobEntryTableset& ds) in C:\_Releases\ERP\UD10.1.500.8\Source\Server\Services\BO\JobEntry\JobEntrySvcFacade.cs:line 4043
at Epicor.Customization.Bpm.BO1A649256125F45B2A3A14D0B240477F1.GetNewABCCodePreProcessingDirective_TEST_E93C55B5ED684B728BF4D2BC44B8F28A.A001_CustomCodeAction()
at Epicor.Customization.Bpm.BO1A649256125F45B2A3A14D0B240477F1.GetNewABCCodePreProcessingDirective_TEST_E93C55B5ED684B728BF4D2BC44B8F28A.ExecuteCore()
at Epicor.Customization.Bpm.DirectiveBase`3.Execute(TParam parameters) in c:\_Releases\ICE\3.1.500\Current\Source\Server\Internal\Lib\Epicor.Customization.Bpm\DirectiveBase.Generic.cs:line 160
at Epicor.Customization.Bpm.MethodCustomizationBase2`3.<>c__DisplayClass20_0.<RunDirectives>b__3(MethodDirectiveBase`3 dir) in c:\_Releases\ICE\3.1.500\Current\Source\Server\Internal\Lib\Epicor.Customization.Bpm\MethodCustomizationBase2.cs:line 151
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at Epicor.Customization.Bpm.MethodCustomizationBase2`3.RunDirectives(TParam parameters) in c:\_Releases\ICE\3.1.500\Current\Source\Server\Internal\Lib\Epicor.Customization.Bpm\MethodCustomizationBase2.cs:line 153
at Epicor.Customization.Bpm.CustomizationBase2`3.Execute(TParam parameters) in c:\_Releases\ICE\3.1.500\Current\Source\Server\Internal\Lib\Epicor.Customization.Bpm\CustomizationBase2.cs:line 77
at Epicor.Customization.Bpm.BO1A649256125F45B2A3A14D0B240477F1.ABCCodeSvcCustomization.GetNewABCCode(ABCCodeTableset& ds)
at Erp.Services.BO.ABCCodeSvcFacade.GetNewABCCode(ABCCodeTableset& ds) in c:\_Releases\ERP\RL10.1.500\Source\Server\Services\BO\ABCCode\ABCCodeSvcFacade.cs:line 60
at SyncInvokeGetNewABCCode(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at Epicor.Hosting.OperationBoundInvoker.InnerInvoke(Object instance, Func`2 func) in C:\_Releases\ICE\3.1.500.8\Source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 59
at Epicor.Hosting.OperationBoundInvoker.Invoke(Object instance, Func`2 func) in C:\_Releases\ICE\3.1.500.8\Source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 28
at Epicor.Hosting.Wcf.EpiOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) in C:\_Releases\ICE\3.1.500.8\Source\Framework\Epicor.System\Hosting\Wcf\EpiOperationInvoker.cs:line 23
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.InnerTryReceiveCompletedCallback(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceiveAsyncResult.OnReceive(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.OnReceiveComplete(Object state)
at System.ServiceModel.Channels.SessionConnectionReader.OnAsyncReadComplete(Object state)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Security._SslStream.ProcessFrameBody(Int32 readBytes, Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security._SslStream.ReadFrameCallback(AsyncProtocolRequest asyncRequest)
at System.Net.AsyncProtocolRequest.CompleteRequest(Int32 result)
at System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(Int32 bytes)
at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.ConnectionStream.IOAsyncResult.OnAsyncIOComplete(Object state)
at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e)
at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Client Stack Trace
==================
at Epicor.ServiceModel.Channels.ImplBase`1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets)
at Erp.Proxy.BO.ABCCodeImpl.GetNewABCCode(ABCCodeDataSet ds)
at Erp.Adapters.ABCCodeAdapter.GetNewAbcCode()
at Erp.UI.App.AbcCodeEntry.Transaction.GetNew()
at Ice.Lib.Framework.EpiSingleViewTransaction.Ice.Lib.Framework.IEpiAdapterLink.GetNew()
at Ice.Lib.Framework.EpiViewUtils.OnGetNew(EpiTransaction trans, EpiDataView view, IEpiAdapterLink link, Boolean displayExceptions)
Full Stack Trace for Training DB Below (though it should be the same as above)
Business Layer Exception
Update not allowed, Engineered and Prevent Changes.
Exception caught in: Epicor.ServiceModel
Error Detail
============
Description: Update not allowed, Engineered and Prevent Changes.
Program: Erp.Services.BO.JobEntry.dll
Method: valPreventChange
Line Number: 5954
Column Number: 29
Table: JobAsmbl
Server Trace Stack: at Erp.Services.BO.JobEntrySvc.valPreventChange() in C:\_Releases\ERP\UD10.1.500.7\Source\Server\Services\BO\JobEntry\JobEntry.cs:line 5954
at Erp.Services.BO.JobEntrySvc.BeforeUpdate() in C:\_Releases\ERP\UD10.1.500.7\Source\Server\Services\BO\JobEntry\JobEntry.cs:line 5963
at Erp.Services.BO.JobEntrySvc.OnTablesetEvent(DatasetEventType type) in C:\_Releases\ERP\UD10.1.500.7\Source\Server\Services\BO\JobEntry\JobEntry.Designer.cs:line 619
at Ice.Services.Trace.TablesetProfilingCollector.DoTablesetEventTrace(String tablesetName, String methodName, Action action) in C:\_Releases\ICE\3.1.500.7\Source\Framework\Epicor.Ice\Services\TablesetProfilingCollector.cs:line 200
at Ice.TablesetBound`3.InnerUpdate(IceDataContext dataContext, TFullTableset tableset) in C:\_Releases\ICE\3.1.500.7\Source\Framework\Epicor.Ice\Services\TablesetBound.cs:line 794
at Erp.Services.BO.JobEntrySvc.Update(JobEntryTableset& ds) in C:\_Releases\ERP\UD10.1.500.7\Source\Server\Services\BO\JobEntry\JobEntry.Designer.cs:line 7392
at Erp.Services.BO.JobEntrySvcFacade.Update(JobEntryTableset& ds) in C:\_Releases\ERP\UD10.1.500.7\Source\Server\Services\BO\JobEntry\JobEntrySvcFacade.cs:line 4043
at Epicor.Customization.Bpm.BO9AF352B197AD49158C3BF8C381E20873.GetNewABCCodePreProcessingDirective_TEST_BAD_BPM_E93C55B5ED684B728BF4D2BC44B8F28A.A001_CustomCodeAction()
at Epicor.Customization.Bpm.BO9AF352B197AD49158C3BF8C381E20873.GetNewABCCodePreProcessingDirective_TEST_BAD_BPM_E93C55B5ED684B728BF4D2BC44B8F28A.ExecuteCore()
at Epicor.Customization.Bpm.DirectiveBase`3.Execute(TParam parameters) in c:\_Releases\ICE\3.1.500\Current\Source\Server\Internal\Lib\Epicor.Customization.Bpm\DirectiveBase.Generic.cs:line 160
at Epicor.Customization.Bpm.MethodCustomizationBase2`3.<>c__DisplayClass20_0.<RunDirectives>b__3(MethodDirectiveBase`3 dir) in c:\_Releases\ICE\3.1.500\Current\Source\Server\Internal\Lib\Epicor.Customization.Bpm\MethodCustomizationBase2.cs:line 151
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at Epicor.Customization.Bpm.MethodCustomizationBase2`3.RunDirectives(TParam parameters) in c:\_Releases\ICE\3.1.500\Current\Source\Server\Internal\Lib\Epicor.Customization.Bpm\MethodCustomizationBase2.cs:line 153
at Epicor.Customization.Bpm.CustomizationBase2`3.Execute(TParam parameters) in c:\_Releases\ICE\3.1.500\Current\Source\Server\Internal\Lib\Epicor.Customization.Bpm\CustomizationBase2.cs:line 77
at Epicor.Customization.Bpm.BO9AF352B197AD49158C3BF8C381E20873.ABCCodeSvcCustomization.GetNewABCCode(ABCCodeTableset& ds)
at Erp.Services.BO.ABCCodeSvcFacade.GetNewABCCode(ABCCodeTableset& ds) in c:\_Releases\ERP\RL10.1.500\Source\Server\Services\BO\ABCCode\ABCCodeSvcFacade.cs:line 60
at SyncInvokeGetNewABCCode(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at Epicor.Hosting.OperationBoundInvoker.InnerInvoke(Object instance, Func`2 func) in C:\_Releases\ICE\3.1.500.7\Source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 59
at Epicor.Hosting.OperationBoundInvoker.Invoke(Object instance, Func`2 func) in C:\_Releases\ICE\3.1.500.7\Source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 28
at Epicor.Hosting.Wcf.EpiOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) in C:\_Releases\ICE\3.1.500.7\Source\Framework\Epicor.System\Hosting\Wcf\EpiOperationInvoker.cs:line 23
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
at System.ServiceModel.Dispatcher.ChannelHandler.DispatchAndReleasePump(RequestContext request, Boolean cleanThread, OperationContext currentOperationContext)
at System.ServiceModel.Dispatcher.ChannelHandler.HandleRequest(RequestContext request, OperationContext currentOperationContext)
at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.InnerTryReceiveCompletedCallback(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.TransportDuplexSessionChannel.TryReceiveAsyncResult.OnReceive(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.SynchronizedMessageSource.ReceiveAsyncResult.OnReceiveComplete(Object state)
at System.ServiceModel.Channels.SessionConnectionReader.OnAsyncReadComplete(Object state)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Security.NegotiateStream.ProcessFrameBody(Int32 readBytes, Byte[] buffer, Int32 offset, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.NegotiateStream.ReadCallback(AsyncProtocolRequest asyncRequest)
at System.Net.AsyncProtocolRequest.CompleteRequest(Int32 result)
at System.Net.FixedSizeReader.CheckCompletionBeforeNextRead(Int32 bytes)
at System.Net.FixedSizeReader.ReadCallback(IAsyncResult transportResult)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.ConnectionStream.IOAsyncResult.OnAsyncIOComplete(Object state)
at System.Net.Sockets.SocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs e)
at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationSuccess(SocketError socketError, Int32 bytesTransferred, SocketFlags flags)
at System.Net.Sockets.SocketAsyncEventArgs.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Client Stack Trace
==================
at Epicor.ServiceModel.Channels.ImplBase`1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets)
at Erp.Proxy.BO.ABCCodeImpl.GetNewABCCode(ABCCodeDataSet ds)
at Erp.Adapters.ABCCodeAdapter.GetNewAbcCode()
at Erp.UI.App.AbcCodeEntry.Transaction.GetNew()
at Ice.Lib.Framework.EpiSingleViewTransaction.Ice.Lib.Framework.IEpiAdapterLink.GetNew()
at Ice.Lib.Framework.EpiViewUtils.OnGetNew(EpiTransaction trans, EpiDataView view, IEpiAdapterLink link, Boolean displayExceptions)
public static TService GetService(bool ignoreFacade = false) where TService : class
ignoreFacade bypasses BPM firing. By default that is false so no BPM will be fired. (This defaults false so we don’t end up in an endless loop accidentally with a BPM firing itself recursively).
I think you meant the opposite of this, it defaults to ignore=false meaning it will not ignore the facade. I just tried this and by default BPM does fire, if ingorefacade = true then no BPM fires…
Regardless though this isn’t related to the initial issue (I don’t think) of why the code behaves differently from the client side vs the bpm. Any ideas on that?
No clue if both are firing the bpm. I wonder if that logic is doing something with cross services as well. It would take a bit to unravel. Queue up a call if you need it looked into.
I’ve been a little buried in 10.2 efforts in a new role. Don’t have as much free time as previous with the holidays