176 lines
5.4 KiB
Go
176 lines
5.4 KiB
Go
package usecase
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
"users_management/m/model/dto/req"
|
|
"users_management/m/model/dto/res"
|
|
"users_management/m/model/entity"
|
|
"users_management/m/repository"
|
|
"users_management/m/utils/helper"
|
|
"users_management/m/utils/service"
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type DeviceDetailsUseCase interface {
|
|
CreateDeviceDetails(device req.DeviceDetailsDTO) error
|
|
GetAllDeviceDetails() ([]res.DeviceDetailsResponse, error)
|
|
GetDeviceDetailsByID(id uuid.UUID) (res.DeviceDetailsResponse, error)
|
|
UpdateDeviceDetails(id uuid.UUID, device req.UpdateDeviceDetailsDTO) error
|
|
DeleteDeviceDetails(id uuid.UUID) error
|
|
|
|
// Port management
|
|
// ValidatePortUsage(deviceID uuid.UUID, requiredPorts int) error
|
|
RecalculatePortUsage(deviceID uuid.UUID) error
|
|
}
|
|
|
|
type deviceDetailsUseCase struct {
|
|
deviceDetailsRepo repository.DeviceDetailsRepo
|
|
geocoder service.GeocodingService
|
|
validate *validator.Validate
|
|
}
|
|
|
|
func NewDeviceDetailsUseCase(deviceDetailsRepo repository.DeviceDetailsRepo, geocoder service.GeocodingService) DeviceDetailsUseCase {
|
|
return &deviceDetailsUseCase{
|
|
deviceDetailsRepo: deviceDetailsRepo,
|
|
geocoder: geocoder,
|
|
validate: validator.New(),
|
|
}
|
|
}
|
|
|
|
func (u *deviceDetailsUseCase) CreateDeviceDetails(deviceDTO req.DeviceDetailsDTO) error {
|
|
err := u.validate.Struct(deviceDTO)
|
|
if err != nil {
|
|
return fmt.Errorf("validation error: %w", err)
|
|
}
|
|
|
|
newDevice := entity.Device{
|
|
ID: uuid.New(),
|
|
DeviceCode: deviceDTO.DeviceCode,
|
|
DeviceType: entity.DeviceType(deviceDTO.DeviceType),
|
|
Longitude: deviceDTO.Longitude,
|
|
Latitude: deviceDTO.Latitude,
|
|
PortAmount: deviceDTO.PortAmount,
|
|
Status: entity.DeviceStatus(deviceDTO.Status),
|
|
Province: deviceDTO.Province,
|
|
City: deviceDTO.City,
|
|
District: deviceDTO.District,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
return u.deviceDetailsRepo.Create(newDevice)
|
|
}
|
|
|
|
func (u *deviceDetailsUseCase) GetAllDeviceDetails() ([]res.DeviceDetailsResponse, error) {
|
|
devices, err := u.deviceDetailsRepo.GetAll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return helper.ConvertToDeviceDetailsResponses(devices, u.geocoder)
|
|
}
|
|
|
|
func (u *deviceDetailsUseCase) GetDeviceDetailsByID(id uuid.UUID) (res.DeviceDetailsResponse, error) {
|
|
device, err := u.deviceDetailsRepo.GetByID(id)
|
|
if err != nil {
|
|
return res.DeviceDetailsResponse{}, err
|
|
}
|
|
|
|
return helper.ConvertToDeviceDetailsResponse(device, u.geocoder)
|
|
}
|
|
|
|
func (u *deviceDetailsUseCase) UpdateDeviceDetails(id uuid.UUID, deviceDTO req.UpdateDeviceDetailsDTO) error {
|
|
err := u.validate.Struct(deviceDTO)
|
|
if err != nil {
|
|
return fmt.Errorf("validation error: %w", err)
|
|
}
|
|
|
|
// Check if device exists
|
|
|
|
updates := map[string]interface{}{}
|
|
|
|
if deviceDTO.DeviceCode != nil {
|
|
updates["device_code"] = *deviceDTO.DeviceCode
|
|
}
|
|
if deviceDTO.DeviceType != nil {
|
|
updates["device_type"] = *deviceDTO.DeviceType
|
|
}
|
|
if deviceDTO.Longitude != nil {
|
|
updates["longitude"] = *deviceDTO.Longitude
|
|
}
|
|
if deviceDTO.Latitude != nil {
|
|
updates["latitude"] = *deviceDTO.Latitude
|
|
}
|
|
if deviceDTO.PortAmount != nil {
|
|
// Validate port amount change
|
|
currentUsed, _, err := u.deviceDetailsRepo.GetPortUsageByDevice(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if *deviceDTO.PortAmount < currentUsed {
|
|
return fmt.Errorf("cannot reduce port amount to %d, currently using %d ports", *deviceDTO.PortAmount, currentUsed)
|
|
}
|
|
updates["port_amount"] = *deviceDTO.PortAmount
|
|
}
|
|
if deviceDTO.Status != nil {
|
|
updates["status"] = *deviceDTO.Status
|
|
}
|
|
if deviceDTO.Region != nil {
|
|
updates["region"] = *deviceDTO.Region
|
|
}
|
|
if deviceDTO.Province != nil {
|
|
updates["province"] = *deviceDTO.Province
|
|
}
|
|
if deviceDTO.City != nil {
|
|
updates["city"] = *deviceDTO.City
|
|
}
|
|
if deviceDTO.District != nil {
|
|
updates["district"] = *deviceDTO.District
|
|
}
|
|
|
|
if len(updates) == 0 {
|
|
return errors.New("no fields to update")
|
|
}
|
|
|
|
updates["updated_at"] = time.Now()
|
|
|
|
return u.deviceDetailsRepo.Update(id, updates)
|
|
}
|
|
|
|
func (u *deviceDetailsUseCase) DeleteDeviceDetails(id uuid.UUID) error {
|
|
// Check if device has connections
|
|
backbones, err := u.deviceDetailsRepo.GetBackbonesByDeviceID(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(backbones) > 0 {
|
|
return errors.New("cannot delete device with active backbone connections")
|
|
}
|
|
|
|
fishbones, err := u.deviceDetailsRepo.GetFishbonesByDeviceID(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(fishbones) > 0 {
|
|
return errors.New("cannot delete device with active fishbone connections")
|
|
}
|
|
|
|
towers, err := u.deviceDetailsRepo.GetTowersByDeviceID(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(towers) > 0 {
|
|
return errors.New("cannot delete device with active tower connections")
|
|
}
|
|
|
|
return u.deviceDetailsRepo.Delete(id)
|
|
}
|
|
|
|
|
|
func (u *deviceDetailsUseCase) RecalculatePortUsage(deviceID uuid.UUID) error {
|
|
return u.deviceDetailsRepo.UpdateDevicePortUsage(deviceID)
|
|
} |