示例#1
0
        internal List <OccurrenceGroupCapacityModel> GetSubscriptionGroups(Course course)
        {
            var groups = new List <OccurrenceGroupCapacityModel>();

            foreach (var semGroup in course.SemesterGroups)
            {
                var occGroup = course.Occurrence.Groups.FirstOrDefault(g => g.SemesterGroups.Any(s => s.Id == semGroup.Id));

                // u.U. fehlende Gruppen automatisch ergänzen
                if (occGroup == null)
                {
                    occGroup = new OccurrenceGroup
                    {
                        FitToCurriculumOnly = false,
                        Capacity            = 0,
                    };
                    occGroup.SemesterGroups.Add(semGroup);
                    course.Occurrence.Groups.Add(occGroup);
                    Db.SaveChanges();
                }

                groups.Add(new OccurrenceGroupCapacityModel
                {
                    CourseId        = course.Id,
                    SemesterGroupId = semGroup.Id,
                    Semester        = semGroup.Semester.Name,
                    Curriculum      = semGroup.CapacityGroup.CurriculumGroup.Curriculum.ShortName,
                    Group           = semGroup.GroupName,
                    Organiser       = semGroup.CapacityGroup.CurriculumGroup.Curriculum.Organiser.ShortName,
                    Capacity        = occGroup.Capacity
                });
            }

            return(groups);
        }
示例#2
0
        private void ImportKurs(Kurs kurs)
        {
            _Logger.DebugFormat("Importiere Fach: {0}", kurs.Fach.FachID);
            var db = new TimeTableDbContext();

            var organiser = db.Organisers.SingleOrDefault(s => s.Id == _orgId);

            long msStart = sw.ElapsedMilliseconds;
            var  course  = new Course
            {
                ExternalSource = "GPUNTIS",
                ExternalId     = kurs.Id,
                Organiser      = organiser,
                ShortName      = kurs.Fach.FachID,
                Name           = kurs.Fach.Name,
                Occurrence     = CreateDefaultOccurrence(),
                IsInternal     = false,
            };

            // Kurs sofort speichern, damit die ID gesichert ist
            db.Activities.Add(course);
            db.SaveChanges();
            long msEnd = sw.ElapsedMilliseconds;

            _Logger.DebugFormat("Dauer: {0}ms", msEnd - msStart);
            msStart = msEnd;

            // Alle Gruppen durchgehen, die im gpUntis zugeordnet wurden
            var semester = db.Semesters.SingleOrDefault(s => s.Id == _semId);

            foreach (var g in kurs.Gruppen)
            {
                // diesen Semestergruppen soll der Kurs zugeordnet werden
                var semGroups = InitSemesterGroups(db, g.GruppenID);

                // TODO: Was macht eigentlich die OccurrenceGroup?
                foreach (var semesterGroup in semGroups)
                {
                    course.SemesterGroups.Add(semesterGroup);
                    semesterGroup.Activities.Add(course);

                    var occGroup =
                        course.Occurrence.Groups.SingleOrDefault(
                            gg => gg.SemesterGroups.Any(s => s.Id == semesterGroup.Id));

                    if (occGroup == null)
                    {
                        occGroup = new OccurrenceGroup
                        {
                            Capacity            = 0,
                            FitToCurriculumOnly = true,
                            Occurrence          = course.Occurrence
                        };
                        occGroup.SemesterGroups.Add(semesterGroup);
                        semesterGroup.OccurrenceGroups.Add(occGroup);
                        course.Occurrence.Groups.Add(occGroup);
                        db.OccurrenceGroups.Add(occGroup);
                    }
                }
            }

            if (!course.SemesterGroups.Any())
            {
                _Logger.ErrorFormat("Kurs {0} ohne Gruppe", kurs);
            }


            if (semester != null)
            {
                // jetzt die Termine für diesen Kurs anlegen
                foreach (var termin in kurs.Termine)
                {
                    // Die Zeiten werden jetzt aus dem Kontext gelesen
                    if (!_import.Stunden.ContainsKey(termin.VonStunde))
                    {
                        _import.AddErrorMessage("Import", string.Format("Stunde {0} nicht definiert", termin.VonStunde), false);
                        continue;
                    }
                    if (!_import.Stunden.ContainsKey(termin.BisStunde))
                    {
                        _import.AddErrorMessage("Import", string.Format("Stunde {0} nicht definiert", termin.BisStunde), false);
                        continue;
                    }

                    // Termin liegt an einem Tag, der nicht importiert werden soll
                    if (!_import.Tage.ContainsKey(termin.Tag))
                    {
                        _import.AddErrorMessage("Import", string.Format("Tag {0} nicht definiert", termin.Tag), false);
                        continue;
                    }

                    if (!_import.Tage[termin.Tag])
                    {
                        _import.AddErrorMessage("Import", string.Format("Tag {0} soll nicht importiert werden", termin.Tag), false);
                        continue;
                    }


                    var occBegin = _import.Stunden[termin.VonStunde].Start;
                    var occEnd   = _import.Stunden[termin.BisStunde].Ende;

                    // den wahren zeitraum bestimmen
                    // Hypothese: immer Vorlesungszeitraum des Semesters
                    var semesterAnfang = semester.StartCourses;
                    var semesterEnde   = semester.EndCourses;

                    // abweichende Angaben? dann diese nehmen
                    if (_firstDate.HasValue)
                    {
                        semesterAnfang = _firstDate.Value;
                    }

                    if (_lastDate.HasValue)
                    {
                        semesterEnde = _lastDate.Value;
                    }

                    // Tag der ersten Veranstaltung nach Vorlesungsbeginn ermitteln
                    var semesterStartTag = (int)semesterAnfang.DayOfWeek;
                    var day   = termin.Tag;
                    int nDays = day - semesterStartTag;
                    if (nDays < 0)
                    {
                        nDays += 7;
                    }

                    DateTime occDate = semesterAnfang.AddDays(nDays);


                    //Solange neue Termine anlegen bis das Enddatum des Semesters erreicht ist
                    int numOcc = 0;
                    while (occDate <= semesterEnde)
                    {
                        bool isVorlesung = true;
                        foreach (var sd in semester.Dates)
                        {
                            // Wenn der Termin in eine vorlesungsfreie Zeit fällt, dann nicht importieren
                            if (sd.From.Date <= occDate.Date &&
                                occDate.Date <= sd.To.Date &&
                                sd.HasCourses == false)
                            {
                                isVorlesung = false;
                            }
                        }

                        if (isVorlesung)
                        {
                            var ocStart = new DateTime(occDate.Year, occDate.Month, occDate.Day, occBegin.Hour,
                                                       occBegin.Minute, occBegin.Second);
                            var ocEnd = new DateTime(occDate.Year, occDate.Month, occDate.Day, occEnd.Hour,
                                                     occEnd.Minute, occEnd.Second);

                            var occ = new ActivityDate
                            {
                                Begin      = ocStart,
                                End        = ocEnd,
                                Activity   = course,
                                Occurrence = CreateDefaultOccurrence(),
                            };

                            foreach (Raum raum in termin.Raeume)
                            {
                                var room = InitRoom(db, raum, organiser);
                                if (room != null)
                                {
                                    occ.Rooms.Add(room);
                                }
                            }

                            foreach (var dozent in termin.Dozenten)
                            {
                                var lecturer = InitLecturer(db, dozent, organiser);
                                if (lecturer != null)
                                {
                                    occ.Hosts.Add(lecturer);
                                }
                            }

                            db.ActivityDates.Add(occ);
                            numOcc++;
                        }

                        occDate = occDate.AddDays(7);
                    }

                    _Logger.DebugFormat("Veranstaltung {0} hat {1} Termine", termin, numOcc);
                }
            }

            db.SaveChanges();

            msEnd = sw.ElapsedMilliseconds;
            _Logger.DebugFormat("Dauer {0}ms", msEnd - msStart);
        }
示例#3
0
        public ActionResult CreateEvent(CourseCreateModelExtended model)
        {
            Init(null);
            var user = GetCurrentUser();

            var org = _union;

            var @event = new Event
            {
                Name        = model.Name,
                ShortName   = model.ShortName,
                Description = model.Description,
                Organiser   = org,
                Occurrence  = new Occurrence
                {
                    Capacity          = -1,
                    IsAvailable       = true,
                    FromIsRestricted  = false,
                    UntilIsRestricted = false,
                    IsCanceled        = false,
                    IsMoved           = false,
                    UseGroups         = false,
                },
            };

            if (model.GroupIds != null)
            {
                foreach (var groupId in model.GroupIds)
                {
                    var semGroup = Db.SemesterGroups.SingleOrDefault(g => g.Id == groupId);

                    if (semGroup != null)
                    {
                        @event.SemesterGroups.Add(semGroup);

                        var occGroup = new OccurrenceGroup
                        {
                            Capacity            = 0,
                            FitToCurriculumOnly = true,
                            Occurrence          = @event.Occurrence
                        };
                        occGroup.SemesterGroups.Add(semGroup);
                        semGroup.OccurrenceGroups.Add(occGroup);
                        @event.Occurrence.Groups.Add(occGroup);
                        Db.OccurrenceGroups.Add(occGroup);
                    }
                }
            }

            /*
             * var member = GetMember(user.UserName, _union.ShortName);
             *
             * if (member != null)
             * {
             *  // das Objeklt muss aus dem gleichen Kontext kommen
             *  var me = Db.Members.SingleOrDefault(m => m.Id == member.Id);
             *
             *  ActivityOwner owner = new ActivityOwner
             *  {
             *      Activity = @event,
             *      Member = me,
             *      IsLocked = false
             *  };
             *
             *  @event.Owners.Add(owner);
             *  Db.ActivityOwners.Add(owner);
             * }*/

            var dozList = new List <OrganiserMember>();

            if (model.DozIds != null)
            {
                dozList.AddRange(model.DozIds.Select(dozId => Db.Members.SingleOrDefault(g => g.Id == dozId)).Where(doz => doz != null));
            }

            var roomList = new List <Room>();

            if (model.RoomIds != null)
            {
                roomList.AddRange(model.RoomIds.Select(roomId => Db.Rooms.SingleOrDefault(g => g.Id == roomId)).Where(doz => doz != null));
            }

            // Termine anelegen
            var semesterService = new SemesterService();

            if (model.Dates != null)
            {
                foreach (var date in model.Dates)
                {
                    string[] elems = date.Split('#');
                    var      day   = DateTime.Parse(elems[0]);
                    var      begin = TimeSpan.Parse(elems[1]);
                    var      end   = TimeSpan.Parse(elems[2]);
                    var      isWdh = bool.Parse(elems[3]);

                    ICollection <DateTime> dayList;
                    var semester = semesterService.GetSemester(day);

                    if (isWdh && semester != null)
                    {
                        dayList = semesterService.GetDays(semester.Id, day);
                    }
                    else
                    {
                        dayList = new List <DateTime> {
                            day
                        };
                    }


                    foreach (var dateDay in dayList)
                    {
                        var activityDate = new ActivityDate
                        {
                            Activity   = @event,
                            Begin      = dateDay.Add(begin),
                            End        = dateDay.Add(end),
                            Occurrence = new Occurrence
                            {
                                Capacity          = -1,
                                IsAvailable       = true,
                                FromIsRestricted  = false,
                                UntilIsRestricted = false,
                                IsCanceled        = false,
                                IsMoved           = false,
                                UseGroups         = false,
                            },
                        };

                        foreach (var room in roomList)
                        {
                            activityDate.Rooms.Add(room);
                        }

                        foreach (var doz in dozList)
                        {
                            activityDate.Hosts.Add(doz);
                        }

                        Db.ActivityDates.Add(activityDate);
                    }
                }
            }


            Db.Activities.Add(@event);
            Db.SaveChanges();


            return(PartialView("_CreateEventSuccess", @event));
        }
示例#4
0
        public string ImportCourse(CieCourse scheduleCourse)
        {
            string msg;

            _Logger.DebugFormat("Importiere Fach: {0}", scheduleCourse.name);
            _report.AppendFormat("<h1>Erzeuge LV \"{0}\" - [{1}]</h1>", scheduleCourse.name,
                                 scheduleCourse.id);
            _report.AppendLine();

            var db = new TimeTableDbContext();

            var organiser = db.Organisers.SingleOrDefault(s => s.ShortName.Equals(scheduleCourse.department));
            var sem       = db.Semesters.SingleOrDefault(s => s.Id == _semId);

            var cieSemGroup = db.SemesterGroups.SingleOrDefault(x =>
                                                                x.Semester.Id == sem.Id &&
                                                                x.CapacityGroup.CurriculumGroup.Curriculum.ShortName.Equals("CIE") &&
                                                                x.CapacityGroup.CurriculumGroup.Curriculum.ShortName.Equals("CIE") &&
                                                                x.CapacityGroup.CurriculumGroup.Name.Equals("CIE"));

            long msStart = sw.ElapsedMilliseconds;
            // suche den Kurs im bisherigen Angebot auf Grundlage des Namens
            var course = GetCourse(db, sem, organiser, scheduleCourse);

            if (course == null)
            {
                course = new Course
                {
                    ExternalSource = "CIE",
                    ExternalId     = scheduleCourse.id,
                    Organiser      = organiser,
                    ShortName      = "",
                    Name           = scheduleCourse.name,
                    Description    = scheduleCourse.description,
                    Occurrence     = CreateDefaultOccurrence(scheduleCourse.availableSlots),
                    IsInternal     = true,
                };
                // Kurs sofort speichern, damit die ID gesichert ist
                db.Activities.Add(course);
                db.SaveChanges();
            }
            long msEnd = sw.ElapsedMilliseconds;

            _Logger.DebugFormat("Dauer: {0}ms", msEnd - msStart);
            msStart = msEnd;

            _report.AppendLine("<h2>Bezeichnungen</h2>");
            _report.AppendLine("<table>");
            _report.AppendFormat("<tr><td>Name</td><td>{0}</td></tr>", course.Name);
            _report.AppendFormat("<tr><td>Kurzname</td><td>{0}</td></tr>", course.ShortName);
            _report.AppendFormat("<tr><td>Beschreibung</td><td>{0}</td></tr>", course.Description);
            _report.AppendLine("</table>");


            // jetzt die Gruppen
            // Studiengänge ermitteln
            // Den Kurs gibt es nur einmal
            // Zuordnungen pro Studiengang
            // Modul => d.h. duplizieren von ECTS, SWS
            var curricula = GetCurricula(db, sem, scheduleCourse.department, scheduleCourse.level);

            // Semestergruppe => auch hier eine "intelligente" Zuordnung
            // nur machen, wenn Kurs keine Gruppen hat
            if (!course.SemesterGroups.Any())
            {
                foreach (var curriculum in curricula)
                {
                    // Annahme: ein CIE sind immer WPM
                    var wpmCurrciculumGroup = curriculum.CurriculumGroups.SingleOrDefault(x => x.Name.Equals("WPM"));

                    var wpmCapacityGroup = wpmCurrciculumGroup.CapacityGroups.FirstOrDefault();

                    var wpmSemesterGroup = db.SemesterGroups.FirstOrDefault(x =>
                                                                            x.CapacityGroup.Id == wpmCapacityGroup.Id && x.Semester.Id == sem.Id);

                    course.SemesterGroups.Add(wpmSemesterGroup);


                    // zu jeder Semestergruppe gibt es dann noch eine
                    // Gruppe für Platzverlosung
                    var occGroup =
                        course.Occurrence.Groups.SingleOrDefault(
                            gg => gg.SemesterGroups.Any(s => s.Id == wpmSemesterGroup.Id));

                    if (occGroup == null)
                    {
                        occGroup = new OccurrenceGroup
                        {
                            Capacity            = 0,
                            FitToCurriculumOnly = true,
                            Occurrence          = course.Occurrence
                        };
                        occGroup.SemesterGroups.Add(wpmSemesterGroup);
                        wpmSemesterGroup.OccurrenceGroups.Add(occGroup);
                        course.Occurrence.Groups.Add(occGroup);
                        db.OccurrenceGroups.Add(occGroup);
                    }
                }
            }

            // Die Semestergruppe FK 13 / CIE / CIE muss immer dran
            if (!course.SemesterGroups.Contains(cieSemGroup))
            {
                course.SemesterGroups.Add(cieSemGroup);
            }
            db.SaveChanges();

            if (!course.SemesterGroups.Any())
            {
                _Logger.ErrorFormat("Kurs {0} ohne Gruppe", scheduleCourse.id);
            }

            // jetzt die Module
            // wieder pro Studiengang

            /*
             * foreach (var curriculum in curricula)
             * {
             *  //var module = GetModule(db, curriculum, scheduleCourse);
             *
             *  var nexus = new CourseModuleNexus();
             *  //nexus.Requirement = module;
             *  nexus.Course = course;
             *  // nexus.ModuleCourse = // fehlt noch
             *
             *  course.Nexus.Add(nexus);
             *
             *  db.CourseNexus.Add(nexus);
             * }
             */
            db.SaveChanges();


            // Das Ampelsystem
            if (scheduleCourse.courseStatus.Equals("RED"))
            {
                course.Occurrence.IsCoterie   = true;
                course.Occurrence.HasHomeBias = true; // Bedeutungslos
            }
            else if (scheduleCourse.courseStatus.Equals("YELLOW"))
            {
                course.Occurrence.IsCoterie   = false;
                course.Occurrence.HasHomeBias = true;
            }
            else //(scheduleCourse.courseStatus.Equals("GREEN"))
            {
                course.Occurrence.IsCoterie   = false;
                course.Occurrence.HasHomeBias = false;
            }

            db.SaveChanges();

            // zum Schluss die Termine
            // Dummy Termin mit Dozent
            _report.AppendLine("<h2>Neue Termine</h2>");
            _report.AppendLine("<table>");

            // Der Dummy Termin ist Vorlesungsbeginn 08:00-10:00
            var occDate = sem.StartCourses.Date;

            var occ = new ActivityDate
            {
                Begin      = occDate.AddHours(8),
                End        = occDate.AddHours(10),
                Activity   = course,
                Occurrence = CreateDefaultOccurrence(),
            };

            _report.AppendLine("<tr>");
            _report.AppendFormat("<td>{0}</td><td>{1}</td><td>{2}</td>", occ.Begin.ToShortDateString(), occ.Begin.ToShortTimeString(), occ.End.ToShortTimeString());

            // Kein Raum
            _report.AppendFormat("<td>");
            _report.AppendFormat("</td>");

            // Dozent => der angegebene
            var lec = scheduleCourse.lecturer.Split(',');

            _report.AppendFormat("<td>");

            foreach (var s in lec)
            {
                var scheduleDateLecturer = s.Trim();
                _report.AppendFormat("<p>{0} ({1})", scheduleDateLecturer, scheduleDateLecturer);

                var lecturer = organiser.Members.SingleOrDefault(l => l.ShortName.Equals(scheduleDateLecturer) || l.Name.Equals(scheduleDateLecturer));
                if (lecturer == null)
                {
                    lecturer = new OrganiserMember
                    {
                        ShortName   = scheduleDateLecturer,
                        Name        = scheduleDateLecturer,
                        Role        = String.Empty,
                        Description = String.Empty
                    };
                    organiser.Members.Add(lecturer);
                    db.Members.Add(lecturer);
                    db.SaveChanges();
                    _report.AppendFormat(" !!!NEUER DOZENT!!!");
                }

                occ.Hosts.Add(lecturer);
                _report.AppendFormat("</p>");
            }
            _report.AppendFormat("</td>");

            db.ActivityDates.Add(occ);

            _report.AppendLine();
            _report.AppendLine("</tr>");

            _report.AppendLine("</table>");
            db.SaveChanges();

            msEnd = sw.ElapsedMilliseconds;
            _Logger.DebugFormat("Dauer {0}ms", msEnd - msStart);

            msg = $"Kurs {course.ShortName} mit Terminen importiert";

            return(msg);
        }
示例#5
0
        public ActionResult CreateThesis(CourseCreateModelExtended model)
        {
            var org      = GetMyOrganisation();
            var semester = SemesterService.GetSemester(model.SemesterId);

            var course = new Exam
            {
                Name       = model.Name,
                ShortName  = model.ShortName,
                Organiser  = org,
                Occurrence = new Occurrence
                {
                    Capacity          = -1,
                    IsAvailable       = true,
                    FromIsRestricted  = false,
                    UntilIsRestricted = false,
                    IsCanceled        = false,
                    IsMoved           = false,
                    UseGroups         = false,
                },
            };

            // da kommen Kapazitätsgruppen
            // d.h. Semestergruppe suchen und ggf. anlegen
            if (model.GroupIds != null)
            {
                foreach (var groupId in model.GroupIds)
                {
                    var capGroup = Db.CapacityGroups.SingleOrDefault(g => g.Id == groupId);

                    var semGroup =
                        Db.SemesterGroups.SingleOrDefault(
                            g => g.Semester.Id == semester.Id && g.CapacityGroup.Id == groupId);

                    // die Semestergruppe gibt es nicht => anlegen
                    if (semGroup == null)
                    {
                        semGroup = new SemesterGroup
                        {
                            CapacityGroup = capGroup,
                            Semester      = semester,
                            IsAvailable   = false,
                        };
                        Db.SemesterGroups.Add(semGroup);
                    }
                    course.SemesterGroups.Add(semGroup);

                    var occGroup = new OccurrenceGroup
                    {
                        Capacity            = 0,
                        FitToCurriculumOnly = true,
                        Occurrence          = course.Occurrence
                    };
                    occGroup.SemesterGroups.Add(semGroup);
                    semGroup.OccurrenceGroups.Add(occGroup);
                    course.Occurrence.Groups.Add(occGroup);
                    Db.OccurrenceGroups.Add(occGroup);
                }
            }



            var member = GetMyMembership();

            if (member != null)
            {
                // das Objeklt muss aus dem gleichen Kontext kommen
                var me = Db.Members.SingleOrDefault(m => m.Id == member.Id);

                ActivityOwner owner = new ActivityOwner
                {
                    Activity = course,
                    Member   = me,
                    IsLocked = false
                };

                course.Owners.Add(owner);
                Db.ActivityOwners.Add(owner);
            }


            Db.Activities.Add(course);
            Db.SaveChanges();

            return(PartialView("_CreateThesisSuccess", course));
        }
示例#6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="allSubscriptions"></param>
        /// <param name="group"></param>
        /// <returns></returns>
        public List <OccurrenceSubscription> GetSubscriptionsForGroup(ICollection <OccurrenceSubscription> allSubscriptions, OccurrenceGroup group)
        {
            var semSubService = new SemesterSubscriptionService();

            var subList = new List <OccurrenceSubscription>();

            foreach (var subscription in allSubscriptions)
            {
                var user = UserManager.FindById(subscription.UserId);
                if (user != null)
                {
                    bool isInGroup = semSubService.IsSubscribed(user.Id, group.SemesterGroups, group.Occurrence.UseExactFit);

                    if (isInGroup)
                    {
                        subList.Add(subscription);
                    }
                }
            }

            return(subList);
        }
示例#7
0
        public string ImportCourse(ScheduleCourse scheduleCourse)
        {
            string msg;

            _Logger.DebugFormat("Importiere Fach: {0}", scheduleCourse.Name);
            _report.AppendFormat("<h1>Erzeuge LV \"{0} ({1})\" - [{2}]</h1>", scheduleCourse.Name, scheduleCourse.ShortName,
                                 scheduleCourse.CourseId);
            _report.AppendLine();

            var db = new TimeTableDbContext();

            var organiser = db.Organisers.SingleOrDefault(s => s.Id == _orgId);
            var sem       = db.Semesters.SingleOrDefault(s => s.Id == _semId);

            long msStart = sw.ElapsedMilliseconds;
            var  course  = new Course
            {
                ExternalSource = "JSON",
                ExternalId     = scheduleCourse.CourseId,
                Organiser      = organiser,
                ShortName      = scheduleCourse.ShortName,
                Name           = scheduleCourse.Name,
                Description    = scheduleCourse.Description,
                Occurrence     = CreateDefaultOccurrence(scheduleCourse.SeatRestriction ?? 0),
                IsInternal     = true,
            };

            // Kurs sofort speichern, damit die ID gesichert ist
            db.Activities.Add(course);
            db.SaveChanges();
            long msEnd = sw.ElapsedMilliseconds;

            _Logger.DebugFormat("Dauer: {0}ms", msEnd - msStart);
            msStart = msEnd;

            _report.AppendLine("<h2>Bezeichnungen</h2>");
            _report.AppendLine("<table>");
            _report.AppendFormat("<tr><td>Name</td><td>{0}</td></tr>", course.Name);
            _report.AppendFormat("<tr><td>Kurzname</td><td>{0}</td></tr>", course.ShortName);
            _report.AppendFormat("<tr><td>Beschreibung</td><td>{0}</td></tr>", course.Description);
            _report.AppendLine("</table>");


            // jetzt die Gruppen
            foreach (var scheduleGroup in scheduleCourse.Groups)
            {
                // Fakultät ermitteln
                var org = db.Organisers.SingleOrDefault(x => x.ShortName.Equals(scheduleGroup.FacultyName));

                // Studiengang innerhalb der Fakultät ermitteln
                var curr = org.Curricula.SingleOrDefault(x => x.ShortName.Equals(scheduleGroup.CurriculumShortName));
                if (curr == null)
                {
                    curr = new TimeTable.Data.Curriculum
                    {
                        ShortName = scheduleGroup.CurriculumShortName,
                        Name      = scheduleGroup.CurriculumName,
                        Organiser = org
                    };
                    db.Curricula.Add(curr);
                    db.SaveChanges();
                }

                // Studiengruppe innerhalb des Studiengangs ermitteln
                var groupName = scheduleGroup.GroupName;

                // Sonderlocke FK 11
                // aus der LV-Nummer das Semester raussuchen

                /* OHI 20180720: wieder ausgebaut, weil Schnittstelle jetzt sauber befüllt ist
                 * if (org.ShortName.Equals("FK 11"))
                 * {
                 *  if (!string.IsNullOrEmpty(course.ShortName))
                 *  {
                 *      groupName = course.ShortName[1].ToString();
                 *
                 *  }
                 *  else
                 *  {
                 *      groupName = "#N.V.";
                 *  }
                 * }
                 */

                var currGroup = curr.CurriculumGroups.SingleOrDefault(x => x.Name.Equals(groupName));
                if (currGroup == null)
                {
                    currGroup = new CurriculumGroup
                    {
                        Curriculum     = curr,
                        Name           = groupName,
                        IsSubscribable = true,
                    };
                    db.CurriculumGroups.Add(currGroup);
                    db.SaveChanges();
                }

                // Kapazitätsgruppe innerhalb der Studiengruppe ermitteln
                CapacityGroup capGroup = null;
                if (string.IsNullOrEmpty(scheduleGroup.SubGroupName))
                {
                    capGroup = currGroup.CapacityGroups.SingleOrDefault(x => string.IsNullOrEmpty(x.Name));
                    if (capGroup == null)
                    {
                        capGroup = new CapacityGroup
                        {
                            CurriculumGroup = currGroup,
                            Name            = string.Empty,
                            InSS            = scheduleGroup.SemesterName.StartsWith("SS"),
                            InWS            = scheduleGroup.SemesterName.StartsWith("WS")
                        };
                        db.CapacityGroups.Add(capGroup);
                        db.SaveChanges();
                    }
                }
                else
                {
                    capGroup = currGroup.CapacityGroups.SingleOrDefault(x => !string.IsNullOrEmpty(x.Name) && x.Name.Equals(scheduleGroup.SubGroupName));
                    if (capGroup == null)
                    {
                        capGroup = new CapacityGroup
                        {
                            CurriculumGroup = currGroup,
                            Name            = scheduleGroup.SubGroupName,
                            InSS            = scheduleGroup.SemesterName.StartsWith("SS"),
                            InWS            = scheduleGroup.SemesterName.StartsWith("WS")
                        };
                        db.CapacityGroups.Add(capGroup);
                        db.SaveChanges();
                    }
                }

                // Semester ermitteln
                var semester = db.Semesters.SingleOrDefault(x => x.Name.Equals(scheduleGroup.SemesterName));

                if (semester.Id == sem.Id)
                {
                    // jetzt können wir die Semestergruppe ermitteln
                    var semGroup =
                        db.SemesterGroups.SingleOrDefault(x => x.Semester.Id == semester.Id &&
                                                          x.CapacityGroup.Id == capGroup.Id);
                    if (semGroup == null)
                    {
                        semGroup = new SemesterGroup
                        {
                            Semester      = semester,
                            CapacityGroup = capGroup,
                            IsAvailable   = false // zu Beginn nicht freigegeben
                        };
                        db.SemesterGroups.Add(semGroup);
                        db.SaveChanges();
                    }

                    course.SemesterGroups.Add(semGroup);
                    semGroup.Activities.Add(course);

                    // zu jeder Semestergruppe gibt es dann noch eine
                    // Gruppe für Platzverlosung
                    var occGroup =
                        course.Occurrence.Groups.SingleOrDefault(
                            gg => gg.SemesterGroups.Any(s => s.Id == semGroup.Id));

                    if (occGroup == null)
                    {
                        occGroup = new OccurrenceGroup
                        {
                            Capacity            = 0,
                            FitToCurriculumOnly = true,
                            Occurrence          = course.Occurrence
                        };
                        occGroup.SemesterGroups.Add(semGroup);
                        semGroup.OccurrenceGroups.Add(occGroup);
                        course.Occurrence.Groups.Add(occGroup);
                        db.OccurrenceGroups.Add(occGroup);
                    }

                    // NEU: Chapter und Topics
                    if (!string.IsNullOrEmpty(scheduleGroup.ChapterName) &&
                        !string.IsNullOrEmpty(scheduleGroup.TopicName))
                    {
                        var chapter = curr.Chapters.FirstOrDefault(x => x.Name.Equals(scheduleGroup.ChapterName));
                        if (chapter == null)
                        {
                            chapter = new CurriculumChapter
                            {
                                Curriculum = curr,
                                Name       = scheduleGroup.ChapterName
                            };
                            db.CurriculumChapters.Add(chapter);
                        }

                        var topic = chapter.Topics.FirstOrDefault(x => x.Name.Equals(scheduleGroup.TopicName));
                        if (topic == null)
                        {
                            topic = new CurriculumTopic
                            {
                                Chapter = chapter,
                                Name    = scheduleGroup.TopicName
                            };
                            db.CurriculumTopics.Add(topic);
                        }

                        var semTopic = db.SemesterTopics.FirstOrDefault(x =>
                                                                        x.Semester.Id == sem.Id && x.Topic.Id == topic.Id);

                        if (semTopic == null)
                        {
                            semTopic = new SemesterTopic
                            {
                                Semester = sem,
                                Topic    = topic,
                            };
                            db.SemesterTopics.Add(semTopic);
                        }

                        semTopic.Activities.Add(course);
                    }
                }
                // else => Semestergruppe wird nicht angelegt
            }

            db.SaveChanges();

            if (!course.SemesterGroups.Any())
            {
                _Logger.ErrorFormat("Kurs {0} ohne Gruppe", scheduleCourse.CourseId);
            }

            // zum Schluss die Termine
            _report.AppendLine("<h2>Neue Termine</h2>");
            _report.AppendLine("<table>");

            foreach (var scheduleDate in scheduleCourse.Dates)
            {
                // Der Tag
                var occDate = scheduleDate.Begin.Date;

                bool isVorlesung = true;
                foreach (var sd in _semester.Dates)
                {
                    // Wenn der Termin in eine vorlesungsfreie Zeit fällt, dann nicht importieren
                    if (sd.From.Date <= occDate.Date &&
                        occDate.Date <= sd.To.Date &&
                        sd.HasCourses == false)
                    {
                        isVorlesung = false;
                    }
                }

                if (isVorlesung)
                {
                    var occ = new ActivityDate
                    {
                        Begin      = scheduleDate.Begin,
                        End        = scheduleDate.End,
                        Activity   = course,
                        Occurrence = CreateDefaultOccurrence(),
                    };
                    _report.AppendLine("<tr>");
                    _report.AppendFormat("<td>{0}</td><td>{1}</td><td>{2}</td>", occ.Begin.ToShortDateString(), occ.Begin.ToShortTimeString(), occ.End.ToShortTimeString());

                    _report.AppendFormat("<td>");
                    foreach (var scheduleDateRoom in scheduleDate.Rooms)
                    {
                        _report.AppendFormat("<p>{0}", scheduleDateRoom.RoomNumber);
                        if (!string.IsNullOrEmpty(scheduleDateRoom.RoomNumber))
                        {
                            var room = db.Rooms.SingleOrDefault(r => r.Number.Equals(scheduleDateRoom.RoomNumber));
                            if (room == null)
                            {
                                room = new Room
                                {
                                    Number      = scheduleDateRoom.RoomNumber,
                                    Capacity    = 0,
                                    Description = string.Empty,
                                    Owner       = string.Empty,
                                };
                                db.Rooms.Add(room);
                                db.SaveChanges();

                                _numRooms++;
                                _report.AppendFormat(" !!!NEUER RAUM!!!");
                            }


                            var assignment = db.RoomAssignments.SingleOrDefault(x =>
                                                                                x.Room.Id == room.Id &&
                                                                                x.Organiser.Id == organiser.Id);
                            if (assignment == null)
                            {
                                assignment = new RoomAssignment
                                {
                                    Organiser = organiser,
                                    InternalNeedConfirmation = false, // offen für interne
                                    ExternalNeedConfirmation = true   // geschlossen für externe
                                };

                                room.Assignments.Add(assignment);
                                db.RoomAssignments.Add(assignment);
                                db.SaveChanges();
                            }

                            occ.Rooms.Add(room);
                            _report.AppendFormat("</p>");
                        }
                    }
                    _report.AppendFormat("</td>");

                    _report.AppendFormat("<td>");
                    foreach (var scheduleDateLecturer in scheduleDate.Lecturers)
                    {
                        _report.AppendFormat("<p>{0} ({1})", scheduleDateLecturer.Name, scheduleDateLecturer.ShortName);

                        var lecturer = organiser.Members.SingleOrDefault(l => l.ShortName.Equals(scheduleDateLecturer.ShortName));
                        if (lecturer == null)
                        {
                            lecturer = new OrganiserMember
                            {
                                ShortName   = scheduleDateLecturer.ShortName,
                                Name        = scheduleDateLecturer.Name,
                                Role        = String.Empty,
                                Description = String.Empty
                            };
                            organiser.Members.Add(lecturer);
                            db.Members.Add(lecturer);
                            db.SaveChanges();
                            _numLecturers++;
                            _report.AppendFormat(" !!!NEUER DOZENT!!!");
                        }

                        occ.Hosts.Add(lecturer);
                        _report.AppendFormat("</p>");
                    }
                    _report.AppendFormat("</td>");

                    db.ActivityDates.Add(occ);

                    _report.AppendLine();
                    _report.AppendLine("</tr>");
                }
            }

            _report.AppendLine("</table>");
            db.SaveChanges();

            msEnd = sw.ElapsedMilliseconds;
            _Logger.DebugFormat("Dauer {0}ms", msEnd - msStart);

            msg = $"Kurs {course.ShortName} mit Terminen importiert";

            return(msg);
        }