242 lines
8.8 KiB
Go
242 lines
8.8 KiB
Go
package helper
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"users_management/m/model/dto/res"
|
|
"users_management/m/model/entity"
|
|
"users_management/m/utils/service"
|
|
)
|
|
|
|
func ConvertToDeviceDetailsResponses(devices []entity.DeviceDetails, geocoder service.GeocodingService) ([]res.DeviceDetailsResponse, error) {
|
|
var responses []res.DeviceDetailsResponse
|
|
|
|
for _, device := range devices {
|
|
response, err := ConvertToDeviceDetailsResponse(device, geocoder)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
responses = append(responses, response)
|
|
}
|
|
|
|
return responses, nil
|
|
}
|
|
|
|
func ConvertToDeviceDetailsResponse(device entity.DeviceDetails, geocoder service.GeocodingService) (res.DeviceDetailsResponse, error) {
|
|
// Get address
|
|
address := ""
|
|
if geocoder != nil {
|
|
addr, err := geocoder.GetAddressFromCoordinates(device.Latitude, device.Longitude)
|
|
if err != nil {
|
|
log.Printf("Geocoding error for device %s: %v", device.DeviceCode, err)
|
|
address = fmt.Sprintf("Coordinates: %.6f, %.6f", device.Latitude, device.Longitude)
|
|
} else {
|
|
address = addr
|
|
}
|
|
}
|
|
|
|
// Get all backbones connected to this device
|
|
allBackbones := device.GetAllBackbones()
|
|
backboneInfos := make([]res.BackboneConnectionInfo, 0)
|
|
for _, backbone := range allBackbones {
|
|
isStartDevice := backbone.DeviceStartID == device.ID
|
|
connectedTo := ""
|
|
|
|
if isStartDevice && backbone.DeviceEnd.DeviceCode != "" {
|
|
connectedTo = backbone.DeviceEnd.DeviceCode
|
|
} else if !isStartDevice && backbone.DeviceStart.DeviceCode != "" {
|
|
connectedTo = backbone.DeviceStart.DeviceCode
|
|
}
|
|
|
|
info := res.BackboneConnectionInfo{
|
|
ID: backbone.ID,
|
|
BackboneCode: backbone.BackboneCode,
|
|
CoreAmount: backbone.CoreAmount,
|
|
IsStartDevice: isStartDevice,
|
|
ConnectedTo: connectedTo,
|
|
}
|
|
backboneInfos = append(backboneInfos, info)
|
|
}
|
|
|
|
// Get all fishbones connected to this device
|
|
allFishbones := device.GetAllFishbones()
|
|
fishboneInfos := make([]res.FishboneConnectionInfo, 0)
|
|
for _, fishbone := range allFishbones {
|
|
isStartDevice := fishbone.DeviceStartID == device.ID
|
|
connectedTo := ""
|
|
|
|
if isStartDevice && fishbone.DeviceEnd.DeviceCode != "" {
|
|
connectedTo = fishbone.DeviceEnd.DeviceCode
|
|
} else if !isStartDevice && fishbone.DeviceStart.DeviceCode != "" {
|
|
connectedTo = fishbone.DeviceStart.DeviceCode
|
|
}
|
|
|
|
info := res.FishboneConnectionInfo{
|
|
ID: fishbone.ID,
|
|
FishboneCode: fishbone.FishboneCode,
|
|
CoreAmount: fishbone.CoreAmount,
|
|
BackboneCode: fishbone.Backbone.BackboneCode,
|
|
IsStartDevice: isStartDevice,
|
|
ConnectedTo: connectedTo,
|
|
}
|
|
fishboneInfos = append(fishboneInfos, info)
|
|
}
|
|
|
|
// COMBINE ALL TOWERS INTO A SINGLE ARRAY
|
|
towerInfos := make([]res.TowerConnectionDetail, 0)
|
|
|
|
// First, add the assigned tower (tower referenced by device.TowerID)
|
|
if device.TowerID != nil && device.Tower != nil {
|
|
distance := calculateDistance(device.Latitude, device.Longitude, device.Tower.Latitude, device.Tower.Longitude)
|
|
|
|
var externalTower *bool
|
|
if device.Tower.ExternalTower != nil {
|
|
externalTower = device.Tower.ExternalTower
|
|
}
|
|
|
|
// Get all tower image URLs
|
|
allTowerImageURLs := device.Tower.GetAllImageURLs()
|
|
|
|
// Primary image URL
|
|
var imageURL *string
|
|
if device.Tower.ImageURL != "" {
|
|
imageURL = &device.Tower.ImageURL
|
|
}
|
|
|
|
assignedTowerInfo := res.TowerConnectionDetail{
|
|
ID: device.Tower.ID,
|
|
TowerCode: device.Tower.TowerCode,
|
|
Distance: distance,
|
|
ExternalTower: externalTower,
|
|
ImageURL: imageURL,
|
|
ImageURLs: allTowerImageURLs,
|
|
}
|
|
towerInfos = append(towerInfos, assignedTowerInfo)
|
|
}
|
|
|
|
// Then, add towers that reference this device via dev_id (but avoid duplicates)
|
|
for _, tower := range device.Towers {
|
|
// Skip if this tower is already added as assigned tower
|
|
if device.TowerID != nil && tower.ID == *device.TowerID {
|
|
continue
|
|
}
|
|
|
|
distance := calculateDistance(device.Latitude, device.Longitude, tower.Latitude, tower.Longitude)
|
|
|
|
var externalTower *bool
|
|
if tower.ExternalTower != nil {
|
|
externalTower = tower.ExternalTower
|
|
}
|
|
|
|
// Get all tower image URLs
|
|
allTowerImageURLs := tower.GetAllImageURLs()
|
|
|
|
// Primary image URL
|
|
var imageURL *string
|
|
if tower.ImageURL != "" {
|
|
imageURL = &tower.ImageURL
|
|
}
|
|
|
|
info := res.TowerConnectionDetail{
|
|
ID: tower.ID,
|
|
TowerCode: tower.TowerCode,
|
|
Distance: distance,
|
|
ExternalTower: externalTower,
|
|
ImageURL: imageURL,
|
|
ImageURLs: allTowerImageURLs,
|
|
}
|
|
towerInfos = append(towerInfos, info)
|
|
}
|
|
|
|
// Convert port assignments - only for ODP devices
|
|
var finalPortAssignments []res.PortAssignmentResponse
|
|
var customerNames []string
|
|
|
|
if device.DeviceType == "ODP" {
|
|
// Only ODP devices have port assignments and customers
|
|
entityPortAssignments := device.DevicePort.GetPortAssignmentsWithDetails()
|
|
|
|
// Ensure we show all ports up to PortAmount
|
|
portAssignmentMap := make(map[int]res.PortAssignmentResponse)
|
|
for _, pa := range entityPortAssignments {
|
|
portAssignmentMap[pa.PortNumber] = res.PortAssignmentResponse{
|
|
PortNumber: pa.PortNumber,
|
|
CustomerName: pa.CustomerName,
|
|
IsOccupied: pa.IsOccupied,
|
|
Status: pa.Status,
|
|
Bandwidth: pa.Bandwidth,
|
|
}
|
|
}
|
|
|
|
// Fill in missing ports
|
|
finalPortAssignments = make([]res.PortAssignmentResponse, 0)
|
|
for i := 1; i <= device.PortAmount; i++ {
|
|
if assignment, exists := portAssignmentMap[i]; exists {
|
|
finalPortAssignments = append(finalPortAssignments, assignment)
|
|
} else {
|
|
finalPortAssignments = append(finalPortAssignments, res.PortAssignmentResponse{
|
|
PortNumber: i,
|
|
CustomerName: nil,
|
|
IsOccupied: false,
|
|
Status: entity.PortStatusOff,
|
|
Bandwidth: nil,
|
|
})
|
|
}
|
|
}
|
|
|
|
// Get customer names for ODP devices
|
|
customerNames = device.DevicePort.GetCustomerNamesWithPorts()
|
|
} else {
|
|
// OTB and other device types don't have customers or detailed port assignments
|
|
finalPortAssignments = []res.PortAssignmentResponse{}
|
|
customerNames = []string{}
|
|
}
|
|
|
|
// Get all image URLs
|
|
allImageURLs := device.GetAllImageURLs()
|
|
|
|
// Handle empty slice vs nil for JSON response
|
|
if len(allImageURLs) == 0 {
|
|
allImageURLs = []string{} // Return empty array instead of nil
|
|
}
|
|
|
|
// Handle OLT information
|
|
var oltName *string
|
|
if device.OLT != nil && device.OLT.OLTName != "" {
|
|
oltName = &device.OLT.OLTName
|
|
}
|
|
|
|
response := res.DeviceDetailsResponse{
|
|
ID: device.ID,
|
|
DeviceCode: device.DeviceCode,
|
|
DeviceType: string(device.DeviceType),
|
|
Address: address,
|
|
Longitude: device.Longitude,
|
|
Latitude: device.Latitude,
|
|
Status: string(device.Status),
|
|
PortAmount: device.PortAmount,
|
|
PortUsed: device.DevicePort.PortUsed,
|
|
PortAvailable: device.DevicePort.PortAvailable,
|
|
CustomerNames: customerNames, // Empty for OTB
|
|
PortAssignments: finalPortAssignments, // Empty for OTB
|
|
Province: device.Province,
|
|
City: device.City,
|
|
District: device.District,
|
|
ImageURL: device.ImageURL,
|
|
ImageURLs: allImageURLs,
|
|
TowerID: device.TowerID, // Keep TowerID for reference
|
|
// Remove AssignedTower field - now everything is in Towers
|
|
OLTID: device.OLTID, // Add OLTID
|
|
OLTName: oltName, // Add OLT name
|
|
Backbones: backboneInfos,
|
|
Fishbones: fishboneInfos,
|
|
Towers: towerInfos, // All towers combined here
|
|
CreatedAt: device.CreatedAt,
|
|
UpdatedAt: device.UpdatedAt,
|
|
}
|
|
|
|
return response, nil
|
|
}
|
|
|
|
|