Пример #1
0
        public List <ICalendarDay> GenerateWeeks(DateTime dateTime, int weeksCount)
        {
            var days     = new List <ICalendarDay>();
            int dayCount = _calendar.WeekTemplate.Count;

            for (var i = 0; i < weeksCount; i++)
            {
                for (var j = 0; j < dayCount; j++)
                {
                    ICalendarDay day;
                    DateTime     calendarDate = dateTime.AddDays(j + dayCount * i);
                    ICalendarDay dayOff       = _calendar.DayOffs
                                                .FirstOrDefault(d => d.CalendarDateTime.Date == calendarDate.Date);
                    if (dayOff != null)
                    {
                        day = (ICalendarDay)dayOff.Clone();
                    }
                    else
                    {
                        var dayOfWeek = _calendar.WeekTemplate
                                        .FirstOrDefault(d => d.DayOfWeek == calendarDate.DayOfWeek);
                        day = (ICalendarDay)dayOfWeek.Clone();
                        day.CalendarDateTime = calendarDate;
                    }
                    days.Add(day);
                }
            }
            return(days);
        }
Пример #2
0
        /// <summary>
        /// Get amount of non-working minutes on the day of case registration.
        /// </summary>
        /// <param name="days">Calendar days.</param>
        /// <param name="registrationDate">Case registration date.</param>
        /// <returns>Non-working minutes on the day of case registration.</returns>
        public static int GetNonWorkingMinutes(this IEnumerable <ICalendarDay> days, DateTime registrationDate)
        {
            ICalendarDay calendarDay = days.FirstOrDefault(day => day.DayOfWeek == registrationDate.DayOfWeek);

            if (calendarDay != null && !calendarDay.IsNonWorking)
            {
                IList <WorkingInterval> intervals       = calendarDay.WorkingIntervals;
                WorkingInterval         workingInterval =
                    intervals.FirstOrDefault(interval => interval.GetIsDateBetween(registrationDate));
                if (!workingInterval.Equals(default(WorkingInterval)))
                {
                    int    index       = intervals.IndexOf(workingInterval);
                    double minutesSumm = 0;
                    for (int i = 0; i < index; i++)
                    {
                        minutesSumm += intervals[i].Length.TotalMinutes;
                    }
                    TimeSpan intervalMinuteOffset = registrationDate.TimeOfDay - intervals[index].Start;
                    minutesSumm += intervalMinuteOffset.TotalMinutes;
                    return((int)minutesSumm);
                }
                return((int)calendarDay.GetWorkingTime());
            }
            return(default(int));
        }
Пример #3
0
 protected void LogFirstCalculationInterval(ICalendarDay day)
 {
     if (TermCalculationLogStore != null)
     {
         new TermCalculationLogger(TermCalculationLogStore)
         .AddFirstNonWorkingCalculationInterval(day);
     }
 }
Пример #4
0
        /// <summary>
        /// Actualize calendar days for calculation.
        /// </summary>
        /// <param name="days">Calendar days.</param>
        /// <param name="dateTime">Calculation pivot.</param>
        public override void ActualizeDays(ref IEnumerable <ICalendarDay> days, DateTime dateTime)
        {
            ICalendarDay day = days.FirstOrDefault(d => d.CalendarDateTime.Date == dateTime.Date);

            if (day != default(ICalendarDay))
            {
                day.WorkingIntervals = day.WorkingIntervals.Select(i => i.Truncate(dateTime)).ToList();
            }
        }
Пример #5
0
 /// <summary>
 /// Fills calculated working minutes time intervals.
 /// </summary>
 /// <param name="day">Calendar day.</param>
 /// <param name="workingTime">Working minute time.</param>
 public void FillWorkingMinuteCalculationInterval(ICalendarDay day, double workingTime)
 {
     _logStore.CalculationIntervals.Add(new CalculationInterval {
         IsWorkingDay       = !day.IsNonWorking,
         SpentIntervalValue = workingTime,
         DayOfWeek          = GetLocalDayOfWeek(day.DayOfWeek),
         CalendarDateTime   = day.CalendarDateTime.ToString(_logStore.UserCulture.DateTimeFormat.ShortDatePattern)
     });
 }
Пример #6
0
 /// <summary>
 /// Fills first calculated working days time interval.
 /// </summary>
 /// <param name="day">Calendar day.</param>
 public void AddFirstNonWorkingCalculationInterval(ICalendarDay day)
 {
     if (_logStore.IsUsedIntervalCalculated)
     {
         _logStore.CalculationIntervals.Add(new CalculationInterval {
             IsWorkingDay       = !day.IsNonWorking,
             SpentIntervalValue = 0,
             DayOfWeek          = GetLocalDayOfWeek(day.DayOfWeek),
             CalendarDateTime   = day.CalendarDateTime.ToString(_logStore.UserCulture.DateTimeFormat.ShortDatePattern)
         });
     }
 }
Пример #7
0
        public void Run(int day, string input)
        {
            if (!HasBeenSolved(day))
            {
                Console.WriteLine($"Day {day} has not been solved!");
                return;
            }

            ICalendarDay solution = Get(day);

            Console.WriteLine($"Day: {day}");
            Console.WriteLine($"First Task: {solution.RunFirstPart(input)}");
            Console.WriteLine($"Second Task: {solution.RunSecondPart(input)}\n");
        }
Пример #8
0
        /// <summary>
        /// Gets amount of time units from the very left day time point up to the <paramref name="end"/>.
        /// </summary>
        /// <param name="days">Calendar days.</param>
        /// <param name="end">Date and time of the end.</param>
        /// <returns>Time units amount.</returns>
        protected virtual int GetTimeUnits(IEnumerable <ICalendarDay> days, DateTime end)
        {
            double result = days
                            .TakeWhile(day => day.CalendarDateTime.Date < end.Date)
                            .Sum(day => day.GetWorkingTime());
            ICalendarDay lastDay = days.FirstOrDefault(day => day.CalendarDateTime.Date == end.Date);

            if (lastDay != default(ICalendarDay))
            {
                int least = GetSingleDayTimeUnits(lastDay, end);
                result += least;
            }
            return((int)result);
        }
Пример #9
0
        /// <summary>
        /// Actualize calendar days for calculation.
        /// </summary>
        /// <param name="days">Calendar days.</param>
        /// <param name="dateTime">Calculation pivot.</param>
        public override void ActualizeDays(ref IEnumerable <ICalendarDay> days, DateTime dateTime)
        {
            ICalendarDay day = days.FirstOrDefault(d => d.CalendarDateTime.Date == dateTime.Date);

            if (day.WorkingIntervals.Count == 0)
            {
                return;
            }
            TimeSpan startInterval = day.WorkingIntervals.Min(i => i.Start);

            if (dateTime.TimeOfDay > startInterval)
            {
                days = days.Except(new[] { day });
            }
        }
Пример #10
0
        /// <summary>
        /// Adds <paramref name="minutes"/> by given days of the calendar.
        /// </summary>
        /// <param name="days">Calendar days.</param>
        /// <param name="minutes">Minutes to add.</param>
        /// <returns>Calculated date and time.</returns>
        public override DateTime Calculate(IEnumerable <ICalendarDay> days, int minutes)
        {
            var    result          = default(DateTime);
            double timeLeft        = minutes;
            bool   keepEnumeration = true;
            IEnumerator <ICalendarDay> daysEnumerator = days.GetEnumerator();

            while (daysEnumerator.MoveNext() && keepEnumeration)
            {
                ICalendarDay day = daysEnumerator.Current;
                IEnumerator <WorkingInterval> intervalEnumerator = day.WorkingIntervals.GetEnumerator();
                var workingTime = day.GetWorkingTime();
                if (timeLeft > workingTime)
                {
                    timeLeft -= workingTime;
                    if (TermCalculationLogStore != null)
                    {
                        new TermCalculationLogger(TermCalculationLogStore)
                        .FillWorkingMinuteCalculationInterval(day, workingTime);
                    }
                }
                else
                {
                    if (TermCalculationLogStore != null)
                    {
                        new TermCalculationLogger(TermCalculationLogStore)
                        .FillWorkingMinuteCalculationInterval(day, timeLeft);
                    }
                    while (intervalEnumerator.MoveNext() && keepEnumeration)
                    {
                        WorkingInterval interval        = intervalEnumerator.Current;
                        double          intervalMinutes = interval.Length.TotalMinutes;
                        if (timeLeft > intervalMinutes)
                        {
                            timeLeft -= intervalMinutes;
                        }
                        else
                        {
                            result = day.CalendarDateTime.Date
                                     .Add(interval.Start)
                                     .AddMinutes(timeLeft);
                            keepEnumeration = false;
                        }
                    }
                }
            }
            return(result);
        }
Пример #11
0
        private int GetSingleDayTimeUnits(ICalendarDay day, DateTime end)
        {
            var length = default(TimeSpan);
            IEnumerator <WorkingInterval> enumerator = day.WorkingIntervals.GetEnumerator();

            if (!day.WorkingIntervals.Any(interval => interval.GetIsDateBetween(end)))
            {
                return(0);
            }
            while (enumerator.MoveNext() && !enumerator.Current.GetIsDateBetween(end))
            {
                length += enumerator.Current.Length;
            }
            length += enumerator.Current.Truncate(end, true).Length;
            return((int)length.TotalMinutes);
        }
Пример #12
0
        /// <summary>
        /// Fills calendar week template.
        /// </summary>
        /// <param name="calendar">Calendar.</param>
        private void FillWeekTemplate(T calendar)
        {
            var    query               = new EntitySchemaQuery(_userConnection.EntitySchemaManager, "DayInCalendar");
            string dayOfWeekCode       = query.AddColumn("DayOfWeek.Code").Name;
            string dayOfWeekNonWorking = query.AddColumn("DayType.NonWorking").Name;
            string dayType             = query.AddColumn("DayType.Id").Name;
            var    intervalToColumn    = query.AddColumn("[WorkingTimeInterval:DayInCalendar].To");

            intervalToColumn.OrderByAsc(0);
            var intervalFromColumn = query.AddColumn("[WorkingTimeInterval:DayInCalendar].From");

            intervalFromColumn.OrderByAsc(1);
            string dayOfWeekFromPeriod = intervalFromColumn.Name;
            string dayOfWeekToPeriod   = intervalToColumn.Name;

            query.Filters.Add(
                query.CreateFilterWithParameters(FilterComparisonType.Equal, "Calendar", calendar.Id));
            EntityCollection collection = query.GetEntityCollection(_userConnection);

            foreach (var record in collection)
            {
                var          start     = record.GetTypedColumnValue <DateTime>(dayOfWeekFromPeriod);
                var          end       = record.GetTypedColumnValue <DateTime>(dayOfWeekToPeriod);
                var          dayCode   = record.GetTypedColumnValue <string>(dayOfWeekCode);
                var          dayOfWeek = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), dayCode);
                ICalendarDay day       = calendar.WeekTemplate.FirstOrDefault(item => item.DayOfWeek == dayOfWeek);
                if (day == default(ICalendarDay))
                {
                    var isNonWorking = record.GetTypedColumnValue <bool>(dayOfWeekNonWorking);
                    var dayTypeUId   = record.GetTypedColumnValue <Guid>(dayType);
                    day = new CalendarDay {
                        DayOfWeek    = dayOfWeek,
                        IsNonWorking = isNonWorking,
                        DayTypeUId   = dayTypeUId
                    };
                    calendar.WeekTemplate.Add(day);
                }
                if (!day.IsNonWorking)
                {
                    day.WorkingIntervals.Add(new WorkingInterval(start.TimeOfDay, end.TimeOfDay));
                }
            }
        }
Пример #13
0
        /// <summary>
        /// Fills calendar day offs.
        /// </summary>
        /// <param name="calendar">Calendar.</param>
        private void FillDayOffInfo(T calendar)
        {
            var    query            = new EntitySchemaQuery(_userConnection.EntitySchemaManager, "DayOff");
            string date             = query.AddColumn("Date").Name;
            string dayType          = query.AddColumn("DayType.Id").Name;
            string dayOffNonWorking = query.AddColumn("DayType.NonWorking").Name;
            string dayOffFromPeriod = query.AddColumn("[WorkingTimeInterval:DayOff].From").Name;
            string dayOffToPeriod   = query.AddColumn("[WorkingTimeInterval:DayOff].To").Name;

            query.Filters.Add(query.CreateFilterWithParameters(FilterComparisonType.Equal, "Calendar", calendar.Id));
            EntityCollection collection = query.GetEntityCollection(_userConnection);

            foreach (var record in collection)
            {
                var start        = record.GetTypedColumnValue <DateTime>(dayOffFromPeriod);
                var end          = record.GetTypedColumnValue <DateTime>(dayOffToPeriod);
                var dayTypeId    = record.GetTypedColumnValue <Guid>(dayType);
                var isNonWorking = record.GetTypedColumnValue <bool>(dayOffNonWorking);
                if (!isNonWorking && (start == default(DateTime) || end == default(DateTime)))
                {
                    continue;
                }
                var          dayDate = record.GetTypedColumnValue <DateTime>(date);
                ICalendarDay dayOff  = calendar.DayOffs.FirstOrDefault(item => item.CalendarDateTime.Date == dayDate);
                if (dayOff == default(ICalendarDay))
                {
                    dayOff = new CalendarDay {
                        CalendarDateTime = dayDate,
                        IsNonWorking     = isNonWorking,
                        DayTypeUId       = dayTypeId,
                        DayOfWeek        = dayDate.DayOfWeek
                    };
                    calendar.DayOffs.Add(dayOff);
                }
                if (!dayOff.IsNonWorking)
                {
                    dayOff.WorkingIntervals.Add(new WorkingInterval(start.TimeOfDay, end.TimeOfDay));
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Generate calendar days by calendar week template.
        /// </summary>
        /// <param name="calendar">The calendar.</param>
        /// <param name="dateTime">The date time.</param>
        /// <param name="weeksCount">Number of weeks to generate.</param>
        /// <returns>
        /// Calendar days.
        /// </returns>
        /// <exception cref="Exception">Unable to find day of week in week template</exception>
        public static IEnumerable <ICalendarDay> GenerateWeeks(this ICalendar <ICalendarDay> calendar, DateTime dateTime,
                                                               int weeksCount)
        {
            int daysOffInPeriod = 0;
            var days            = new List <ICalendarDay>();
            int dayCount        = calendar.WeekTemplate.Count;

            for (var i = 0; i < weeksCount + Math.Ceiling((decimal)daysOffInPeriod / 7); i++)
            {
                for (var j = 0; j < dayCount; j++)
                {
                    ICalendarDay day;
                    DateTime     calendarDate = dateTime.AddDays(j + dayCount * i);
                    ICalendarDay dayOff       = calendar.DayOffs
                                                .FirstOrDefault(d => d.CalendarDateTime.Date == calendarDate.Date);
                    if (dayOff != null)
                    {
                        day = (ICalendarDay)dayOff.Clone();
                        daysOffInPeriod++;
                    }
                    else
                    {
                        var dayOfWeek = calendar.WeekTemplate
                                        .FirstOrDefault(d => d.DayOfWeek == calendarDate.DayOfWeek);
                        if (dayOfWeek == default(ICalendarDay))
                        {
                            throw new Exception("Unable to find day of week in week template");
                        }
                        day = (ICalendarDay)dayOfWeek.Clone();
                        day.CalendarDateTime = calendarDate;
                    }
                    days.Add(day);
                }
            }
            return(days);
        }
Пример #15
0
 private void Add(int day, ICalendarDay solution)
 {
     _calendarDays.Add(day, solution);
 }