I am thinking about building up a dashboard that allows the user to review a group of job numbers, and then select specific jobs to be what-if scheduled. I ran a trace for the methods, and I really only see one method that seems to matter:
Erp.Proxy.BO.ScheduleEngineImpl.MoveJobItem()
Has anyone else done some what-if scheduling in a dashboard? How did you approach it?
Thanks!
We built a “custom Global Scheduling” with an Epicor Function. Essentially, you build a ScheduleEngineTableSet in which you enter each job you want to schedule with some properties, including what-if. The tableSet is then submited to MoveJobItem method. Here is the code:
var jobToSchedule = Db.JobHead.Where(w=>w.PersonID == "TEST" && w.JobEngineered == true && w.JobClosed == false && w.JobComplete == false && w.ReqDueDate != null && w.SchedLocked == false);
string outError;
bool ScheduleFinished = false;
try
{
var ScheduleEngineTableSet = new Erp.Tablesets.ScheduleEngineTableset();
this.CallService<Erp.Contracts.ScheduleEngineSvcContract>(
bo =>
{
bo.GetScheduleRecord(ref ScheduleEngineTableSet);
});
foreach(var job in jobToSchedule)
{
//Set schedule engine parameters in the Schedule Table Set
var schedEngRow = ScheduleEngineTableSet.ScheduleEngine.NewRow();
schedEngRow["Company"] = callContextClient.CurrentCompany;
schedEngRow["JobNum"] = job.JobNum ;
schedEngRow["AssemblySeq"] = 0;
schedEngRow["OprSeq"] = 0;
schedEngRow["OpDtlSeq"] = 0;
schedEngRow["StartDate"] = DateTime.Today;
schedEngRow["StartTime"] = 0;
schedEngRow["EndDate"] = job.ReqDueDate; ;
schedEngRow["EndTime"] = 0;
schedEngRow["WhatIf"] = false;
schedEngRow["Finite"] = false ;
schedEngRow["SchedTypeCode"] = "JJ";
schedEngRow["SetupComplete"] = false;
schedEngRow["ProductionComplete"] = false;
schedEngRow["OverrideMtlCon"] = false;
schedEngRow["OverRideHistDateSetting"] = 2;
schedEngRow["RecalcExpProdYld"] = false;
schedEngRow["UseSchedulingMultiJob"] = true;
schedEngRow["SchedulingMultiJobIgnoreLocks"] = false;
schedEngRow["SchedulingMultiJobMinimizeWIP"] = true;
schedEngRow["SchedulingMultiJobMoveJobsAcrossPlants"] = true;
schedEngRow["RowMod"] = "A";
if(job.SchedCode == "IMMED")
{
schedEngRow["ScheduleDirection"] = "Start";
}
else
{
schedEngRow["ScheduleDirection"] = "End";
}
ScheduleEngineTableSet.ScheduleEngine.Add(schedEngRow);
}
//Schedule the jobs
this.CallService<Erp.Contracts.ScheduleEngineSvcContract>(
bo =>
{
bo.MoveJobItem(
ScheduleEngineTableSet,
out ScheduleFinished,
out outError);
});
}
You could try to call the Epicor Function from a button in your dashboard. You pass the jobNum of the selected rows to the function and build the tableSet from there.
I am not familiar enough with functions to utilize that, but I think it can be done in a custom code widget in a UBAQ. I have converted your code to this in an attempt to use it from the UBAQ:
//go through each checked row of data
//verify that sales ship by is filled in for each checked row.
//verify job is not locked
//run what-if scheduling to move the job to the sales ship by
var jobToSchedule = (from ttResults_row in queryResultDataset.Results where ttResults_row.JobHead_PersonID == "TEST" && ttResults_row.JobHead_JobEngineered == true && ttResults_row.JobHead_JobClosed == false && ttResults_row.JobHead_JobComplete == false && ttResults_row.JobHead_ReqDueDate != null && ttResults_row.JobHead_SchedLocked == false && ttResults_row.Calculated_CheckBox == true select ttResults_row);
string outError;
bool ScheduleFinished = false;
var ScheduleEngineTableSet = new Erp.Tablesets.ScheduleEngineTableset();
this.CallService<Erp.Contracts.ScheduleEngineSvcContract>(bo => {bo.GetScheduleRecord(ref ScheduleEngineTableSet);});
foreach(var job in jobToSchedule)
{
//Set schedule engine parameters in the Schedule Table Set
var schedEngRow = ScheduleEngineTableSet.ScheduleEngine.NewRow();
schedEngRow["Company"] = callContextClient.CurrentCompany;
schedEngRow["JobNum"] = job.JobNum ;
schedEngRow["AssemblySeq"] = 0;
schedEngRow["OprSeq"] = 0;
schedEngRow["OpDtlSeq"] = 0;
schedEngRow["StartDate"] = DateTime.Today;
schedEngRow["StartTime"] = 0;
schedEngRow["EndDate"] = job.ReqDueDate;
schedEngRow["EndTime"] = 0;
schedEngRow["WhatIf"] = true;
schedEngRow["Finite"] = true ;
schedEngRow["SchedTypeCode"] = "JJ";
schedEngRow["SetupComplete"] = false;
schedEngRow["ProductionComplete"] = false;
schedEngRow["OverrideMtlCon"] = false;
schedEngRow["OverRideHistDateSetting"] = 2;
schedEngRow["RecalcExpProdYld"] = false;
schedEngRow["UseSchedulingMultiJob"] = true;
schedEngRow["SchedulingMultiJobIgnoreLocks"] = false;
schedEngRow["SchedulingMultiJobMinimizeWIP"] = false;
schedEngRow["SchedulingMultiJobMoveJobsAcrossPlants"] = false;
schedEngRow["RowMod"] = "A";
schedEngRow["ScheduleDirection"] = "End";
ScheduleEngineTableSet.ScheduleEngine.Add(schedEngRow);
}
//Schedule the jobs
this.CallService<Erp.Contracts.ScheduleEngineSvcContract>(
bo => {bo.MoveJobItem(ScheduleEngineTableSet, out ScheduleFinished, out outError); });
However, I am getting an error on setting the Job Number and the ReqDueDate.
'ResultsUbaqRow' does not contain a definition for JobNum and no accessible extensions method.... yadda yadda...
Can I do this from a UBAQ without using a function? What did I mess up in my syntax? I have also tried this code without any luck:
schedEngRow["JobNum"] = job.JobHead_JobNum;
I forgot that in my BAQ, I took out JobHead.JobNum, and put in JobProd.JobNum. I changed the assignment to job.JobProd_JobNum, and it seems to compile ok. Thank you! Testing now.