public async Task <List <DowntimeDto> > GetDowntime(DowntimeResourceParameter parameter) { if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } var start = parameter.Start.AddMonths(-1); var end = parameter.End.AddDays(1).Date; //to get end of that day var machines = await _fmsbContext.MachineList .Where(x => x.MachineMapper != null) .ToListAsync() .ConfigureAwait(false); var owners = await GetDowntimeOwner().ConfigureAwait(false); // Get data in parallel var tasks = new List <Task>(); // Get call box downtime records var callBoxQry = _context.OverallCallbox.AsQueryable(); callBoxQry = callBoxQry.Where( x => x.RequestDateTime >= start && x.RequestDateTime <= end ); callBoxQry = parameter.Lines.Any() ? callBoxQry.Where(x => parameter.Lines.Contains(x.HxHLine)) : !string.IsNullOrEmpty(parameter.Line) ? callBoxQry.Where(x => x.HxHLine == parameter.Line) : callBoxQry; var callBoxTask = callBoxQry.ToListAsync(); // Get manual downtime records var manualDowntimeQry = _fmsbContext.DowntimeDataList2.AsQueryable(); manualDowntimeQry = manualDowntimeQry.Where( x => x.Shiftdate >= parameter.Start && x.Shiftdate <= parameter.End ); manualDowntimeQry = manualDowntimeQry.Where( x => x.DeptName.ToLower().Contains(parameter.Dept.Trim().ToLower()) ); manualDowntimeQry = manualDowntimeQry.Where( x => x.Shift.ToLower().Contains(parameter.Shift.Trim().ToLower()) ); manualDowntimeQry = parameter.Lines.Any() ? manualDowntimeQry.Where(x => parameter.Lines.Contains(x.MachineName)) : !string.IsNullOrEmpty(parameter.Line) ? manualDowntimeQry.Where( x => x.MachineName.ToLower() == parameter.Line.ToLower() ) : manualDowntimeQry; var manualDowntimeEntryTask = manualDowntimeQry.ToListAsync(); tasks.Add(callBoxTask); tasks.Add(manualDowntimeEntryTask); await Task.WhenAll(tasks).ConfigureAwait(false); var callBox = callBoxTask.Result; var manualDowntimeEntry = manualDowntimeEntryTask.Result; var spreadDowntimeData = SpreadHours(callBox); var spreadCallBoxData = spreadDowntimeData .Select( x => { var dept = machines.FirstOrDefault( m => string.Equals( m.MachineMapper, x.Line, StringComparison.CurrentCultureIgnoreCase ) )?.DeptName ?? x.Department; var line = machines.FirstOrDefault( m => string.Equals( m.MachineMapper, x.Line, StringComparison.CurrentCultureIgnoreCase ) )?.MachineName ?? x.Line; var dto = new DowntimeDto { Dept = dept, Line = line, Machine = x.Machine, Reason1 = x.PrimaryReason, Reason2 = x.SecondaryReason, Comments = $"<b>Operator Comment:</b> {x.OperatorComment} <br> <b>{x.Type} Comment:</b> {x.CompletionComment}", DowntimeLoss = (decimal)_dateShift.ElapsedTime( x.RequestDateTime, x.CompletedDateTime ), ShifDate = _dateShift.GetDateShift(x.RequestDateTime, dept).ShiftDate, Shift = _dateShift.GetDateShift(x.RequestDateTime, dept).Shift, ModifiedDate = x.RequestDateTime, Hour = _hour.GetHour(x.CompletedDateTime, dept), Type = x.Type, TypeColor = owners.FirstOrDefault(o => o.Owner == x.Type)?.Color ?? "" }; return(dto); } ) .Where(x => x.ShifDate >= parameter.Start && x.ShifDate <= parameter.End) .ToList(); var manualDowntime = manualDowntimeEntry .Select( x => new DowntimeDto { Dept = x.DeptName, Line = x.MachineName, Machine = x.MachineNumber, Reason1 = x.Reason1, Reason2 = x.Reason2, Comments = x.Comments, DowntimeLoss = x.Downtimeloss, ShifDate = x.Shiftdate, Shift = x.Shift, ModifiedDate = x.Modifieddate, Hour = x.Hour, Type = "Operator (Manual)", TypeColor = owners.FirstOrDefault(o => o.Owner == "Operator (Manual)")?.Color ?? "" } ) .ToList(); spreadCallBoxData.AddRange(manualDowntime); return(spreadCallBoxData .Where(x => x.Dept.ToLower().Contains(parameter.Dept.Trim().ToLower())) .OrderBy(x => x.ShifDate) .ThenBy(x => x.Shift) .ThenBy(x => x.Hour) .ToList()); }