añadimos el apartado de pujas, para que se puedan ver las pujas y poder crear el informe
Some checks failed
Deploy Spring Boot App / build-and-deploy (push) Has been cancelled

This commit is contained in:
2025-11-22 12:09:17 -04:00
parent 5f2942f700
commit 0e65f8dae6
12 changed files with 436 additions and 7 deletions

View File

@@ -0,0 +1,31 @@
package com.example.fercoganbackend.controller;
import com.example.fercoganbackend.dto.PujaRequest;
import com.example.fercoganbackend.dto.PujaResponse;
import com.example.fercoganbackend.entity.HistorialLotes;
import com.example.fercoganbackend.service.HistorialLotesService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/HistorialPujas")
public class HistorialLotesController {
private final HistorialLotesService historialLote;
public HistorialLotesController(HistorialLotesService historialLote) {
this.historialLote = historialLote;
}
@PostMapping
public PujaResponse realizarPuja(@RequestBody PujaRequest request) {
return historialLote.registrarPuja(request);
}
@GetMapping
public List<HistorialLotes> getHistorialLote(){
return historialLote.getHistorialLoteAll();
}
}

View File

@@ -20,16 +20,31 @@ public class PujaController {
return pujaService.findAll();
}
@GetMapping("/{id}")
@GetMapping("/id/{id}")
public ResponseEntity<Puja> getById(@PathVariable Long id) {
return pujaService.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@GetMapping("/informe/{remateId}")
public List<Puja> getForInforme(@PathVariable Long remateId){
return pujaService.fingForReporte(remateId);
}
@GetMapping("/remate/{id}")
public List<Puja> getForRemate(@PathVariable Long id){
return pujaService.findForRemtae(id);
}
//get coincidir con lote y remate
@GetMapping("/loteyremate/{loteId}/{remateId}")
public List<Puja> getForLoteAndRemate(@PathVariable Long loteId,@PathVariable Long remateId){
return pujaService.findForLoteAndRemate(loteId,remateId);
}
@PostMapping
public Puja create(@RequestBody Puja remate) {
return pujaService.save(remate);
public Puja create(@RequestBody Puja puja) {
return pujaService.save(puja);
}
@PutMapping("/{id}")

View File

@@ -0,0 +1,29 @@
package com.example.fercoganbackend.dto;
import java.time.LocalDateTime;
public class PujaRequest {
private LocalDateTime fecha;
private Double monto;
private Boolean visible;
private Long usuarioId;
private Long cabanaId;
private Long loteId;
private Long remateId;
public Long getRemateId(){
return remateId;
}
public Long getUsuarioId() {
return usuarioId;
}
public Long getLoteId() {
return loteId;
}
public Double getMonto() {
return monto;
}
}

View File

@@ -0,0 +1,53 @@
package com.example.fercoganbackend.dto;
import java.time.LocalDateTime;
public class PujaResponse {
private Long pujaId;
private Long loteId;
private Long remateId;
private Long usuarioId;
private Double montoPujado;
private LocalDateTime fecha;
private String estado;
public PujaResponse(Long pujaId, Long loteId, Long usuarioId,Long remateId,
Double montoPujado, LocalDateTime fecha, String estado) {
this.pujaId = pujaId;
this.loteId = loteId;
this.remateId = remateId;
this.usuarioId = usuarioId;
this.montoPujado = montoPujado;
this.fecha = fecha;
this.estado = estado;
}
public Long getRemateId(){
return remateId;
}
public Long getPujaId() {
return pujaId;
}
public Long getLoteId() {
return loteId;
}
public Long getUsuarioId() {
return usuarioId;
}
public Double getMontoPujado() {
return montoPujado;
}
public LocalDateTime getFecha() {
return fecha;
}
public String getEstado() {
return estado;
}
}

View File

@@ -0,0 +1,107 @@
package com.example.fercoganbackend.entity;
import jakarta.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "historial_lotes")
public class HistorialLotes {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
// Usuario que realizó la puja
@ManyToOne
@JoinColumn(name = "usuario_id", nullable = false)
private Usuario usuario;
// Lote al que pertenece la puja
@ManyToOne
@JoinColumn(name = "lote_id", nullable = false)
private Lote lote;
@ManyToOne
@JoinColumn(name= "remate_id",nullable = false)
private Remate remate;
// Monto pujado
@Column(nullable = false)
private Double monto;
// Fecha y hora de la puja
@Column(nullable = false)
private LocalDateTime fecha;
// Estado de la puja (opcional)
private String estado;
public HistorialLotes() {}
public HistorialLotes(Usuario usuario, Lote lote, Double monto, LocalDateTime fecha, String estado, Remate remate) {
this.usuario = usuario;
this.lote = lote;
this.remate = remate;
this.monto = monto;
this.fecha = fecha;
this.estado = estado;
}
public Remate getRemate() {
return remate;
}
public void setRemate(Remate remate) {
this.remate = remate;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Usuario getUsuario() {
return usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
public Lote getLote() {
return lote;
}
public void setLote(Lote lote) {
this.lote = lote;
}
public Double getMonto() {
return monto;
}
public void setMonto(Double monto) {
this.monto = monto;
}
public LocalDateTime getFecha() {
return fecha;
}
public void setFecha(LocalDateTime fecha) {
this.fecha = fecha;
}
public String getEstado() {
return estado;
}
public void setEstado(String estado) {
this.estado = estado;
}
}

View File

@@ -28,6 +28,7 @@ public class Puja {
@JoinColumn(name = "lote_id")
private Lote lote;
public Long getId() {
return id;
}

View File

@@ -0,0 +1,30 @@
package com.example.fercoganbackend.repository;
import com.example.fercoganbackend.entity.HistorialLotes;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.List;
@Repository
public interface HistorialLotesRepository extends JpaRepository<HistorialLotes, Long> {
List<HistorialLotes> findByLoteIdOrderByFechaDesc(Long loteId);
HistorialLotes findFirstByLoteIdOrderByFechaDesc(Long loteId);
List<HistorialLotes> findByLote_Remate_Id(Long remateId);
List<HistorialLotes> findByLote_IdAndLote_Remate_Id(Long loteId, Long remateId);
List<HistorialLotes> findByLote_IdAndLote_Remate_IdAndFechaAfter(
Long loteId,
Long remateId,
LocalDateTime fecha
);
List<HistorialLotes> findByLote_Remate_IdAndFechaAfter(
Long remateId,
LocalDateTime fecha
);
}

View File

@@ -12,4 +12,5 @@ public interface LoteRepository extends JpaRepository<Lote, Long> {
// Para paginación
List<Lote> findByCabanaId(Long cabanaId);
}

View File

@@ -1,6 +1,35 @@
package com.example.fercoganbackend.repository;
import com.example.fercoganbackend.entity.HistorialLotes;
import com.example.fercoganbackend.entity.Puja;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface PujaRepository extends JpaRepository<Puja, Long> {}
import java.time.LocalDateTime;
import java.util.List;
public interface PujaRepository extends JpaRepository<Puja, Long> {
List<Puja> findByLote_Remate_Id(Long remateId);
List<Puja> findByLote_IdAndLote_Remate_Id(Long loteId, Long remateId);
List<Puja> findByLote_IdAndLote_Remate_IdAndFechaAfter(
Long loteId,
Long remateId,
LocalDateTime fecha
);
List<Puja> findByLote_Remate_IdAndFechaAfter(Long id,LocalDateTime fecha);
@Query(value = """
SELECT p.* FROM pujas p
INNER JOIN (
SELECT lote_id, MAX(monto) AS max_monto
FROM pujas
WHERE lote_id IN (SELECT id FROM lotes WHERE remate_id = :remateId)
GROUP BY lote_id
) pm ON p.lote_id = pm.lote_id AND p.monto = pm.max_monto
""", nativeQuery = true)
List<Puja> findMayorPujaPorLotePorRemateNative(Long remateId);
}

View File

@@ -0,0 +1,72 @@
package com.example.fercoganbackend.service;
import com.example.fercoganbackend.dto.PujaRequest;
import com.example.fercoganbackend.dto.PujaResponse;
import com.example.fercoganbackend.entity.HistorialLotes;
import com.example.fercoganbackend.entity.Remate;
import com.example.fercoganbackend.entity.Usuario;
import com.example.fercoganbackend.entity.Lote;
import com.example.fercoganbackend.repository.HistorialLotesRepository;
import com.example.fercoganbackend.repository.RemateRepository;
import com.example.fercoganbackend.repository.UsuarioRepository;
import com.example.fercoganbackend.repository.LoteRepository;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class HistorialLotesService {
private final HistorialLotesRepository historialRepo;
private final UsuarioRepository usuarioRepo;
private final LoteRepository loteRepo;
private final RemateRepository remateRepo;
public HistorialLotesService(HistorialLotesRepository historialRepo,
UsuarioRepository usuarioRepo,
LoteRepository loteRepo, RemateRepository remateRepo) {
this.historialRepo = historialRepo;
this.remateRepo = remateRepo;
this.usuarioRepo = usuarioRepo;
this.loteRepo = loteRepo;
}
public List<HistorialLotes> getHistorialLoteAll(){
return historialRepo.findAll();
}
public PujaResponse registrarPuja(PujaRequest request) {
Usuario usuario = usuarioRepo.findById(request.getUsuarioId())
.orElseThrow(() -> new RuntimeException("Usuario no encontrado"));
Lote lote = loteRepo.findById(request.getLoteId())
.orElseThrow(() -> new RuntimeException("Lote no encontrado"));
Remate remate = remateRepo.findById(request.getRemateId())
.orElseThrow(() -> new RuntimeException("No se encontro el remate"));
HistorialLotes nuevaPuja = new HistorialLotes(
usuario,
lote,
request.getMonto(),
LocalDateTime.now(),
"ACEPTADA",
remate
);
historialRepo.save(nuevaPuja);
return new PujaResponse(
nuevaPuja.getId(),
lote.getId(),
usuario.getId(),
remate.getId(),
nuevaPuja.getMonto(),
nuevaPuja.getFecha(),
nuevaPuja.getEstado()
);
}
}

View File

@@ -1,15 +1,33 @@
package com.example.fercoganbackend.service;
import com.example.fercoganbackend.entity.Puja;
import com.example.fercoganbackend.entity.Remate;
import com.example.fercoganbackend.repository.PujaRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.fercoganbackend.repository.UsuarioRepository;
import com.example.fercoganbackend.repository.CabanaRepository;
import com.example.fercoganbackend.repository.LoteRepository;
import com.example.fercoganbackend.repository.RemateRepository;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@Service
public class PujaService {
@Autowired
private UsuarioRepository usuarioRepository;
@Autowired
private CabanaRepository cabanaRepository;
@Autowired
private LoteRepository loteRepository;
@Autowired
private RemateRepository remateRepository;
@Autowired
private PujaRepository pujaRepository;
@@ -18,14 +36,57 @@ public class PujaService {
return pujaRepository.findAll();
}
public List<Puja> findForRemtae(Long id){
return pujaRepository.findByLote_Remate_Id(id);
}
public List<Puja> findForLoteAndRemate(Long loteId, Long remateId){
return pujaRepository.findByLote_IdAndLote_Remate_Id(loteId,remateId);
}
public List<Puja> findForLoteAndRemateAndDate(Long loteId, Long remateId, LocalDateTime fecha){
return pujaRepository.findByLote_IdAndLote_Remate_IdAndFechaAfter(loteId, remateId, fecha);
}
public List<Puja> fingForReporte(Long id){
return pujaRepository.findMayorPujaPorLotePorRemateNative(id);
}
public Optional<Puja> findById(Long id) {
return pujaRepository.findById(id);
}
public Puja save(Puja remate) {
return pujaRepository.save(remate);
public Puja save(Puja puja) {
// Validar USUARIO
if (puja.getUsuario() == null || puja.getUsuario().getId() == null) {
throw new RuntimeException("El usuario es obligatorio");
}
var usuario = usuarioRepository.findById(puja.getUsuario().getId())
.orElseThrow(() -> new RuntimeException("Usuario no encontrado"));
// Validar CABAÑA
if (puja.getCabana() == null || puja.getCabana().getId() == null) {
throw new RuntimeException("La cabaña es obligatoria");
}
var cabana = cabanaRepository.findById(puja.getCabana().getId())
.orElseThrow(() -> new RuntimeException("Cabaña no encontrada"));
// Validar LOTE
if (puja.getLote() == null || puja.getLote().getId() == null) {
throw new RuntimeException("El lote es obligatorio");
}
var lote = loteRepository.findById(puja.getLote().getId())
.orElseThrow(() -> new RuntimeException("Lote no encontrado"));
// Asignar entidades reales para que JPA las maneje correctamente
puja.setUsuario(usuario);
puja.setCabana(cabana);
puja.setLote(lote);
return pujaRepository.save(puja);
}
public void delete(Long id) {
pujaRepository.deleteById(id);
}