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());
        }