# Same Code different behavior Client vs Server 10.1.500.8 **Category:** [Epicor ERP 10](https://www.epiusers.help/c/e10/5) **Created:** 2016-12-19 18:25 UTC **Views:** 6577 **Replies:** 23 **URL:** https://www.epiusers.help/t/same-code-different-behavior-client-vs-server-10-1-500-8/36663 --- ## Post #1 by @josecgomez 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, ```cs /**** Customization Code triggered from a button Click, works fine Result: Job is Un-Released, no Errors */ JobEntryImpl svc = WCFServiceSupport.CreateImpl((Ice.Core.Session)oTrans.Session, Epicor.ServiceModel.Channels.ImplBase.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); ``` ```cs /*** 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(); //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. @Bart_Elia, @Edge --- ## Post #2 by @tkoch Check this company setting. --- ## Post #3 by @josecgomez 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 --- ## Post #4 by @tkoch I've had this issue to in the past with BPMs, just wasn't sure if it was that checkbox causing problems also. Maybe try changing the RowMod again after the ChangeJobHeadJobReleased method? --- ## Post #5 by @josecgomez Tried that... no change. --- ## Post #6 by @tkoch Try to wrap it in this using statement? using (System.Transactions.TransactionScope txScope = IceDataContext.CreateDefaultTransactionScope()) { } --- ## Post #7 by @josecgomez I am invoking the business which carries its own transaction scope when it reaches back into the server. --- ## Post #8 by @hkeric.wci 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. --- ## Post #9 by @josecgomez Thanks @hkeric.wci good idea, however I just tried it with passing Db ...same result :frowning: --- ## Post #10 by @Edge Seems a bit odd. Can you include the detail from the error so we can see the stack trace. Also can you recreate this in Training DB? It is as if you are getting back changed data from the ChangeJobHeadJobReleased method. Have you attached a debugger and compared what is being passed into update, or tried without the ChangeJob method in the chain? --- ## Post #11 by @josecgomez @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 ```txt 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.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) ``` --- ## Post #12 by @josecgomez BTW I tried without the ChangeMethod just now, same result. --- ## Post #13 by @josecgomez Tried it in Education DB Company "Epicor Education" Job: 2031 BPM Attached / Modified for Job 2031 in Training DB, Same Result E10TestEducation.bpm (11.3 KB) You need to set the Prevent Changes in the Company Configuration (below) Full Stack Trace for Training DB Below (though it should be the same as above) ```txt 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.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) ``` Thanks @Edge --- ## Post #14 by @Bart_Elia I think that is your delta in the usage. _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). --- ## Post #15 by @josecgomez [quote="Bart_Elia, post:14, topic:36663"] (This defaults false so we don't end up in an endless loop accidentally with a BPM firing itself recursively) [/quote] 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? --- ## Post #16 by @Bart_Elia 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 ;) --- ## Post #17 by @josecgomez [quote="Bart_Elia, post:16, topic:36663"] No clue if both are firing the bpm. [/quote] No I did them independently, no worries I worked around it for now Thanks! PS: New Role? DO TELL --- ## Post #18 by @djariwala I am running into the same problem. Do we know the cause of the problem? --- ## Post #19 by @Jason_Woods [quote="josecgomez, post:17, topic:36663"] I worked around it for now [/quote] How did you work around this? I can't seem to get it at all. --- ## Post #20 by @josecgomez I used BeforeImage. https://www.epiusers.help/t/update-bo-deleting-packslip/50541/4?u=josecgomez --- ## Post #21 by @Jason_Woods Well, I tried it and no, it still did not care. I solved some of my BO errors, but not the final update. instead I used UpdateExt... Then, it would allow me to delete the record. This was likely the ugliest code/logic I have ever written (there is a lot more in the rest of the requirement and not below) and it still isn't 100%... ```cs this.CallService(hJob =>{ Erp.Tablesets.JobHeadRow row = new Erp.Tablesets.JobHeadRow(){ Company = CompanyID, JobNum = oldJobNum, PartNum = callContextBpmData.Character03, Plant = callContextClient.CurrentPlant, JobEngineered = false, ChangeDescription = "Rename Job to: " + newJobNum, }; dsOldJobExt.JobHead.Add(row); dsErrors = hJob.UpdateExt(ref dsOldJobExt, true, true, out errorsOccured); dsOldJob = hJob.GetByID("oldJobNum"); dsOldJob.JobProd[0].RowMod = "D"; hJob.Update(ref dsOldJob); hJob.DeleteByID(oldJobNum); }); ``` --- ## Post #22 by @jtownsend I've been struggling with this exact same issue to try and automate the closing of maintenance jobs upon the completion of the final op. Except I couldn't even get a direct call to JobEntry.UpdateExt to work. So I tried my go-to (read: "overly abused") method of routing things through DynamicQuery and it worked. The UBAQ this calls also updates via JobEntry.UpdateExt. So I remain at a loss as to how/why this works when all other, better methods failed. However, I'm also at the point were I don't care either. At the very least, I think I take the :crown: for "ugliest solution". ``` using (var svc = Ice.Assemblies.ServiceRenderer.GetService(Db)) { var paramRow = new ExecutionParameterRow(); paramRow.ParameterID = "JobNum"; paramRow.ParameterValue = ttLaborDtl[0].JobNum; paramRow.ValueType = "nvarchar"; qeds.Tables[1].Add(paramRow); baqds = svc.ExecuteByID("mnt", qeds); if (baqds.Tables["Results"].Rows.Count > 0) { var resultRow = baqds.Tables["Results"].Rows[0]; resultRow["JobHead_JobClosed"] = true; resultRow["JobHead_ResTopicID1"] = "PASS"; resultRow["JobHead_CommentText"] = "Automatically closed by " + callContextClient.CurrentUserId; svc.UpdateByID("mnt", baqds); } } ``` --- ## Post #23 by @Chris Add me to the list of people that received the error "Update not allowed, Engineered and Prevent Changes." when modifying JobReleased (and JobEngineered) values. I had what I thought was functional code performing a simple task, and it did work using WCF BO calls on JobEntry, but stopped working once I converted the code to use the service library for JobEntry (as necessary for BPMs and Functions). I tried adding the original row into the dataset, but that didn't work in my case. I tried about a thousand other changes, variations, etc, with no success. I even tried the changes in REST with the exact same results and error. What did work, was to remove all rows from all the tables, except the original and modified rows for JobHead. I accomplished this by creating a new Job Entry dataset (tableset) and copying the two necessary rows into the JobHead table, as shown in the abbreviated code below. ```cs var context = Ice.Services.ContextFactory.CreateContext(); using (var boJob = Ice.Assemblies.ServiceRenderer.GetService(context, false)) { //get current dataset; Erp.Tablesets.JobEntryTableset dsJeTmp = boJob.GetDatasetForTree(jobNum, 0, 0, false, "MFG,PRJ,SRV"); //get the current datarow of interest; var jeRowTmp = (from fromJe in dsJeTmp.JobHead select fromJe).FirstOrDefault(); //create new dataset to pass through as parameter; Erp.Tablesets.JobEntryTableset dsJe = new Erp.Tablesets.JobEntryTableset(); //create copy of original row; var origRow = dsJe.JobHead.NewRow(); BufferCopy.Copy(jeRowTmp, origRow); dsJe.JobHead.Add(origRow); //create second copy of original row to become the modified row; var jeRow = (Erp.Tablesets.JobHeadRow) dsJe.JobHead.NewRow(); BufferCopy.Copy(jeRowTmp, jeRow); dsJe.JobHead.Add(jeRow); //set fields jeRow.JobReleased = false; jeRow.RowMod = "U"; //call methods boJob.ChangeJobHeadJobReleased(ref dsJe); boJob.Update(ref dsJe); } ``` Side note - this same fix applies to the REST call as well. Remove all rows from all tables, except the original and modified rows for JobHead. Thanks, everyone, for the help on this and the many other areas this community shares its knowledge. --- ## Post #24 by @jtownsend So, I looking at @Chris code, and playing around with what I had already, it seems Update() wants *just* the header row and gets angry if you have anything in the child tables. (Running this in a function, for those not sure why my syntax is a bit different from the post above) ``` this.CallService(svc => { Erp.Tablesets.JobEntryTableset jets = svc.GetByID(job.JobNum); var emptyJets = new Erp.Tablesets.JobEntryTableset(); //Copy the JobHead row, and only that, to the empty tableset. var newRow = emptyJets.JobHead.NewRow(); BufferCopy.Copy(jets.JobHead[0], newRow); emptyJets.JobHead.Add(newRow); //modify the row emptyJets.JobHead[0].JobEngineered = false; emptyJets.JobHead[0].RowMod = "U"; //Let this method do its thing. svc.ChangeJobHeadJobEngineered(ref emptyJets); //run the update svc.Update(ref emptyJets); }); ``` --- **Canonical:** https://www.epiusers.help/t/same-code-different-behavior-client-vs-server-10-1-500-8/36663 **Original content:** https://www.epiusers.help/t/same-code-different-behavior-client-vs-server-10-1-500-8/36663