224 lines
7.0 KiB
Go
224 lines
7.0 KiB
Go
package repository
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
"users_management/m/model/entity"
|
|
|
|
"github.com/google/uuid"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type DevicesRepo interface {
|
|
Post(device entity.Device) error
|
|
GetAll() ([]entity.Device, error)
|
|
Update(id uuid.UUID,updates map[string]interface{}) error
|
|
|
|
GetByID(id uuid.UUID) (entity.Device, error)
|
|
GetByType(deviceType string) ([]entity.Device, error)
|
|
BulkUpdateImages(updates map[uuid.UUID]string) error
|
|
BulkUpdateImagesMultiple(updates map[uuid.UUID][]string) error
|
|
SyncTowerLocationWithDevice(deviceID uuid.UUID) error
|
|
ValidateTowerExists(towerID uuid.UUID) (bool, error)
|
|
}
|
|
|
|
type devicesRepo struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewDevicesRepo(db *gorm.DB) DevicesRepo {
|
|
return &devicesRepo{
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
func (r *devicesRepo) SyncTowerLocationWithDevice(deviceID uuid.UUID) error {
|
|
return r.db.Transaction(func(tx *gorm.DB) error {
|
|
// Get device details
|
|
var device entity.Device
|
|
if err := tx.Where("id = ?", deviceID).First(&device).Error; err != nil {
|
|
return fmt.Errorf("device not found: %w", err)
|
|
}
|
|
|
|
// Update tower location if device has a tower assigned
|
|
if device.TowerID != nil {
|
|
if err := tx.Model(&entity.Tower{}).
|
|
Where("id = ?", *device.TowerID).
|
|
Updates(map[string]interface{}{
|
|
"longitude": device.Longitude,
|
|
"latitude": device.Latitude,
|
|
"updated_at": time.Now(),
|
|
}).Error; err != nil {
|
|
return fmt.Errorf("failed to sync tower location: %w", err)
|
|
}
|
|
}
|
|
|
|
// Also update any towers that reference this device via dev_id
|
|
if err := tx.Model(&entity.Tower{}).
|
|
Where("dev_id = ?", deviceID).
|
|
Updates(map[string]interface{}{
|
|
"longitude": device.Longitude,
|
|
"latitude": device.Latitude,
|
|
"updated_at": time.Now(),
|
|
}).Error; err != nil {
|
|
return fmt.Errorf("failed to sync related towers location: %w", err)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (r *devicesRepo) ValidateTowerExists(towerID uuid.UUID) (bool, error) {
|
|
var count int64
|
|
err := r.db.Model(&entity.Tower{}).Where("id = ?", towerID).Count(&count).Error
|
|
return count > 0, err
|
|
}
|
|
|
|
func (r *devicesRepo) BulkUpdateImages(updates map[uuid.UUID]string) error {
|
|
multipleUpdates := make(map[uuid.UUID][]string)
|
|
for deviceID, imageURL := range updates {
|
|
multipleUpdates[deviceID] = []string{imageURL}
|
|
}
|
|
return r.BulkUpdateImagesMultiple(multipleUpdates)
|
|
}
|
|
|
|
func (r *devicesRepo) BulkUpdateImagesMultiple(updates map[uuid.UUID][]string) error {
|
|
return r.db.Transaction(func(tx *gorm.DB) error {
|
|
for deviceID, imageURLs := range updates {
|
|
updateFields := map[string]interface{}{
|
|
"updated_at": time.Now(),
|
|
}
|
|
|
|
if len(imageURLs) > 0 {
|
|
// Set primary image (first one)
|
|
updateFields["image_url"] = imageURLs[0]
|
|
|
|
// Set all images using StringSlice
|
|
updateFields["image_urls"] = entity.StringSlice(imageURLs)
|
|
}
|
|
|
|
if err := tx.Model(&entity.Device{}).
|
|
Where("id = ?", deviceID).
|
|
Updates(updateFields).Error; err != nil {
|
|
return fmt.Errorf("failed to update device %s: %w", deviceID, err)
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
|
|
func (r *devicesRepo) Post(device entity.Device) error {
|
|
return r.db.Transaction(func(tx *gorm.DB) error {
|
|
// Create the device first
|
|
if err := tx.Create(&device).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// Create the corresponding DevicePort record
|
|
customerCount := 0
|
|
customerNames := make([]string, 0)
|
|
|
|
// For ODP devices, initialize customer tracking
|
|
if device.DeviceType == "ODP" {
|
|
// Customer count starts at 0, will be updated when fishbones are connected
|
|
customerCount = 0
|
|
}
|
|
|
|
devicePort := entity.DevicePort{
|
|
ID: uuid.New(),
|
|
DeviceID: device.ID,
|
|
PortUsed: 0,
|
|
PortAvailable: device.PortAmount,
|
|
CustomerCount: customerCount,
|
|
CustomerNames: customerNames,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
if err := tx.Create(&devicePort).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// Sync tower location with device location
|
|
if device.TowerID != nil {
|
|
if err := tx.Model(&entity.Tower{}).
|
|
Where("id = ?", *device.TowerID).
|
|
Updates(map[string]interface{}{
|
|
"longitude": device.Longitude,
|
|
"latitude": device.Latitude,
|
|
"updated_at": time.Now(),
|
|
}).Error; err != nil {
|
|
return fmt.Errorf("failed to sync tower location: %w", err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
func (r *devicesRepo) GetAll() ([]entity.Device, error) {
|
|
var devices []entity.Device
|
|
err := r.db.Find(&devices).Error
|
|
if err != nil {
|
|
return devices, err
|
|
}
|
|
return devices, nil
|
|
}
|
|
func (r *devicesRepo) Update(id uuid.UUID, updates map[string]interface{}) error {
|
|
return r.db.Transaction(func(tx *gorm.DB) error {
|
|
// Validate tower exists if TowerID is being updated
|
|
if towerID, exists := updates["TowerID"]; exists && towerID != nil {
|
|
towerUUID := towerID.(uuid.UUID)
|
|
var towerExists bool
|
|
var err error
|
|
if towerExists, err = r.ValidateTowerExists(towerUUID); err != nil {
|
|
return fmt.Errorf("failed to validate tower: %w", err)
|
|
}
|
|
if !towerExists {
|
|
return fmt.Errorf("tower with ID %s not found", towerUUID.String())
|
|
}
|
|
}
|
|
|
|
// Update device
|
|
if err := tx.Model(&entity.Device{}).Where("id = ?", id).Updates(updates).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
// If location is updated, sync with tower
|
|
if _, hasLng := updates["Longitude"]; hasLng {
|
|
if _, hasLat := updates["Latitude"]; hasLat {
|
|
if err := r.SyncTowerLocationWithDevice(id); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
// If TowerID is updated, sync location
|
|
if _, exists := updates["TowerID"]; exists {
|
|
if err := r.SyncTowerLocationWithDevice(id); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (r *devicesRepo) GetByID(id uuid.UUID) (entity.Device, error) {
|
|
var device entity.Device
|
|
err := r.db.Where("id = ?", id).First(&device).Error
|
|
if err != nil {
|
|
return device, err
|
|
}
|
|
return device, nil
|
|
}
|
|
|
|
func (r *devicesRepo) GetByType(deviceType string) ([]entity.Device, error) {
|
|
var devices []entity.Device
|
|
err := r.db.Where("device_type = ?", deviceType).Find(&devices).Error
|
|
if err != nil {
|
|
return devices, err
|
|
}
|
|
return devices, nil
|
|
}
|