diff --git a/backend/service/db/dbEvents.go b/backend/service/db/dbEvents.go index f13742f..ca70bc5 100644 --- a/backend/service/db/dbEvents.go +++ b/backend/service/db/dbEvents.go @@ -185,7 +185,7 @@ func GetPlanForModules(app *pocketbase.PocketBase, modules map[string]model.Feed var selectedModulesQuery = buildIcalQueryForModules(moduleBatch) // get all events from event records in the events collection - err := app.Dao().DB().Select("*").From("events").Where(selectedModulesQuery).All(&events) + err := app.Dao().DB().Select("*").From("events").Where(selectedModulesQuery).OrderBy("start").All(&events) if err != nil { return nil, err } diff --git a/backend/service/feed/feedFunctions.go b/backend/service/feed/feedFunctions.go index 5beaab3..fba2c0a 100644 --- a/backend/service/feed/feedFunctions.go +++ b/backend/service/feed/feedFunctions.go @@ -22,7 +22,6 @@ import ( "github.com/pocketbase/pocketbase/daos" "htwkalender/model" database "htwkalender/service/db" - "htwkalender/service/functions" localTime "htwkalender/service/functions/time" "log/slog" "strings" @@ -55,87 +54,69 @@ func ClearFeeds(db *daos.Dao, months int, clock localTime.Clock) { } func CombineEventsInFeed(events model.Events) model.Events { - // Combine events with the same Prof, Name, Start and End time into one event - // if the note is empty then there is no room displayed in the new note - // room listing isn't displayed if there is only one event. + // Combine events with the same name, start, end and course + combinedEvents := model.Events{events[0]} - combinedEvents := make(model.Events, 0) - combinedEvents = append(combinedEvents, events[0]) - - for index1 := 1; index1 < len(events); index1++ { - for index2 := 0; index2 < len(combinedEvents); index2++ { - - if events[index1].Name == combinedEvents[index2].Name && - events[index1].Start == combinedEvents[index2].Start && - events[index1].End == combinedEvents[index2].End && - events[index1].Course == combinedEvents[index2].Course { - - // if no notes are present skip - if !functions.OnlyWhitespace(events[index1].Notes) { - // if combinedEvents notes are empty, add the new notes - if functions.OnlyWhitespace(combinedEvents[index2].Notes) { - combinedEvents[index2].Notes = descriptionString(events[index1]) - } else { - addNotesIfAlreadyRoomsAdded(events, combinedEvents, index2, index1) - } - } - - combineRooms(events, index1, combinedEvents, index2) - combineProfs(events, index1, combinedEvents, index2) - - // remove the event from the events list - events = append(events[:index1], events[index1+1:]...) + for i := 1; i < len(events); i++ { + // check if the event is already in the combinedEvents + alreadyInCombinedEvents := false + for j := 0; j < len(combinedEvents); j++ { + if events[i].Name == combinedEvents[j].Name && + events[i].Start == combinedEvents[j].Start && + events[i].End == combinedEvents[j].End && + events[i].Course == combinedEvents[j].Course { + alreadyInCombinedEvents = true + combinedEvents[j].Notes = addNotesIfAlreadyRoomsAdded(events, combinedEvents, j, i) + combinedEvents[j].Prof = combineProfs(events, i, combinedEvents, j) + combinedEvents[j].Rooms = combineRooms(events, i, combinedEvents, j) break - - } else { - // if the event is not in the combinedEvents list, add it - if index2 == len(combinedEvents)-1 { - combinedEvents = append(combinedEvents, events[index1]) - events = append(events[:index1], events[index1+1:]...) - break - } } } + if !alreadyInCombinedEvents { + combinedEvents = append(combinedEvents, events[i]) + } } return combinedEvents } -func addNotesIfAlreadyRoomsAdded(events model.Events, combinedEvents model.Events, index2 int, index1 int) { +func addNotesIfAlreadyRoomsAdded(events model.Events, combinedEvents model.Events, index2 int, index1 int) string { // check if combinedEvents[index2].Rooms string contains comma "," , if !strings.Contains(combinedEvents[index2].Rooms, ",") { - combinedEvents[index2].Notes = descriptionString(combinedEvents[index2]) + "\n" + descriptionString(events[index1]) + return descriptionString(combinedEvents[index2]) + "\n" + descriptionString(events[index1]) } else { - combinedEvents[index2].Notes += "\n" + descriptionString(events[index1]) + return combinedEvents[index2].Notes + "\n" + descriptionString(events[index1]) } } -func combineProfs(events model.Events, index1 int, combinedEvents model.Events, index2 int) { +func combineProfs(events model.Events, index1 int, combinedEvents model.Events, index2 int) string { // combine the profs if events[index1].Prof != "" { if combinedEvents[index2].Prof == "" { - combinedEvents[index2].Prof = events[index1].Prof + return events[index1].Prof } else { if !strings.Contains(combinedEvents[index2].Prof, events[index1].Prof) { - combinedEvents[index2].Prof += ", " + events[index1].Prof + return combinedEvents[index2].Prof + ", " + events[index1].Prof } } } + return combinedEvents[index2].Prof } func descriptionString(event model.Event) string { return event.Rooms + " - " + event.Notes + " (" + event.Prof + ")" } -func combineRooms(events model.Events, index1 int, combinedEvents model.Events, index2 int) { +func combineRooms(events model.Events, index1 int, combinedEvents model.Events, index2 int) string { // combine the rooms if events[index1].Rooms != "" { if combinedEvents[index2].Rooms == "" { - combinedEvents[index2].Rooms = events[index1].Rooms + return events[index1].Rooms } else { if !strings.Contains(combinedEvents[index2].Rooms, events[index1].Rooms) { - combinedEvents[index2].Rooms += ", " + events[index1].Rooms + return combinedEvents[index2].Rooms + ", " + events[index1].Rooms } } } + return combinedEvents[index2].Rooms } diff --git a/backend/service/feed/feedFunctions_test.go b/backend/service/feed/feedFunctions_test.go index cc068bb..85a10e2 100644 --- a/backend/service/feed/feedFunctions_test.go +++ b/backend/service/feed/feedFunctions_test.go @@ -141,6 +141,47 @@ func TestCombineEventsInFeed(t *testing.T) { }, }, }, + { + name: "CannotCombineEventsInFeed", + args: args{ + events: model.Events{ + { + Name: "Modellierung", + Start: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC)), + End: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 4, 0, 0, 0, time.UTC)), + Prof: "Prof. Bunt", + Rooms: "LI001", + Notes: "Gruppe 2", + }, + { + Name: "Modellierung - 2", + Start: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC)), + End: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 4, 0, 0, 0, time.UTC)), + Prof: "Prof. Bunt", + Rooms: "LI002", + Notes: "Gruppe 1", + }, + }, + }, + want: model.Events{ + { + Name: "Modellierung", + Start: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC)), + End: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 4, 0, 0, 0, time.UTC)), + Prof: "Prof. Bunt", + Rooms: "LI001", + Notes: "Gruppe 2", + }, + { + Name: "Modellierung - 2", + Start: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC)), + End: mockTime.ParseAsTypesDatetime(time.Date(2023, 12, 1, 4, 0, 0, 0, time.UTC)), + Prof: "Prof. Bunt", + Rooms: "LI002", + Notes: "Gruppe 1", + }, + }, + }, } for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { diff --git a/backend/service/ical/ical.go b/backend/service/ical/ical.go index e94a2af..d1cea64 100644 --- a/backend/service/ical/ical.go +++ b/backend/service/ical/ical.go @@ -21,6 +21,7 @@ import ( "encoding/json" "htwkalender/model" "htwkalender/service/db" + "htwkalender/service/feed" "time" "github.com/jordic/goics" @@ -62,7 +63,7 @@ func createFeedForToken(app *pocketbase.PocketBase, modules map[string]model.Fee } // Combine Events - //events = feed.CombineEventsInFeed(events) + events = feed.CombineEventsInFeed(events) b := bytes.Buffer{} goics.NewICalEncode(&b).Encode(IcalModel{Events: events, Mapping: modules})