feat: otimização de performance e ajustes finais
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>br.gov.sigefp</groupId>
|
||||
<artifactId>sigefp-parent</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>sigefp-org</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>SIGEFP Org</name>
|
||||
<description>Módulo de organização: ministérios, unidades, posições</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>br.gov.sigefp</groupId>
|
||||
<artifactId>sigefp-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package br.gov.sigefp.org.api;
|
||||
|
||||
import br.gov.sigefp.org.api.dto.MinistryDTO;
|
||||
import br.gov.sigefp.org.service.MinistryService;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Controller REST para gestão de ministérios.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/org/ministries")
|
||||
@RequiredArgsConstructor
|
||||
public class MinistryController {
|
||||
|
||||
private final MinistryService ministryService;
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<Page<MinistryDTO>> findAll(
|
||||
@RequestParam(value = "page", defaultValue = "0") int page,
|
||||
@RequestParam(value = "size", defaultValue = "20") int size,
|
||||
@RequestParam(value = "sortBy", required = false) String sortBy,
|
||||
@RequestParam(value = "sortDirection", required = false, defaultValue = "ASC") String sortDirection) {
|
||||
|
||||
Sort sort = sortBy != null
|
||||
? Sort.by(Sort.Direction.fromString(sortDirection), sortBy)
|
||||
: Sort.by(Sort.Direction.ASC, "code");
|
||||
|
||||
Pageable pageable = PageRequest.of(page, size, sort);
|
||||
Page<MinistryDTO> result = ministryService.findAll(pageable);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<MinistryDTO> findById(@PathVariable("id") UUID id) {
|
||||
try {
|
||||
MinistryDTO dto = ministryService.findById(id);
|
||||
return ResponseEntity.ok(dto);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<MinistryDTO> create(@Valid @RequestBody MinistryDTO dto) {
|
||||
try {
|
||||
MinistryDTO created = ministryService.create(dto);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(created);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<MinistryDTO> update(
|
||||
@PathVariable("id") UUID id,
|
||||
@Valid @RequestBody MinistryDTO dto) {
|
||||
try {
|
||||
MinistryDTO updated = ministryService.update(id, dto);
|
||||
return ResponseEntity.ok(updated);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
@DeleteMapping("/{id}")
|
||||
public ResponseEntity<Void> delete(@PathVariable("id") UUID id) {
|
||||
try {
|
||||
ministryService.delete(id);
|
||||
return ResponseEntity.noContent().build();
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
package br.gov.sigefp.org.api;
|
||||
|
||||
import br.gov.sigefp.org.api.dto.OrgUnitDTO;
|
||||
import br.gov.sigefp.org.service.OrgUnitService;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Controller REST para gestão de unidades organizacionais.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/org/org-units")
|
||||
@RequiredArgsConstructor
|
||||
public class OrgUnitController {
|
||||
|
||||
private final OrgUnitService orgUnitService;
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<?> findAll(
|
||||
@RequestParam(value = "ministryId", required = false) UUID ministryId,
|
||||
@RequestParam(value = "parentUnitId", required = false) UUID parentUnitId,
|
||||
@RequestParam(value = "page", defaultValue = "0") int page,
|
||||
@RequestParam(value = "size", defaultValue = "20") int size,
|
||||
@RequestParam(value = "sortBy", required = false) String sortBy,
|
||||
@RequestParam(value = "sortDirection", required = false, defaultValue = "ASC") String sortDirection) {
|
||||
|
||||
// Se há filtros, retornar lista (sem paginação)
|
||||
if (ministryId != null || parentUnitId != null) {
|
||||
List<OrgUnitDTO> result;
|
||||
if (ministryId != null) {
|
||||
result = orgUnitService.findByMinistryId(ministryId);
|
||||
if (parentUnitId != null) {
|
||||
result = result.stream()
|
||||
.filter(ou -> parentUnitId.equals(ou.getParentUnitId()))
|
||||
.toList();
|
||||
}
|
||||
} else {
|
||||
// Apenas parentUnitId - buscar todas e filtrar
|
||||
result = orgUnitService.findAll(PageRequest.of(0, Integer.MAX_VALUE)).getContent().stream()
|
||||
.filter(ou -> parentUnitId.equals(ou.getParentUnitId()))
|
||||
.toList();
|
||||
}
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
// Sem filtros, retornar paginado
|
||||
Sort sort = sortBy != null
|
||||
? Sort.by(Sort.Direction.fromString(sortDirection), sortBy)
|
||||
: Sort.by(Sort.Direction.ASC, "code");
|
||||
|
||||
Pageable pageable = PageRequest.of(page, size, sort);
|
||||
Page<OrgUnitDTO> result = orgUnitService.findAll(pageable);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
@GetMapping("/tree/{ministryId}")
|
||||
public ResponseEntity<List<OrgUnitDTO>> findTreeByMinistry(@PathVariable("ministryId") UUID ministryId) {
|
||||
try {
|
||||
List<OrgUnitDTO> tree = orgUnitService.findTreeByMinistryId(ministryId);
|
||||
return ResponseEntity.ok(tree);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<OrgUnitDTO> findById(@PathVariable("id") UUID id) {
|
||||
try {
|
||||
OrgUnitDTO dto = orgUnitService.findById(id);
|
||||
return ResponseEntity.ok(dto);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<OrgUnitDTO> create(@Valid @RequestBody OrgUnitDTO dto) {
|
||||
try {
|
||||
OrgUnitDTO created = orgUnitService.create(dto);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(created);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<OrgUnitDTO> update(
|
||||
@PathVariable("id") UUID id,
|
||||
@Valid @RequestBody OrgUnitDTO dto) {
|
||||
try {
|
||||
OrgUnitDTO updated = orgUnitService.update(id, dto);
|
||||
return ResponseEntity.ok(updated);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package br.gov.sigefp.org.api;
|
||||
|
||||
import br.gov.sigefp.org.api.dto.PositionDTO;
|
||||
import br.gov.sigefp.org.service.PositionService;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Controller REST para gestão de posições/cargos.
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/org/positions")
|
||||
@RequiredArgsConstructor
|
||||
public class PositionController {
|
||||
|
||||
private final PositionService positionService;
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<?> findAll(
|
||||
@RequestParam(value = "orgUnitId", required = false) UUID orgUnitId,
|
||||
@RequestParam(value = "page", defaultValue = "0") int page,
|
||||
@RequestParam(value = "size", defaultValue = "20") int size,
|
||||
@RequestParam(value = "sortBy", required = false) String sortBy,
|
||||
@RequestParam(value = "sortDirection", required = false, defaultValue = "ASC") String sortDirection) {
|
||||
|
||||
if (orgUnitId != null) {
|
||||
// Retornar lista quando filtrado por orgUnitId
|
||||
List<PositionDTO> positions = positionService.findByOrgUnitId(orgUnitId);
|
||||
return ResponseEntity.ok(positions);
|
||||
}
|
||||
|
||||
Sort sort = sortBy != null
|
||||
? Sort.by(Sort.Direction.fromString(sortDirection), sortBy)
|
||||
: Sort.by(Sort.Direction.ASC, "code");
|
||||
|
||||
Pageable pageable = PageRequest.of(page, size, sort);
|
||||
Page<PositionDTO> result = positionService.findAll(pageable);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public ResponseEntity<PositionDTO> findById(@PathVariable("id") UUID id) {
|
||||
try {
|
||||
PositionDTO dto = positionService.findById(id);
|
||||
return ResponseEntity.ok(dto);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.notFound().build();
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<PositionDTO> create(@Valid @RequestBody PositionDTO dto) {
|
||||
try {
|
||||
PositionDTO created = positionService.create(dto);
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(created);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ResponseEntity<PositionDTO> update(
|
||||
@PathVariable("id") UUID id,
|
||||
@Valid @RequestBody PositionDTO dto) {
|
||||
try {
|
||||
PositionDTO updated = positionService.update(id, dto);
|
||||
return ResponseEntity.ok(updated);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ResponseEntity.badRequest().build();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package br.gov.sigefp.org.api.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* DTO para transferência de dados de ministério.
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MinistryDTO {
|
||||
|
||||
private UUID id;
|
||||
|
||||
@NotBlank(message = "Código é obrigatório")
|
||||
@Size(min = 1, max = 50, message = "Código deve ter entre 1 e 50 caracteres")
|
||||
private String code;
|
||||
|
||||
@NotBlank(message = "Nome é obrigatório")
|
||||
@Size(max = 200, message = "Nome deve ter no máximo 200 caracteres")
|
||||
private String name;
|
||||
|
||||
@NotBlank(message = "Sigla é obrigatória")
|
||||
@Size(max = 20, message = "Sigla deve ter no máximo 20 caracteres")
|
||||
private String acronym;
|
||||
|
||||
private String description;
|
||||
|
||||
private String logo;
|
||||
|
||||
private Boolean isActive;
|
||||
}
|
||||
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package br.gov.sigefp.org.api.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* DTO para transferência de dados de unidade organizacional.
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OrgUnitDTO {
|
||||
|
||||
private UUID id;
|
||||
|
||||
@NotNull(message = "ID do ministério é obrigatório")
|
||||
private UUID ministryId;
|
||||
|
||||
private UUID parentUnitId;
|
||||
|
||||
@NotBlank(message = "Código é obrigatório")
|
||||
@Size(min = 1, max = 50, message = "Código deve ter entre 1 e 50 caracteres")
|
||||
private String code;
|
||||
|
||||
@NotBlank(message = "Nome é obrigatório")
|
||||
@Size(max = 200, message = "Nome deve ter no máximo 200 caracteres")
|
||||
private String name;
|
||||
|
||||
@NotBlank(message = "Tipo de unidade é obrigatório")
|
||||
@Size(max = 50, message = "Tipo de unidade deve ter no máximo 50 caracteres")
|
||||
private String type;
|
||||
|
||||
@Size(max = 20, message = "Sigla deve ter no máximo 20 caracteres")
|
||||
private String acronym;
|
||||
|
||||
@Size(max = 255, message = "Endereço deve ter no máximo 255 caracteres")
|
||||
private String address;
|
||||
|
||||
@Size(max = 100, message = "Email deve ter no máximo 100 caracteres")
|
||||
private String email;
|
||||
|
||||
@Size(max = 20, message = "Telefone deve ter no máximo 20 caracteres")
|
||||
private String phone;
|
||||
|
||||
private Boolean isActive;
|
||||
|
||||
// Para representar a árvore hierárquica
|
||||
private List<OrgUnitDTO> children;
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package br.gov.sigefp.org.api.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* DTO para transferência de dados de posição/cargo.
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class PositionDTO {
|
||||
|
||||
private UUID id;
|
||||
|
||||
@NotNull(message = "ID da unidade organizacional é obrigatório")
|
||||
private UUID orgUnitId;
|
||||
|
||||
@NotBlank(message = "Código é obrigatório")
|
||||
@Size(min = 1, max = 50, message = "Código deve ter entre 1 e 50 caracteres")
|
||||
private String code;
|
||||
|
||||
@NotBlank(message = "Título é obrigatório")
|
||||
@Size(max = 200, message = "Título deve ter no máximo 200 caracteres")
|
||||
private String title;
|
||||
|
||||
@Size(max = 50, message = "Nível deve ter no máximo 50 caracteres")
|
||||
private String level;
|
||||
|
||||
private Boolean isActive;
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package br.gov.sigefp.org.domain;
|
||||
|
||||
import br.gov.sigefp.common.domain.BaseEntity;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* Entidade que representa um ministério.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "ministry", indexes = {
|
||||
@Index(name = "idx_ministry_code", columnList = "code")
|
||||
})
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class Ministry extends BaseEntity {
|
||||
|
||||
@Column(nullable = false, unique = true, length = 50)
|
||||
private String code;
|
||||
|
||||
@Column(nullable = false, length = 200)
|
||||
private String name;
|
||||
|
||||
@Column(length = 20)
|
||||
private String acronym;
|
||||
|
||||
@Column(length = 255)
|
||||
private String description;
|
||||
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private String logo;
|
||||
|
||||
@Column(nullable = false, name = "is_active")
|
||||
@Builder.Default
|
||||
private Boolean isActive = true;
|
||||
}
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package br.gov.sigefp.org.domain;
|
||||
|
||||
import br.gov.sigefp.common.domain.BaseEntity;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* Entidade que representa uma unidade organizacional.
|
||||
* Suporta hierarquia através de parentUnit (auto-relacionamento).
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "org_unit", indexes = {
|
||||
@Index(name = "idx_org_unit_code", columnList = "code"),
|
||||
@Index(name = "idx_org_unit_ministry", columnList = "ministry_id"),
|
||||
@Index(name = "idx_org_unit_parent", columnList = "parent_unit_id")
|
||||
})
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class OrgUnit extends BaseEntity {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "ministry_id", nullable = false)
|
||||
private Ministry ministry;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "parent_unit_id")
|
||||
private OrgUnit parentUnit;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 50)
|
||||
private String code;
|
||||
|
||||
@Column(nullable = false, length = 200)
|
||||
private String name;
|
||||
|
||||
@Column(nullable = false, length = 50, name = "unit_type")
|
||||
private String unitType; // DEPARTMENT, DIVISION, SECTION, etc.
|
||||
|
||||
@Column(length = 20)
|
||||
private String acronym;
|
||||
|
||||
@Column(length = 255)
|
||||
private String address;
|
||||
|
||||
@Column(length = 100)
|
||||
private String email;
|
||||
|
||||
@Column(length = 20)
|
||||
private String phone;
|
||||
|
||||
@Column(nullable = false, name = "is_active")
|
||||
@Builder.Default
|
||||
private Boolean isActive = true;
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package br.gov.sigefp.org.domain;
|
||||
|
||||
import br.gov.sigefp.common.domain.BaseEntity;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.*;
|
||||
|
||||
/**
|
||||
* Entidade que representa uma posição/cargo dentro de uma unidade organizacional.
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "position", indexes = {
|
||||
@Index(name = "idx_position_code", columnList = "code"),
|
||||
@Index(name = "idx_position_org_unit", columnList = "org_unit_id")
|
||||
})
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class Position extends BaseEntity {
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "org_unit_id", nullable = false)
|
||||
private OrgUnit orgUnit;
|
||||
|
||||
@Column(nullable = false, unique = true, length = 50)
|
||||
private String code;
|
||||
|
||||
@Column(nullable = false, length = 200)
|
||||
private String title;
|
||||
|
||||
@Column(length = 50)
|
||||
private String level;
|
||||
|
||||
@Column(nullable = false, name = "is_active")
|
||||
@Builder.Default
|
||||
private Boolean isActive = true;
|
||||
}
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package br.gov.sigefp.org.repository;
|
||||
|
||||
import br.gov.sigefp.org.domain.Ministry;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface MinistryRepository extends JpaRepository<Ministry, UUID> {
|
||||
|
||||
Optional<Ministry> findByCode(String code);
|
||||
|
||||
boolean existsByCode(String code);
|
||||
|
||||
Page<Ministry> findAllByIsActiveTrue(Pageable pageable);
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package br.gov.sigefp.org.repository;
|
||||
|
||||
import br.gov.sigefp.org.domain.OrgUnit;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.EntityGraph;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface OrgUnitRepository extends JpaRepository<OrgUnit, UUID> {
|
||||
|
||||
@EntityGraph(attributePaths = { "ministry", "parentUnit" })
|
||||
Page<OrgUnit> findAll(Pageable pageable);
|
||||
|
||||
Optional<OrgUnit> findByCode(String code);
|
||||
|
||||
boolean existsByCode(String code);
|
||||
|
||||
@EntityGraph(attributePaths = { "ministry", "parentUnit" })
|
||||
List<OrgUnit> findByMinistryId(UUID ministryId);
|
||||
|
||||
List<OrgUnit> findByParentUnitId(UUID parentUnitId);
|
||||
|
||||
@Query("SELECT ou FROM OrgUnit ou WHERE ou.ministry.id = :ministryId AND ou.parentUnit IS NULL")
|
||||
List<OrgUnit> findRootUnitsByMinistryId(@Param("ministryId") UUID ministryId);
|
||||
|
||||
@Query("SELECT ou FROM OrgUnit ou WHERE ou.ministry.id = :ministryId AND ou.parentUnit.id = :parentUnitId")
|
||||
List<OrgUnit> findByMinistryIdAndParentUnitId(@Param("ministryId") UUID ministryId,
|
||||
@Param("parentUnitId") UUID parentUnitId);
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package br.gov.sigefp.org.repository;
|
||||
|
||||
import br.gov.sigefp.org.domain.Position;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.EntityGraph;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@Repository
|
||||
public interface PositionRepository extends JpaRepository<Position, UUID> {
|
||||
|
||||
Optional<Position> findByCode(String code);
|
||||
|
||||
boolean existsByCode(String code);
|
||||
|
||||
@EntityGraph(attributePaths = { "orgUnit" })
|
||||
Page<Position> findAll(Pageable pageable);
|
||||
|
||||
@EntityGraph(attributePaths = { "orgUnit" })
|
||||
List<Position> findByOrgUnitId(UUID orgUnitId);
|
||||
}
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
package br.gov.sigefp.org.service;
|
||||
|
||||
import br.gov.sigefp.org.api.dto.MinistryDTO;
|
||||
import br.gov.sigefp.org.domain.Ministry;
|
||||
import br.gov.sigefp.org.repository.MinistryRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Serviço de aplicação para gestão de ministérios.
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
public class MinistryService {
|
||||
|
||||
private final MinistryRepository ministryRepository;
|
||||
|
||||
public MinistryDTO create(MinistryDTO dto) {
|
||||
if (ministryRepository.existsByCode(dto.getCode())) {
|
||||
throw new IllegalArgumentException("Código de ministério já existe: " + dto.getCode());
|
||||
}
|
||||
|
||||
Ministry ministry = Ministry.builder()
|
||||
.code(dto.getCode())
|
||||
.name(dto.getName())
|
||||
.acronym(dto.getAcronym())
|
||||
.description(dto.getDescription())
|
||||
.logo(dto.getLogo())
|
||||
.isActive(dto.getIsActive() != null ? dto.getIsActive() : true)
|
||||
.build();
|
||||
|
||||
Ministry saved = ministryRepository.save(ministry);
|
||||
return toDTO(saved);
|
||||
}
|
||||
|
||||
public MinistryDTO update(UUID id, MinistryDTO dto) {
|
||||
Ministry ministry = ministryRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
|
||||
|
||||
if (dto.getCode() != null && !dto.getCode().equals(ministry.getCode())) {
|
||||
if (ministryRepository.existsByCode(dto.getCode())) {
|
||||
throw new IllegalArgumentException("Código de ministério já existe: " + dto.getCode());
|
||||
}
|
||||
ministry.setCode(dto.getCode());
|
||||
}
|
||||
|
||||
if (dto.getName() != null) {
|
||||
ministry.setName(dto.getName());
|
||||
}
|
||||
if (dto.getAcronym() != null) {
|
||||
ministry.setAcronym(dto.getAcronym());
|
||||
}
|
||||
if (dto.getDescription() != null) {
|
||||
ministry.setDescription(dto.getDescription());
|
||||
}
|
||||
if (dto.getLogo() != null) {
|
||||
ministry.setLogo(dto.getLogo());
|
||||
}
|
||||
if (dto.getIsActive() != null) {
|
||||
ministry.setIsActive(dto.getIsActive());
|
||||
}
|
||||
|
||||
Ministry saved = ministryRepository.save(ministry);
|
||||
return toDTO(saved);
|
||||
}
|
||||
|
||||
public MinistryDTO activate(UUID id) {
|
||||
Ministry ministry = ministryRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
|
||||
ministry.setIsActive(true);
|
||||
Ministry saved = ministryRepository.save(ministry);
|
||||
return toDTO(saved);
|
||||
}
|
||||
|
||||
public MinistryDTO deactivate(UUID id) {
|
||||
Ministry ministry = ministryRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
|
||||
ministry.setIsActive(false);
|
||||
Ministry saved = ministryRepository.save(ministry);
|
||||
return toDTO(saved);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public MinistryDTO findById(UUID id) {
|
||||
Ministry ministry = ministryRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
|
||||
return toDTO(ministry);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<MinistryDTO> findAll(Pageable pageable) {
|
||||
return ministryRepository.findAllByIsActiveTrue(pageable).map(this::toDTO);
|
||||
}
|
||||
|
||||
private MinistryDTO toDTO(Ministry ministry) {
|
||||
return MinistryDTO.builder()
|
||||
.id(ministry.getId())
|
||||
.code(ministry.getCode())
|
||||
.name(ministry.getName())
|
||||
.acronym(ministry.getAcronym())
|
||||
.description(ministry.getDescription())
|
||||
.logo(ministry.getLogo())
|
||||
.isActive(ministry.getIsActive())
|
||||
.build();
|
||||
}
|
||||
|
||||
public void delete(UUID id) {
|
||||
Ministry ministry = ministryRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + id));
|
||||
|
||||
ministry.setIsActive(false);
|
||||
ministryRepository.save(ministry);
|
||||
}
|
||||
}
|
||||
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
package br.gov.sigefp.org.service;
|
||||
|
||||
import br.gov.sigefp.org.api.dto.OrgUnitDTO;
|
||||
import br.gov.sigefp.org.domain.Ministry;
|
||||
import br.gov.sigefp.org.domain.OrgUnit;
|
||||
import br.gov.sigefp.org.repository.MinistryRepository;
|
||||
import br.gov.sigefp.org.repository.OrgUnitRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Serviço de aplicação para gestão de unidades organizacionais.
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
public class OrgUnitService {
|
||||
|
||||
private final OrgUnitRepository orgUnitRepository;
|
||||
private final MinistryRepository ministryRepository;
|
||||
private final br.gov.sigefp.common.service.GlobalAuditLogService auditLogService;
|
||||
|
||||
@CacheEvict(value = { "orgUnits", "orgUnitsByMinistry" }, allEntries = true)
|
||||
public OrgUnitDTO create(OrgUnitDTO dto) {
|
||||
// Validação: unicidade de código
|
||||
if (orgUnitRepository.existsByCode(dto.getCode())) {
|
||||
throw new IllegalArgumentException("Código de unidade já existe: " + dto.getCode());
|
||||
}
|
||||
|
||||
Ministry ministry = ministryRepository.findById(dto.getMinistryId())
|
||||
.orElseThrow(() -> new IllegalArgumentException("Ministério não encontrado: " + dto.getMinistryId()));
|
||||
|
||||
OrgUnit parentUnit = null;
|
||||
if (dto.getParentUnitId() != null) {
|
||||
parentUnit = orgUnitRepository.findById(dto.getParentUnitId())
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException("Unidade pai não encontrada: " + dto.getParentUnitId()));
|
||||
|
||||
// Validação: parentUnit deve pertencer ao mesmo ministério
|
||||
if (!parentUnit.getMinistry().getId().equals(ministry.getId())) {
|
||||
throw new IllegalArgumentException("Unidade pai deve pertencer ao mesmo ministério");
|
||||
}
|
||||
}
|
||||
|
||||
OrgUnit orgUnit = OrgUnit.builder()
|
||||
.ministry(ministry)
|
||||
.parentUnit(parentUnit)
|
||||
.code(dto.getCode())
|
||||
.name(dto.getName())
|
||||
.unitType(dto.getType())
|
||||
.acronym(dto.getAcronym())
|
||||
.address(dto.getAddress())
|
||||
.email(dto.getEmail())
|
||||
.phone(dto.getPhone())
|
||||
.isActive(dto.getIsActive() != null ? dto.getIsActive() : true)
|
||||
.build();
|
||||
|
||||
OrgUnit saved = orgUnitRepository.save(orgUnit);
|
||||
return toDTO(saved);
|
||||
}
|
||||
|
||||
@CacheEvict(value = { "orgUnits", "orgUnitsByMinistry" }, allEntries = true)
|
||||
public OrgUnitDTO update(UUID id, OrgUnitDTO dto) {
|
||||
OrgUnit orgUnit = orgUnitRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Unidade organizacional não encontrada: " + id));
|
||||
|
||||
StringBuilder log = new StringBuilder();
|
||||
|
||||
if (dto.getCode() != null && !dto.getCode().equals(orgUnit.getCode())) {
|
||||
if (orgUnitRepository.existsByCode(dto.getCode())) {
|
||||
throw new IllegalArgumentException("Código de unidade já existe: " + dto.getCode());
|
||||
}
|
||||
log.append("Código: [").append(orgUnit.getCode()).append("] -> [").append(dto.getCode()).append("]. ");
|
||||
orgUnit.setCode(dto.getCode());
|
||||
}
|
||||
|
||||
if (dto.getMinistryId() != null && !dto.getMinistryId().equals(orgUnit.getMinistry().getId())) {
|
||||
Ministry ministry = ministryRepository.findById(dto.getMinistryId())
|
||||
.orElseThrow(
|
||||
() -> new IllegalArgumentException("Ministério não encontrado: " + dto.getMinistryId()));
|
||||
log.append("Ministério: [").append(orgUnit.getMinistry().getName()).append("] -> [")
|
||||
.append(ministry.getName()).append("]. ");
|
||||
orgUnit.setMinistry(ministry);
|
||||
}
|
||||
|
||||
if (dto.getParentUnitId() != null) {
|
||||
if (orgUnit.getParentUnit() == null || !dto.getParentUnitId().equals(orgUnit.getParentUnit().getId())) {
|
||||
OrgUnit parentUnit = orgUnitRepository.findById(dto.getParentUnitId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(
|
||||
"Unidade pai não encontrada: " + dto.getParentUnitId()));
|
||||
|
||||
if (!parentUnit.getMinistry().getId().equals(orgUnit.getMinistry().getId())) {
|
||||
throw new IllegalArgumentException("Unidade pai deve pertencer ao mesmo ministério");
|
||||
}
|
||||
String oldParent = orgUnit.getParentUnit() != null ? orgUnit.getParentUnit().getName() : "N/A";
|
||||
log.append("Unidade Pai: [").append(oldParent).append("] -> [").append(parentUnit.getName())
|
||||
.append("]. ");
|
||||
orgUnit.setParentUnit(parentUnit);
|
||||
}
|
||||
} else if (dto.getParentUnitId() == null && orgUnit.getParentUnit() != null) {
|
||||
log.append("Unidade Pai: [").append(orgUnit.getParentUnit().getName()).append("] -> [N/A]. ");
|
||||
orgUnit.setParentUnit(null);
|
||||
}
|
||||
|
||||
if (dto.getName() != null && !dto.getName().equals(orgUnit.getName())) {
|
||||
log.append("Nome: [").append(orgUnit.getName()).append("] -> [").append(dto.getName()).append("]. ");
|
||||
orgUnit.setName(dto.getName());
|
||||
}
|
||||
if (dto.getType() != null && !dto.getType().equals(orgUnit.getUnitType())) {
|
||||
log.append("Tipo: [").append(orgUnit.getUnitType()).append("] -> [").append(dto.getType()).append("]. ");
|
||||
orgUnit.setUnitType(dto.getType());
|
||||
}
|
||||
if (dto.getAcronym() != null && !dto.getAcronym().equals(orgUnit.getAcronym())) {
|
||||
log.append("Sigla: [").append(orgUnit.getAcronym()).append("] -> [").append(dto.getAcronym()).append("]. ");
|
||||
orgUnit.setAcronym(dto.getAcronym());
|
||||
}
|
||||
if (dto.getIsActive() != null && !dto.getIsActive().equals(orgUnit.getIsActive())) {
|
||||
log.append("Ativo: [").append(orgUnit.getIsActive()).append("] -> [").append(dto.getIsActive())
|
||||
.append("]. ");
|
||||
orgUnit.setIsActive(dto.getIsActive());
|
||||
}
|
||||
|
||||
// Outros campos técnicos (contato/endereço) - log simplificado
|
||||
if (dto.getEmail() != null && !dto.getEmail().equals(orgUnit.getEmail()))
|
||||
orgUnit.setEmail(dto.getEmail());
|
||||
if (dto.getPhone() != null && !dto.getPhone().equals(orgUnit.getPhone()))
|
||||
orgUnit.setPhone(dto.getPhone());
|
||||
if (dto.getAddress() != null && !dto.getAddress().equals(orgUnit.getAddress()))
|
||||
orgUnit.setAddress(dto.getAddress());
|
||||
|
||||
OrgUnit saved = orgUnitRepository.save(orgUnit);
|
||||
|
||||
if (log.length() > 0) {
|
||||
// Nota: id do usuário viria do SecurityContext em produção
|
||||
auditLogService.logAction(null, "system", "ORG", "UPDATE", "OrgUnit", id, log.toString());
|
||||
}
|
||||
|
||||
return toDTO(saved);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Cacheable(value = "orgUnits", key = "#id")
|
||||
public OrgUnitDTO findById(UUID id) {
|
||||
OrgUnit orgUnit = orgUnitRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Unidade organizacional não encontrada: " + id));
|
||||
return toDTO(orgUnit);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<OrgUnitDTO> findAll(Pageable pageable) {
|
||||
return orgUnitRepository.findAll(pageable).map(this::toDTO);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@Cacheable(value = "orgUnitsByMinistry", key = "#ministryId")
|
||||
public List<OrgUnitDTO> findByMinistryId(UUID ministryId) {
|
||||
return orgUnitRepository.findByMinistryId(ministryId).stream()
|
||||
.map(this::toDTO)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<OrgUnitDTO> findTreeByMinistryId(UUID ministryId) {
|
||||
// Buscar unidades raiz (sem parentUnit) do ministério
|
||||
List<OrgUnit> rootUnits = orgUnitRepository.findRootUnitsByMinistryId(ministryId);
|
||||
|
||||
// Construir árvore recursivamente
|
||||
return rootUnits.stream()
|
||||
.map(this::buildTree)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private OrgUnitDTO buildTree(OrgUnit orgUnit) {
|
||||
OrgUnitDTO dto = toDTO(orgUnit);
|
||||
|
||||
// Buscar filhos
|
||||
List<OrgUnit> children = orgUnitRepository.findByParentUnitId(orgUnit.getId());
|
||||
if (!children.isEmpty()) {
|
||||
List<OrgUnitDTO> childrenDTOs = children.stream()
|
||||
.map(this::buildTree)
|
||||
.collect(Collectors.toList());
|
||||
dto.setChildren(childrenDTOs);
|
||||
} else {
|
||||
dto.setChildren(new ArrayList<>());
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private OrgUnitDTO toDTO(OrgUnit orgUnit) {
|
||||
return OrgUnitDTO.builder()
|
||||
.id(orgUnit.getId())
|
||||
.ministryId(orgUnit.getMinistry().getId())
|
||||
.parentUnitId(orgUnit.getParentUnit() != null ? orgUnit.getParentUnit().getId() : null)
|
||||
.code(orgUnit.getCode())
|
||||
.name(orgUnit.getName())
|
||||
.type(orgUnit.getUnitType())
|
||||
.acronym(orgUnit.getAcronym())
|
||||
.address(orgUnit.getAddress())
|
||||
.email(orgUnit.getEmail())
|
||||
.phone(orgUnit.getPhone())
|
||||
.isActive(orgUnit.getIsActive())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
package br.gov.sigefp.org.service;
|
||||
|
||||
import br.gov.sigefp.org.api.dto.PositionDTO;
|
||||
import br.gov.sigefp.org.domain.OrgUnit;
|
||||
import br.gov.sigefp.org.domain.Position;
|
||||
import br.gov.sigefp.org.repository.OrgUnitRepository;
|
||||
import br.gov.sigefp.org.repository.PositionRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Serviço de aplicação para gestão de posições/cargos.
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Transactional
|
||||
public class PositionService {
|
||||
|
||||
private final PositionRepository positionRepository;
|
||||
private final OrgUnitRepository orgUnitRepository;
|
||||
private final br.gov.sigefp.common.service.GlobalAuditLogService auditLogService;
|
||||
|
||||
public PositionDTO create(PositionDTO dto) {
|
||||
// Validação: unicidade de código
|
||||
if (positionRepository.existsByCode(dto.getCode())) {
|
||||
throw new IllegalArgumentException("Código de posição já existe: " + dto.getCode());
|
||||
}
|
||||
|
||||
OrgUnit orgUnit = orgUnitRepository.findById(dto.getOrgUnitId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(
|
||||
"Unidade organizacional não encontrada: " + dto.getOrgUnitId()));
|
||||
|
||||
Position position = Position.builder()
|
||||
.orgUnit(orgUnit)
|
||||
.code(dto.getCode())
|
||||
.title(dto.getTitle())
|
||||
.level(dto.getLevel())
|
||||
.isActive(dto.getIsActive() != null ? dto.getIsActive() : true)
|
||||
.build();
|
||||
|
||||
Position saved = positionRepository.save(position);
|
||||
return toDTO(saved);
|
||||
}
|
||||
|
||||
public PositionDTO update(UUID id, PositionDTO dto) {
|
||||
Position position = positionRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Posição não encontrada: " + id));
|
||||
|
||||
StringBuilder log = new StringBuilder();
|
||||
|
||||
if (dto.getCode() != null && !dto.getCode().equals(position.getCode())) {
|
||||
if (positionRepository.existsByCode(dto.getCode())) {
|
||||
throw new IllegalArgumentException("Código de posição já existe: " + dto.getCode());
|
||||
}
|
||||
log.append("Código: [").append(position.getCode()).append("] -> [").append(dto.getCode()).append("]. ");
|
||||
position.setCode(dto.getCode());
|
||||
}
|
||||
|
||||
if (dto.getOrgUnitId() != null && !dto.getOrgUnitId().equals(position.getOrgUnit().getId())) {
|
||||
OrgUnit orgUnit = orgUnitRepository.findById(dto.getOrgUnitId())
|
||||
.orElseThrow(() -> new IllegalArgumentException(
|
||||
"Unidade organizacional não encontrada: " + dto.getOrgUnitId()));
|
||||
log.append("Unidade: [").append(position.getOrgUnit().getName()).append("] -> [").append(orgUnit.getName())
|
||||
.append("]. ");
|
||||
position.setOrgUnit(orgUnit);
|
||||
}
|
||||
|
||||
if (dto.getTitle() != null && !dto.getTitle().equals(position.getTitle())) {
|
||||
log.append("Título: [").append(position.getTitle()).append("] -> [").append(dto.getTitle()).append("]. ");
|
||||
position.setTitle(dto.getTitle());
|
||||
}
|
||||
if (dto.getLevel() != null && !dto.getLevel().equals(position.getLevel())) {
|
||||
log.append("Nível: [").append(position.getLevel()).append("] -> [").append(dto.getLevel()).append("]. ");
|
||||
position.setLevel(dto.getLevel());
|
||||
}
|
||||
if (dto.getIsActive() != null && !dto.getIsActive().equals(position.getIsActive())) {
|
||||
log.append("Ativo: [").append(position.getIsActive()).append("] -> [").append(dto.getIsActive())
|
||||
.append("]. ");
|
||||
position.setIsActive(dto.getIsActive());
|
||||
}
|
||||
|
||||
Position saved = positionRepository.save(position);
|
||||
|
||||
if (log.length() > 0) {
|
||||
// Nota: id do usuário viria do SecurityContext em produção
|
||||
auditLogService.logAction(null, "system", "ORG", "UPDATE", "Position", id, log.toString());
|
||||
}
|
||||
|
||||
return toDTO(saved);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public PositionDTO findById(UUID id) {
|
||||
Position position = positionRepository.findById(id)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Posição não encontrada: " + id));
|
||||
return toDTO(position);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<PositionDTO> findAll(Pageable pageable) {
|
||||
return positionRepository.findAll(pageable).map(this::toDTO);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<PositionDTO> findByOrgUnitId(UUID orgUnitId) {
|
||||
return positionRepository.findByOrgUnitId(orgUnitId).stream()
|
||||
.map(this::toDTO)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private PositionDTO toDTO(Position position) {
|
||||
return PositionDTO.builder()
|
||||
.id(position.getId())
|
||||
.orgUnitId(position.getOrgUnit().getId())
|
||||
.code(position.getCode())
|
||||
.title(position.getTitle())
|
||||
.level(position.getLevel())
|
||||
.isActive(position.getIsActive())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user