/// <summary> /// Get the number of blocks for this type of equipment /// </summary> /// <param name="item"></param> /// <param name="context"></param> /// <param name="configuration"></param> /// <returns></returns> private static int GetNumberOfBlocks(HetRentalRequest item, DbAppContext context, IConfiguration configuration) { int numberOfBlocks = -1; try { SeniorityScoringRules scoringRules = new SeniorityScoringRules(configuration); // get record HetDistrictEquipmentType equipment = context.HetDistrictEquipmentType.AsNoTracking() .Include(x => x.EquipmentType) .FirstOrDefault(x => x.DistrictEquipmentTypeId == item.DistrictEquipmentTypeId); if (equipment == null) { return(0); } numberOfBlocks = equipment.EquipmentType.IsDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") : scoringRules.GetTotalBlocks(); } catch { // do nothing } return(numberOfBlocks); }
/// <summary> /// Seniority List view model /// </summary> /// <param name="model"></param> /// <param name="scoringRules"></param> /// <param name="rotationList"></param> /// <param name="context"></param> /// <returns></returns> public static SeniorityViewModel ToSeniorityViewModel(HetEquipment model, SeniorityScoringRules scoringRules, HetRentalRequestRotationList rotationList, DbAppContext context) { SeniorityViewModel seniorityViewModel = new SeniorityViewModel(); if (model == null) { return(seniorityViewModel); } int numberOfBlocks = 0; // get number of blocks for this equipment type if (model.DistrictEquipmentType != null) { numberOfBlocks = model.DistrictEquipmentType.EquipmentType.IsDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") + 1 : scoringRules.GetTotalBlocks() + 1; } // get equipment block number int blockNumber = 0; if (model.BlockNumber != null) { blockNumber = (int)model.BlockNumber; } // get equipment block number int numberInBlock = 0; if (model.NumberInBlock != null) { numberInBlock = (int)model.NumberInBlock; } // ************************************************************* // check if this record/owner was called last // ************************************************************* bool callLast = rotationList != null && rotationList.EquipmentId == model.EquipmentId; seniorityViewModel.LastCalled = callLast ? "Y" : " "; // ************************************************************* // map data to view model // ************************************************************* seniorityViewModel.Id = model.EquipmentId; if (model.DistrictEquipmentType != null) { seniorityViewModel.EquipmentType = model.DistrictEquipmentType.DistrictEquipmentName; } if (model.Owner != null) { seniorityViewModel.OwnerName = model.Owner.OrganizationName; seniorityViewModel.OwnerId = model.OwnerId; } // replacing Open with 3 (HETS-968 Rotation list -Wrong Block number for Open block) seniorityViewModel.Block = blockNumber == numberOfBlocks ? "3" : blockNumber.ToString(); // format the seniority value seniorityViewModel.Seniority = $"{model.Seniority:0.###}"; // format year / make / model / size seniorityViewModel.YearMakeModelSize = $"{model.Year}/{model.Make}/{model.Model}/{model.Size}"; seniorityViewModel.EquipmentCode = model.EquipmentCode; seniorityViewModel.YearsRegistered = model.YearsOfService.ToString(); // Determine if this equipment is currently hired seniorityViewModel.IsHired = EquipmentHelper.IsHired(model.EquipmentId, context) ? "Y" : "N"; // calculate and format the ytd hours float tempHours = EquipmentHelper.GetYtdServiceHours(model.EquipmentId, context); seniorityViewModel.YtdHours = string.Format("{0:0.###}", tempHours); // format the hours seniorityViewModel.HoursYearMinus1 = string.Format("{0:0.###}", model.ServiceHoursLastYear); seniorityViewModel.HoursYearMinus2 = string.Format("{0:0.###}", model.ServiceHoursTwoYearsAgo); seniorityViewModel.HoursYearMinus3 = string.Format("{0:0.###}", model.ServiceHoursThreeYearsAgo); // add the correct sorting order (numeric) seniorityViewModel.SenioritySortOrder = EquipmentHelper.CalculateSenioritySortOrder(blockNumber, numberInBlock); return(seniorityViewModel); }
/// <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> /// Get rental request record /// </summary> /// <param name="id"></param> /// <param name="scoringRules"></param> /// <param name="context"></param> public static HetRentalRequest GetRecordWithRotationList(int id, SeniorityScoringRules scoringRules, DbAppContext context) { HetRentalRequest request = context.HetRentalRequest.AsNoTracking() .Include(x => x.DistrictEquipmentType) .ThenInclude(y => y.EquipmentType) .Include(x => x.FirstOnRotationList) .Include(x => x.HetRentalRequestAttachment) .Include(x => x.HetRentalRequestRotationList) .ThenInclude(y => y.Equipment) .ThenInclude(r => r.HetEquipmentAttachment) .Include(x => x.HetRentalRequestRotationList) .ThenInclude(y => y.Equipment) .ThenInclude(r => r.LocalArea) .Include(x => x.HetRentalRequestRotationList) .ThenInclude(y => y.Equipment) .ThenInclude(r => r.DistrictEquipmentType) .Include(x => x.HetRentalRequestRotationList) .ThenInclude(y => y.Equipment) .ThenInclude(e => e.Owner) .ThenInclude(c => c.PrimaryContact) .FirstOrDefault(a => a.RentalRequestId == id); if (request != null) { // re-sort list using: LocalArea / District Equipment Type and SenioritySortOrder (desc) request.HetRentalRequestRotationList = request.HetRentalRequestRotationList .OrderBy(e => e.RotationListSortOrder) .ToList(); // calculate the Yes Count based on the RentalRequestList request.YesCount = CalculateYesCount(request); // calculate YTD hours for the equipment records if (request.HetRentalRequestRotationList != null) { foreach (HetRentalRequestRotationList rotationList in request.HetRentalRequestRotationList) { if (rotationList.Equipment != null) { int numberOfBlocks = 0; // get number of blocks for this equipment type if (rotationList.Equipment.DistrictEquipmentType != null) { numberOfBlocks = rotationList.Equipment.DistrictEquipmentType.EquipmentType.IsDumpTruck ? scoringRules.GetTotalBlocks("DumpTruck") + 1 : scoringRules.GetTotalBlocks() + 1; } // get equipment seniority float seniority = 0F; if (rotationList.Equipment.Seniority != null) { seniority = (float)rotationList.Equipment.Seniority; } // get equipment block number int blockNumber = 0; if (rotationList.Equipment.BlockNumber != null) { blockNumber = (int)rotationList.Equipment.BlockNumber; //HETS-968 - Rotation list -Wrong Block number for Open block if (blockNumber == numberOfBlocks) { blockNumber = 3; rotationList.Equipment.BlockNumber = blockNumber; } } rotationList.Equipment.HoursYtd = EquipmentHelper.GetYtdServiceHours(rotationList.Equipment.EquipmentId, context); rotationList.Equipment.SeniorityString = EquipmentHelper.FormatSeniorityString(seniority, blockNumber, numberOfBlocks); } } } } return(request); }
/// <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; } }