234 lines
7.2 KiB
Go
234 lines
7.2 KiB
Go
package usecase
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"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 OLTUsecase interface {
|
|
CreateOLT(oltDTO req.OLTDTO) error
|
|
GetAllOLTs() ([]res.OLTResponse, error)
|
|
GetOLTByID(id uuid.UUID) (res.OLTDetailResponse, error)
|
|
UpdateOLT(id uuid.UUID, updateDTO req.UpdateOLTDTO) error
|
|
DeleteOLT(id uuid.UUID) error
|
|
AssignDeviceToOLT(oltID, deviceID uuid.UUID) error
|
|
UnassignDeviceFromOLT(deviceID uuid.UUID) error
|
|
GetDevicesByOLT(oltID uuid.UUID) ([]res.OLTDeviceResponse, error)
|
|
}
|
|
|
|
type oltUsecase struct {
|
|
oltRepo repository.OLTRepo
|
|
deviceRepo repository.DeviceDetailsRepo
|
|
validate *validator.Validate
|
|
geocoder service.GeocodingService
|
|
}
|
|
|
|
func NewOLTUsecase(oltRepo repository.OLTRepo, deviceRepo repository.DeviceDetailsRepo, geocoder service.GeocodingService) OLTUsecase {
|
|
return &oltUsecase{
|
|
oltRepo: oltRepo,
|
|
deviceRepo: deviceRepo,
|
|
validate: validator.New(),
|
|
geocoder: geocoder,
|
|
}
|
|
}
|
|
|
|
func (u *oltUsecase) CreateOLT(oltDTO req.OLTDTO) error {
|
|
if err := u.validate.Struct(oltDTO); err != nil {
|
|
return fmt.Errorf("validation error: %w", err)
|
|
}
|
|
|
|
// Check if OLT name already exists
|
|
existingOLT, err := u.oltRepo.GetByName(oltDTO.OLTName)
|
|
if err == nil && existingOLT.ID != uuid.Nil {
|
|
return errors.New("OLT name already exists")
|
|
}
|
|
|
|
olt := entity.OLT{
|
|
ID: uuid.New(),
|
|
OLTName: oltDTO.OLTName,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
|
|
return u.oltRepo.Create(olt)
|
|
}
|
|
|
|
func (u *oltUsecase) GetAllOLTs() ([]res.OLTResponse, error) {
|
|
olts, err := u.oltRepo.GetAll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var responses []res.OLTResponse
|
|
for _, olt := range olts {
|
|
response := res.OLTResponse{
|
|
ID: olt.ID,
|
|
OLTName: olt.OLTName,
|
|
CreatedAt: olt.CreatedAt,
|
|
UpdatedAt: olt.UpdatedAt,
|
|
}
|
|
responses = append(responses, response)
|
|
}
|
|
|
|
return responses, nil
|
|
}
|
|
|
|
func (u *oltUsecase) GetOLTByID(id uuid.UUID) (res.OLTDetailResponse, error) {
|
|
// First, check if OLT exists using the basic GetByID method
|
|
olt, err := u.oltRepo.GetByID(id)
|
|
if err != nil {
|
|
log.Printf("OLT not found: %v", err)
|
|
return res.OLTDetailResponse{}, errors.New("OLT not found")
|
|
}
|
|
|
|
log.Printf("OLT found: %+v", olt)
|
|
|
|
// Try to get OLT with devices, but fallback to basic info if it fails
|
|
oltWithDevices, err := u.oltRepo.GetByIDWithDevices(id)
|
|
if err != nil {
|
|
log.Printf("Error getting OLT with devices, using basic OLT info: %v", err)
|
|
// Use the basic OLT info we already retrieved
|
|
oltWithDevices = olt
|
|
oltWithDevices.Devices = []entity.Device{} // Ensure devices is empty slice, not nil
|
|
}
|
|
|
|
log.Printf("OLT retrieved with devices: %+v", oltWithDevices)
|
|
|
|
// Convert devices to device details responses
|
|
var deviceResponses []res.DeviceDetailsResponse
|
|
for _, device := range oltWithDevices.Devices {
|
|
log.Printf("Processing device: %s", device.DeviceCode)
|
|
|
|
// Get the device details using the existing method which properly loads DevicePort
|
|
deviceDetails, err := u.deviceRepo.GetByID(device.ID)
|
|
if err != nil {
|
|
log.Printf("Error getting device details for %s: %v", device.DeviceCode, err)
|
|
continue
|
|
}
|
|
|
|
deviceResponse, err := helper.ConvertToDeviceDetailsResponse(deviceDetails, u.geocoder)
|
|
if err != nil {
|
|
log.Printf("Error converting device response for %s: %v", device.DeviceCode, err)
|
|
continue
|
|
}
|
|
deviceResponses = append(deviceResponses, deviceResponse)
|
|
}
|
|
|
|
// Initialize empty slice if nil to ensure JSON response shows empty array instead of null
|
|
if deviceResponses == nil {
|
|
deviceResponses = []res.DeviceDetailsResponse{}
|
|
}
|
|
|
|
response := res.OLTDetailResponse{
|
|
ID: oltWithDevices.ID,
|
|
OLTName: oltWithDevices.OLTName,
|
|
DeviceCount: len(deviceResponses),
|
|
Devices: deviceResponses,
|
|
CreatedAt: oltWithDevices.CreatedAt,
|
|
UpdatedAt: oltWithDevices.UpdatedAt,
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
func (u *oltUsecase) UpdateOLT(id uuid.UUID, updateDTO req.UpdateOLTDTO) error {
|
|
if err := u.validate.Struct(updateDTO); err != nil {
|
|
return fmt.Errorf("validation error: %w", err)
|
|
}
|
|
|
|
// Check if OLT exists
|
|
_, err := u.oltRepo.GetByID(id)
|
|
if err != nil {
|
|
return errors.New("OLT not found")
|
|
}
|
|
|
|
// Check if new name already exists (if name is being updated)
|
|
if updateDTO.OLTName != nil {
|
|
existingOLT, err := u.oltRepo.GetByName(*updateDTO.OLTName)
|
|
if err == nil && existingOLT.ID != id {
|
|
return errors.New("OLT name already exists")
|
|
}
|
|
}
|
|
|
|
return u.oltRepo.Update(id, updateDTO)
|
|
}
|
|
|
|
func (u *oltUsecase) DeleteOLT(id uuid.UUID) error {
|
|
// Check if OLT exists
|
|
_, err := u.oltRepo.GetByID(id)
|
|
if err != nil {
|
|
return errors.New("OLT not found")
|
|
}
|
|
|
|
return u.oltRepo.Delete(id)
|
|
}
|
|
|
|
func (u *oltUsecase) AssignDeviceToOLT(oltID, deviceID uuid.UUID) error {
|
|
return u.oltRepo.AssignDeviceToOLT(oltID, deviceID)
|
|
}
|
|
|
|
func (u *oltUsecase) UnassignDeviceFromOLT(deviceID uuid.UUID) error {
|
|
return u.oltRepo.UnassignDeviceFromOLT(deviceID)
|
|
}
|
|
|
|
func (u *oltUsecase) GetDevicesByOLT(oltID uuid.UUID) ([]res.OLTDeviceResponse, error) {
|
|
// Check if OLT exists
|
|
_, err := u.oltRepo.GetByID(oltID)
|
|
if err != nil {
|
|
return nil, errors.New("OLT not found")
|
|
}
|
|
|
|
devices, err := u.oltRepo.GetDevicesByOLTID(oltID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var responses []res.OLTDeviceResponse
|
|
for _, device := range devices {
|
|
// Get address using geocoder
|
|
address := ""
|
|
if u.geocoder != nil {
|
|
addr, err := u.geocoder.GetAddressFromCoordinates(device.Latitude, device.Longitude)
|
|
if err == nil {
|
|
address = addr
|
|
}
|
|
}
|
|
|
|
// Get port usage from device port repository
|
|
portUsed := 0
|
|
portUsageInfo, _, err := u.deviceRepo.GetPortUsageByDevice(device.ID)
|
|
if err == nil {
|
|
portUsed = portUsageInfo
|
|
}
|
|
|
|
response := res.OLTDeviceResponse{
|
|
ID: device.ID,
|
|
DeviceCode: device.DeviceCode,
|
|
DeviceType: string(device.DeviceType),
|
|
Address: address,
|
|
Province: device.Province,
|
|
City: device.City,
|
|
District: device.District,
|
|
Status: string(device.Status),
|
|
PortAmount: device.PortAmount,
|
|
PortUsed: portUsed,
|
|
ImageURL: device.ImageURL,
|
|
CreatedAt: device.CreatedAt,
|
|
UpdatedAt: device.UpdatedAt,
|
|
}
|
|
responses = append(responses, response)
|
|
}
|
|
|
|
return responses, nil
|
|
} |