diff --git a/api/reportHandler.go b/api/reportHandler.go new file mode 100644 index 0000000..a84ec9c --- /dev/null +++ b/api/reportHandler.go @@ -0,0 +1,148 @@ +package api + +import ( + "net/http" + "slices" + + "gitea.tecamino.com/paadi/memberDB/models" + "github.com/gin-gonic/gin" +) + +type counter struct { + event int + total int +} + +func (a *APIHandler) GetReport(c *gin.Context) { + if !a.DBHandlerIsInitialized() { + a.logger.Error("DeleteEvent", "database handler is not initialized") + c.JSON(http.StatusInternalServerError, nil) + return + } + + var err error + var report models.Report + var request models.ReportFilter + + err = c.BindJSON(&request) + if err != nil { + a.logger.Error("GetReport", err) + c.JSON(http.StatusBadRequest, nil) + return + } + + var events []models.Event + + if len(request.Name) > 0 { + events, err = a.DbHandler.GetEventByKey("name", request.Name, true) + } else { + events, err = a.DbHandler.GetEvent(0) + } + if err != nil { + a.logger.Error("GetReport", err) + c.JSON(http.StatusBadRequest, gin.H{ + "message": err.Error(), + }) + return + } + + report.Data = make(map[string]*models.Data) + + //helper + count := make(map[string]*counter) + + addedMember := make(map[uint]bool) + + for _, e := range events { + // skip if date lower or not equal from date as well as greater than to date + if (e.Date < request.Date.From || e.Date > request.Date.From) && e.Date != request.Date.From { + continue + } + + // skip if day not selected + switch e.Day { + case "Monday": + if !request.Weekdays.Monday { + continue + } + case "Tuesday": + if !request.Weekdays.Tuesday { + continue + } + case "Wednesday": + if !request.Weekdays.Wednesday { + continue + } + case "Thursday": + if !request.Weekdays.Thursday { + continue + } + case "Friday": + if !request.Weekdays.Friday { + continue + } + case "Saturday": + if !request.Weekdays.Saturday { + continue + } + case "Sunday": + if !request.Weekdays.Sunday { + continue + } + } + + var data *models.Data + if _, ok := count[e.Day]; !ok { + count[e.Day] = &counter{} + } + count[e.Day].event += 1 + + data, ok := report.Data[e.Day] + if !ok { + data = &models.Data{} + report.Data[e.Day] = data + } + + if data.Minimal > len(e.Attendees) { + data.Minimal = len(e.Attendees) + } + + if data.Maximal < len(e.Attendees) { + data.Maximal = len(e.Attendees) + } + + count[e.Day].total = +len(e.Attendees) + data.Average = count[e.Day].total / count[e.Day].event + + for _, a := range e.Attendees { + if _, ok := addedMember[a.Id]; ok { + continue + } + report.Attendees = append(report.Attendees, a) + addedMember[a.Id] = true + } + } + + // add all member not attended + members, err := a.DbHandler.GetMember(0) + if err != nil { + a.logger.Error("GetReport", err) + c.JSON(http.StatusBadRequest, gin.H{ + "message": err.Error(), + }) + return + } + + for _, m := range members { + if _, ok := addedMember[m.Id]; ok { + continue + } else if !slices.Contains(request.Groups, m.Group.Id) { + continue + } + report.NonAttendees = append(report.NonAttendees, &m) + } + + c.JSON(http.StatusOK, gin.H{ + "data": report, + }) +} diff --git a/handlers/events.go b/handlers/events.go index 1c43a50..1c43688 100644 --- a/handlers/events.go +++ b/handlers/events.go @@ -40,6 +40,29 @@ func (dh *DatabaseHandler) GetEvent(id uint) (events []models.Event, err error) return } +func (dh *DatabaseHandler) GetEventByKey(key string, value any, likeSearch bool) (events []models.Event, err error) { + if !dh.DatabaseOpened() { + return events, errors.New("database not opened") + } + + err = dh.database.GetByKey(&events, key, value, likeSearch, "Attendees") + + idMap := make(map[uint]bool) + for i := range events { + for j := range events[i].Attendees { + if _, ok := idMap[events[i].Attendees[j].Id]; ok { + continue + } + idMap[events[i].Attendees[j].Id] = true + events[i].Attendees[j].Decrypt(dh.token) + } + } + if err != nil { + return + } + return +} + func (dh *DatabaseHandler) UpdateEvent(id int, event models.Event) (err error) { if !dh.DatabaseOpened() { return errors.New("database not opened")