private bool DoesNextProcessAndPathGroupMatch(JobPlan job, JobLogDB.QueuedMaterial qm, int proc, int pathGroup) { var matLog = _log.GetLogForMaterial(qm.MaterialID); var lastProc = matLog .SelectMany(e => e.Material) .Where(m => m.MaterialID == qm.MaterialID) .Select(m => m.Process) .DefaultIfEmpty(0) .Max(); if (lastProc != proc) { return(false); } //now try and calculate path. Just check pallet. var lastPallet = matLog .SelectMany(e => e.Material.Select(m => new { log = e, mat = m })) .Where(x => x.mat.MaterialID == qm.MaterialID && x.mat.Process == proc) .Select(x => x.log.Pallet) .Where(x => !string.IsNullOrEmpty(x)) .DefaultIfEmpty("") .First() ; if (string.IsNullOrEmpty(lastPallet)) { throw new UnableToFindPathGroup(); } Log.Debug("Calculated last pallet {pal} for {@qm} and proc {proc}", lastPallet, qm); for (int path = 1; path <= job.GetNumPaths(proc); path++) { if (job.HasPallet(proc, path, lastPallet)) { return(job.GetPathGroup(proc, path) == pathGroup); } } throw new UnableToFindPathGroup(); }
/// Count up how many JobPaths have an earlier simulation start time and also share a fixture/face with the current job private static int CountEarlierConflicts(JobPlan jobToCheck, int proc1path, IEnumerable <JobPlan> jobs) { var startT = jobToCheck.GetSimulatedStartingTimeUTC(process: 1, path: proc1path); if (startT == DateTime.MinValue) { return(0); } // first, calculate the fixtures and faces used by the job to check var group = jobToCheck.GetPathGroup(process: 1, path: proc1path); var usedFixtureFaces = new HashSet <ValueTuple <string, string> >(); for (int proc = 1; proc <= jobToCheck.NumProcesses; proc++) { for (int path = 1; path <= jobToCheck.GetNumPaths(proc); path++) { if (jobToCheck.GetPathGroup(proc, path) != group) { continue; } var(plannedFix, plannedFace) = jobToCheck.PlannedFixture(proc, path); if (string.IsNullOrEmpty(plannedFix)) { continue; } usedFixtureFaces.Add((plannedFix, plannedFace.ToString())); } } int earlierConflicts = 0; // go through each other job and process 1 path foreach (var otherJob in jobs) { for (var otherProc1Path = 1; otherProc1Path <= otherJob.GetNumPaths(process: 1); otherProc1Path++) { if (otherJob.UniqueStr == jobToCheck.UniqueStr && proc1path == otherProc1Path) { continue; } // see if the process 1 starting time is later and if so skip the remaining checks var otherStart = otherJob.GetSimulatedStartingTimeUTC(process: 1, path: otherProc1Path); if (otherStart == DateTime.MinValue) { goto checkNextPath; } if (otherStart >= startT) { goto checkNextPath; } var otherGroup = otherJob.GetPathGroup(process: 1, path: otherProc1Path); //the job-path combo starts earlier than the job-path to check, but need to see if it conflicts. // go through all processes matching the path group and if a fixture face matches, // count it as a conflict. for (var otherProc = 1; otherProc <= otherJob.NumProcesses; otherProc++) { for (var otherPath = 1; otherPath <= otherJob.GetNumPaths(otherProc); otherPath++) { if (otherJob.GetPathGroup(otherProc, otherPath) != otherGroup) { continue; } var(otherFix, otherFace) = otherJob.PlannedFixture(otherProc, otherPath); if (usedFixtureFaces.Contains((otherFix, otherFace.ToString()))) { earlierConflicts += 1; goto checkNextPath; } } } checkNextPath :; } } return(earlierConflicts); }