/// <summary> /// Calculate the Seniority List /// </summary> /// <param name="localAreaId"></param> /// <param name="districtEquipmentTypeId"></param> /// <param name="equipmentTypeId"></param> /// <param name="context"></param> /// <param name="configuration"></param> public static void CalculateSeniorityList(int localAreaId, int districtEquipmentTypeId, int equipmentTypeId, DbAppContext context, IConfiguration configuration) { try { // validate data if (context != null && context.HetLocalArea.Any(x => x.LocalAreaId == localAreaId) && context.HetDistrictEquipmentType.Any(x => x.DistrictEquipmentTypeId == districtEquipmentTypeId)) { // get processing rules SeniorityScoringRules scoringRules = new SeniorityScoringRules(configuration); // get the associated equipment type HetEquipmentType equipmentTypeRecord = context.HetEquipmentType .FirstOrDefault(x => x.EquipmentTypeId == equipmentTypeId); if (equipmentTypeRecord != null) { // get rules int seniorityScoring = equipmentTypeRecord.IsDumpTruck ? scoringRules.GetEquipmentScore("DumpTruck") : scoringRules.GetEquipmentScore(); int blockSize = equipmentTypeRecord.IsDumpTruck ? scoringRules.GetBlockSize("DumpTruck") : scoringRules.GetBlockSize(); int totalBlocks = equipmentTypeRecord.IsDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") : scoringRules.GetTotalBlocks(); // get all equipment records IQueryable <HetEquipment> data = context.HetEquipment .Include(x => x.EquipmentStatusType) .Where(x => x.LocalAreaId == localAreaId && x.DistrictEquipmentTypeId == districtEquipmentTypeId); // get status id int?eqStatusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", context); if (eqStatusId == null) { throw new ArgumentException("Status Code not found"); } // update the seniority score foreach (HetEquipment equipment in data) { if (equipment.EquipmentStatusTypeId != eqStatusId) { equipment.SeniorityEffectiveDate = DateTime.UtcNow; equipment.BlockNumber = null; equipment.Seniority = null; equipment.NumberInBlock = null; } else { equipment.CalculateSeniority(seniorityScoring); equipment.SeniorityEffectiveDate = DateTime.UtcNow; } context.HetEquipment.Update(equipment); } context.SaveChanges(); // put equipment into the correct blocks AssignBlocks(localAreaId, districtEquipmentTypeId, blockSize, totalBlocks, context); } } } catch (Exception e) { Console.WriteLine("ERROR: CalculateSeniorityList"); Console.WriteLine(e); throw; } }
/// <summary> /// Annual Rollover /// </summary> /// <param name="context"></param> /// <param name="districtId"></param> /// <param name="seniorityScoringRules"></param> /// <param name="connectionString"></param> public static void AnnualRolloverJob(PerformContext context, int districtId, string seniorityScoringRules, string connectionString) { try { // open a connection to the database DbAppContext dbContext = new DbAppContext(connectionString); // get processing rules SeniorityScoringRules scoringRules = new SeniorityScoringRules(seniorityScoringRules); // update progress bar IProgressBar progress = context.WriteProgressBar(); context.WriteLine("Starting Annual Rollover Job - District #" + districtId); progress.SetValue(0); // validate district id HetDistrict district = dbContext.HetDistrict.AsNoTracking() .FirstOrDefault(x => x.DistrictId == districtId); if (district == null) { context.WriteLine("District not found"); progress.SetValue(100); return; } // get status record - and ensure we're active HetDistrictStatus status = GetRecord(districtId, dbContext); if (status == null) { context.WriteLine("District Status not found"); progress.SetValue(100); return; } // get equipment status int?statusId = StatusHelper.GetStatusId(HetEquipment.StatusApproved, "equipmentStatus", dbContext); if (statusId == null) { context.WriteLine("Equipment Status not found"); progress.SetValue(100); return; } // determine the "Rollover Date" (required for testing) DateTime rolloverDate; if (DateTime.UtcNow.Month == 1 || DateTime.UtcNow.Month == 2 || DateTime.UtcNow.Month == 3) { if (status.NextFiscalYear == null) { status.NextFiscalYear = DateTime.UtcNow.Year; } rolloverDate = new DateTime((int)status.NextFiscalYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); } else { if (status.CurrentFiscalYear == null) { status.CurrentFiscalYear = DateTime.UtcNow.Year; } rolloverDate = new DateTime((int)status.CurrentFiscalYear, DateTime.UtcNow.Month, DateTime.UtcNow.Day); } // get all district equipment types List <HetDistrictEquipmentType> equipmentTypes = dbContext.HetDistrictEquipmentType.AsNoTracking() .Include(x => x.EquipmentType) .Where(x => x.DistrictId == districtId).ToList(); // get all local areas List <HetLocalArea> localAreas = dbContext.HetLocalArea.AsNoTracking() .Where(a => a.ServiceArea.DistrictId == districtId).ToList(); // update status - job is kicked off int localAreaCompleteCount = 0; int equipmentCompleteCount = 0; UpdateStatusKickoff(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); // process all local areas and equipment types foreach (HetLocalArea localArea in localAreas.WithProgress(progress)) { // re-open the connection dbContext = new DbAppContext(connectionString); if (localArea.Name != null) { context.WriteLine("Local Area: " + localArea.Name); } else { context.WriteLine("Local Area ID: " + localArea.LocalAreaId); } // reset equipment counter equipmentCompleteCount = 0; foreach (HetDistrictEquipmentType equipmentType in equipmentTypes) { // it this a dump truck? bool isDumpTruck = equipmentType.EquipmentType.IsDumpTruck; // get rules for scoring and seniority block int seniorityScoring = isDumpTruck ? scoringRules.GetEquipmentScore("DumpTruck") : scoringRules.GetEquipmentScore(); int blockSize = isDumpTruck ? scoringRules.GetBlockSize("DumpTruck") : scoringRules.GetBlockSize(); int totalBlocks = isDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") : scoringRules.GetTotalBlocks(); using (DbAppContext etContext = new DbAppContext(connectionString)) { List <HetEquipment> data = etContext.HetEquipment .Include(x => x.LocalArea) .Include(x => x.DistrictEquipmentType.EquipmentType) .Where(x => x.EquipmentStatusTypeId == statusId && x.LocalAreaId == localArea.LocalAreaId && x.DistrictEquipmentTypeId == equipmentType.DistrictEquipmentTypeId) .ToList(); foreach (HetEquipment equipment in data) { // rollover the year equipment.ServiceHoursThreeYearsAgo = equipment.ServiceHoursTwoYearsAgo; equipment.ServiceHoursTwoYearsAgo = equipment.ServiceHoursLastYear; equipment.ServiceHoursLastYear = EquipmentHelper.GetYtdServiceHours(equipment.EquipmentId, dbContext, rolloverDate); equipment.CalculateYearsOfService(DateTime.UtcNow); // blank out the override reason equipment.SeniorityOverrideReason = ""; // update the seniority score equipment.CalculateSeniority(seniorityScoring); etContext.HetEquipment.Update(equipment); etContext.SaveChanges(); } } // now update the rotation list using (DbAppContext abContext = new DbAppContext(connectionString)) { int localAreaId = localArea.LocalAreaId; int equipmentTypeId = equipmentType.DistrictEquipmentTypeId; SeniorityListHelper.AssignBlocks(localAreaId, equipmentTypeId, blockSize, totalBlocks, abContext); } // increment counters and update status equipmentCompleteCount++; UpdateStatus(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); } // increment counters and update status localAreaCompleteCount++; UpdateStatus(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); if (status.ProgressPercentage != null) { progress.SetValue((int)status.ProgressPercentage); } } // done! UpdateStatusComplete(dbContext, status, localAreaCompleteCount, equipmentCompleteCount); progress.SetValue(100); // ********************************************************** // regenerate Owner Secret Keys for this district // ********************************************************** dbContext = new DbAppContext(connectionString); context.WriteLine(""); context.WriteLine("Generate New Secret Keys - District #" + districtId); progress = context.WriteProgressBar(); progress.SetValue(0); // get records List <HetOwner> owners = dbContext.HetOwner.AsNoTracking() .Where(x => x.BusinessId == null && x.LocalArea.ServiceArea.DistrictId == districtId) .ToList(); int i = 0; int ownerCount = owners.Count; foreach (HetOwner owner in owners) { i++; string key = SecretKeyHelper.RandomString(8, owner.OwnerId); string temp = owner.OwnerCode; if (string.IsNullOrEmpty(temp)) { temp = SecretKeyHelper.RandomString(4, owner.OwnerId); } key = temp + "-" + (rolloverDate.Year + 1) + "-" + key; // get owner and update HetOwner ownerRecord = dbContext.HetOwner.First(x => x.OwnerId == owner.OwnerId); ownerRecord.SharedKey = key; dbContext.HetOwner.Update(ownerRecord); decimal tempProgress = Convert.ToDecimal(i) / Convert.ToDecimal(ownerCount); tempProgress = tempProgress * 100; int percentComplete = Convert.ToInt32(tempProgress); if (percentComplete < 1) { percentComplete = 1; } if (percentComplete > 99) { percentComplete = 100; } progress.SetValue(percentComplete); } // save remaining updates - done! dbContext.SaveChangesForImport(); progress.SetValue(100); context.WriteLine("Generate New Secret Keys - Done"); } catch (Exception e) { Console.WriteLine(e); throw; } }