Job ReScheduling Dashboard

Hi everyone,

We have an updateable dashboard for rescheduling jobs so that we can reschedule whole orders a lot quicker. I did not write the code and I am unsure how to change it to make it do what we want it to. At the moment it will only reschedule into the future but we tend to move jobs out to the end of the year if we are unsure of delivery dates and then bring them back in when delivery is confirmed. At the moment we have to bring them back one job at a time which is very time-consuming. Here is the code. If someone could point me in the right direction I would be extremely grateful.
Adrian.

var boJobEntry = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.JobEntrySvcContract>(Db);
var boSched = Ice.Assemblies.ServiceRenderer.GetService<Erp.Contracts.ScheduleEngineSvcContract>(Db);

string jobNum = "" ;
string Msg = "" ;
bool logit = true ;



//================================================================================================================================================
// f u n c t i o n s    f u n c t i o n s    f u n c t i o n s    f u n c t i o n s    f u n c t i o n s    f u n c t i o n s    f u n c t i o n s   
//================================================================================================================================================


//log function ==========================================
Func< string, bool > logMsg = (message) =>
{
    if (logit)
        this.PublishInfoMessage(message, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,"UBAQ", "Advanced");
    return true ;
};


//error message function ================================
Func< string, bool > errorMsg = (message) =>
{
    this.PublishInfoMessage(message, Ice.Common.BusinessObjectMessageType.Information, Ice.Bpm.InfoMessageDisplayMode.Individual,"UBAQ", "Advanced");
    return true ;
};



//=========================================================================================================================================
// m a i n   c o d e  m a i n   c o d e   m a i n   c o d e   m a i n   c o d e   m a i n   c o d e   m a i n   c o d e   m a i n   c o d e 
//=========================================================================================================================================


switch (actionID)
{
		case "SELECT":
				foreach (var ttr in ttResults)
				{
						ttr.Calculated_Select = true ;
						ttr.RowMod = "U" ;
				}
				return ;
				break;

		case "UNSELECT":
				foreach (var ttr in ttResults)
				{
						ttr.Calculated_Select = false ;
						ttr.RowMod = "U" ;
				}
				return ;
				break;

		case "RELEASE":
				foreach (var ttr in ttResults.Where(r=> r.Calculated_Select == true && r.JobHead_JobReleased == false ))
				{
						jobNum = ttr.JobHead_JobNum ;
						var jh = Db.JobHead.Where(h=> h.Company == callContextClient.CurrentCompany && h.JobNum == jobNum).FirstOrDefault() ;
						if (jh != null)
						{
								jh.JobEngineered = true ;
								jh.JobReleased = true ;
								ttr.Calculated_Status = "Released" ;		
								ttr.JobHead_JobReleased = true ;	
						}
				}
				return ;
				break;

		case "UNRELEASE":
				foreach (var ttr in ttResults.Where(r=> r.Calculated_Select == true && r.JobHead_JobReleased == true))
				{
						jobNum = ttr.JobHead_JobNum ;
						var jh = Db.JobHead.Where(h=> h.Company == callContextClient.CurrentCompany && h.JobNum == jobNum).FirstOrDefault() ;
						if (jh != null)
						{
								jh.JobReleased = false ;
								ttr.Calculated_Status = "NOT Released" ;		
								ttr.JobHead_JobReleased = false ;	
						}
				}
				return ;
				break;

		case "HOLD":
				foreach (var ttr in ttResults.Where(r=> r.Calculated_Select == true && r.JobHead_JobHeld == false))
				{
						jobNum = ttr.JobHead_JobNum ;
						var jh = Db.JobHead.Where(h=> h.Company == callContextClient.CurrentCompany && h.JobNum == jobNum).FirstOrDefault() ;
						if (jh != null)
						{
								jh.JobHeld = true ;
								ttr.Calculated_Status = "Held" ;		
								ttr.JobHead_JobHeld = true ;	
						}
				}
				return ;
				break;

		case "UNHOLD":
				foreach (var ttr in ttResults.Where(r=> r.Calculated_Select == true && r.JobHead_JobHeld == true))
				{
						jobNum = ttr.JobHead_JobNum ;
						var jh = Db.JobHead.Where(h=> h.Company == callContextClient.CurrentCompany && h.JobNum == jobNum).FirstOrDefault() ;
						if (jh != null)
						{
								jh.JobHeld = false ;
								ttr.Calculated_Status = "NOT Held" ;		
								ttr.JobHead_JobHeld = false ;	
						}
				}
				return ;
				break;

		case "SCHEDULE":
				foreach (var ttr in ttResults.Where(r=> r.Calculated_Select == true ))
				{
						DateTime startDate = DateTime.Today ;
						DateTime dueDate   = (DateTime) ttr.OrderRel_ReqDate ; //DateTime.Today ;
						jobNum = ttr.JobHead_JobNum ;
						var jh = Db.JobHead.Where(h=> h.Company == callContextClient.CurrentCompany && h.JobNum == jobNum).FirstOrDefault() ;
						if (jh != null)
						{
								jh.ReqDueDate = dueDate ;	
								jh.DueDate = dueDate ;	
						}
						bool finished = false ;
						try
						{
							var schedDS = new Erp.Tablesets.ScheduleEngineTableset() ;
							var sp = schedDS.ScheduleEngine.NewRow() ;
							sp["Company"]	 	   = callContextClient.CurrentCompany ;
							sp["JobNum"]		     = jobNum ;
							sp["AssemblySeq"] 	 = 0 ;
							sp["OprSeq"]      	 = 0 ;
							sp["OpDtlSeq"]    	 = 0 ;
							sp["StartDate"]   	 = startDate ;
							sp["StartTime"]   	 = 0 ;
							sp["EndDate"]     	 = dueDate ;
							sp["EndTime"]     	 = 0 ;
							sp["WhatIf"] 		    = false ;
							sp["Finite"] 		    = false ;
							sp["SchedTypeCode"]  	  = "jj" ;
							sp["ScheduleDirection"]  = "End" ; //"Start" ;
							sp["SetupComplete"]  	  = false ;
							sp["ProductionComplete"] = false ;
							sp["OverrideMtlCon"]	   = false ;
							sp["OverRideHistDateSetting"] = 2 ; 
							sp["RecalcExpProdYld"] 	     = false ;
							sp["UseSchedulingMultiJob"]   = true ;
							sp["SchedulingMultiJobIgnoreLocks"]  = false ;
							sp["SchedulingMultiJobMinimizeWIP"]  = false ;
							sp["SchedulingMultiJobMoveJobsAcrossPlants"] = false ;
							sp["SysRowID"] 		 = Guid.NewGuid() ;
							sp["RowMod"]        = "A" ;
							schedDS.ScheduleEngine.Add( sp );
							boSched.MoveJobItem( schedDS, out finished, out Msg  ) ;
							ttr.Calculated_Status = "Scheduled - " + Msg ;
						} catch (Exception ex) {
							ttr.Calculated_Status = string.Format("Error: {0} Scheduling Job: {1}", ex.Message, jobNum) ;
						}
				}
				return ;
				break;
}

Hi Adrian,
i am a bit confused here, -please forgive my ignorance-, is your problem how to mass update the required date for selected jobs or reschedule ? i am asking because it looks more logical to run the Global scheduling after changing the required dates NOT to reschedule each job you want to change the req, date for.

1 Like

Hi Al,
Thanks for the reply. Yes, that is the problem. I just spoke with one of the guys from the Orders dept and apparently what they do is to change the required by date on the sales order but the required by dates on all the jobs for that order stay as they were. The only way we know of is to go into job entry for each job and reschedule them individually. If there is already a built-in simpler way to reschedule all the jobs at once it would be very helpful to us.

1 Like

Adrian, our systems may be set up differently, but this is how our system functions.

Order department changes a Sales Order Date, Line and Release dates are changed too.
Global Scheduling is run and this updates the Required Date on the Job.
Global Scheduling is run a second time and this sets the Start and Due dates on the Job.

For this to work, the ‘Synchronize Req By Date with Demand Links’ box needs to be checked on the Job

This is often not efficient enough for our Scheduling folks, so we did create an external app that will change all of these dates for us outside of the Global Scheduling process.

1 Like

That code looks like it should work. Can you upload the whole baq and i will test it in my system. We are moving to 10 and have not used global scheduling and this could save our planners a lot of time. I am willing to debug it.

Greg

1 Like

Job Rescheduler 10-04-2019.dbd (281.0 KB)
Hi Greg,
I have uploaded the whole dashboard, with the 2 BAQs. Like I said it works perfectly for scheduling forward but not backwards.
@mhelfrey Matt,
Thanks for your reply. I tried ticking the box and running the global scheduling but the dates on the job did not change for some reason.
Adrian.

Hi @Matt,
this checkbox works ONLY if you make to order, i have tested it on make to stock in my environment and did not work, that is why we had to create a workflow in Service Connect to do this mass update task for us.

@Adrian_Mepham
could you explain what is your final objective, your code might work to trigger the global scheduling, but why?, launching the process from its UI is very straightforward, and if you want you can call it from your updatable dashboard on button Click Event, finally backward scheduling should work unless you ticked not to schedule in the past in the Company Configuration UI, if you do not want to change it there then check if your code is calling this flag from JCSyst table within the BPM class and see if you can alter it, your updatable dashboard will work to mass update the required date on job level -if you bypass the BO restriction such as engineered or/and released flag-, but the trick is how to calculate/decide the new required by date if you not making to order i.e. it is another algorithm you need to create and test based on your business rules and Epicor environment to link/peg each job to its relevant sales release.

1 Like

@A.Baeisa Hi Al,

I don’t think we would ever want to reschedule jobs to before today but what we do a lot is reschedule order dates to the end of the year if we do not know the new required date. This takes the jobs out of various reports, MRP etc. The dashboard does this with no problem. When the customer contacts us to confirm delivery in 3 weeks for example, we can change the dates on the order but the dashboard will not reschedule the jobs backwards from the end of the year so we have to do them all individually.

@Adrian_Mepham,
i think that there is a terminology misunderstanding here, so let me clear what i mean,

  1. deciding the required by date on jobs is an MRP task, either when suggesting new jobs or changes on existed open ones and obviously based on group of setting - i have a post about them i can send to you if you want-, so when demand due date changes job required date will only change if the synchronous checkbox has been ticked for jobs that have made to order demand type, if you creating jobs using different demand strategy then when MRP runs suggestions to change the required by date will appear on the planning Bench asking users to do that manually, so this is the MRP jobs in breife.

  2. scheduling is set the start and end date and time for each operation and loading the calculated time to each linked resource groups and resources, this process can run for one job or for all jobs which called global scheduling and also depends on group of setting parameters as well as the required date at each job, i.e. running scheduling process will not change your job required by date.

now, based on what i said, are you saying that your jobs are making to order and when order release shipby date change they do not get synchronized with it ?

Blockquote
Yes Al, that is what I mean.

@Adrian_Mepham
hmmmm, i just created the whole situation in my Test environment, and run two trials first one running MRP for the part i created, then run global scheduling for the whole site, i can see your issue, required by date won’t be updated,

now, you said that your Updatable dashboard working ok in updating the required by date, so how did you bypass the released flag ?

I just asked the guys and they told me there has never been a problem with the released flag. Most of the time our jobs are created and released at the same time. Are you saying that because the job is released I should not be able to change the dates (using std funtionality)?

yes, when use ExtUpdate method from Updatable dashboard BPM, and try to update any released Job record you will get an error, unless you modify the BPM code to bypass this BO logic

The BPM code is in my initial post. It seems to be using the BOs but as you say I can’t see any mention of the JobReleased flag under “SCHEDULE” so maybe it is just adding the row regardless.

@Adrian_Mepham I was able to get time to test this today. I could not get the external query to work, so I took the scheduling baq and added it to an updateable dashboard on its own. I took released and engineered jobs and scheduled them in. Then I moved all of their sales order dates to 12/31 and scheduled them out. I then moved all of the sales order dates back to today thru May and scheduled them all back in without any problems, so the code works. I did notice that my BPMs are getting called during the process. Is it possible some other BPM or setting is causing the move from 12/31 back in to fail? I did a trace of the dashboard running and the listing in E10 shows all of the bpms that are called.

So let’s go back to the original question. Why does this code fail in your system for pulling in dates, but runs in mine? Are there any error messages in the event log on the IIS server?

Greg

Hi Greg,
I managed to get it working on my machine by changing the < to <> in the criteria;


However when I then deployed the dashboard the users had not options available in the Actions menu, I did however.

Do you think it might be something to do with the fact that it is an exrernal BAQ? If I copy everything into a standard BAQ do you think it will work better. Really strange that it works for me but not for anyone else.
Best regards
Adrian.

I don’t see any reason for the query to be external. It looks simple. I don’t know why that would cause the custom actions to not show, but I would make it a normal baq if I was working on this.

1 Like

Hi,
We are a Mixed Mode Manufacturer - both Make To Order and Make To Stock.
When we have a large bill of materials with multi levels in the Make To Stock environment - changes to delivery dates by the Customer creates quite a bit of admin to manually push/pull the relevant Jobs.
How do you tackle this problem?
Roberto

make to stock should be managed by running the MRP and the global scheduling, these two processes - presuming that all required setup been done correctly- then Planning Workbench should tell you all the required changes to be made on WIP Jobs, so you can then DMT them, or create a workflow in service connect to do the whole task automatically.

@A.Baeisa
Thank you for the reply.
The scenario I am discussing relates to Released Jobs - the Global Scheduling does not contain this functionality.
I have compared the data from MRP and MRP Pegging.
MRP does not suggest correctly for me all the rescheduling that is required - I have changed the various parameters but I still only get some suggestions.
MRP Pegging appears to contain all the data required to reschedule Jobs - this for me is the starting point to create a custom process.
What have you found using these tools? - how do you reschedule Released Jobs?

Roberto.