package notification import ( "jannex/admin-dashboard-backend/modules/database" "jannex/admin-dashboard-backend/modules/requestclient" "jannex/admin-dashboard-backend/modules/structs" "jannex/admin-dashboard-backend/modules/utils" "jannex/admin-dashboard-backend/socketclients" "time" "git.ex.umbach.dev/Alex/roese-utils/rspagination" "github.com/gofiber/fiber/v2" "github.com/google/uuid" ) func GetTotalNotifications(userId string) int { var totalNotifications int64 database.DB.Model(&structs.Notification{}).Where("user_id = ?", userId).Count(&totalNotifications) return int(totalNotifications) } func GetNotifications(query rspagination.PageQuery, userId string) []structs.Notification { var notifications []structs.Notification rspagination.DbPageQuery(database.DB, query, utils.NotificationsPaginationLimit, ¬ifications, "created_at DESC", "user_id = ?", userId) return notifications } func AddNotification(c *fiber.Ctx, body structs.AddNotificationRequest) error { var userIds []string if len(body.UserIds) == 0 && body.NeededPermission == "" && len(body.RoleIds) == 0 { // c not defined when called from code itself if c == nil { return nil } return c.SendStatus(fiber.StatusBadRequest) } if len(body.UserIds) > 0 { // check if user with provided user id in body.UserIds exist in database and add to userIds database.DB.Model(&structs.User{}).Where("id IN ?", body.UserIds).Select("id").Find(&userIds) } var roleIds []string if body.NeededPermission != "" { // fetch all role_ids from role_permissions and use the role_id to get all users which are in the role from database which have the permission provided in body.NeededPermission and add to userIds database.DB.Model(&structs.RolePermission{}).Where("permission_id = ?", body.NeededPermission).Select("role_id").Find(&roleIds) var userIdsTemp []string database.DB.Model(&structs.User{}).Where("role_id IN ?", roleIds).Select("id").Find(&userIdsTemp) userIds = append(userIds, userIdsTemp...) } if len(body.RoleIds) > 0 { var userIdsTemp []string database.DB.Model(&structs.User{}).Where("role_id IN ?", body.RoleIds).Select("id").Find(&userIdsTemp) userIds = append(userIds, userIdsTemp...) } // no users found if len(userIds) == 0 { // c not defined when called from code itself if c == nil { return nil } return c.SendStatus(fiber.StatusUnprocessableEntity) } // remove duplicates userIds = unique(userIds) // add notification to database for _, userId := range userIds { notify := structs.Notification{ Id: uuid.New().String(), UserId: userId, Type: body.Type, Title: body.Title, CreatedAt: time.Now(), } database.DB.Create(¬ify) // send notification to user socketclients.SendMessageToUser(userId, "", structs.SendSocketMessage{ Cmd: utils.SentCmdNewNotification, Body: struct { Notification structs.Notification TotalPages int }{ Notification: notify, TotalPages: rspagination.GetTotalPages(database.DB, utils.NotificationsPaginationLimit, []structs.Notification{}, "user_id = ?", userId), }, }) } requestclient.TelegramBotManagerRequestClient(structs.TelegramBotManagerRequestBody{ UserIds: userIds, Title: body.Title, Type: body.Type, }) // c not defined when called from code itself if c == nil { return nil } return c.SendStatus(fiber.StatusOK) } func unique(slice []string) []string { keys := make(map[string]bool) list := []string{} for _, entry := range slice { if _, value := keys[entry]; !value { keys[entry] = true list = append(list, entry) } } return list } func DeleteAllNotifications(userId string) { database.DB.Delete(&structs.Notification{}, "user_id = ?", userId) socketclients.SendMessageToUser(userId, "", structs.SendSocketMessage{ Cmd: utils.SentCmdAllNotificationsDeleted, }) } func DeleteOneNotification(userId string, notificationId string) { database.DB.Delete(&structs.Notification{}, "user_id = ? AND id = ?", userId, notificationId) socketclients.SendMessageToUser(userId, "", structs.SendSocketMessage{ Cmd: utils.SentCmdOneNotificationDeleted, Body: notificationId, }) }