Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/main/java/br/com/acta/common/utils/ConversorObject.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package br.com.acta.common.utils;

import br.com.acta.common.handler.exception.InvalidRequestException;
import br.com.acta.entity.enums.IconeCiclo;

import java.math.BigDecimal;
import java.time.LocalDate;
Expand Down Expand Up @@ -78,4 +79,12 @@ public static <T extends Enum<T>> T toEnum(Object valor, Class<T> enumClass) thr
throw new InvalidRequestException("O valor informado é inválido");
}
}
}

public static String toIconeCicloUrl(Object valor) {
if (valor == null) throw new InvalidRequestException("A URL do ícone não pode ser removida");

String url = valor.toString();
if (!IconeCiclo.permite(url)) throw new InvalidRequestException("A URL do ícone informada não é permitida");
return url;
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
package br.com.acta.dto.core.colaborador;

import java.time.LocalDate;
import java.util.List;

import org.hibernate.validator.constraints.br.CPF;

import com.fasterxml.jackson.annotation.JsonFormat;

import br.com.acta.common.config.swagger.examples.SwaggerRequestExamples;
import br.com.acta.dto.core.contato.email.EmailRequestDTO;
import br.com.acta.dto.core.contato.telefone.TelefoneRequestDTO;
import br.com.acta.dto.core.usuario.UsuarioRequestDTO;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.*;
import org.hibernate.validator.constraints.br.CPF;

import java.time.LocalDate;
import java.util.List;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Past;
import jakarta.validation.constraints.PastOrPresent;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;

public record ColaboradorRequestDTO(
@Schema(description = "CPF do colaborador", example = SwaggerRequestExamples.CPF, minLength = 11, maxLength = 11)
Expand All @@ -26,6 +34,10 @@ public record ColaboradorRequestDTO(
@Size(max = 160, message = "{validation.nome.size}")
String nome,

@Schema(description = "Nome do colaborador exibido na interface", example = SwaggerRequestExamples.NOME, maxLength = 160)
@Size(max = 160, message = "{validation.colaborador.nickname.size}")
String nickname,

@Schema(description = "Cargo do colaborador", example = SwaggerRequestExamples.CARGO, maxLength = 100)
@NotBlank(message = "{validation.colaborador.cargo.notblank}")
@Size(max = 100, message = "{validation.colaborador.cargo.size}")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package br.com.acta.dto.core.colaborador;

import br.com.acta.dto.core.contato.email.EmailResponseDTO;
import br.com.acta.dto.core.contato.telefone.TelefoneResponseDTO;
import br.com.acta.entity.enums.StatusGeral;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonFormat;

import br.com.acta.dto.core.contato.email.EmailResponseDTO;
import br.com.acta.dto.core.contato.telefone.TelefoneResponseDTO;
import br.com.acta.entity.enums.StatusGeral;

public record ColaboradorResponseDTO(
Long id,
String cpf,
String nome,
String nickname,
String cargo,
String area,

Expand All @@ -34,4 +37,4 @@ public record ColaboradorResponseDTO(
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
OffsetDateTime atualizadoEm
) {
}
}
18 changes: 13 additions & 5 deletions src/main/java/br/com/acta/dto/pdca/ciclo/CicloRequestDTO.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package br.com.acta.dto.pdca.ciclo;

import br.com.acta.common.config.swagger.examples.SwaggerRequestExamples;
import java.time.LocalDate;

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;

import java.time.LocalDate;
import br.com.acta.common.config.swagger.examples.SwaggerRequestExamples;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.FutureOrPresent;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Positive;
import jakarta.validation.constraints.Size;

public record CicloRequestDTO(
@Schema(description = "Título do ciclo", example = SwaggerRequestExamples.TITULO_CICLO)
Expand All @@ -30,6 +35,9 @@ public record CicloRequestDTO(
@FutureOrPresent(message = "{validation.ciclo.dataEstimadaFim.future}")
LocalDate dataEstimadaFim,

@Schema(description = "URL do ícone do ciclo. Quando omitida, utiliza people-icon.svg")
String iconeUrl,

@Schema(description = "ID da empresa", example = SwaggerRequestExamples.ID_EMPRESA)
@NotNull(message = "{validation.idEmpresa.notnull}")
@Positive(message = "{validation.idEmpresa.positive}")
Expand All @@ -40,4 +48,4 @@ public record CicloRequestDTO(
@Positive(message = "{validation.ciclo.idGestor.positive}")
Long idGestor
) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public record CicloResponseDTO(
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/yyyy")
LocalDate dataFimReal,

String iconeUrl,

Long idEmpresa,
Long idGestor,
List<UsuarioCicloResponseDTO> colaboradores,
Expand All @@ -30,4 +32,4 @@ public record CicloResponseDTO(
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssXXX")
OffsetDateTime atualizadoEm
) {
}
}
30 changes: 22 additions & 8 deletions src/main/java/br/com/acta/entity/core/Colaborador.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
package br.com.acta.entity.core;

import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

import br.com.acta.entity.base.auditoria.AuditoriaBase;
import br.com.acta.entity.core.contato.EmailColaborador;
import br.com.acta.entity.core.contato.TelefoneColaborador;
import br.com.acta.entity.enums.StatusGeral;
import jakarta.persistence.*;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

import java.time.LocalDate;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "colaborador", schema = "public")
Expand All @@ -26,6 +37,9 @@ public class Colaborador extends AuditoriaBase {
@Column(name = "nome", length = 160, nullable = false)
private String nome;

@Column(name = "nickname", length = 160, nullable = false)
private String nickname;

@Column(name = "cargo", length = 100, nullable = false)
private String cargo;

Expand Down Expand Up @@ -58,4 +72,4 @@ public class Colaborador extends AuditoriaBase {

@OneToMany(mappedBy = "colaborador", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<TelefoneColaborador> telefones = new HashSet<>();
}
}
27 changes: 27 additions & 0 deletions src/main/java/br/com/acta/entity/enums/IconeCiclo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package br.com.acta.entity.enums;

import java.util.Arrays;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter @RequiredArgsConstructor
public enum IconeCiclo {
WALLET("https://res.cloudinary.com/kcypohk3/image/upload/v1790336465/wallet-icon.svg"),
TARGET("https://res.cloudinary.com/kcypohk3/image/upload/v1790336454/target-icon.svg"),
SHIELD("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/shield-icon.svg"),
SETTINGS("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/settings-icon.svg"),
PEOPLE("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/people-icon.svg"),
HEADPHONE("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/headphone-icon.svg"),
FOLDER("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/folder-icon.svg"),
DATABASE("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/database-icon.svg"),
CODE("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/code-icon.svg"),
CLOCK("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/clock-icon.svg"),
BOX("https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/box-icon.svg");

private final String url;

public static boolean permite(String url) {
return Arrays.stream(values()).anyMatch(icone -> icone.url.equals(url));
}
}
3 changes: 3 additions & 0 deletions src/main/java/br/com/acta/entity/pdca/Ciclo.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ public class Ciclo extends TituloDescricaoBase {
@Column(name = "data_fim_real")
private LocalDate dataFimReal;

@Column(name = "icone_url", nullable = false)
private String iconeUrl;

@OneToMany(mappedBy = "ciclo", fetch = FetchType.LAZY)
private Set<UsuarioCiclo> colaboradores;

Expand Down
13 changes: 10 additions & 3 deletions src/main/java/br/com/acta/service/CicloService.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import br.com.acta.dto.pdca.ciclo.CicloResponseDTO;
import br.com.acta.entity.core.Empresa;
import br.com.acta.entity.core.Usuario;
import br.com.acta.entity.enums.IconeCiclo;
import br.com.acta.entity.enums.StatusCiclo;
import br.com.acta.entity.pdca.Ciclo;
import br.com.acta.repository.padrao.CicloRepository;
Expand All @@ -30,8 +31,8 @@ public class CicloService
private final CicloRepository repo;
private final CicloMapper mapper;
private final PatchConfig patchConfig = new PatchConfig(
Set.of("titulo", "descricao", "dataInicio", "dataEstimadaFim", "idGestor", "idEmpresa"),
Set.of("titulo", "descricao", "dataEstimadaFim")
Set.of("titulo", "descricao", "dataInicio", "dataEstimadaFim", "iconeUrl", "idGestor", "idEmpresa"),
Set.of("titulo", "descricao", "dataEstimadaFim", "iconeUrl")
);
private final UsuarioService usuarioService;
private final EmpresaService empresaService;
Expand Down Expand Up @@ -59,6 +60,9 @@ public CicloResponseDTO patch(Long id, Map<String, Object> campos) {
Object dataObject = campos.get("dataEstimadaFim");
ciclo.setDataEstimadaFim(ConversorObject.toLocalDate(dataObject, false));
}
if (campos.containsKey("iconeUrl")) {
ciclo.setIconeUrl(ConversorObject.toIconeCicloUrl(campos.get("iconeUrl")));
}

Ciclo salvo = repo.save(ciclo);
return mapper.toResponse(salvo);
Expand Down Expand Up @@ -120,6 +124,9 @@ protected void antesInserir(Ciclo ciclo, CicloRequestDTO dto) {
Empresa empresa = empresaService.getEntity(dto.idEmpresa());
Usuario gestor = usuarioService.getEntity(dto.idGestor());

if (ciclo.getIconeUrl() == null) ciclo.setIconeUrl(IconeCiclo.PEOPLE.getUrl());
else ciclo.setIconeUrl(ConversorObject.toIconeCicloUrl(ciclo.getIconeUrl()));

ciclo.setStatus(StatusCiclo.PLANEJAMENTO);
ciclo.setEmpresa(empresa);
ciclo.setGestor(gestor);
Expand All @@ -143,4 +150,4 @@ public Ciclo getEntity(Long id) {
return repo.findByIdAndEmpresaId(id, atual().idEmpresa())
.orElseThrow(() -> new ModelNotFoundException("Ciclo", id));
}
}
}
24 changes: 14 additions & 10 deletions src/main/java/br/com/acta/service/ColaboradorService.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
package br.com.acta.service;

import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import br.com.acta.common.handler.exception.ActiveEntityDeletionException;
import br.com.acta.common.handler.exception.ModelNotFoundException;
import br.com.acta.common.handler.exception.RegexException;
import br.com.acta.common.handler.exception.UniqueViolationException;
import br.com.acta.common.utils.PatchConfig;
import br.com.acta.common.utils.Validador;
import br.com.acta.dto.core.colaborador.ColaboradorMapper;
import br.com.acta.dto.core.colaborador.ColaboradorRequestDTO;
import br.com.acta.dto.core.colaborador.ColaboradorResponseDTO;
import br.com.acta.dto.core.colaborador.ColaboradorMapper;
import br.com.acta.dto.core.usuario.UsuarioResponseDTO;
import br.com.acta.dto.core.contato.email.EmailColaboradorMapper;
import br.com.acta.dto.core.contato.telefone.TelefoneColaboradorMapper;
import br.com.acta.dto.core.usuario.UsuarioResponseDTO;
import br.com.acta.entity.core.Colaborador;
import br.com.acta.entity.core.Empresa;
import br.com.acta.entity.core.Usuario;
Expand All @@ -25,13 +33,6 @@
import br.com.acta.repository.padrao.TelefoneColaboradorRepository;
import br.com.acta.service.base.BaseService;
import br.com.caelum.stella.validation.CPFValidator;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
public class ColaboradorService extends BaseService<ColaboradorRequestDTO, ColaboradorResponseDTO, Colaborador> {
Expand All @@ -46,7 +47,7 @@ public class ColaboradorService extends BaseService<ColaboradorRequestDTO, Colab
private final TelefoneColaboradorMapper telefoneMapper;
private final CPFValidator CPFValidator = new CPFValidator();
private final PatchConfig patchConfig = new PatchConfig(
Set.of("cpf", "nome", "cargo", "area", "dataNascimento", "dataContratacao", "permissaoGestor", "status", "emails", "telefones", "usuario", "idEmpresa"),
Set.of("cpf", "nome", "nickname", "cargo", "area", "dataNascimento", "dataContratacao", "permissaoGestor", "status", "emails", "telefones", "usuario", "idEmpresa"),
Set.of("nome", "cargo", "area", "permissaoGestor", "status")
);

Expand Down Expand Up @@ -111,6 +112,9 @@ public ColaboradorResponseDTO inserir(ColaboradorRequestDTO dto) {
colaborador.setEmpresa(empresa);
colaborador.setUsuario(usuario);
colaborador.setStatus(StatusGeral.ATIVO);
if (colaborador.getNickname() == null) {
colaborador.setNickname(colaborador.getNome());
}

dto.emails().forEach(email -> {
if (emailRepo.existsByContatoIgnoreCase(email.email())) throw new UniqueViolationException("E-mail");
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/ValidationMessages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ validation.colaborador.cpf.notblank=O CPF é obrigatório.
validation.colaborador.cpf.invalid=Informe um CPF válido.
validation.colaborador.cpf.size=O CPF deve ter no máximo {max} caracteres.
validation.colaborador.nome.notblank=O nome do colaborador é obrigatório.
validation.colaborador.nickname.size=O nickname deve ter no máximo {max} caracteres.
validation.colaborador.cargo.notblank=O cargo é obrigatório.
validation.colaborador.cargo.size=O cargo deve ter no máximo {max} caracteres.
validation.colaborador.dataNascimento.notnull=A data de nascimento é obrigatória.
Expand Down
6 changes: 4 additions & 2 deletions src/main/resources/sql/script.sql
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ CREATE TABLE IF NOT EXISTS colaborador (
id_usuario BIGINT NOT NULL UNIQUE REFERENCES usuario_sistema(id) ON DELETE CASCADE,
cpf CHAR(11) NOT NULL UNIQUE CHECK (cpf ~ '^[0-9]{11}$'),
nome VARCHAR(160) NOT NULL,
nickname VARCHAR(160) NOT NULL,
cargo VARCHAR(100) NOT NULL,
area VARCHAR(100) NOT NULL,
data_nascimento DATE NOT NULL CHECK(data_nascimento <= CURRENT_DATE - INTERVAL '18 years'),
Expand Down Expand Up @@ -124,6 +125,7 @@ CREATE TABLE IF NOT EXISTS pdca.ciclo (
id_empresa BIGINT NOT NULL REFERENCES empresa(id) ON DELETE CASCADE,
id_responsavel BIGINT NOT NULL REFERENCES usuario_sistema(id),
id_ishikawa_mongo UUID,
icone_url TEXT DEFAULT 'https://res.cloudinary.com/kcypohk3/image/upload/v1790336437/people-icon.svg',
titulo VARCHAR(160) NOT NULL,
descricao TEXT NOT NULL,
status VARCHAR(40) NOT NULL CHECK (status IN ('PLANEJAMENTO', 'EXECUCAO', 'VERIFICACAO', 'PADRONIZACAO', 'CONCLUIDO', 'CANCELADO', 'PAUSADO')),
Expand Down Expand Up @@ -408,7 +410,7 @@ CREATE TABLE IF NOT EXISTS pdca.anexo (
tipo_arquivo VARCHAR(150) NOT NULL,
tamanho_arquivo BIGINT NOT NULL CHECK (tamanho_arquivo > 0),
bucket_arquivo VARCHAR(100) NOT NULL DEFAULT 'acta-arquivos',
caminho_arquivo TEXT NOT NULL,
caminho_arquivo TEXT,
status VARCHAR(30) NOT NULL DEFAULT 'PROCESSANDO' CHECK (status IN ('PROCESSANDO', 'ATIVO', 'ERRO', 'EXCLUIDO')),
descricao TEXT,
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW(),
Expand Down Expand Up @@ -444,4 +446,4 @@ CREATE TABLE IF NOT EXISTS pdca.anexo (
)
OR tipo_arquivo LIKE 'image/%'
)
);
);
Loading