feat: Auto-Migração, Seeding de Preços e CRUD de Eventos
This commit is contained in:
parent
323261fa23
commit
8e67dcfd49
7 changed files with 447 additions and 12 deletions
|
|
@ -85,10 +85,15 @@ func main() {
|
||||||
configCors.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Authorization"}
|
configCors.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Authorization"}
|
||||||
r.Use(cors.New(configCors))
|
r.Use(cors.New(configCors))
|
||||||
|
|
||||||
|
// Swagger
|
||||||
// Swagger
|
// Swagger
|
||||||
// Dynamically update Swagger Info
|
// Dynamically update Swagger Info
|
||||||
docs.SwaggerInfo.Host = cfg.SwaggerHost
|
docs.SwaggerInfo.Host = cfg.SwaggerHost
|
||||||
docs.SwaggerInfo.Schemes = []string{"https", "http"}
|
if cfg.AppEnv == "production" {
|
||||||
|
docs.SwaggerInfo.Schemes = []string{"https", "http"}
|
||||||
|
} else {
|
||||||
|
docs.SwaggerInfo.Schemes = []string{"http", "https"}
|
||||||
|
}
|
||||||
|
|
||||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
|
||||||
|
|
||||||
|
|
@ -158,6 +163,8 @@ func main() {
|
||||||
api.DELETE("/tipos-servicos/:id", tiposServicosHandler.Delete)
|
api.DELETE("/tipos-servicos/:id", tiposServicosHandler.Delete)
|
||||||
|
|
||||||
api.POST("/tipos-eventos", tiposEventosHandler.Create)
|
api.POST("/tipos-eventos", tiposEventosHandler.Create)
|
||||||
|
api.PUT("/tipos-eventos/:id", tiposEventosHandler.Update)
|
||||||
|
api.DELETE("/tipos-eventos/:id", tiposEventosHandler.Delete)
|
||||||
api.POST("/tipos-eventos/precos", tiposEventosHandler.SetPrice)
|
api.POST("/tipos-eventos/precos", tiposEventosHandler.SetPrice)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1116,6 +1116,82 @@ const docTemplate = `{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/tipos-eventos/{id}": {
|
||||||
|
"put": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"tipos_eventos"
|
||||||
|
],
|
||||||
|
"summary": "Update an event type",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Event ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Event Data",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/tipos_eventos.CreateEventoRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/tipos_eventos.EventoResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"tipos_eventos"
|
||||||
|
],
|
||||||
|
"summary": "Delete an event type",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Event ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/tipos-eventos/{id}/precos": {
|
"/api/tipos-eventos/{id}/precos": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
|
@ -1888,6 +1964,12 @@ const docTemplate = `{
|
||||||
},
|
},
|
||||||
"nome": {
|
"nome": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"precos": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/tipos_eventos.PrecoResponse"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1110,6 +1110,82 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/tipos-eventos/{id}": {
|
||||||
|
"put": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"tipos_eventos"
|
||||||
|
],
|
||||||
|
"summary": "Update an event type",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Event ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "Event Data",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/tipos_eventos.CreateEventoRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/tipos_eventos.EventoResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"tipos_eventos"
|
||||||
|
],
|
||||||
|
"summary": "Delete an event type",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "Event ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "No Content"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/tipos-eventos/{id}/precos": {
|
"/api/tipos-eventos/{id}/precos": {
|
||||||
"get": {
|
"get": {
|
||||||
"security": [
|
"security": [
|
||||||
|
|
@ -1882,6 +1958,12 @@
|
||||||
},
|
},
|
||||||
"nome": {
|
"nome": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"precos": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/tipos_eventos.PrecoResponse"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,10 @@ definitions:
|
||||||
type: string
|
type: string
|
||||||
nome:
|
nome:
|
||||||
type: string
|
type: string
|
||||||
|
precos:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/tipos_eventos.PrecoResponse'
|
||||||
|
type: array
|
||||||
type: object
|
type: object
|
||||||
tipos_eventos.PrecoResponse:
|
tipos_eventos.PrecoResponse:
|
||||||
properties:
|
properties:
|
||||||
|
|
@ -966,6 +970,53 @@ paths:
|
||||||
summary: Create a new event type
|
summary: Create a new event type
|
||||||
tags:
|
tags:
|
||||||
- tipos_eventos
|
- tipos_eventos
|
||||||
|
/api/tipos-eventos/{id}:
|
||||||
|
delete:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
parameters:
|
||||||
|
- description: Event ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"204":
|
||||||
|
description: No Content
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Delete an event type
|
||||||
|
tags:
|
||||||
|
- tipos_eventos
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
parameters:
|
||||||
|
- description: Event ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: Event Data
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/tipos_eventos.CreateEventoRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/tipos_eventos.EventoResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: Update an event type
|
||||||
|
tags:
|
||||||
|
- tipos_eventos
|
||||||
/api/tipos-eventos/{id}/precos:
|
/api/tipos-eventos/{id}/precos:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
|
|
|
||||||
|
|
@ -145,8 +145,142 @@ CREATE TABLE IF NOT EXISTS precos_tipos_eventos (
|
||||||
UNIQUE(tipo_evento_id, funcao_profissional_id)
|
UNIQUE(tipo_evento_id, funcao_profissional_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Initial Pricing Seed (Examples based on image, requires joining IDs which makes raw SQL insert hard without known UUIDs.
|
-- Seed Pricing Data
|
||||||
-- For simplicity in schema.sql, we'll skip complex dynamic inserts.
|
DO $$
|
||||||
-- The user can populate via API or we can write a more complex PL/pgSQL block if absolutely necessary,
|
DECLARE
|
||||||
-- but usually schema.sql is structure + static data. Dynamic pricing is better handled via admin or separate migration script.
|
-- IDs for Functions
|
||||||
-- Leaving table empty for now, or adding a comment.)
|
id_foto UUID;
|
||||||
|
id_cine UUID;
|
||||||
|
id_recep UUID;
|
||||||
|
|
||||||
|
-- IDs for Events
|
||||||
|
id_identificacao UUID;
|
||||||
|
id_baile UUID;
|
||||||
|
id_colacao UUID;
|
||||||
|
id_col_baile_mesmo UUID;
|
||||||
|
id_col_baile_dif UUID;
|
||||||
|
id_missa UUID;
|
||||||
|
id_churrasco UUID;
|
||||||
|
id_trote UUID;
|
||||||
|
id_outro UUID;
|
||||||
|
id_balada UUID;
|
||||||
|
id_jantar UUID;
|
||||||
|
id_festa_junina UUID;
|
||||||
|
id_colacao_oficial UUID;
|
||||||
|
id_family_day UUID;
|
||||||
|
id_refeicao UUID;
|
||||||
|
id_estudio_id UUID;
|
||||||
|
id_estudio_col UUID;
|
||||||
|
BEGIN
|
||||||
|
-- Fetch Function IDs
|
||||||
|
SELECT id INTO id_foto FROM funcoes_profissionais WHERE nome = 'Fotógrafo';
|
||||||
|
SELECT id INTO id_cine FROM funcoes_profissionais WHERE nome = 'Cinegrafista';
|
||||||
|
SELECT id INTO id_recep FROM funcoes_profissionais WHERE nome = 'Recepcionista';
|
||||||
|
|
||||||
|
-- Fetch Event IDs
|
||||||
|
SELECT id INTO id_identificacao FROM tipos_eventos WHERE nome = 'Identificação';
|
||||||
|
SELECT id INTO id_baile FROM tipos_eventos WHERE nome = 'Baile';
|
||||||
|
SELECT id INTO id_colacao FROM tipos_eventos WHERE nome = 'Colação';
|
||||||
|
SELECT id INTO id_col_baile_mesmo FROM tipos_eventos WHERE nome = 'Col/Baile (mesmo local)';
|
||||||
|
SELECT id INTO id_col_baile_dif FROM tipos_eventos WHERE nome = 'Col/Baile (local diferente)';
|
||||||
|
SELECT id INTO id_missa FROM tipos_eventos WHERE nome = 'Missa / Culto';
|
||||||
|
SELECT id INTO id_churrasco FROM tipos_eventos WHERE nome = 'Churrasco';
|
||||||
|
SELECT id INTO id_trote FROM tipos_eventos WHERE nome = 'Trote';
|
||||||
|
SELECT id INTO id_outro FROM tipos_eventos WHERE nome = 'Outro';
|
||||||
|
SELECT id INTO id_balada FROM tipos_eventos WHERE nome = 'Balada';
|
||||||
|
SELECT id INTO id_jantar FROM tipos_eventos WHERE nome = 'Jantar';
|
||||||
|
SELECT id INTO id_festa_junina FROM tipos_eventos WHERE nome = 'Festa Junina';
|
||||||
|
SELECT id INTO id_colacao_oficial FROM tipos_eventos WHERE nome = 'Colação Oficial';
|
||||||
|
SELECT id INTO id_family_day FROM tipos_eventos WHERE nome = 'Family Day';
|
||||||
|
SELECT id INTO id_refeicao FROM tipos_eventos WHERE nome = 'Refeição';
|
||||||
|
SELECT id INTO id_estudio_id FROM tipos_eventos WHERE nome = 'Estudio ID e Family Day';
|
||||||
|
SELECT id INTO id_estudio_col FROM tipos_eventos WHERE nome = 'Estudio Colação / Baile';
|
||||||
|
|
||||||
|
-- Helper temp table for inserts to keep code clean? No, direct inserts are clearer.
|
||||||
|
|
||||||
|
-- Identificação: Rec 90, Foto 160
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_identificacao, id_recep, 90.00), (id_identificacao, id_foto, 160.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Baile: Rec 115, Cin 450, Foto 310
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_baile, id_recep, 115.00), (id_baile, id_cine, 450.00), (id_baile, id_foto, 310.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Colação: Rec 115, Cin 450, Foto 280
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_colacao, id_recep, 115.00), (id_colacao, id_cine, 450.00), (id_colacao, id_foto, 280.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Col/Baile (mesmo local): Rec 140, Cin 510, Foto 350
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_col_baile_mesmo, id_recep, 140.00), (id_col_baile_mesmo, id_cine, 510.00), (id_col_baile_mesmo, id_foto, 350.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Col/Baile (local diferente): Rec 150, Cin 610, Foto 390
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_col_baile_dif, id_recep, 150.00), (id_col_baile_dif, id_cine, 610.00), (id_col_baile_dif, id_foto, 390.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Missa / Culto: Rec 115, Cin 440, Foto 230
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_missa, id_recep, 115.00), (id_missa, id_cine, 440.00), (id_missa, id_foto, 230.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Churrasco: Rec 90, Cin 440, Foto 250
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_churrasco, id_recep, 90.00), (id_churrasco, id_cine, 440.00), (id_churrasco, id_foto, 250.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Trote: Rec 70, Foto 100
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_trote, id_recep, 70.00), (id_trote, id_foto, 100.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Outro: Foto 250
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_outro, id_foto, 250.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Balada: Rec 115, Cin 440, Foto 250
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_balada, id_recep, 115.00), (id_balada, id_cine, 440.00), (id_balada, id_foto, 250.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Jantar: Rec 115, Cin 440, Foto 310
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_jantar, id_recep, 115.00), (id_jantar, id_cine, 440.00), (id_jantar, id_foto, 310.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Festa Junina: Foto 200
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_festa_junina, id_foto, 200.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Colação Oficial: Rec 115, Cin 450, Foto 280
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_colacao_oficial, id_recep, 115.00), (id_colacao_oficial, id_cine, 450.00), (id_colacao_oficial, id_foto, 280.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Family Day: Rec 210, Cin 670, Foto 490
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_family_day, id_recep, 210.00), (id_family_day, id_cine, 670.00), (id_family_day, id_foto, 490.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Refeição: Rec 35 (Assuming Rec column corresponds to Refeição cost based on position, or just mapping single value)
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_refeicao, id_recep, 35.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Estudio ID e Family Day: Rec 80
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_estudio_id, id_recep, 80.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
-- Estudio Colação / Baile: Rec 50
|
||||||
|
INSERT INTO precos_tipos_eventos (tipo_evento_id, funcao_profissional_id, valor) VALUES
|
||||||
|
(id_estudio_col, id_recep, 50.00)
|
||||||
|
ON CONFLICT (tipo_evento_id, funcao_profissional_id) DO UPDATE SET valor = EXCLUDED.valor;
|
||||||
|
|
||||||
|
END $$;
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,9 @@ func NewHandler(service *Service) *Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
type EventoResponse struct {
|
type EventoResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Nome string `json:"nome"`
|
Nome string `json:"nome"`
|
||||||
|
Precos []PrecoResponse `json:"precos"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type PrecoResponse struct {
|
type PrecoResponse struct {
|
||||||
|
|
@ -87,9 +88,33 @@ func (h *Handler) List(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var response []EventoResponse
|
response := []EventoResponse{}
|
||||||
for _, e := range events {
|
for _, e := range events {
|
||||||
response = append(response, toEventoResponse(e))
|
eventID := uuid.UUID(e.ID.Bytes).String()
|
||||||
|
|
||||||
|
// Fetch prices for this event
|
||||||
|
prices, err := h.service.ListPrices(c.Request.Context(), eventID)
|
||||||
|
if err != nil {
|
||||||
|
// If fetching prices fails, we log/error (or just return empty prices depending on requirement)
|
||||||
|
// For now, failing the request ensures data consistency
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pricesResp := []PrecoResponse{}
|
||||||
|
for _, p := range prices {
|
||||||
|
pricesResp = append(pricesResp, PrecoResponse{
|
||||||
|
ID: uuid.UUID(p.ID.Bytes).String(),
|
||||||
|
TipoEventoID: uuid.UUID(p.TipoEventoID.Bytes).String(),
|
||||||
|
FuncaoProfissionalID: uuid.UUID(p.FuncaoProfissionalID.Bytes).String(),
|
||||||
|
FuncaoNome: p.FuncaoNome,
|
||||||
|
Valor: fromPgNumeric(p.Valor),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
evtResp := toEventoResponse(e)
|
||||||
|
evtResp.Precos = pricesResp
|
||||||
|
response = append(response, evtResp)
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, response)
|
c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
@ -136,7 +161,7 @@ func (h *Handler) ListPrices(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var response []PrecoResponse
|
response := []PrecoResponse{}
|
||||||
for _, p := range prices {
|
for _, p := range prices {
|
||||||
response = append(response, PrecoResponse{
|
response = append(response, PrecoResponse{
|
||||||
ID: uuid.UUID(p.ID.Bytes).String(),
|
ID: uuid.UUID(p.ID.Bytes).String(),
|
||||||
|
|
@ -148,3 +173,50 @@ func (h *Handler) ListPrices(c *gin.Context) {
|
||||||
}
|
}
|
||||||
c.JSON(http.StatusOK, response)
|
c.JSON(http.StatusOK, response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update godoc
|
||||||
|
// @Summary Update an event type
|
||||||
|
// @Tags tipos_eventos
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param id path string true "Event ID"
|
||||||
|
// @Param request body CreateEventoRequest true "Event Data"
|
||||||
|
// @Success 200 {object} EventoResponse
|
||||||
|
// @Router /api/tipos-eventos/{id} [put]
|
||||||
|
func (h *Handler) Update(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
var req CreateEventoRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
event, err := h.service.Update(c.Request.Context(), id, req.Nome)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, toEventoResponse(*event))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete godoc
|
||||||
|
// @Summary Delete an event type
|
||||||
|
// @Tags tipos_eventos
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param id path string true "Event ID"
|
||||||
|
// @Success 204
|
||||||
|
// @Router /api/tipos-eventos/{id} [delete]
|
||||||
|
func (h *Handler) Delete(c *gin.Context) {
|
||||||
|
id := c.Param("id")
|
||||||
|
err := h.service.Delete(c.Request.Context(), id)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusNoContent, nil)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package tipos_eventos
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"photum-backend/internal/db/generated"
|
"photum-backend/internal/db/generated"
|
||||||
|
|
||||||
|
|
@ -107,6 +108,12 @@ func (s *Service) ListPrices(ctx context.Context, eventoID string) ([]generated.
|
||||||
// Helper (Assuming user doesn't have it in shared utils or similar)
|
// Helper (Assuming user doesn't have it in shared utils or similar)
|
||||||
func toPgNumeric(f float64) pgtype.Numeric {
|
func toPgNumeric(f float64) pgtype.Numeric {
|
||||||
var n pgtype.Numeric
|
var n pgtype.Numeric
|
||||||
n.Scan(f)
|
// Convert to string first to ensure precise scanning
|
||||||
|
s := strconv.FormatFloat(f, 'f', -1, 64)
|
||||||
|
if err := n.Scan(s); err != nil {
|
||||||
|
// Fallback or log if needed, but for valid floats this should work.
|
||||||
|
// Returning invalid (NULL) numeric if scan fails.
|
||||||
|
return pgtype.Numeric{Valid: false}
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue