photum/backend/internal/cadastro_fot/handler.go

320 lines
9.6 KiB
Go

package cadastro_fot
import (
"net/http"
"photum-backend/internal/db/generated"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgtype"
)
type Handler struct {
service *Service
}
func NewHandler(service *Service) *Handler {
return &Handler{service: service}
}
type CadastroFotResponse struct {
ID string `json:"id"`
Fot string `json:"fot"`
EmpresaID string `json:"empresa_id"`
EmpresaNome string `json:"empresa_nome,omitempty"`
CursoID string `json:"curso_id"`
CursoNome string `json:"curso_nome,omitempty"`
AnoFormaturaID string `json:"ano_formatura_id"`
AnoFormaturaLabel string `json:"ano_formatura_label,omitempty"`
Instituicao string `json:"instituicao"`
Cidade string `json:"cidade"`
Estado string `json:"estado"`
Observacoes string `json:"observacoes"`
GastosCaptacao float64 `json:"gastos_captacao"`
PreVenda bool `json:"pre_venda"`
Finalizada bool `json:"finalizada"`
}
func fromPgNumeric(n pgtype.Numeric) float64 {
f, _ := n.Float64Value()
return f.Float64
}
// Map Create result (no joins)
func toResponse(c generated.CadastroFot) CadastroFotResponse {
return CadastroFotResponse{
ID: uuid.UUID(c.ID.Bytes).String(),
Fot: c.Fot,
EmpresaID: uuid.UUID(c.EmpresaID.Bytes).String(),
CursoID: uuid.UUID(c.CursoID.Bytes).String(),
AnoFormaturaID: uuid.UUID(c.AnoFormaturaID.Bytes).String(),
Instituicao: c.Instituicao.String,
Cidade: c.Cidade.String,
Estado: c.Estado.String,
Observacoes: c.Observacoes.String,
GastosCaptacao: fromPgNumeric(c.GastosCaptacao),
PreVenda: c.PreVenda.Bool,
Finalizada: c.Finalizada.Bool,
}
}
// Map List result (with joins)
func toListResponse(r generated.ListCadastroFotRow) CadastroFotResponse {
return CadastroFotResponse{
ID: uuid.UUID(r.ID.Bytes).String(),
Fot: r.Fot,
EmpresaID: uuid.UUID(r.EmpresaID.Bytes).String(),
EmpresaNome: r.EmpresaNome,
CursoID: uuid.UUID(r.CursoID.Bytes).String(),
CursoNome: r.CursoNome,
AnoFormaturaID: uuid.UUID(r.AnoFormaturaID.Bytes).String(),
AnoFormaturaLabel: r.AnoFormaturaLabel,
Instituicao: r.Instituicao.String,
Cidade: r.Cidade.String,
Estado: r.Estado.String,
Observacoes: r.Observacoes.String,
GastosCaptacao: fromPgNumeric(r.GastosCaptacao),
PreVenda: r.PreVenda.Bool,
Finalizada: r.Finalizada.Bool,
}
}
// Map GetByID result
func toGetResponse(r generated.GetCadastroFotByIDRow) CadastroFotResponse {
return CadastroFotResponse{
ID: uuid.UUID(r.ID.Bytes).String(),
Fot: r.Fot,
EmpresaID: uuid.UUID(r.EmpresaID.Bytes).String(),
EmpresaNome: r.EmpresaNome,
CursoID: uuid.UUID(r.CursoID.Bytes).String(),
CursoNome: r.CursoNome,
AnoFormaturaID: uuid.UUID(r.AnoFormaturaID.Bytes).String(),
AnoFormaturaLabel: r.AnoFormaturaLabel,
Instituicao: r.Instituicao.String,
Cidade: r.Cidade.String,
Estado: r.Estado.String,
Observacoes: r.Observacoes.String,
GastosCaptacao: fromPgNumeric(r.GastosCaptacao),
PreVenda: r.PreVenda.Bool,
Finalizada: r.Finalizada.Bool,
}
}
// Create godoc
// @Summary Create a new FOT record
// @Tags cadastro_fot
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body CreateInput true "FOT Data"
// @Success 201 {object} CadastroFotResponse
// @Router /api/cadastro-fot [post]
func (h *Handler) Create(c *gin.Context) {
var req CreateInput
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
regiao := c.GetString("regiao")
if regiao == "" {
regiao = c.GetHeader("x-regiao")
}
if regiao == "" {
regiao = "SP"
}
res, err := h.service.Create(c.Request.Context(), req, regiao)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusCreated, toResponse(*res))
}
// List godoc
// @Summary List all FOT records
// @Tags cadastro_fot
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param empresa_id query string false "Filter by Company ID"
// @Success 200 {array} CadastroFotResponse
// @Router /api/cadastro-fot [get]
func (h *Handler) List(c *gin.Context) {
empresaID := c.Query("empresa_id")
regiao := c.GetString("regiao")
if regiao == "" {
regiao = c.GetHeader("x-regiao")
}
if regiao == "" {
regiao = "SP"
}
var response []CadastroFotResponse
if empresaID != "" {
rows, err := h.service.ListByEmpresa(c.Request.Context(), empresaID, regiao)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// Conversion for specific row type
for _, r := range rows {
response = append(response, CadastroFotResponse{
ID: uuid.UUID(r.ID.Bytes).String(),
Fot: r.Fot,
EmpresaID: uuid.UUID(r.EmpresaID.Bytes).String(),
EmpresaNome: r.EmpresaNome,
CursoID: uuid.UUID(r.CursoID.Bytes).String(),
CursoNome: r.CursoNome,
AnoFormaturaID: uuid.UUID(r.AnoFormaturaID.Bytes).String(),
AnoFormaturaLabel: r.AnoFormaturaLabel,
Instituicao: r.Instituicao.String,
Cidade: r.Cidade.String,
Estado: r.Estado.String,
Observacoes: r.Observacoes.String,
GastosCaptacao: fromPgNumeric(r.GastosCaptacao),
PreVenda: r.PreVenda.Bool,
Finalizada: r.Finalizada.Bool,
})
}
} else {
rows, err := h.service.List(c.Request.Context(), regiao)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
for _, r := range rows {
response = append(response, toListResponse(r))
}
}
c.JSON(http.StatusOK, response)
}
// Get godoc
// @Summary Get FOT record by ID
// @Tags cadastro_fot
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "ID"
// @Success 200 {object} CadastroFotResponse
// @Router /api/cadastro-fot/{id} [get]
func (h *Handler) Get(c *gin.Context) {
id := c.Param("id")
regiao := c.GetString("regiao")
res, err := h.service.GetByID(c.Request.Context(), id, regiao)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Record not found"})
return
}
c.JSON(http.StatusOK, toGetResponse(*res))
}
// Update godoc
// @Summary Update FOT record
// @Tags cadastro_fot
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "ID"
// @Param request body CreateInput true "Data"
// @Success 200 {object} CadastroFotResponse
// @Router /api/cadastro-fot/{id} [put]
func (h *Handler) Update(c *gin.Context) {
id := c.Param("id")
var req CreateInput
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
regiao := c.GetString("regiao")
res, err := h.service.Update(c.Request.Context(), id, req, regiao)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, toResponse(*res))
}
// Delete godoc
// @Summary Delete FOT record
// @Tags cadastro_fot
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "ID"
// @Success 204
// @Router /api/cadastro-fot/{id} [delete]
func (h *Handler) Delete(c *gin.Context) {
id := c.Param("id")
regiao := c.GetString("regiao")
err := h.service.Delete(c.Request.Context(), id, regiao)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusNoContent, nil)
}
// Import godoc
// @Summary Import FOT data
// @Tags cadastro_fot
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body []ImportInput true "List of FOTs"
// @Success 200 {object} ImportResult
// @Router /api/import/fot [post]
func (h *Handler) Import(c *gin.Context) {
var req []ImportInput
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
regiao := c.GetString("regiao")
res := h.service.BatchImport(c.Request.Context(), req, regiao)
c.JSON(http.StatusOK, res)
}
// ToggleFinalizada godoc
// @Summary Toggle FOT finalized status
// @Tags cadastro_fot
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param id path string true "ID"
// @Param status body object{finalizada=boolean} true "Status"
// @Success 200 {object} CadastroFotResponse
// @Router /api/cadastro-fot/{id}/finalize [post]
func (h *Handler) ToggleFinalizada(c *gin.Context) {
id := c.Param("id")
var req struct {
Finalizada bool `json:"finalizada"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
regiao := c.GetString("regiao")
// Using headers/context for region if not set
if regiao == "" {
regiao = c.GetHeader("x-regiao")
}
if regiao == "" {
regiao = "SP"
}
res, err := h.service.ToggleFinalizada(c.Request.Context(), id, req.Finalizada, regiao)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, toResponse(*res))
}