public DayTimeTrackPartViewModel(TimeTrackPart timeTrackPart) { string zoneName = null; var gkZone = GKManager.SKDZones.FirstOrDefault(x => x.UID == timeTrackPart.ZoneUID); if (gkZone != null) zoneName = gkZone.PresentationName; UID = timeTrackPart.PassJournalUID; Update(timeTrackPart.StartTime, timeTrackPart.EndTime, zoneName); }
void CalculateDocuments() { DocumentTrackParts = new List<TimeTrackPart>(); foreach (var document in Documents) { TimeTrackPart timeTrackPart = null; if (document.StartDateTime.Date < Date && document.EndDateTime.Date > Date) { timeTrackPart = new TimeTrackPart() { StartTime = TimeSpan.Zero, EndTime = new TimeSpan(24, 0, 0) }; } if (document.StartDateTime.Date == Date && document.EndDateTime.Date > Date) { timeTrackPart = new TimeTrackPart() { StartTime = document.StartDateTime.TimeOfDay, EndTime = new TimeSpan(24, 0, 0) }; } if (document.StartDateTime.Date == Date && document.EndDateTime.Date == Date) { timeTrackPart = new TimeTrackPart() { StartTime = document.StartDateTime.TimeOfDay, EndTime = document.EndDateTime.TimeOfDay }; } if (document.StartDateTime.Date < Date && document.EndDateTime.Date == Date) { timeTrackPart = new TimeTrackPart() { StartTime = TimeSpan.Zero, EndTime = document.EndDateTime.TimeOfDay }; } if (timeTrackPart != null) { timeTrackPart.MinTimeTrackDocumentType = document.TimeTrackDocumentType; DocumentTrackParts.Add(timeTrackPart); } } DocumentTrackParts = DocumentTrackParts.OrderBy(x => x.StartTime.Ticks).ToList(); var timeSpans = new List<TimeSpan>(); foreach (var trackPart in DocumentTrackParts) { timeSpans.Add(trackPart.StartTime); timeSpans.Add(trackPart.EndTime); } timeSpans = timeSpans.OrderBy(x => x.TotalSeconds).ToList(); var result = new List<TimeTrackPart>(); for (int i = 0; i < timeSpans.Count - 1; i++) { var startTimeSpan = timeSpans[i]; var endTimeSpan = timeSpans[i + 1]; var timeTrackParts = DocumentTrackParts.Where(x => x.StartTime <= startTimeSpan && x.EndTime > startTimeSpan); if (timeTrackParts.Count() > 0) { var newTimeTrackPart = new TimeTrackPart() { StartTime = startTimeSpan, EndTime = endTimeSpan, }; foreach (var timeTrackPart in timeTrackParts) { if (newTimeTrackPart.MinTimeTrackDocumentType == null) newTimeTrackPart.MinTimeTrackDocumentType = timeTrackPart.MinTimeTrackDocumentType; else if (timeTrackPart.MinTimeTrackDocumentType.DocumentType < newTimeTrackPart.MinTimeTrackDocumentType.DocumentType) newTimeTrackPart.MinTimeTrackDocumentType = timeTrackPart.MinTimeTrackDocumentType; newTimeTrackPart.TimeTrackDocumentTypes.Add(timeTrackPart.MinTimeTrackDocumentType); } result.Add(newTimeTrackPart); } } DocumentTrackParts = result; }
public static List<TimeTrackPart> NormalizeTimeTrackParts(List<TimeTrackPart> timeTrackParts) { if (timeTrackParts.Count == 0) return new List<TimeTrackPart>(); var result = new List<TimeTrackPart>(); var timeSpans = new List<TimeSpan>(); foreach (var timeTrackPart in timeTrackParts) { timeSpans.Add(timeTrackPart.StartTime); timeSpans.Add(timeTrackPart.EndTime); } timeSpans = timeSpans.OrderBy(x => x.TotalSeconds).ToList(); for (int i = 0; i < timeSpans.Count - 1; i++) { var startTimeSpan = timeSpans[i]; var endTimeSpan = timeSpans[i + 1]; var timeTrackPart = timeTrackParts.FirstOrDefault(x => x.StartTime <= startTimeSpan && x.EndTime > startTimeSpan); if (timeTrackPart != null) { var newTimeTrackPart = new TimeTrackPart() { StartTime = startTimeSpan, EndTime = endTimeSpan, TimeTrackPartType = timeTrackPart.TimeTrackPartType, ZoneUID = timeTrackPart.ZoneUID, StartsInPreviousDay = timeTrackPart.StartsInPreviousDay, EndsInNextDay = timeTrackPart.EndsInNextDay, DayName = timeTrackPart.DayName, PassJournalUID = timeTrackPart.PassJournalUID }; result.Add(newTimeTrackPart); } } for (int i = result.Count - 1; i > 0; i--) { if (result[i].StartTime == result[i - 1].EndTime && result[i].ZoneUID == result[i - 1].ZoneUID) { result[i].StartTime = result[i - 1].StartTime; result.RemoveAt(i - 1); } } return result; }
void CalculateCombinedTimeTrackParts() { var firstPlanned = new TimeSpan(); var lastPlanned = new TimeSpan(); var slideTime = new TimeSpan(SlideTime.Ticks); if (PlannedTimeTrackParts.Count > 0) { firstPlanned = PlannedTimeTrackParts.FirstOrDefault().StartTime; lastPlanned = PlannedTimeTrackParts.LastOrDefault().EndTime; } var firstEnter = new TimeSpan(); var lastExit = new TimeSpan(); if (RealTimeTrackParts.Count > 0) { firstEnter = RealTimeTrackParts.FirstOrDefault().StartTime; lastExit = RealTimeTrackParts.LastOrDefault().EndTime; } var combinedTimeSpans = new List<TimeSpan>(); foreach (var trackPart in RealTimeTrackParts) { combinedTimeSpans.Add(trackPart.StartTime); combinedTimeSpans.Add(trackPart.EndTime); if (PlannedTimeTrackParts.Count == 0 && SlideTime > TimeSpan.Zero) slideTime -= trackPart.Delta; } var slideTimeWithNoReal = new TimeSpan(slideTime.Ticks); foreach (var trackPart in PlannedTimeTrackParts) { combinedTimeSpans.Add(trackPart.StartTime); combinedTimeSpans.Add(trackPart.EndTime); } foreach (var trackPart in DocumentTrackParts) { if (PlannedTimeTrackParts.Count == 0 && slideTime > TimeSpan.Zero) { combinedTimeSpans.Add(trackPart.StartTime); if (trackPart.Delta > slideTime) { combinedTimeSpans.Add(trackPart.StartTime + slideTime); slideTime -= trackPart.Delta; } else combinedTimeSpans.Add(trackPart.EndTime); } else { combinedTimeSpans.Add(trackPart.StartTime); combinedTimeSpans.Add(trackPart.EndTime); } } if (NightSettings != null && NightSettings.NightEndTime != NightSettings.NightStartTime) { combinedTimeSpans.Add(NightSettings.NightStartTime); combinedTimeSpans.Add(NightSettings.NightEndTime); if (NightSettings.NightEndTime < NightSettings.NightStartTime) { combinedTimeSpans.Add(TimeSpan.FromDays(1)); combinedTimeSpans.Add(TimeSpan.Zero); } } combinedTimeSpans.Sort(); CombinedTimeTrackParts = new List<TimeTrackPart>(); for (int i = 0; i < combinedTimeSpans.Count - 1; i++) { var startTime = combinedTimeSpans[i]; var endTime = combinedTimeSpans[i + 1]; var timeTrackPart = new TimeTrackPart(); timeTrackPart.StartTime = startTime; timeTrackPart.EndTime = endTime; CombinedTimeTrackParts.Add(timeTrackPart); var isNight = false; if (NightSettings != null && NightSettings.NightEndTime != NightSettings.NightStartTime) { if (NightSettings.NightEndTime > NightSettings.NightStartTime) isNight = startTime >= NightSettings.NightStartTime && endTime <= NightSettings.NightEndTime; else isNight = startTime >= NightSettings.NightStartTime && endTime <= new TimeSpan(24, 00, 00) || startTime >= new TimeSpan(0, 0, 0) && endTime <= NightSettings.NightEndTime; } var hasRealTimeTrack = RealTimeTrackParts.Any(x => x.StartTime <= startTime && x.EndTime >= endTime); var hasPlannedTimeTrack = PlannedTimeTrackParts.Any(x => x.StartTime <= startTime && x.EndTime >= endTime); var documentTimeTrack = DocumentTrackParts.FirstOrDefault(x => x.StartTime <= startTime && x.EndTime >= endTime); if (hasRealTimeTrack && hasPlannedTimeTrack) { if (isNight) timeTrackPart.TimeTrackPartType = TimeTrackType.Night; else timeTrackPart.TimeTrackPartType = TimeTrackType.Presence; } if (!hasRealTimeTrack && !hasPlannedTimeTrack) { timeTrackPart.TimeTrackPartType = TimeTrackType.None; } if (hasRealTimeTrack && !hasPlannedTimeTrack) { timeTrackPart.TimeTrackPartType = TimeTrackType.Overtime; if (timeTrackPart.StartTime > firstPlanned && timeTrackPart.EndTime < lastPlanned) timeTrackPart.TimeTrackPartType = TimeTrackType.PresenceInBrerak; } if (!hasRealTimeTrack && hasPlannedTimeTrack) { timeTrackPart.TimeTrackPartType = TimeTrackType.Absence; if (IsOnlyFirstEnter && timeTrackPart.StartTime >= firstEnter && timeTrackPart.EndTime <= lastExit) { timeTrackPart.TimeTrackPartType = TimeTrackType.AbsenceInsidePlan; } if (PlannedTimeTrackParts.Any(x => x.StartTime == timeTrackPart.StartTime) && !PlannedTimeTrackParts.Any(x => x.EndTime == timeTrackPart.EndTime) && RealTimeTrackParts.Any(x => x.StartTime == timeTrackPart.EndTime)) { var firstPlannedTimeTrack = PlannedTimeTrackParts.FirstOrDefault(x => x.StartTime == timeTrackPart.StartTime); if (firstPlannedTimeTrack.StartsInPreviousDay) timeTrackPart.TimeTrackPartType = TimeTrackType.Absence; else if (timeTrackPart.TimeTrackPartType != TimeTrackType.AbsenceInsidePlan) timeTrackPart.TimeTrackPartType = TimeTrackType.Late; } if (!PlannedTimeTrackParts.Any(x => x.StartTime == timeTrackPart.StartTime) && PlannedTimeTrackParts.Any(x => x.EndTime == timeTrackPart.EndTime) && RealTimeTrackParts.Any(x => x.EndTime == timeTrackPart.StartTime)) { var lastPlannedTimeTrack = PlannedTimeTrackParts.FirstOrDefault(x => x.EndTime == timeTrackPart.EndTime); if (lastPlannedTimeTrack.EndsInNextDay) timeTrackPart.TimeTrackPartType = TimeTrackType.Absence; else if (timeTrackPart.TimeTrackPartType != TimeTrackType.AbsenceInsidePlan) timeTrackPart.TimeTrackPartType = TimeTrackType.EarlyLeave; } } if (documentTimeTrack != null) { var documentType = documentTimeTrack.MinTimeTrackDocumentType.DocumentType; timeTrackPart.MinTimeTrackDocumentType = documentTimeTrack.MinTimeTrackDocumentType; if (documentType == DocumentType.Overtime) { timeTrackPart.TimeTrackPartType = TimeTrackType.DocumentOvertime; } if (documentType == DocumentType.Presence) { if (hasPlannedTimeTrack) timeTrackPart.TimeTrackPartType = TimeTrackType.DocumentPresence; else if (PlannedTimeTrackParts.Count == 0) { if (hasRealTimeTrack) timeTrackPart.TimeTrackPartType = TimeTrackType.DocumentPresence; else if (slideTimeWithNoReal > TimeSpan.Zero) { timeTrackPart.TimeTrackPartType = TimeTrackType.DocumentPresence; slideTimeWithNoReal -= timeTrackPart.Delta; } } else timeTrackPart.TimeTrackPartType = TimeTrackType.None; } if (documentType == DocumentType.Absence) { if (hasRealTimeTrack || hasPlannedTimeTrack) timeTrackPart.TimeTrackPartType = TimeTrackType.DocumentAbsence; else timeTrackPart.TimeTrackPartType = TimeTrackType.None; } } if (PlannedTimeTrackParts.Count == 0 && SlideTime.TotalSeconds > 0 && timeTrackPart.TimeTrackPartType == TimeTrackType.Overtime) { if (isNight) timeTrackPart.TimeTrackPartType = TimeTrackType.Night; else timeTrackPart.TimeTrackPartType = TimeTrackType.Presence; } } }
string GetTooltip(TimeTrackPart timeTrackPart) { var result = ""; if (timeTrackPart.StartsInPreviousDay && timeTrackPart.EndsInNextDay) result = "\n" + "Интервал начинается днем раньше и заканчивается днем позже"; else if (timeTrackPart.StartsInPreviousDay) result = "\n" + "Интервал начинается днем раньше"; else if (timeTrackPart.EndsInNextDay) result = "\n" + "Интервал заканчивается днем позже"; return result; }
public DayTimeTrack GetRealTimeTrack(Guid employeeUID, IEnumerable<ScheduleZone> scheduleZones, DateTime date, IEnumerable<PassJournal> passJournals) { var dayTimeTrack = new DayTimeTrack(); dayTimeTrack.Date = date; foreach (var passJournal in passJournals.Where(x => x.EmployeeUID == employeeUID && x.EnterTime != null && x.EnterTime.Date <= date.Date && x.ExitTime != null && x.ExitTime.Value.Date >= date.Date && scheduleZones.Select(scheduleZone => scheduleZone.ZoneUID).Contains(x.ZoneUID)).ToList()) { var startTime = new TimeSpan(); var endTime = new TimeSpan(); var startsInPreviousDay = false; var endsInNextDay = false; var enterTime = passJournal.EnterTime; var exitTime = passJournal.ExitTime.Value; if (enterTime.Date == date && exitTime.Date >= date) { startTime = enterTime.TimeOfDay; if (exitTime.Date == date) endTime = exitTime.TimeOfDay; else if (exitTime.Date > date) endTime = TimeSpan.FromDays(1); endsInNextDay = exitTime.Date > date; } else if (enterTime.Date < date && exitTime.Date == date) { startTime = TimeSpan.Zero; ; endTime = exitTime.TimeOfDay; startsInPreviousDay = true; } else if (enterTime.Date < date && exitTime.Date > date) { startTime = TimeSpan.Zero; ; endTime = TimeSpan.FromDays(1); startsInPreviousDay = true; endsInNextDay = true; } if (passJournal.ExitTime.HasValue) { var timeTrackPart = new TimeTrackPart() { StartTime = startTime, EndTime = endTime, ZoneUID = passJournal.ZoneUID, PassJournalUID = passJournal.UID, StartsInPreviousDay = startsInPreviousDay, EndsInNextDay = endsInNextDay }; dayTimeTrack.RealTimeTrackParts.Add(timeTrackPart); } } dayTimeTrack.RealTimeTrackParts = dayTimeTrack.RealTimeTrackParts.OrderBy(x => x.StartTime.Ticks).ToList(); return dayTimeTrack; }
PlannedTimeTrackPart GetPlannedTimeTrackPart(Employee employee, Schedule schedule, ScheduleScheme scheduleScheme, IEnumerable<ScheduleDay> days, DateTime date, bool ignoreHolidays, IEnumerable<Holiday> holidays) { var scheduleSchemeType = (ScheduleSchemeType)scheduleScheme.Type; int dayNo = -1; switch (scheduleSchemeType) { case ScheduleSchemeType.Week: dayNo = (int)date.DayOfWeek - 1; if (dayNo == -1) dayNo = 6; break; case ScheduleSchemeType.SlideDay: var daysCount = days.Count(); var ticksDelta = new TimeSpan(date.Date.Ticks - employee.ScheduleStartDate.Date.Ticks); var daysDelta = Math.Abs((int)ticksDelta.TotalDays); dayNo = daysDelta % daysCount; break; case ScheduleSchemeType.Month: dayNo = (int)date.Day - 1; break; } var day = days.FirstOrDefault(x => x.Number == dayNo); if (day == null) return new PlannedTimeTrackPart("Не найден день"); var dayInterval = day.DayInterval; if (day.DayInterval == null || day.DayInterval.IsDeleted) return new PlannedTimeTrackPart("Не найден дневной интервал"); TimeTrackPart nightTimeTrackPart = null; ScheduleDay previousDay = null; if (dayNo > 0) previousDay = days.FirstOrDefault(x => x.Number == dayNo - 1); else previousDay = days.FirstOrDefault(x => x.Number == days.Count() - 1); if (previousDay != null) { if (previousDay.DayIntervalUID != null) { var previousDayInterval = previousDay.DayInterval; if (previousDayInterval != null && !previousDayInterval.IsDeleted) { var previousIntervals = previousDayInterval.DayIntervalParts; var nightInterval = previousIntervals.FirstOrDefault(x => x.EndTimeTotalSeconds < x.BeginTimeTotalSeconds); if (nightInterval != null) { nightTimeTrackPart = new TimeTrackPart(); nightTimeTrackPart.StartTime = new TimeSpan(); nightTimeTrackPart.EndTime = new TimeSpan(0, 0, 0, (int)nightInterval.EndTimeTotalSeconds); nightTimeTrackPart.StartsInPreviousDay = true; nightTimeTrackPart.DayName = previousDayInterval.Name; } } } } var result = new PlannedTimeTrackPart(); if (dayInterval != null) result.SlideTime = dayInterval.SlideTimeSpan; if (!ignoreHolidays) { if (!schedule.IsIgnoreHoliday) { var holiday = holidays.FirstOrDefault(x => x.Date == date && x.Type == (int)HolidayType.Holiday && !x.IsDeleted); if (holiday != null) { result.IsHoliday = true; } holiday = holidays.FirstOrDefault(x => x.Date == date && x.Type == (int)HolidayType.BeforeHoliday && !x.IsDeleted); if (holiday != null) { result.HolidayReduction = (int)holiday.ReductionTimeSpan.TotalSeconds; } holiday = holidays.FirstOrDefault(x => x.TransferDate == date && x.Type == (int)HolidayType.WorkingHoliday && !x.IsDeleted); if (holiday != null) { result.IsHoliday = true; } } } if (!result.IsHoliday) { foreach (var tableInterval in dayInterval.DayIntervalParts) { var timeTrackPart = new TimeTrackPart(); timeTrackPart.StartTime = new TimeSpan(0, 0, 0, (int)tableInterval.BeginTimeTotalSeconds); if (tableInterval.EndTimeTotalSeconds < tableInterval.BeginTimeTotalSeconds) timeTrackPart.EndsInNextDay = true; if (timeTrackPart.EndsInNextDay) timeTrackPart.EndTime = new TimeSpan(24, 0, 0); else timeTrackPart.EndTime = new TimeSpan(0, 0, 0, (int)tableInterval.EndTimeTotalSeconds); timeTrackPart.DayName = dayInterval.Name; result.TimeTrackParts.Add(timeTrackPart); } if (nightTimeTrackPart != null) { result.TimeTrackParts.Add(nightTimeTrackPart); } result.TimeTrackParts = result.TimeTrackParts.OrderBy(x => x.StartTime.Ticks).ToList(); } if (result.HolidayReduction > 0) { var reductionTimeSpan = TimeSpan.FromSeconds(result.HolidayReduction); switch (result.SlideTime.TotalSeconds > reductionTimeSpan.TotalSeconds) { case true: result.SlideTime -= reductionTimeSpan; break; case false: result.SlideTime = TimeSpan.Zero; break; } while (reductionTimeSpan.TotalSeconds > 0 && result.TimeTrackParts.Count > 0) { var lastTimeTrack = result.TimeTrackParts.LastOrDefault(); if (lastTimeTrack != null) { if (lastTimeTrack.Delta.TotalHours > reductionTimeSpan.TotalHours) { lastTimeTrack.EndTime = lastTimeTrack.EndTime.Subtract(reductionTimeSpan); reductionTimeSpan = TimeSpan.Zero; } else { result.TimeTrackParts.Remove(lastTimeTrack); reductionTimeSpan -= lastTimeTrack.Delta; } } } } return result; }