Schedule Job in C#

I have a data directive BPM that creates a Job and gets the method details. What I haven’t been able to figure out is how to then run it the scheduling engine. Anyone ever done this?

// Get Details
using (var txScope2 = IceContext.CreateDefaultTransactionScope())
{
	foreach (var JH_iterator in (from JH_Row in Db.JobHead
									where JH_Row.Company == Session.CompanyID &&
									JH_Row.JobCode == "$!"
									select JH_Row))
	{
		var JobHeadRow = JH_iterator;
		JobHeadRow.JobCode = "";
		Erp.Contracts.JobEntrySvcContract JH = null;
		JH =Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.JobEntrySvcContract>(Db);	
		
		if (JH != null && JobHeadRow != null) 
		{
			string currJobNum = JobHeadRow.JobNum;
			int currAsmSeq = 0;
			string sourceFile = "Method";
			int sourceQuote = 0;
			int sourceLine = 0;
			string sourceJob = "";
			int sourceAsm = 0;
			string sourcePart = JobHeadRow.PartNum;
			string sourceRev = JobHeadRow.RevisionNum;
			string sourceAltMethod = "";
			bool resequence = false;
			bool useMethodForParts = false;
			bool getCostsFromInv = false; // Required paramter for 10.1 but not 10.0
			bool getCostsFromTemp = false; // Required paramter for 10.1 but not 10.0
			 
			JH.GetDetails(currJobNum,currAsmSeq,sourceFile,sourceQuote,
							sourceLine,sourceJob,sourceAsm,sourcePart,
							sourceRev,sourceAltMethod,resequence,
							useMethodForParts,getCostsFromInv,getCostsFromTemp);
		}
	}
	Db.Validate(); 
	txScope2.Complete();
}
	private void ScheduleJob(string jobNum, DateTime reqDate)
{
	try 
		{	        
			ScheduleEngineDataSet ds = new ScheduleEngineDataSet();
			ScheduleEngineDataSet.ScheduleEngineRow row = ds.ScheduleEngine.NewScheduleEngineRow();
	        row.Company = ((Session)oTrans.Session).CompanyID;
	        row.JobNum = jobNum;
	        row.AssemblySeq = 0;
	        row.OprSeq = 0;
	        row.OpDtlSeq = 0;
	        row.StartDate = DateTime.Today; //new DateTime(2015, 12, 18);
	        row.StartTime = 0;
	        row.EndDate = reqDate;
	        row.EndTime = 0;
	        row.WhatIf = false;
	        row.Finite = false;
	        row.SchedTypeCode = "ja";
	        row.ScheduleDirection = "End";
	        row.SetupComplete = false;
	        row.ProductionComplete = false;
	        row.OverrideMtlCon = true;
	        row.OverRideHistDateSetting = 2;
	        row.RecalcExpProdYld = false;
	        ds.ScheduleEngine.AddScheduleEngineRow(row);
	        bool l_finished;
	        string c_WarnLogTxt;
	        engine.MoveJobItem(ds, out l_finished, out c_WarnLogTxt);				
		}
		catch (Exception ex)
		{
			MessageBox.Show(ex.Message);
		}
}

You’ll need to edit some row properties to suit your needs.

1 Like

Thanks Tkoch,

I’m getting an error when I try to compile the BPM. I’ve added the “Erp.Contracts.BO.ScheduleEngine” to my references and built the service connection.

Erp.Contracts.ScheduleEngineSvcContract JS = null;
JS = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.ScheduleEngineSvcContract>(Db); .

Not sure what else needs to be added. Any Ideas?

Server Side Exception

There is at least one compilation error.

Exception caught in: Epicor.ServiceModel

Error Detail

Description: There is at least one compilation error.
Details:
Error CS0246: The type or namespace name ‘ScheduleEngineDataSet’ could not be found (are you missing a using directive or an assembly reference?) [InTran.Auto_Add_SubJobs.cs(252,18)]
Error CS0246: The type or namespace name ‘ScheduleEngineDataSet’ could not be found (are you missing a using directive or an assembly reference?) [InTran.Auto_Add_SubJobs.cs(253,5)]
Program: Epicor.Customization.dll
Method: PrepareException
Line Number: 99
Column Number: 13
Server Trace Stack: at Epicor.Customization.Standard.CustomizationCompiler.PrepareException(CompilerErrorCollection errors) in c:_Releases\ICE\3.1.400.14\source\Framework\Epicor.Customization\Standard\CustomizationCompiler.cs:line 99
at Epicor.Customization.Standard.CustomizationCompiler.Compile(BuildEnvironment input, String outputAssembly) in c:_Releases\ICE\3.1.400.14\source\Framework\Epicor.Customization\Standard\CustomizationCompiler.cs:line 29
at Epicor.Customization.Standard.CustomizationBuilder.Process(CustomizationProject project) in c:_Releases\ICE\3.1.400.14\source\Framework\Epicor.Customization\Standard\CustomizationBuilder.cs:line 78
at Ice.BO.BpMethod.Internal.CustomizationToolBase.Regenerate(BOMethod method) in c:_Releases\ICE\3.1.400.14\source\Server\Services\BO\BpMethod\Internal\CustomizationToolBase.cs:line 72
at Ice.Services.BO.BpMethodSvc.AfterUpdate() in c:_Releases\ICE\3.1.400.14\source\Server\Services\BO\BpMethod\BpMethod.Events.cs:line 85
at Ice.Services.Trace.TablesetProfilingCollector.DoTablesetEventTrace(String tablesetName, String methodName, Action action) in c:_Releases\ICE\3.1.400.14\source\Framework\Epicor.Ice\Services\TablesetProfilingCollector.cs:line 200
at Ice.TablesetBound3.InnerUpdate(IceDataContext dataContext, TFullTableset tableset) in c:\_Releases\ICE\3.1.400.14\source\Framework\Epicor.Ice\Services\TablesetBound.cs:line 814 at Ice.Services.BO.BpMethodSvc.Update(BpMethodTableset& ds) in c:\_Releases\ICE\3.1.400.14\source\Server\Services\BO\BpMethod\BpMethod.Designer.cs:line 835 at Ice.Services.BO.BpMethodSvcFacade.Update(BpMethodTableset& ds) in c:\_Releases\ICE\3.1.400.14\source\Server\Services\BO\BpMethod\BpMethodSvcFacade.cs:line 224 at SyncInvokeUpdate(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at Epicor.Hosting.OperationBoundInvoker.InnerInvoke(Object instance, Func2 func) in c:_Releases\ICE\3.1.400.14\source\Framework\Epicor.System\Hosting\OperationBoundInvoker.cs:line 59
at Epicor.Hosting.OperationBoundInvoker.Invoke(Object instance, Func2 func) in c:\_Releases\ICE\3.1.400.14\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.400.14\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.SecurityChannelListener1.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.ImplBase1.ShouldRethrowNonRetryableException(Exception ex, DataSet[] dataSets) at Ice.Proxy.BO.BpMethodImpl.Update(BpMethodDataSet ds) at Ice.Adapters.BpMethodAdapter.OnUpdate() at Ice.Lib.Framework.EpiBaseAdapter.Update() at Ice.UI.App.BpTriggerEntry.Transactions.MainTransaction.adapterUpdate() at Ice.Lib.Framework.EpiMultiViewTransaction.Update(IEnumerable1 dataSets)

In BPMs you dno’t generally use DataSet rather Tableset @zwilli526

Yes, sorry.

This was copied from a customization, it was meant to give an idea of how to accomplish this.

Hello, I am trying to reschedule a job via VB.NET automation code. I followed the C# example above and have it running w/o errors. My question is about the “SchedTypeCode” and “ScheduleDirection” properties. What are the valid values for these? I used “ja” and “End” and my job gets the new ReqDueDate, but the start and end dates don’t update. I have to open the job and manually do the scheduling for that to stick. We use backward scheduling as a default. Maybe the “JA” and/or “END” are the wrong values. Could not find anything in E10 documentation. We are running 10.1.500.16.

Get your typeCodes:

public bool GetSchedTypeCodes(out string schedTypecodes, out string operationOnlySchedTypecodes)

I have no idea what it does - maybe if you try it, you can tell me :slight_smile:

I think the SchedTypeCode is related to the shceduling parameters when you are moving jobs in the Scheduling board. You can select the move operation from the likes of ‘Operation Only’ (‘oo’), ‘Job-All Operations’ (‘ja’), etc. The ScheduleDirection, I believe, is Forward “Start” or backward “End”, but you might want to check that.

I also am attempting something similar and get a reference error using the code above. I have added the assemblies already. Any ideas what I missed, I basically copied and pasted.

Error: CS0246 - line 77 (380) - The type or namespace name ‘ScheduleEngineDataSet’ could not be found (are you missing a using directive or an assembly reference?)

@mmcwilliams add these two usings.

using Erp.BO;
using Erp.Proxy.BO;

That did the trick Thanks. So close. Just getting this now.

Error: CS1501 - line 102 (405) - No overload for method ‘MoveJobItem’ takes 3 arguments
It compiles without ds in the parameters, but obviously does nothing.

SchedAdapt.MoveJobItem(ds, out l_finished, out c_WarnLogTxt);

You’re on V8? You could reference the dll in VS to see what parameters it expects.

This is on 10.1 and the BL Tester has (ds, out l_finished, out c_warnLogTxt

Most likely you just remove the ref to the ds and use the internal dataset of the adapter.

I didn’t realize you are using the adapter, the data will already be in the ScheduleEngineData property of the adapter. So, SchedAdapt.MoveJobItem(out l_finished, out c_WarnLogTxt); is correct.

PS - You’re version says 8.03.408 on your profile.

Unfortunately that is correct :slight_smile: Will be live on 10.1 soon enough though.
Thanks for the input. Will mess with it a bit more this afternoon.

When you reference engine.MoveJobItem I am not seeing anything related to “engine”

Using the adapter does not seem to work because I am not sure how to populate the adapter dataset.
Thanks

I assume you have already created an instance of the adapter - Erp.Adapters.ScheduleEngineAdapter

Erp.Adapters.ScheduleEngineAdapter sea = new Erp.Adapters.ScheduleEngineAdapter(oTrans);
sea.BOConnect();
<— At some point here you would probably be bringing in some data - GetByID or similar
sea.MoveJobItem(you params here)

					adScheduleEngine.GetScheduleRecord();
					ScheduleEngineDataSet dsScheduleEngine = (ScheduleEngineDataSet)adScheduleEngine.GetCurrentDataSet(DataSetMode.RowsDataSet);
					System.Data.DataRow scheduleEngineRow = dsScheduleEngine.Tables["ScheduleEngine"].Rows[0];
						scheduleEngineRow["JobNum"] = jobNum;
						scheduleEngineRow["StartDate"] = schedDate;
						scheduleEngineRow["OverrideMtlCon"] = true;
						scheduleEngineRow["WhatIf"] = false;
						scheduleEngineRow["Finite"] = false;
						scheduleEngineRow["ScheduleDirection"] = "Start";
					adScheduleEngine.MoveJobItem(out finished, out warnLog);
					adScheduleEngine.ScheduleEngineData.AcceptChanges();
5 Likes

That works perfectly Brian.
Thanks!