/// <summary>
        /// Gets the last schedule that has ending date right before starting day of a schedule that is about to be generated.
        /// </summary>
        /// <param name="StartingDay">First day of a schedule to generate</param>
        /// <param name="db">An instance of DbContext</param>
        /// <returns>Returns a <see cref="CustomScheduleClass"/> object, that contains unserialized Schedule and HangingDays property.</returns>
        private CustomScheduleClass GetLastSchedule(DateTime StartingDay, P_zpp_2DbContext db)
        {
            var DayBeforeStartingDay = StartingDay.AddDays(-1);
            var lastschedule         = db.schedules
                                       .Where(x => x.LastScheduleDay == DayBeforeStartingDay.Date)
                                       .FirstOrDefault();

            if (lastschedule != null)
            {
                var ScheduleInDictionary             = JsonConvert.DeserializeObject <Dictionary <ApplicationUser, List <SingleShift> > >(lastschedule.ScheduleInJSON);
                var HangingDays                      = JsonConvert.DeserializeObject <List <LastShiftInfo> >(lastschedule.HangingDaysInJSON);
                CustomScheduleClass scheduleToReturn = new CustomScheduleClass(ScheduleInDictionary, HangingDays);
                return(scheduleToReturn);
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Takes the already created <see cref="ShiftGroup"/>s and puts <see cref="Team"/>s teams in it.
        /// </summary>
        /// <param name="shifts">Tuple containing two items: <see cref="List{}"/> of <see cref="ShiftGroup"/> items, and <see cref="List{T}"/> of <see cref="LastShiftInfo"/>.</param>
        /// <param name="teams"><see cref="List{T}"/> of <see cref="Team"/>s that contains <see cref="ApplicationUser"/>s.</param>
        /// <param name="lastSchedule"><see cref="CustomScheduleClass"/> object that contains information about "hanging days"</param>
        /// <param name="shiftInfo"><see cref="List{T}"/> of <see cref="ShiftInfoForScheduleGenerating"/> which contains instructions about creating the shifts.</param>
        /// <returns><see cref="Tuple{T1, T2}"/> build with item1 as <see cref="Dictionary{ShiftGroup, TValue}"/> of key <see cref="ShiftGroup"/> and value of <see cref="Team"/>, and item2 as <see cref="List{T}"/> of <see cref="LastShiftInfo"/></returns>
        private Tuple <Dictionary <ShiftGroup, Team>, List <LastShiftInfo> > PutTeamsIntoShifts(Tuple <List <ShiftGroup>, List <LastShiftInfo> > shifts, List <Team> teams, CustomScheduleClass lastSchedule, List <ShiftInfoForScheduleGenerating> shiftInfo)
        {
            int x = 0;
            var ScheduleInDictionary            = new Dictionary <ShiftGroup, Team>();
            List <LastShiftInfo> lastShiftInfos = new();
            int y;

            if (lastSchedule == null)
            {
                y = 0;
            }
            else
            {
                foreach (var item in lastSchedule.HangingDays)
                {
                    ScheduleInDictionary.Add(shifts.Item1[lastSchedule.HangingDays.IndexOf(item)], teams[item.TeamNumber]);
                }
                y = lastSchedule.HangingDays.Count;
                x = lastSchedule.HangingDays.Last().TeamNumber;
                if (x == 3)
                {
                    x = 0;
                }
            }
            for (int i = y; i < shifts.Item1.Count; i++)
            {
                ScheduleInDictionary.Add(shifts.Item1[i], teams[x]);
                if (x == 3)
                {
                    x = 0;
                }
                else
                {
                    x++;
                }
            }
            var last3 = ScheduleInDictionary.Skip(ScheduleInDictionary.Count - 5).ToList();

            foreach (var item in last3)
            {
                lastShiftInfos.Add(new LastShiftInfo(item.Key.ShiftNumber, shiftInfo.First().ShiftLengthInDays, item.Value.TeamNumber, last3.IndexOf(item)));
            }
            return(Tuple.Create(ScheduleInDictionary, lastShiftInfos));
        }
        /// <summary>
        /// Creates shifts when there are hanging days in last schedule.
        /// </summary>
        /// <param name="shiftInfoForScheduleGenerating"></param>
        /// <param name="lastSchedule"></param>
        /// <param name="ListOfLastShiftInfos"></param>
        /// <param name="GroupedShifts"></param>
        /// <param name="d1"></param>
        /// <param name="d2"></param>
        /// <returns>Tuple with grouped list and list of LastShiftInfo.</returns>
        private Tuple <List <ShiftGroup>, List <LastShiftInfo> > CreateShiftsWithHangingDays(List <ShiftInfoForScheduleGenerating> shiftInfoForScheduleGenerating, CustomScheduleClass lastSchedule, List <LastShiftInfo> ListOfLastShiftInfos, List <ShiftGroup> GroupedShifts, DateTime d1, DateTime d2)
        {
            var  dateTimeList          = new List <SingleShift>();
            var  dateTimeListToAdd     = new List <SingleShift>();
            bool isFirstShiftOfItsType = false;
            int  ShiftNumber           = 0;
            var  time = (d2 - d1).Days;

            foreach (var item in lastSchedule.HangingDays)
            {
                var shiftInfo = shiftInfoForScheduleGenerating[item.ShiftType];
                for (int i = 1; i <= item.DaysToGenerate; i++)
                {
                    var      begin = new DateTime(DateTime.Now.Year, 5, i, shiftInfo.ShiftSetBeginTime.Hour, shiftInfo.ShiftSetBeginTime.Minute, shiftInfo.ShiftSetBeginTime.Second);
                    DateTime end;
                    if (shiftInfo.IsOvernight == false)
                    {
                        end = new DateTime(DateTime.Now.Year, 5, i, shiftInfo.ShiftSetEndTime.Hour, shiftInfo.ShiftSetEndTime.Minute, shiftInfo.ShiftSetEndTime.Second);
                    }
                    else
                    {
                        if (i == 31)
                        {
                            end = new DateTime(DateTime.Now.Year, 6, 1, shiftInfo.ShiftSetEndTime.Hour, shiftInfo.ShiftSetEndTime.Minute, shiftInfo.ShiftSetEndTime.Second);
                        }
                        else
                        {
                            end = new DateTime(DateTime.Now.Year, 5, i + 1, shiftInfo.ShiftSetEndTime.Hour, shiftInfo.ShiftSetEndTime.Minute, shiftInfo.ShiftSetEndTime.Second);
                        }
                    }
                    dateTimeList.Add(new SingleShift(begin, end));
                    dateTimeListToAdd = dateTimeList.ConvertAll(x => (SingleShift)x);
                    if (isFirstShiftOfItsType == false)
                    {
                        ShiftNumber = shiftInfoForScheduleGenerating.IndexOf(shiftInfo) + 1;
                        GroupedShifts.Add(new ShiftGroup(ShiftNumber, dateTimeListToAdd));
                        isFirstShiftOfItsType = true;
                    }
                    else
                    {
                        ShiftNumber += 3;
                        GroupedShifts.Add(new ShiftGroup(ShiftNumber, dateTimeListToAdd));
                    }
                    dateTimeList.Clear();
                }
            }
            foreach (var item in shiftInfoForScheduleGenerating)
            {
                for (int i = lastSchedule.HangingDays.First().DaysToGenerate + 1; i <= time; i++)
                {
                    var      begin = new DateTime(DateTime.Now.Year, 5, i, item.ShiftSetBeginTime.Hour, item.ShiftSetBeginTime.Minute, item.ShiftSetBeginTime.Second);
                    DateTime end;
                    if (item.IsOvernight == false)
                    {
                        end = new DateTime(DateTime.Now.Year, 5, i, item.ShiftSetEndTime.Hour, item.ShiftSetEndTime.Minute, item.ShiftSetEndTime.Second);
                    }
                    else
                    {
                        if (i == 31)
                        {
                            end = new DateTime(DateTime.Now.Year, 6, 1, item.ShiftSetEndTime.Hour, item.ShiftSetEndTime.Minute, item.ShiftSetEndTime.Second);
                        }
                        else
                        {
                            end = new DateTime(DateTime.Now.Year, 5, i + 1, item.ShiftSetEndTime.Hour, item.ShiftSetEndTime.Minute, item.ShiftSetEndTime.Second);
                        }
                    }

                    dateTimeList.Add(new SingleShift(begin, end));
                    if ((dateTimeList.Count == item.ShiftLengthInDays) || i == time)
                    {
                        dateTimeListToAdd = dateTimeList.ConvertAll(x => (SingleShift)x);
                        if (isFirstShiftOfItsType == false)
                        {
                            ShiftNumber = shiftInfoForScheduleGenerating.IndexOf(item) + 1;
                            GroupedShifts.Add(new ShiftGroup(ShiftNumber, dateTimeListToAdd));
                            isFirstShiftOfItsType = true;
                        }
                        else
                        {
                            ShiftNumber += 3;
                            GroupedShifts.Add(new ShiftGroup(ShiftNumber, dateTimeListToAdd));

                            if (i == time)
                            {
                                ListOfLastShiftInfos.Add(new LastShiftInfo(ShiftNumber, item.ShiftLengthInDays - dateTimeListToAdd.Count, shiftInfoForScheduleGenerating.IndexOf(item)));
                            }
                        }
                        dateTimeList.Clear();
                    }
                }
                isFirstShiftOfItsType = false;
                ShiftNumber           = 0;
            }
            GroupedShifts = (List <ShiftGroup>)GroupedShifts.OrderBy(x => x.ShiftNumber).ToList();

            return(Tuple.Create(GroupedShifts, ListOfLastShiftInfos));
        }
        /// <summary>
        /// Method that runs either <see cref="CreateShiftsWithHangingDays(List{ShiftInfoForScheduleGenerating}, CustomScheduleClass, List{LastShiftInfo}, List{ShiftGroup}, DateTime, DateTime)">CreateShiftWithHangingDays</see> method or <see cref="CreateShiftsWithoutHangingDays(List{ShiftInfoForScheduleGenerating}, List{LastShiftInfo}, List{ShiftGroup}, DateTime, DateTime)">CreateShiftsWithoutHaningDays</see> method, regarding if "lastschedule" parameter is null
        /// </summary>
        /// <param name="shiftInfoForScheduleGenerating">List of instructions for generating shifts.</param>
        /// <param name="lastSchedule">Last schedule from the database</param>
        /// <param name="d1">Date of beggining of schedule.</param>
        /// <param name="d2">Date of ending of schedule.</param>
        /// <returns>Tuple with grouped list and list of LastShiftInfo.</returns>
        private Tuple <List <ShiftGroup>, List <LastShiftInfo> > CreateShifts(List <ShiftInfoForScheduleGenerating> shiftInfoForScheduleGenerating, CustomScheduleClass lastSchedule, DateTime d1, DateTime d2)
        {
            List <LastShiftInfo> ListOfLastShiftInfos = new();
            List <ShiftGroup>    GroupedShifts        = new();

            if (lastSchedule == null)
            {
                var tuple = CreateShiftsWithoutHangingDays(shiftInfoForScheduleGenerating, ListOfLastShiftInfos, GroupedShifts, d1, d2);
                return(tuple);
            }
            else
            {
                var tuple = CreateShiftsWithHangingDays(shiftInfoForScheduleGenerating, lastSchedule, ListOfLastShiftInfos, GroupedShifts, d1, d2);
                return(tuple);
            }
        }