diff --git a/NOVA.postman_collection.json b/NOVA.postman_collection.json index 4f6a834..3136506 100644 --- a/NOVA.postman_collection.json +++ b/NOVA.postman_collection.json @@ -610,6 +610,95 @@ } ] }, + { + "name": "Get Notifications", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{URL}}/notifications?user_id=1&time=1656192796", + "host": [ + "{{URL}}" + ], + "path": [ + "notifications" + ], + "query": [ + { + "key": "user_id", + "value": "1" + }, + { + "key": "time", + "value": "1656192796" + } + ] + } + }, + "response": [ + { + "name": "Get Notifications", + "originalRequest": { + "method": "GET", + "header": [], + "url": { + "raw": "{{URL}}/notifications?user_id=1&time=1656192796", + "host": [ + "{{URL}}" + ], + "path": [ + "notifications" + ], + "query": [ + { + "key": "user_id", + "value": "1" + }, + { + "key": "time", + "value": "1656192796" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Access-Control-Allow-Credentials", + "value": "true" + }, + { + "key": "Access-Control-Allow-Headers", + "value": "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With" + }, + { + "key": "Access-Control-Allow-Methods", + "value": "POST, OPTIONS, GET, PUT" + }, + { + "key": "Access-Control-Allow-Origin", + "value": "*" + }, + { + "key": "Content-Type", + "value": "application/json; charset=utf-8" + }, + { + "key": "Date", + "value": "Mon, 16 Oct 2023 11:10:37 GMT" + }, + { + "key": "Content-Length", + "value": "554" + } + ], + "cookie": [], + "body": "{\n \"data\": [\n {\n \"type\": \"warning\",\n \"title\": \"Contract 4587347502\",\n \"message\": \"Temperature anomaly detected\",\n \"datetime\": \"2023-09-13T08:36:41.742294+02:00\"\n },\n {\n \"type\": \"warning\",\n \"title\": \"Contract 4587347502\",\n \"message\": \"Temperature anomaly detected\",\n \"datetime\": \"2023-09-13T08:36:41.742294+02:00\"\n },\n {\n \"type\": \"warning\",\n \"title\": \"Contract 4587347502\",\n \"message\": \"Temperature anomaly detected\",\n \"datetime\": \"2023-09-13T08:36:41.742294+02:00\"\n },\n {\n \"type\": \"warning\",\n \"title\": \"Contract 4587347502\",\n \"message\": \"Temperature anomaly detected\",\n \"datetime\": \"2022-09-13T08:36:41.742294+02:00\"\n }\n ]\n}" + } + ] + }, { "name": "Save device info", "request": { diff --git a/controllers/notifications_controller.go b/controllers/notifications_controller.go new file mode 100644 index 0000000..9be2957 --- /dev/null +++ b/controllers/notifications_controller.go @@ -0,0 +1,50 @@ +package controllers + +import ( + "log" + "net/http" + "strconv" + "time" + + "github.com/gin-gonic/gin" + "gitlab.com/pactual1/backend/database/notification" +) + +func GetNotifications(c *gin.Context) { + // Get the User ID and Time from query parameters + userIDStr := c.DefaultQuery("user_id", "") + timeStr := c.DefaultQuery("time", "") + + if userIDStr == "" || timeStr == "" { + log.Printf("GetNotifications Error: User ID and Time are required") + c.JSON(http.StatusBadRequest, gin.H{"error": "User ID and Time are required"}) + return + } + + // Convert string to int for UserID + userID, err := strconv.Atoi(userIDStr) + if err != nil { + log.Printf("GetNotifications Error: Invalid User ID: %v", err) + c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid User ID"}) + return + } + + timestamp, err := strconv.ParseInt(timeStr, 10, 64) + if err != nil { + log.Printf("GetNotifications Error: afterTime parameter ID: %v", err) + c.JSON(http.StatusBadRequest, gin.H{"error": "After time parameter ID"}) + return + } + afterTime := time.Unix(timestamp, 0) + + log.Printf("This is the User ID: %v and Time: %v", userID, afterTime) + notifications, st, err := notification.GetNotificationsForUserID(userID, afterTime) + + if err != nil { + c.JSON(st, gin.H{"error": err.Error()}) + return + } + + // Respond with the notifications + c.JSON(http.StatusOK, gin.H{"data": notifications}) +} diff --git a/database/notification/notificaiton.go b/database/notification/notificaiton.go new file mode 100644 index 0000000..ab5880f --- /dev/null +++ b/database/notification/notificaiton.go @@ -0,0 +1,44 @@ +package notification + +import ( + "errors" + "log" + "net/http" + "time" + + "github.com/jinzhu/gorm" + "gitlab.com/pactual1/backend/models" + "gitlab.com/pactual1/backend/shared" +) + + +func GetNotificationsForUserID(userID int, afterTime time.Time) ([]models.GetNotificationsResponse, int, error) { + // Create a slice to hold the notifications + var notifications []models.Notification + var customNotifications []models.GetNotificationsResponse + + // Fetch notifications from the database based on UserID and creation time + if err := shared.GetDb().Where("user_id = ? AND created_at > ?", userID, afterTime).Find(¬ifications).Error; err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + log.Printf("GetNotificationsForUserID Error: No notifications found: %v", err) + return customNotifications, http.StatusNotFound, err + } else { + log.Printf("GetNotificationsForUserID Error: Database error: %v", err) + return customNotifications, http.StatusInternalServerError, err + } + } + + // Transform to custom response format + for _, n := range notifications { + customNotification := models.GetNotificationsResponse{ + Type: n.NotificationType, + Title: n.Title, + Message: n.Text, + DateTime: n.CreatedAt, + } + customNotifications = append(customNotifications, customNotification) + } + + return customNotifications, http.StatusOK, nil + +} \ No newline at end of file diff --git a/main.go b/main.go index d9be506..162410d 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,6 @@ import ( "gitlab.com/pactual1/backend/services/blockchain" "gitlab.com/pactual1/backend/services/contract" "gitlab.com/pactual1/backend/services/erp" - "gitlab.com/pactual1/backend/services/messaging" "gitlab.com/pactual1/backend/shared" "github.com/gin-gonic/gin" @@ -63,12 +62,12 @@ func main() { }() // Initialize channels - messagingChannel := make(chan string) + // messagingChannel := make(chan string) erpChannel := make(chan string) contractChannel := make(chan string) // Start services and pass the respective channels - go messaging.MessagingService(messagingChannel) + // go messaging.MessagingService(messagingChannel) go erp.ERPService(erpChannel) encryptionClient := shared.NewEncryptionClient(config.AppConfig.Service.BlockchainSecret) @@ -77,7 +76,7 @@ func main() { go contractService.ContractService() // Sending messages via channels - messagingChannel <- "Send an email" + // messagingChannel <- "Send an email" erpChannel <- "Update ERP record" contractChannel <- "Update contract info" diff --git a/models/notification.go b/models/notification.go new file mode 100644 index 0000000..64eab20 --- /dev/null +++ b/models/notification.go @@ -0,0 +1,33 @@ +package models + +import ( + "time" + + "github.com/jinzhu/gorm" +) + +type Notification struct { + gorm.Model + Title string + NotificationType string + Text string + UserID int +} + + +type GetNotificationsResponse struct { + Type string `json:"type"` + Title string `json:"title"` + Message string `json:"message"` + DateTime time.Time `json:"datetime"` +} + +func (Notification) Update() (bool, error) { + return false, nil +} +func (Notification) Create() (bool, error) { + return false, nil +} +func (Notification) Delete() (bool, error) { + return false, nil +} diff --git a/routes/public_routes.go b/routes/public_routes.go index 153792d..a961425 100644 --- a/routes/public_routes.go +++ b/routes/public_routes.go @@ -37,4 +37,8 @@ func RegisterPublicRoutes(r *gin.Engine) { // Locations r.GET("/locations", controllers.SearchPlace) + + + // Notifications + r.GET("/notifications", controllers.GetNotifications) } diff --git a/services/messaging/messaging_service.go b/services/messaging/messaging_service.go index 081837d..d076d41 100644 --- a/services/messaging/messaging_service.go +++ b/services/messaging/messaging_service.go @@ -1,11 +1,31 @@ -package messaging +package notification import ( "fmt" + + "github.com/jinzhu/gorm" + "gitlab.com/pactual1/backend/models" ) -func MessagingService(ch chan string) { - for msg := range ch { - fmt.Println("Messaging Service: ", msg) +type service struct { + ch chan models.Notification + db *gorm.DB +} + +func NewService(ch chan models.Notification, db *gorm.DB) service { + return service{ + ch: ch, + db: db, } } + +func (s service) MessagingService() { + for notification := range s.ch { + fmt.Println("Messaging Service received: ", notification) + + // Save the notification to the database + if err := s.db.Create(¬ification).Error; err != nil { + fmt.Printf("Error saving notification to DB: %v\n", err) + } + } +} \ No newline at end of file diff --git a/shared/database.go b/shared/database.go index 98f3ca8..9533bfd 100644 --- a/shared/database.go +++ b/shared/database.go @@ -32,8 +32,8 @@ func Init() error { } //TODO AUTOMIGRATE models once we have them db.AutoMigrate(&models.User{}, &models.Company{}, &models.Device{}, &models.DeviceInfo{}, - &models.Contract{}, &models.ContractInfo{}, - &models.ProductTemplate{}, &models.TextTemplate{}, &models.Invoice{}, &models.InvoiceItem{} ) + &models.Contract{}, &models.ContractInfo{}, + &models.ProductTemplate{}, &models.TextTemplate{}, &models.Invoice{}, &models.InvoiceItem{}, &models.Notification{} ) return nil