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) } // Convert tower connections towerInfos := make([]res.TowerConnectionDetail, 0) for _, tower := range device.Towers { 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) } // REPLACE ALL THE EXISTING PORT ASSIGNMENT CODE WITH THIS: // 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 } 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, Backbones: backboneInfos, Fishbones: fishboneInfos, Towers: towerInfos, CreatedAt: device.CreatedAt, UpdatedAt: device.UpdatedAt, } return response, nil } // ... rest of helper functions remain the same