347 lines
11 KiB
Go
347 lines
11 KiB
Go
package controller
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"users_management/m/config"
|
|
"users_management/m/middleware"
|
|
"users_management/m/model/dto/req"
|
|
"users_management/m/usecase"
|
|
"users_management/m/utils/common"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type TowerController struct {
|
|
tu usecase.TowerUseCase
|
|
rg *gin.RouterGroup
|
|
cfg *config.Config
|
|
}
|
|
|
|
func (tc *TowerController) Route() {
|
|
rg := tc.rg.Group("/tower")
|
|
rg.Use(middleware.ConditionalRequireAnyRole(tc.cfg,"Teknisi", "Admin","Super Admin")) // Apply middleware to all routes
|
|
{
|
|
rg.GET("", tc.GetTower())
|
|
rg.POST("", tc.CreateTower())
|
|
|
|
rg.GET("/:uuid", tc.GetTowerByID())
|
|
rg.PUT("/:uuid", tc.UpdateTower())
|
|
|
|
rg.POST("/bulk-upload-images", tc.BulkUploadImages())
|
|
}
|
|
}
|
|
|
|
func NewTowerController(tu usecase.TowerUseCase, rg *gin.RouterGroup, cfg *config.Config) *TowerController {
|
|
return &TowerController{
|
|
tu: tu,
|
|
rg: rg,
|
|
cfg: cfg,
|
|
}
|
|
}
|
|
|
|
func (tc *TowerController) BulkUploadImages() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// Parse multipart form
|
|
err := c.Request.ParseMultipartForm(50 << 20) // 50MB max for bulk
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Failed to parse multipart form")
|
|
return
|
|
}
|
|
|
|
// Get tower data from form
|
|
towerDataStr := c.PostForm("towers")
|
|
if towerDataStr == "" {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "towers data is required")
|
|
return
|
|
}
|
|
|
|
// Parse tower data
|
|
var towersData []req.BulkTowerImageUploadDTO
|
|
if err := json.Unmarshal([]byte(towerDataStr), &towersData); err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid towers data format")
|
|
return
|
|
}
|
|
|
|
// Get image files
|
|
form := c.Request.MultipartForm
|
|
files := form.File["images"]
|
|
|
|
if len(files) == 0 {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "No image files provided")
|
|
return
|
|
}
|
|
|
|
if len(files) != len(towersData) {
|
|
common.ErrorResponses(c, http.StatusBadRequest,
|
|
fmt.Sprintf("Number of images (%d) must match number of towers (%d)",
|
|
len(files), len(towersData)))
|
|
return
|
|
}
|
|
|
|
// Call use case
|
|
err = tc.tu.BulkUploadImages(towersData, files)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
common.SingleResponses(c, fmt.Sprintf("%d tower images uploaded successfully", len(towersData)), nil)
|
|
}
|
|
}
|
|
|
|
func (tc *TowerController) GetTower() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
towers, err := tc.tu.GetAll()
|
|
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
common.SingleResponses(c, "Success", towers)
|
|
}
|
|
}
|
|
|
|
func (tc *TowerController) CreateTower() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
|
|
contentType := c.GetHeader("Content-Type")
|
|
|
|
// Handle JSON request (no images)
|
|
if strings.Contains(contentType, "application/json") {
|
|
var towerDTO req.TowerDTO
|
|
if err := c.ShouldBindJSON(&towerDTO); err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid JSON format: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// No image files for JSON requests
|
|
err := tc.tu.Post(towerDTO, nil)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
common.SingleResponses(c, "Tower has been created", nil)
|
|
return
|
|
}
|
|
|
|
// Parse multipart form
|
|
err := c.Request.ParseMultipartForm(50 << 20) // Increase to 50MB for multiple images
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Failed to parse multipart form")
|
|
return
|
|
}
|
|
|
|
// Extract form data
|
|
deviceIDStr := c.PostForm("dev_id")
|
|
towerCode := c.PostForm("tower_code")
|
|
longitudeStr := c.PostForm("longitude")
|
|
latitudeStr := c.PostForm("latitude")
|
|
externalTowerStr := c.PostForm("external_tower")
|
|
|
|
// Validate required fields
|
|
if towerCode == "" || longitudeStr == "" || latitudeStr == "" {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Missing required fields")
|
|
return
|
|
}
|
|
|
|
var deviceID *uuid.UUID
|
|
if deviceIDStr != "" {
|
|
parsedDeviceID, err := uuid.Parse(deviceIDStr)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid device ID")
|
|
return
|
|
}
|
|
deviceID = &parsedDeviceID
|
|
}
|
|
|
|
// Parse coordinates
|
|
longitude, err := strconv.ParseFloat(longitudeStr, 64)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid longitude")
|
|
return
|
|
}
|
|
|
|
latitude, err := strconv.ParseFloat(latitudeStr, 64)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid latitude")
|
|
return
|
|
}
|
|
|
|
var externalTower *bool
|
|
if externalTowerStr != "" {
|
|
parsedExternalTower, err := strconv.ParseBool(externalTowerStr)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid external_tower value")
|
|
return
|
|
}
|
|
externalTower = &parsedExternalTower
|
|
}
|
|
|
|
// Create DTO
|
|
towerDTO := req.TowerDTO{
|
|
DeviceID: deviceID,
|
|
TowerCode: towerCode,
|
|
Longitude: longitude,
|
|
Latitude: latitude,
|
|
ExternalTower: externalTower,
|
|
}
|
|
|
|
// Get multiple image files
|
|
form := c.Request.MultipartForm
|
|
imageFiles := form.File["images"] // Changed from "image" to "images" to support multiple
|
|
|
|
// Also support single image upload for backward compatibility
|
|
if len(imageFiles) == 0 {
|
|
if singleImage, err := c.FormFile("image"); err == nil {
|
|
imageFiles = []*multipart.FileHeader{singleImage}
|
|
}
|
|
}
|
|
|
|
err = tc.tu.PostWithMultipleImages(towerDTO, imageFiles)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
common.SingleResponses(c, "Tower has been created", nil)
|
|
}
|
|
}
|
|
|
|
func (tc *TowerController) GetTowerByID() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id := c.Param("uuid")
|
|
uuid, err := uuid.Parse(id)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
tower, err := tc.tu.GetByID(uuid)
|
|
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
common.SingleResponses(c, "Success", tower)
|
|
}
|
|
}
|
|
|
|
func (tc *TowerController) UpdateTower() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
id := c.Param("uuid")
|
|
|
|
tower_uuid, err := uuid.Parse(id)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
contentType := c.GetHeader("Content-Type")
|
|
|
|
// Handle JSON request (no images)
|
|
if strings.Contains(contentType, "application/json") {
|
|
var towerUpdateDTO req.UpdateTowerDTO
|
|
if err := c.ShouldBindJSON(&towerUpdateDTO); err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid JSON format: "+err.Error())
|
|
return
|
|
}
|
|
|
|
// No image files for JSON requests
|
|
err := tc.tu.UpdateTowerWithMultipleImages(tower_uuid, towerUpdateDTO, nil)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
common.SingleResponses(c, "Tower has been updated", nil)
|
|
return
|
|
}
|
|
|
|
// Handle multipart form request
|
|
err = c.Request.ParseMultipartForm(50 << 20) // Increase to 50MB for multiple images
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Failed to parse multipart form")
|
|
return
|
|
}
|
|
|
|
// Create update DTO
|
|
towerUpdateDTO := req.UpdateTowerDTO{}
|
|
|
|
// Optional fields - handle form data
|
|
if deviceIDStr := c.PostForm("device_id"); deviceIDStr != "" {
|
|
if deviceID, err := uuid.Parse(deviceIDStr); err == nil {
|
|
towerUpdateDTO.DeviceID = &deviceID
|
|
} else {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid device ID format")
|
|
return
|
|
}
|
|
}
|
|
|
|
if towerCode := c.PostForm("tower_code"); towerCode != "" {
|
|
towerUpdateDTO.TowerCode = &towerCode
|
|
}
|
|
|
|
if longitudeStr := c.PostForm("longitude"); longitudeStr != "" {
|
|
if longitude, err := strconv.ParseFloat(longitudeStr, 64); err == nil {
|
|
towerUpdateDTO.Longitude = &longitude
|
|
} else {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid longitude format")
|
|
return
|
|
}
|
|
}
|
|
|
|
if latitudeStr := c.PostForm("latitude"); latitudeStr != "" {
|
|
if latitude, err := strconv.ParseFloat(latitudeStr, 64); err == nil {
|
|
towerUpdateDTO.Latitude = &latitude
|
|
} else {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid latitude format")
|
|
return
|
|
}
|
|
}
|
|
|
|
// Handle external_tower field
|
|
if externalTowerStr := c.PostForm("external_tower"); externalTowerStr != "" {
|
|
if externalTower, err := strconv.ParseBool(externalTowerStr); err == nil {
|
|
towerUpdateDTO.ExternalTower = &externalTower
|
|
} else {
|
|
common.ErrorResponses(c, http.StatusBadRequest, "Invalid external_tower value")
|
|
return
|
|
}
|
|
}
|
|
|
|
// Handle image_url field (for updating image URL directly)
|
|
if imageURL := c.PostForm("image_url"); imageURL != "" {
|
|
towerUpdateDTO.ImageURL = &imageURL
|
|
}
|
|
|
|
// Get multiple image files
|
|
form := c.Request.MultipartForm
|
|
imageFiles := form.File["images"] // Support multiple images
|
|
|
|
// Also support single image upload for backward compatibility
|
|
if len(imageFiles) == 0 {
|
|
if singleImage, err := c.FormFile("image"); err == nil {
|
|
imageFiles = []*multipart.FileHeader{singleImage}
|
|
}
|
|
}
|
|
|
|
// Handle replace_images flag - if true, replace all images; if false, append to existing
|
|
replaceImages := c.PostForm("replace_images") == "true"
|
|
|
|
err = tc.tu.UpdateTowerWithMultipleImages(tower_uuid, towerUpdateDTO, imageFiles, replaceImages)
|
|
if err != nil {
|
|
common.ErrorResponses(c, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
common.SingleResponses(c, "Tower has been updated", nil)
|
|
}
|
|
} |