320 lines
9.6 KiB
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))
|
|
}
|