package agenda import ( "context" "time" "photum-backend/internal/db/generated" "github.com/google/uuid" "github.com/jackc/pgx/v5/pgtype" ) type Service struct { queries *generated.Queries } func NewService(db *generated.Queries) *Service { return &Service{queries: db} } type CreateAgendaRequest struct { FotID uuid.UUID `json:"fot_id"` DataEvento time.Time `json:"data_evento"` TipoEventoID uuid.UUID `json:"tipo_evento_id"` ObservacoesEvento string `json:"observacoes_evento"` LocalEvento string `json:"local_evento"` Endereco string `json:"endereco"` Horario string `json:"horario"` QtdFormandos int32 `json:"qtd_formandos"` QtdFotografos int32 `json:"qtd_fotografos"` QtdRecepcionistas int32 `json:"qtd_recepcionistas"` QtdCinegrafistas int32 `json:"qtd_cinegrafistas"` QtdEstudios int32 `json:"qtd_estudios"` QtdPontoFoto int32 `json:"qtd_ponto_foto"` QtdPontoID int32 `json:"qtd_ponto_id"` QtdPontoDecorado int32 `json:"qtd_ponto_decorado"` QtdPontosLed int32 `json:"qtd_pontos_led"` QtdPlataforma360 int32 `json:"qtd_plataforma_360"` StatusProfissionais string `json:"status_profissionais"` FotoFaltante int32 `json:"foto_faltante"` RecepFaltante int32 `json:"recep_faltante"` CineFaltante int32 `json:"cine_faltante"` LogisticaObservacoes string `json:"logistica_observacoes"` PreVenda bool `json:"pre_venda"` } func (s *Service) CalculateStatus(fotoFaltante, recepFaltante, cineFaltante int32) string { if fotoFaltante < 0 || recepFaltante < 0 || cineFaltante < 0 { return "ERRO" } sum := fotoFaltante + recepFaltante + cineFaltante if sum == 0 { return "OK" } else if sum > 0 { return "FALTA" } return "ERRO" } func (s *Service) Create(ctx context.Context, userID uuid.UUID, req CreateAgendaRequest) (generated.Agenda, error) { status := s.CalculateStatus(req.FotoFaltante, req.RecepFaltante, req.CineFaltante) params := generated.CreateAgendaParams{ FotID: pgtype.UUID{Bytes: req.FotID, Valid: true}, DataEvento: pgtype.Date{Time: req.DataEvento, Valid: true}, TipoEventoID: pgtype.UUID{Bytes: req.TipoEventoID, Valid: true}, ObservacoesEvento: pgtype.Text{String: req.ObservacoesEvento, Valid: req.ObservacoesEvento != ""}, LocalEvento: pgtype.Text{String: req.LocalEvento, Valid: req.LocalEvento != ""}, Endereco: pgtype.Text{String: req.Endereco, Valid: req.Endereco != ""}, Horario: pgtype.Text{String: req.Horario, Valid: req.Horario != ""}, QtdFormandos: pgtype.Int4{Int32: req.QtdFormandos, Valid: true}, QtdFotografos: pgtype.Int4{Int32: req.QtdFotografos, Valid: true}, QtdRecepcionistas: pgtype.Int4{Int32: req.QtdRecepcionistas, Valid: true}, QtdCinegrafistas: pgtype.Int4{Int32: req.QtdCinegrafistas, Valid: true}, QtdEstudios: pgtype.Int4{Int32: req.QtdEstudios, Valid: true}, QtdPontoFoto: pgtype.Int4{Int32: req.QtdPontoFoto, Valid: true}, QtdPontoID: pgtype.Int4{Int32: req.QtdPontoID, Valid: true}, QtdPontoDecorado: pgtype.Int4{Int32: req.QtdPontoDecorado, Valid: true}, QtdPontosLed: pgtype.Int4{Int32: req.QtdPontosLed, Valid: true}, QtdPlataforma360: pgtype.Int4{Int32: req.QtdPlataforma360, Valid: true}, StatusProfissionais: pgtype.Text{String: status, Valid: true}, FotoFaltante: pgtype.Int4{Int32: req.FotoFaltante, Valid: true}, RecepFaltante: pgtype.Int4{Int32: req.RecepFaltante, Valid: true}, CineFaltante: pgtype.Int4{Int32: req.CineFaltante, Valid: true}, LogisticaObservacoes: pgtype.Text{String: req.LogisticaObservacoes, Valid: req.LogisticaObservacoes != ""}, PreVenda: pgtype.Bool{Bool: req.PreVenda, Valid: true}, UserID: pgtype.UUID{Bytes: userID, Valid: true}, } return s.queries.CreateAgenda(ctx, params) } func (s *Service) List(ctx context.Context, userID uuid.UUID, role string) ([]generated.ListAgendasRow, error) { // If role is CLIENT (cliente), filter by userID if role == "cliente" || role == "EVENT_OWNER" { rows, err := s.queries.ListAgendasByUser(ctx, pgtype.UUID{Bytes: userID, Valid: true}) if err != nil { return nil, err } // Convert ListAgendasByUserRow to ListAgendasRow (they are identical structurally but different types in Go) // To avoid manual conversion if types differ slightly by name but not structure, we might need a common interface or cast. // Since sqlc generates separate structs, we have to map them. var result []generated.ListAgendasRow for _, r := range rows { result = append(result, generated.ListAgendasRow{ ID: r.ID, UserID: r.UserID, FotID: r.FotID, DataEvento: r.DataEvento, TipoEventoID: r.TipoEventoID, ObservacoesEvento: r.ObservacoesEvento, LocalEvento: r.LocalEvento, Endereco: r.Endereco, Horario: r.Horario, QtdFormandos: r.QtdFormandos, QtdFotografos: r.QtdFotografos, QtdRecepcionistas: r.QtdRecepcionistas, QtdCinegrafistas: r.QtdCinegrafistas, QtdEstudios: r.QtdEstudios, QtdPontoFoto: r.QtdPontoFoto, QtdPontoID: r.QtdPontoID, QtdPontoDecorado: r.QtdPontoDecorado, QtdPontosLed: r.QtdPontosLed, QtdPlataforma360: r.QtdPlataforma360, StatusProfissionais: r.StatusProfissionais, FotoFaltante: r.FotoFaltante, RecepFaltante: r.RecepFaltante, CineFaltante: r.CineFaltante, LogisticaObservacoes: r.LogisticaObservacoes, PreVenda: r.PreVenda, CriadoEm: r.CriadoEm, AtualizadoEm: r.AtualizadoEm, FotNumero: r.FotNumero, Instituicao: r.Instituicao, CursoNome: r.CursoNome, EmpresaNome: r.EmpresaNome, AnoSemestre: r.AnoSemestre, ObservacoesFot: r.ObservacoesFot, TipoEventoNome: r.TipoEventoNome, }) } return result, nil } return s.queries.ListAgendas(ctx) } func (s *Service) Get(ctx context.Context, id uuid.UUID) (generated.Agenda, error) { return s.queries.GetAgenda(ctx, pgtype.UUID{Bytes: id, Valid: true}) } func (s *Service) Update(ctx context.Context, id uuid.UUID, req CreateAgendaRequest) (generated.Agenda, error) { status := s.CalculateStatus(req.FotoFaltante, req.RecepFaltante, req.CineFaltante) params := generated.UpdateAgendaParams{ ID: pgtype.UUID{Bytes: id, Valid: true}, FotID: pgtype.UUID{Bytes: req.FotID, Valid: true}, DataEvento: pgtype.Date{Time: req.DataEvento, Valid: true}, TipoEventoID: pgtype.UUID{Bytes: req.TipoEventoID, Valid: true}, ObservacoesEvento: pgtype.Text{String: req.ObservacoesEvento, Valid: req.ObservacoesEvento != ""}, LocalEvento: pgtype.Text{String: req.LocalEvento, Valid: req.LocalEvento != ""}, Endereco: pgtype.Text{String: req.Endereco, Valid: req.Endereco != ""}, Horario: pgtype.Text{String: req.Horario, Valid: req.Horario != ""}, QtdFormandos: pgtype.Int4{Int32: req.QtdFormandos, Valid: true}, QtdFotografos: pgtype.Int4{Int32: req.QtdFotografos, Valid: true}, QtdRecepcionistas: pgtype.Int4{Int32: req.QtdRecepcionistas, Valid: true}, QtdCinegrafistas: pgtype.Int4{Int32: req.QtdCinegrafistas, Valid: true}, QtdEstudios: pgtype.Int4{Int32: req.QtdEstudios, Valid: true}, QtdPontoFoto: pgtype.Int4{Int32: req.QtdPontoFoto, Valid: true}, QtdPontoID: pgtype.Int4{Int32: req.QtdPontoID, Valid: true}, QtdPontoDecorado: pgtype.Int4{Int32: req.QtdPontoDecorado, Valid: true}, QtdPontosLed: pgtype.Int4{Int32: req.QtdPontosLed, Valid: true}, QtdPlataforma360: pgtype.Int4{Int32: req.QtdPlataforma360, Valid: true}, StatusProfissionais: pgtype.Text{String: status, Valid: true}, FotoFaltante: pgtype.Int4{Int32: req.FotoFaltante, Valid: true}, RecepFaltante: pgtype.Int4{Int32: req.RecepFaltante, Valid: true}, CineFaltante: pgtype.Int4{Int32: req.CineFaltante, Valid: true}, LogisticaObservacoes: pgtype.Text{String: req.LogisticaObservacoes, Valid: req.LogisticaObservacoes != ""}, PreVenda: pgtype.Bool{Bool: req.PreVenda, Valid: true}, } return s.queries.UpdateAgenda(ctx, params) } func (s *Service) Delete(ctx context.Context, id uuid.UUID) error { return s.queries.DeleteAgenda(ctx, pgtype.UUID{Bytes: id, Valid: true}) }