terminado. trabajando en el carrito. falta mensaje de ya añadido

This commit is contained in:
2025-10-17 13:31:09 +02:00
parent 46715d1017
commit 06e03afa04
21 changed files with 251 additions and 113 deletions

View File

@ -94,7 +94,8 @@ public class CartController {
}
/** Eliminar línea por presupuesto_id (opcional) */
@DeleteMapping("/remove/presupuesto/{presupuestoId}")
@DeleteMapping("/delete/item/{presupuestoId}")
@ResponseBody
public String removeByPresupuesto(@PathVariable Long presupuestoId, Principal principal) {
service.removeByPresupuesto(currentUserId(principal), presupuestoId);
return "redirect:/cart";

View File

@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.imprimelibros.erp.presupuesto.classes.PresupuestoFormatter;
import com.imprimelibros.erp.presupuesto.dto.Presupuesto;
import com.imprimelibros.erp.common.Utils;
import com.imprimelibros.erp.presupuesto.PresupuestoRepository;
@ -30,15 +31,17 @@ public class CartService {
private final MessageSource messageSource;
private final PresupuestoFormatter presupuestoFormatter;
private final PresupuestoRepository presupuestoRepo;
private final Utils utils;
public CartService(CartRepository cartRepo, CartItemRepository itemRepo,
MessageSource messageSource, PresupuestoFormatter presupuestoFormatter,
PresupuestoRepository presupuestoRepo) {
PresupuestoRepository presupuestoRepo, Utils utils) {
this.cartRepo = cartRepo;
this.itemRepo = itemRepo;
this.messageSource = messageSource;
this.presupuestoFormatter = presupuestoFormatter;
this.presupuestoRepo = presupuestoRepo;
this.utils = utils;
}
/** Devuelve el carrito activo o lo crea si no existe. */
@ -137,65 +140,14 @@ public class CartService {
resumen.put("presupuestoId", presupuesto.getId());
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> servicios = new ArrayList<>();
if (presupuesto.getServiciosJson() != null && !presupuesto.getServiciosJson().isBlank())
try{
servicios = mapper.readValue(presupuesto.getServiciosJson(), new TypeReference<>() {
});
} catch (JsonProcessingException e) {
// Manejar la excepción
}
Map<String, Object> detalles = utils.getTextoPresupuesto(presupuesto, locale);
boolean hayDepositoLegal = servicios != null && servicios.stream()
.map(m -> java.util.Objects.toString(m.get("id"), ""))
.map(String::trim)
.anyMatch("deposito-legal"::equals);
resumen.put("baseTotal", Utils.formatCurrency(presupuesto.getBaseImponible(), locale));
resumen.put("base", presupuesto.getBaseImponible());
resumen.put("iva4", presupuesto.getIvaImporte4());
resumen.put("iva21", presupuesto.getIvaImporte21());
List<HashMap<String, Object>> lineas = new ArrayList<>();
HashMap<String, Object> linea = new HashMap<>();
Double precio_unitario = 0.0;
Double precio_total = 0.0;
BigDecimal total = BigDecimal.ZERO;
linea.put("descripcion", presupuestoFormatter.resumen(presupuesto, servicios, locale));
linea.put("cantidad", presupuesto.getSelectedTirada() != null ? presupuesto.getSelectedTirada() : 0);
precio_unitario = (presupuesto.getPrecioUnitario() != null ? presupuesto.getPrecioUnitario().doubleValue() : 0.0);
precio_total = (presupuesto.getPrecioTotalTirada() != null ? presupuesto.getPrecioTotalTirada().doubleValue() : 0.0);
linea.put("precio_unitario", precio_unitario);
linea.put("precio_total", BigDecimal.valueOf(precio_total).setScale(2, RoundingMode.HALF_UP));
total = total.add(BigDecimal.valueOf(precio_total));
lineas.add(linea);
if (hayDepositoLegal) {
linea = new HashMap<>();
linea.put("descripcion", messageSource.getMessage("presupuesto.resumen-deposito-legal", null, locale));
linea.put("cantidad", 4);
linea.put("precio_unitario", precio_unitario);
linea.put("precio_total", BigDecimal.valueOf(precio_unitario * 4).setScale(2, RoundingMode.HALF_UP));
total = total.add(BigDecimal.valueOf(precio_unitario * 4));
lineas.add(linea);
}
List<Map<String, Object>> serviciosExtras = new ArrayList<>();
if (servicios != null) {
for (Map<String, Object> servicio : servicios) {
HashMap<String, Object> servicioData = new HashMap<>();
servicioData.put("id", servicio.get("id"));
servicioData.put("descripcion", servicio.get("label"));
servicioData.put("precio", servicio.get("id").equals("marcapaginas")
? Double.parseDouble(servicio.get("price").toString())
/ Double.parseDouble(servicio.get("units").toString())
: servicio.get("price"));
total = total.add(BigDecimal.valueOf(Double.parseDouble(servicioData.get("precio").toString())));
servicioData.put("unidades", servicio.get("units"));
serviciosExtras.add(servicioData);
}
}
NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(locale);
String formattedString = currencyFormat.format(total.setScale(2, RoundingMode.HALF_UP).doubleValue());
resumen.put("total", formattedString);
resumen.put("lineas", lineas);
resumen.put("servicios", serviciosExtras);
resumen.put("resumen", detalles);
return resumen;
}

View File

@ -93,18 +93,28 @@ public class Utils {
if (hayDepositoLegal) {
linea = new HashMap<>();
linea.put("descripcion",
messageSource.getMessage("pdf.ejemplares-deposito-legal", new Object[]{4}, locale));
messageSource.getMessage("pdf.ejemplares-deposito-legal", new Object[] { 4 },
locale));
lineas.add(linea);
}
String serviciosExtras = "";
if (servicios != null) {
for (Map<String, Object> servicio : servicios) {
serviciosExtras += messageSource.getMessage(
"presupuesto.extras-" + servicio.get("id"), null, locale) + ", ";
if ("deposito-legal".equals(servicio.get("id")) ||
"service-isbn".equals(servicio.get("id"))) {
serviciosExtras += messageSource.getMessage(
"presupuesto.extras-" + servicio.get("id"), null, locale)
+ ", ";
} else {
serviciosExtras += messageSource.getMessage(
"presupuesto.extras-" + servicio.get("id"), null, locale)
.toLowerCase() + ", ";
}
}
if (!serviciosExtras.isEmpty()) {
serviciosExtras = serviciosExtras.substring(0, serviciosExtras.length() - 2);;
serviciosExtras = serviciosExtras.substring(0, serviciosExtras.length() - 2);
;
}
if (servicios.stream().anyMatch(service -> "marcapaginas".equals(service.get("id")))) {
ObjectMapper mapperServicio = new ObjectMapper();

View File

@ -113,8 +113,12 @@ public class SecurityConfig {
RequestMatcher notStatic = new AndRequestMatcher(
new NegatedRequestMatcher(PathRequest.toStaticResources().atCommonLocations()),
new NegatedRequestMatcher(pathStartsWith("/assets/")));
RequestMatcher cartCount = new AndRequestMatcher(
new NegatedRequestMatcher(PathRequest.toStaticResources().atCommonLocations()),
new NegatedRequestMatcher(pathStartsWith("/cart/count")));
cache.setRequestMatcher(new AndRequestMatcher(htmlPage, nonAjax, notStatic, notWellKnown));
cache.setRequestMatcher(new AndRequestMatcher(htmlPage, nonAjax, notStatic, notWellKnown, cartCount));
rc.requestCache(cache);
})
// ========================================================
@ -135,7 +139,8 @@ public class SecurityConfig {
"/presupuesto/public/**",
"/error",
"/favicon.ico",
"/.well-known/**" // opcional
"/.well-known/**", // opcional
"/api/pdf/presupuesto/**"
).permitAll()
.requestMatchers("/users/**").hasAnyRole("SUPERADMIN", "ADMIN")
.anyRequest().authenticated())

View File

@ -118,7 +118,7 @@ public class PdfService {
model.put("empresa", empresa);
model.put("cliente", Map.of(
"nombre", presupuesto.getUser().getFullName()));
"nombre", presupuesto.getUser() != null ? presupuesto.getUser().getFullName() : ""));
model.put("titulo", presupuesto.getTitulo());

View File

@ -38,8 +38,8 @@ public class PresupuestoFormatter {
Object[] args = {
p.getSelectedTirada(),
encuadernacion,
tipoImpresion,
encuadernacion.toLowerCase(),
tipoImpresion.toLowerCase(),
(p.getPaginasColorTotal() != null ? p.getPaginasColorTotal() : p.getPaginasColor())
+ p.getPaginasNegro(),
p.getAncho(), p.getAlto(),