Evets of notification #18
@@ -3,7 +3,6 @@ package controllers
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log"
|
||||
"math/big"
|
||||
"net/http"
|
||||
@@ -11,7 +10,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jinzhu/gorm"
|
||||
"gitlab.com/pactual1/backend/config"
|
||||
"gitlab.com/pactual1/backend/database/contract"
|
||||
"gitlab.com/pactual1/backend/database/device"
|
||||
@@ -28,62 +26,18 @@ func SaveDeviceInfo(c *gin.Context) {
|
||||
err := json.Unmarshal(rawData, &deviceInfo)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid JSON payload"})
|
||||
log.Printf("Invalid json pyload : %v", err)
|
||||
log.Printf("Invalid json payload : %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
deviceInfo.RawJSON = string(rawData)
|
||||
deviceInfo.X = deviceInfo.AccInfo.X
|
||||
deviceInfo.Y = deviceInfo.AccInfo.Y
|
||||
deviceInfo.Z = deviceInfo.AccInfo.Z
|
||||
|
||||
// Attempt to find the device by IMEI; if not found, create a new device
|
||||
var device models.Device
|
||||
if err := shared.GetDb().Unscoped().Where("device_id = ?", deviceInfo.ExternalDeviceID).First(&device).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// Create new device
|
||||
device = models.Device{
|
||||
IMEI: deviceInfo.IMEI,
|
||||
IMSI: deviceInfo.IMSI,
|
||||
DeviceID: deviceInfo.ExternalDeviceID,
|
||||
DeviceConfiguration: string(rawData),
|
||||
}
|
||||
if err := shared.GetDb().Create(&device).Error; err != nil {
|
||||
log.Printf("CREATE -Device DB Error: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not create new device"})
|
||||
return
|
||||
}
|
||||
deviceInfo.DeviceID = device.ID
|
||||
} else {
|
||||
log.Printf("CREATE -Device DB Error: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Database error"})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
log.Printf("Current device deleted at: %v", device.DeletedAt)
|
||||
|
||||
if device.DeletedAt.Valid {
|
||||
// Use raw SQL to update the record
|
||||
if err := shared.GetDb().Exec("UPDATE devices SET deleted_at = NULL, company_id = NULL WHERE id = ?", device.ID).Error; err != nil {
|
||||
log.Printf("UNDELETE -Device DB Error: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not revive deleted device"})
|
||||
return
|
||||
} else {
|
||||
log.Printf("Device undeleted successfuly : %v", device.DeletedAt)
|
||||
}
|
||||
}
|
||||
deviceInfo.DeviceID = device.ID
|
||||
}
|
||||
|
||||
// Save deviceInfo to your database
|
||||
if err := shared.GetDb().Create(&deviceInfo).Error; err != nil {
|
||||
log.Printf("SaveDeviceInfo CREATE -DeviceInfo DB Error: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not save device info"})
|
||||
deviceInfo, currentDevice, err := device.SaveDeviceInfoToDB(deviceInfo, rawData)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if device.CurrentContractID != nil {
|
||||
deviceContract, _, err := contract.GetContractByID(*device.CurrentContractID)
|
||||
if currentDevice.CurrentContractID != nil {
|
||||
deviceContract, _, err := contract.GetContractByID(*currentDevice.CurrentContractID)
|
||||
if err != nil {
|
||||
log.Printf("SaveDeviceInfo - GetContractByID error : %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not fetch device contract"})
|
||||
@@ -99,7 +53,7 @@ func SaveDeviceInfo(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
err = blockchain.NewService(config.AppConfig.Blockchain).AddIOTData(context.Background(), shared.CovertUintToByte32(deviceContract.ID), shared.CovertUintToByte32(device.ID), big.NewInt(time.Now().Unix()), []byte(deviceInfoEncryptedStr))
|
||||
err = blockchain.NewService(config.AppConfig.Blockchain).AddIOTData(context.Background(), shared.CovertUintToByte32(deviceContract.ID), shared.CovertUintToByte32(currentDevice.ID), big.NewInt(time.Now().Unix()), []byte(deviceInfoEncryptedStr))
|
||||
if err != nil {
|
||||
log.Printf("SaveDeviceInfo CREATE -DeviceInfo Blockchain Error: %v", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Could not save device info in blockchain"})
|
||||
@@ -108,6 +62,7 @@ func SaveDeviceInfo(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
log.Printf("Successfully received and saved device info: %v", deviceInfo)
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Successfully received and saved device info", "data": deviceInfo})
|
||||
}
|
||||
|
||||
@@ -11,20 +11,20 @@ import (
|
||||
)
|
||||
|
||||
func GetNotifications(c *gin.Context) {
|
||||
// Get the User ID and Time from query parameters
|
||||
userIDStr := c.DefaultQuery("user_id", "")
|
||||
// Get the Company ID and Time from query parameters
|
||||
companyIDStr := c.DefaultQuery("company_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"})
|
||||
if companyIDStr == "" || timeStr == "" {
|
||||
log.Printf("GetNotifications Error: Company ID and Time are required")
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Company ID and Time are required"})
|
||||
return
|
||||
}
|
||||
|
||||
// Convert string to int for UserID
|
||||
userID, err := strconv.Atoi(userIDStr)
|
||||
userID, err := strconv.Atoi(companyIDStr)
|
||||
if err != nil {
|
||||
log.Printf("GetNotifications Error: Invalid User ID: %v", err)
|
||||
log.Printf("GetNotifications Error: Invalid Company ID: %v", err)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid User ID"})
|
||||
return
|
||||
}
|
||||
@@ -37,8 +37,8 @@ func GetNotifications(c *gin.Context) {
|
||||
}
|
||||
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)
|
||||
log.Printf("This is the Company ID: %v and Time: %v", userID, afterTime)
|
||||
notifications, st, err := notification.GetNotificationsForCompanyID(userID, afterTime)
|
||||
|
||||
if err != nil {
|
||||
c.JSON(st, gin.H{"error": err.Error()})
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"gitlab.com/pactual1/backend/models"
|
||||
"gitlab.com/pactual1/backend/services/messaging"
|
||||
"gitlab.com/pactual1/backend/shared"
|
||||
)
|
||||
|
||||
@@ -99,3 +100,74 @@ func GetDeviceInfoForContract(deviceID uint64, contract models.Contract) (models
|
||||
return featureCollection, 0, nil
|
||||
|
||||
}
|
||||
|
||||
func SaveDeviceInfoToDB(deviceInfo models.DeviceInfo, rawData []byte) (models.DeviceInfo, models.Device, error) {
|
||||
deviceInfo.RawJSON = string(rawData)
|
||||
deviceInfo.X = deviceInfo.AccInfo.X
|
||||
deviceInfo.Y = deviceInfo.AccInfo.Y
|
||||
deviceInfo.Z = deviceInfo.AccInfo.Z
|
||||
|
||||
var device models.Device
|
||||
if err := shared.GetDb().Unscoped().Where("device_id = ?", deviceInfo.ExternalDeviceID).First(&device).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
newDevice := models.Device{
|
||||
IMEI: deviceInfo.IMEI,
|
||||
IMSI: deviceInfo.IMSI,
|
||||
DeviceID: deviceInfo.ExternalDeviceID,
|
||||
DeviceConfiguration: string(rawData),
|
||||
}
|
||||
if err := shared.GetDb().Create(&newDevice).Error; err != nil {
|
||||
return deviceInfo, device, fmt.Errorf("CREATE -Device DB Error: %v", err)
|
||||
}
|
||||
deviceInfo.DeviceID = newDevice.ID
|
||||
} else {
|
||||
return deviceInfo, device, fmt.Errorf("CREATE -Device DB Error: %v", err)
|
||||
}
|
||||
} else {
|
||||
if device.DeletedAt.Valid {
|
||||
if err := shared.GetDb().Exec("UPDATE devices SET deleted_at = NULL, company_id = NULL WHERE id = ?", device.ID).Error; err != nil {
|
||||
return deviceInfo, device, fmt.Errorf("UNDELETE -Device DB Error: %v", err)
|
||||
}
|
||||
}
|
||||
deviceInfo.DeviceID = device.ID
|
||||
}
|
||||
|
||||
if err := shared.GetDb().Create(&deviceInfo).Error; err != nil {
|
||||
return deviceInfo, device, fmt.Errorf("SaveDeviceInfo CREATE -DeviceInfo DB Error: %v", err)
|
||||
}
|
||||
|
||||
|
||||
go func(deviceInfo models.DeviceInfo) {
|
||||
var contract models.Contract
|
||||
if err := shared.GetDb().Where("device_ids @> ARRAY[?]::integer[]", deviceInfo.DeviceID).First(&contract).Error; err != nil {
|
||||
log.Printf("could not find associated contract: %v", err)
|
||||
|
||||
}
|
||||
|
||||
messagingChannel:= messaging.GetMessagingChannel()
|
||||
|
||||
if deviceInfo.Temperature > contract.MaxTemp || deviceInfo.Temperature < contract.MinTemp {
|
||||
|
||||
notification := models.Notification{
|
||||
Title: "Temperature Alert",
|
||||
NotificationType: "Temperature",
|
||||
Text: fmt.Sprintf("Device %s has a temperature outside the permitted range.", deviceInfo.ExternalDeviceID),
|
||||
CompanyID: int(contract.BuyerID),
|
||||
}
|
||||
|
||||
sellerNotification := models.Notification{
|
||||
Title: "Temperature Alert",
|
||||
NotificationType: "Temperature",
|
||||
Text: fmt.Sprintf("Device %s has a temperature outside the permitted range.", deviceInfo.ExternalDeviceID),
|
||||
CompanyID: int(contract.SellerID),
|
||||
}
|
||||
|
||||
messagingChannel <- notification
|
||||
messagingChannel <- sellerNotification
|
||||
}
|
||||
}(deviceInfo)
|
||||
|
||||
|
||||
|
||||
return deviceInfo, device, nil
|
||||
}
|
||||
@@ -12,18 +12,18 @@ import (
|
||||
)
|
||||
|
||||
|
||||
func GetNotificationsForUserID(userID int, afterTime time.Time) ([]models.GetNotificationsResponse, int, error) {
|
||||
func GetNotificationsForCompanyID(companyID 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 err := shared.GetDb().Where("company_id = ? AND created_at > ?", companyID, afterTime).Find(¬ifications).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
log.Printf("GetNotificationsForUserID Error: No notifications found: %v", err)
|
||||
log.Printf("GetNotificationsForCompanyID Error: No notifications found: %v", err)
|
||||
return customNotifications, http.StatusNotFound, err
|
||||
} else {
|
||||
log.Printf("GetNotificationsForUserID Error: Database error: %v", err)
|
||||
log.Printf("GetNotificationsForCompanyID Error: Database error: %v", err)
|
||||
return customNotifications, http.StatusInternalServerError, err
|
||||
}
|
||||
}
|
||||
|
||||
7
main.go
7
main.go
@@ -11,6 +11,7 @@ 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"
|
||||
@@ -67,7 +68,11 @@ func main() {
|
||||
contractChannel := make(chan string)
|
||||
|
||||
// Start services and pass the respective channels
|
||||
// go messaging.MessagingService(messagingChannel)
|
||||
notificationCh := make(chan models.Notification, 100)
|
||||
// Create a new messaging service
|
||||
messagingService := messaging.NewService(notificationCh, shared.GetDb())
|
||||
// Run the messaging service
|
||||
go messagingService.MessagingService()
|
||||
go erp.ERPService(erpChannel)
|
||||
|
||||
encryptionClient := shared.NewEncryptionClient(config.AppConfig.Service.BlockchainSecret)
|
||||
|
||||
@@ -11,7 +11,7 @@ type Notification struct {
|
||||
Title string
|
||||
NotificationType string
|
||||
Text string
|
||||
UserID int
|
||||
CompanyID int
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package notification
|
||||
package messaging
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -12,9 +12,12 @@ type service struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
var MessagingChannel chan models.Notification
|
||||
|
||||
func NewService(ch chan models.Notification, db *gorm.DB) service {
|
||||
MessagingChannel = ch
|
||||
return service{
|
||||
ch: ch,
|
||||
ch: MessagingChannel,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
@@ -28,4 +31,8 @@ func (s service) MessagingService() {
|
||||
fmt.Printf("Error saving notification to DB: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func GetMessagingChannel() chan models.Notification {
|
||||
return MessagingChannel
|
||||
}
|
||||
Reference in New Issue
Block a user