Esempio n. 1
0
        public async Task <ImportResult> ImportPeriodsAsync(UntisExportResult result, IEnumerable <Period> periods)
        {
            ConfigureImporter();

            var periodNames = periods.Select(x => x.Name);
            var periodData  = new List <TimetablePeriodData>();

            foreach (var period in result.Periods)
            {
                var data = new TimetablePeriodData
                {
                    Id    = period.Name,
                    Name  = period.LongName,
                    Start = period.Start
                };

                if (period.Parent == null || result.Periods.LastOrDefault() == period)
                {
                    data.End = period.End;
                }

                var last = periodData.LastOrDefault();

                if (last != null && last.End == default)
                {
                    last.End = (new DateTime(period.Start.Ticks).AddDays(-1));
                }

                periodData.Add(data);
            }

            var response = await importer.ImportTimetablePeriodsAsync(periodData.Where(x => periodNames.Contains(x.Id)).ToList());

            return(HandleResponse(response));
        }
Esempio n. 2
0
        public async Task <ImportResult> ImportAbsencesAsync(UntisExportResult result, DateTime?startDate, DateTime?endDate)
        {
            ConfigureImporter();

            var absences = result.Absences.Where(x => !x.IsInternal)
                           .SelectMany(absence =>
            {
                var absences    = new List <AbsenceData>();
                var currentDate = new DateTime(absence.Start.Ticks);

                while (currentDate <= absence.End)
                {
                    absences.Add(new AbsenceData
                    {
                        Date        = currentDate,
                        LessonStart = currentDate == absence.Start ? absence.LessonStart : result.Settings.NumberOfFirstLesson,
                        LessonEnd   = currentDate == absence.End ? absence.LessonEnd : result.Settings.NumberOfLessonsPerDay,
                        Objective   = absence.Objective,
                        Type        = GetAbsenceType(absence.Type)
                    });
                    currentDate = currentDate.AddDays(1);
                }

                return(absences.Where(x => startDate == null || endDate == null || (startDate <= x.Date && x.Date <= endDate)));
            }).ToList();

            var response = await importer.ImportAbsencesAsync(absences);

            return(HandleResponse(response));
        }
Esempio n. 3
0
        public static List <Week> SchoolWeekToCalendarWeek(UntisExportResult result)
        {
            var weeks     = new List <Week>();
            var weekNames = Enumerable.Range(65, result.Settings.Periodicity).Select(x => (char)x).ToArray();

            var current = new DateTime(result.Settings.Start.Ticks);
            var last    = result.Settings.End;

            var currentWeekIdx = result.Settings.StartWeek - 1;
            var schoolWeek     = 1;
            var tuitionWeek    = 1;

            var holidays  = result.Holidays.Where(x => x.Type == Model.HolidayType.Ferien).ToList();
            var weekShift = 0;

            do
            {
                // check if holidays
                var holiday = holidays.FirstOrDefault(x => x.Start <= current && current <= x.End);

                if (holiday != null)
                {
                    // current day seems to be a holiday
                    if (holiday.ContinueWeekNumbering == false)
                    {
                        weekShift = holiday.WeekAfterHolidays;
                    }
                }
                else
                {
                    if (weekShift > 0)
                    {
                        currentWeekIdx = (currentWeekIdx + weekShift + 1) % result.Settings.Periodicity;
                        weekShift      = 0;
                    }

                    weeks.Add(new Week
                    {
                        FirstDay       = new DateTime(current.Ticks),
                        SchoolYearWeek = schoolWeek,
                        TuitionWeek    = tuitionWeek,
                        CalendarWeek   = CultureInfo.CurrentUICulture.Calendar.GetWeekOfYear(current, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday),
                        WeekName       = weekNames[currentWeekIdx]
                    });

                    tuitionWeek++;
                    currentWeekIdx = (currentWeekIdx + 1) % result.Settings.Periodicity;
                }

                schoolWeek++;
                current = current.AddDays(7); // add a week
            } while (current < last);

            return(weeks);
        }
Esempio n. 4
0
        public async Task <ImportResult> ImportExamsAsync(UntisExportResult result, DateTime?startDate, DateTime?endDate, bool suppressNotifications)
        {
            ConfigureImporter();

            var exams = result.Exams.Where(x => startDate == null || endDate == null || (startDate <= x.Date && x.Date <= endDate))
                        .Select(exam =>
            {
                var period = result.Periods.Reverse <Period>().FirstOrDefault(p => p.Start <= exam.Date);

                if (period == null)
                {
                    return(null);
                }

                var tuitions = exam.Courses.Select(course =>
                {
                    return(ResolveExamTuition(course, result.Tuitions, period));
                });

                var students = new List <string>();

                if (settingsManager.AppSettings.AlwaysIncludeStudents)
                {
                    students.AddRange(exam.Students);

                    if (!string.IsNullOrEmpty(settingsManager.AppSettings.ExcludeRegExp) && Regex.IsMatch(exam.Name, settingsManager.AppSettings.ExcludeRegExp))
                    {
                        students.Clear();
                    }
                }
                else if (!string.IsNullOrEmpty(settingsManager.AppSettings.ExcludeRegExp) && Regex.IsMatch(exam.Name, settingsManager.AppSettings.ExcludeRegExp))
                {
                    students.AddRange(exam.Students);
                }

                return(new ExamData
                {
                    Id = exam.Number.ToString(),
                    Date = exam.Date,
                    LessonStart = exam.LessonStart,
                    LessonEnd = exam.LessonEnd,
                    Description = exam.Text,
                    Tuitions = tuitions.Where(x => x != null).ToList(),
                    Students = students,
                    Supervisions = exam.Supervisions.ToList(),
                    Rooms = exam.Rooms.ToList()
                });
            }).Where(x => x != null).ToList();

            var response = await importer.ImportExamsAsync(exams, suppressNotifications);

            return(HandleResponse(response));
        }
Esempio n. 5
0
        private static List <int> ComputePeriodWeeks(UntisExportResult result, List <Week> weeks, Period period)
        {
            var calendarWeeks = new List <int>();

            var followupPeriod = result.Periods.FirstOrDefault(x => x.Number == period.Number + 1);
            var startDate      = new DateTime(period.Start.Ticks);
            var endDate        = new DateTime((followupPeriod != null ? followupPeriod.Start : period.End).Ticks);

            while (startDate < endDate)
            {
                var calendarWeek = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(startDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
                calendarWeeks.Add(calendarWeek);

                startDate = startDate.AddDays(7);
            }

            return(calendarWeeks);
        }
Esempio n. 6
0
        public async Task <ImportResult> ImportSupervisionsAsync(UntisExportResult result, Period period)
        {
            ConfigureImporter();

            var supervisions = new List <TimetableSupervisionData>();

            var weeks       = WeekResolver.SchoolWeekToCalendarWeek(result);
            var periodWeeks = ComputePeriodWeeks(result, weeks, period);

            foreach (var floor in result.SupervisionFloors)
            {
                foreach (var supervision in floor.Supervisions)
                {
                    var supervisionWeeks = weeks
                                           .Where(x => supervision.Weeks.Contains(x.SchoolYearWeek))
                                           .Select(x => x.CalendarWeek)
                                           .Where(x => periodWeeks.Contains(x))
                                           .ToList();

                    if (supervisionWeeks.Any())
                    {
                        var data = new TimetableSupervisionData
                        {
                            Id       = Guid.NewGuid().ToString(),
                            Day      = supervision.Day,
                            Weeks    = supervisionWeeks,
                            IsBefore = true,
                            Lesson   = supervision.Lesson,
                            Teacher  = supervision.Teacher,
                            Location = floor.Name
                        };

                        supervisions.Add(data);
                    }
                }
            }

            var response = await importer.ImportSupervisionsAsync(period.Name, supervisions);

            return(HandleResponse(response));
        }
Esempio n. 7
0
        public async Task <ImportResult> ImportDayTextsAsync(UntisExportResult result, DateTime?startDate, DateTime?endDate)
        {
            ConfigureImporter();

            var infotexts = result.Days.Where(x => startDate == null || endDate == null || (x.Date >= startDate && x.Date <= endDate))
                            .SelectMany(day =>
            {
                var result = new List <InfotextData>();

                if (!string.IsNullOrEmpty(day.Note))
                {
                    result.Add(new InfotextData
                    {
                        Date    = day.Date,
                        Content = NormalizeHtmlContent(day.Note)
                    });
                }

                foreach (var text in day.Texts)
                {
                    var currentDate = new DateTime(text.StartDate.Ticks);

                    while (currentDate <= text.EndDate)
                    {
                        result.Add(new InfotextData
                        {
                            Date    = currentDate,
                            Content = NormalizeHtmlContent(text.Text)
                        });

                        currentDate = currentDate.AddDays(1);
                    }
                }

                return(result);
            }).ToList();

            var response = await importer.ImportInfotextsAsync(infotexts);

            return(HandleResponse(response));
        }
Esempio n. 8
0
        public async Task <ImportResult> ImportRoomsAsync(UntisExportResult result)
        {
            ConfigureImporter();

            var rooms = result.Rooms.Select(room =>
            {
                var period = room.Periods.Last();

                return(new RoomData
                {
                    Name = period.Name,
                    Description = period.LongName,
                    Capacity = period.Capacity,
                    Id = period.Name
                });
            }).GroupBy(x => x.Name).Select(x => x.First()).ToList();

            var response = await importer.ImportRoomsAsync(rooms);

            return(HandleResponse(response));
        }
Esempio n. 9
0
        public async Task <ImportResult> ImportFreeLessonsAsync(UntisExportResult result, DateTime?startDate, DateTime?endDate)
        {
            ConfigureImporter();

            var free = result.Days.Where(x => startDate == null || endDate == null || (x.Date >= startDate && x.Date <= endDate))
                       .SelectMany(day =>
            {
                var freeLessons = day.FreeLessons.ToArray();
                var spans       = new List <FreeLessonTimespanData>();

                if (freeLessons.Length > 0)
                {
                    var currentSpan = new FreeLessonTimespanData
                    {
                        Date  = day.Date,
                        Start = freeLessons[0],
                        End   = freeLessons[0]
                    };

                    for (int i = 1; i < freeLessons.Length; i++)
                    {
                        var currentLesson = freeLessons[i];
                        if (currentSpan.End == currentLesson - 1)     // append current span
                        {
                            currentSpan.End++;
                        }
                        else
                        {
                            spans.Add(currentSpan);
                            currentSpan = new FreeLessonTimespanData
                            {
                                Date  = day.Date,
                                Start = currentLesson,
                                End   = currentLesson
                            };
                        }
                    }

                    if (currentSpan != null)
                    {
                        spans.Add(currentSpan);
                    }
                }

                if (day.Type == DayType.Feiertag || day.Type == DayType.Unterrichtsfrei)
                {
                    spans.Add(new FreeLessonTimespanData
                    {
                        Date  = day.Date,
                        Start = result.Settings.NumberOfFirstLesson,
                        End   = result.Settings.NumberOfLessonsPerDay
                    });
                }

                return(spans);
            });

            var response = await importer.ImportFreeLessonTimespansAsync(free.ToList());

            return(HandleResponse(response));
        }
Esempio n. 10
0
        public async Task <ImportResult> ImportTimetableAsync(UntisExportResult result, Period period)
        {
            ConfigureImporter();

            var lessons = new List <TimetableLessonData>();
            var subjectReplacementMap = settingsManager.AppSettings.SubjectOverrides.ToDictionary(x => x.UntisSubject, x => x.NewSubject);

            var bereit = result.Tuitions.Where(x => x.Periods.Any(y => y.Subject == "Bereit")).ToList();

            var allowedWeeks = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P" }; // Untis only allows a periodicity of 16

            foreach (var tuition in result.Tuitions)
            {
                foreach (var tuitionPeriod in tuition.Periods)
                {
                    if (tuitionPeriod.PeriodNumber != period.Number)
                    {
                        continue;
                    }

                    // Check if time frame is withing current period
                    if (tuitionPeriod.EndDate < period.Start || tuitionPeriod.StartDate > period.End)
                    {
                        continue;
                    }

                    foreach (var timetable in tuitionPeriod.Timetable)
                    {
                        var weeks = !string.IsNullOrEmpty(timetable.Week) ? new string[] { timetable.Week } : tuitionPeriod.TuitionGroups;

                        foreach (var week in weeks)
                        {
                            if (!allowedWeeks.Contains(week) || timetable.Day == 0 || timetable.Lesson == 0 || string.IsNullOrEmpty(tuitionPeriod.Subject))
                            {
                                // ??!?
                                continue;
                            }

                            var lesson = new TimetableLessonData
                            {
                                Day            = timetable.Day,
                                Lesson         = timetable.Lesson,
                                IsDoubleLesson = false,
                                Room           = timetable.Room,
                                Week           = week,
                                Id             = Guid.NewGuid().ToString(),
                                Grades         = tuitionPeriod.Grades,
                                Subject        = tuitionPeriod.Subject
                            };

                            if (!string.IsNullOrEmpty(tuitionPeriod.Teacher))
                            {
                                lesson.Teachers.Add(tuitionPeriod.Teacher);
                            }

                            var last = lessons.LastOrDefault();

                            if (last != null && last.Day == lesson.Day && last.Room == lesson.Room && last.Week == lesson.Week && last.Subject == lesson.Subject && last.IsDoubleLesson == false && last.Lesson == lesson.Lesson - 1)
                            {
                                last.IsDoubleLesson = true;
                                continue;
                            }

                            lessons.Add(lesson);
                        }
                    }
                }
            }

            var splitLessons = new List <TimetableLessonData>();

            foreach (var lesson in lessons)
            {
                if (lesson.Grades.Count == 0)
                {
                    continue;
                }

                if (settingsManager.AppSettings.SplitCourses.Any(x => x.Subject == lesson.Subject && lesson.Grades.Contains(x.Grade)))
                {
                    var firstGrade = lesson.Grades.First();
                    var grades     = lesson.Grades.Skip(1).ToList();
                    lesson.Grades = new List <string> {
                        firstGrade
                    };

                    foreach (var grade in grades)
                    {
                        var newLesson = new TimetableLessonData
                        {
                            Day            = lesson.Day,
                            Lesson         = lesson.Lesson,
                            IsDoubleLesson = lesson.IsDoubleLesson,
                            Room           = lesson.Room,
                            Week           = lesson.Week,
                            Id             = Guid.NewGuid().ToString(),
                            Grades         = new List <string> {
                                grade
                            },
                            Subject  = lesson.Subject,
                            Teachers = lesson.Teachers
                        };

                        splitLessons.Add(newLesson);
                    }
                }
            }

            lessons.AddRange(splitLessons);

            foreach (var lesson in lessons)
            {
                // Replace subject if necessary
                if (subjectReplacementMap.ContainsKey(lesson.Subject))
                {
                    lesson.Subject = subjectReplacementMap[lesson.Subject];
                }
            }

            var response = await importer.ImportTimetableLessonsAsync(period.Name, lessons);

            return(HandleResponse(response));
        }
Esempio n. 11
0
        public async Task <ImportResult> ImportSubstitutionsAsync(UntisExportResult result, DateTime?startDate, DateTime?endDate, bool suppressNotifications)
        {
            ConfigureImporter();

            var subjectReplacementMap = settingsManager.AppSettings.SubjectOverrides.ToDictionary(x => x.UntisSubject, x => x.NewSubject);

            var substitutions = result.Substitutions.Where(x => startDate == null || endDate == null || (startDate <= x.Date && x.Date <= endDate))
                                .Select(substitution =>
            {
                var data = new SubstitutionData
                {
                    Id                 = substitution.Number.ToString(),
                    Date               = substitution.Date,
                    LessonStart        = substitution.Lesson,
                    LessonEnd          = substitution.Lesson,
                    StartsBefore       = substitution.Type == SubstitutionType.Pausenaufsicht,
                    Subject            = substitution.Subject,
                    ReplacementSubject = substitution.ReplacementSubject,
                    Rooms              = substitution.Rooms,
                    ReplacementRooms   = substitution.ReplacementRooms,
                    Grades             = substitution.Grades.Distinct().ToList(),
                    ReplacementGrades  = substitution.Grades.Distinct().ToList(),
                    Type               = substitution.Type.ToString(),
                    Text               = substitution.Text
                };

                if (!string.IsNullOrEmpty(substitution.Teacher))
                {
                    data.Teachers.Add(substitution.Teacher);
                }

                if (!string.IsNullOrEmpty(substitution.ReplacementTeacher))
                {
                    data.ReplacementTeachers.Add(substitution.ReplacementTeacher);
                }

                if (string.IsNullOrEmpty(data.ReplacementSubject))
                {
                    data.ReplacementSubject = data.Subject;
                }

                // Replace subject if necessary
                if (!string.IsNullOrEmpty(data.Subject) && subjectReplacementMap.ContainsKey(data.Subject))
                {
                    data.Subject = subjectReplacementMap[data.Subject];
                }

                if (!string.IsNullOrEmpty(data.ReplacementSubject) && subjectReplacementMap.ContainsKey(data.ReplacementSubject))
                {
                    data.ReplacementSubject = subjectReplacementMap[data.ReplacementSubject];
                }

                if (substitution.Type == SubstitutionType.Entfall || substitution.Type == SubstitutionType.Freisetzung)
                {
                    data.ReplacementSubject = null;
                    data.ReplacementGrades.Clear();
                }

                return(data);
            }).Collapse().ToList();

            var events = result.Events
                         .SelectMany(x =>
            {
                var data = new List <SubstitutionData>();

                var currentDate = new DateTime(x.StartDate.Ticks);

                while (currentDate <= x.EndDate)
                {
                    if (startDate != null && endDate != null && (startDate > currentDate || endDate < currentDate))
                    {
                        currentDate = currentDate.AddDays(1);
                        continue;
                    }

                    data.Add(new SubstitutionData
                    {
                        Id                 = $"{x.Number}-{currentDate:yyyymd}",
                        Date               = currentDate,
                        Type               = "Veranstaltung",
                        StartsBefore       = false,
                        LessonStart        = currentDate == x.StartDate ? x.StartLesson : result.Settings.NumberOfFirstLesson,
                        LessonEnd          = currentDate == x.EndDate ? x.EndLesson : result.Settings.NumberOfLessonsPerDay,
                        Subject            = null,
                        ReplacementSubject = null,
                        Teachers           = x.Teachers,
                        ReplacementRooms   = x.Rooms,
                        Text               = x.Text,
                        ReplacementGrades  = x.Grades
                    });

                    currentDate = currentDate.AddDays(1);
                }

                return(data);
            }).ToList();

            var response = await importer.ImportSubstitutionsAsync(substitutions.Union(events).ToList(), suppressNotifications);

            return(HandleResponse(response));
        }