PersonaController.java
package com.licensis.notaire.api;
import com.licensis.notaire.negocio.Persona;
import com.licensis.notaire.negocio.TipoIdentificacion;
import com.licensis.notaire.repository.TipoIdentificacionRepository;
import com.licensis.notaire.service.PersonaService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/api/v1/personas")
@Tag(name = "Personas", description = "API para gestionar personas")
public class PersonaController {
private final PersonaService personaService;
private final TipoIdentificacionRepository tipoIdentificacionRepository;
public PersonaController(PersonaService personaService, TipoIdentificacionRepository tipoIdentificacionRepository) {
this.personaService = personaService;
this.tipoIdentificacionRepository = tipoIdentificacionRepository;
}
@GetMapping
@Operation(summary = "Obtener todas las personas")
@Transactional(readOnly = true)
public ResponseEntity<List<Persona>> getAllPersonas() {
List<Persona> personas = personaService.findAll();
return ResponseEntity.ok(personas);
}
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "No encontrado")
})
@GetMapping("/{id}")
@Operation(summary = "Obtener persona por ID")
@Transactional(readOnly = true)
public ResponseEntity<Persona> getPersonaById(@PathVariable Integer id) {
return personaService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@ApiResponses({
@ApiResponse(responseCode = "201", description = "Creado"),
@ApiResponse(responseCode = "400", description = "Solicitud inválida"),
@ApiResponse(responseCode = "409", description = "Conflicto")
})
@PostMapping
@Operation(summary = "Crear nueva persona")
public ResponseEntity<Object> createPersona(@RequestBody Persona persona) {
try {
if (persona.getFkIdTipoIdentificacion() == null) {
TipoIdentificacion defaultTipo = tipoIdentificacionRepository.findById(1)
.orElseGet(() -> {
TipoIdentificacion ti = new TipoIdentificacion();
ti.setNombre("DNI");
return tipoIdentificacionRepository.save(ti);
});
persona.setFkIdTipoIdentificacion(defaultTipo);
}
Persona saved = personaService.save(persona);
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.CONFLICT).body(e.getMessage());
}
}
@ApiResponses({
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(responseCode = "404", description = "No encontrado")
})
@PutMapping("/{id}")
@Operation(summary = "Actualizar persona")
public ResponseEntity<Persona> updatePersona(@PathVariable Integer id, @RequestBody Persona persona) {
return personaService.findById(id)
.map(existing -> {
persona.setIdPersona(id);
persona.setVersion(existing.getVersion());
if (persona.getFkIdTipoIdentificacion() == null) {
persona.setFkIdTipoIdentificacion(existing.getFkIdTipoIdentificacion());
}
Persona updated = personaService.save(persona);
return ResponseEntity.ok(updated);
})
.orElse(ResponseEntity.notFound().build());
}
@ApiResponses({
@ApiResponse(responseCode = "204", description = "Eliminado"),
@ApiResponse(responseCode = "404", description = "No encontrado")
})
@DeleteMapping("/{id}")
@Operation(summary = "Eliminar persona")
public ResponseEntity<Object> deletePersona(@PathVariable Integer id) {
if (personaService.findById(id).isEmpty()) {
return ResponseEntity.notFound().build();
}
try {
personaService.deleteById(id);
return ResponseEntity.noContent().build();
} catch (Exception e) {
// Persona is still referenced (usuario, folio, presupuesto, …):
// surface a 409 instead of a raw 500.
return ResponseEntity.status(HttpStatus.CONFLICT)
.body("No se puede eliminar: la persona está referenciada por otros registros.");
}
}
@GetMapping("/buscar")
@Operation(summary = "Buscar personas por nombre, apellido, numero de identificacion o tipo (CU61)")
@Transactional(readOnly = true)
public ResponseEntity<List<Persona>> buscarPersonas(
@RequestParam(required = false) String nombre,
@RequestParam(required = false) String apellido,
@RequestParam(required = false) String numeroIdentificacion,
@RequestParam(required = false) Integer idTipoIdentificacion,
@RequestParam(required = false) Boolean esCliente) {
List<Persona> personas = personaService.buscar(nombre, apellido, numeroIdentificacion, idTipoIdentificacion, esCliente);
return ResponseEntity.ok(personas);
}
}