terminado resumen

This commit is contained in:
2025-09-23 21:51:51 +02:00
parent 0d205f9488
commit bdfafea458
4 changed files with 122 additions and 7 deletions

View File

@ -783,6 +783,9 @@ public class PresupuestoService {
Presupuesto pressupuestoTemp = presupuesto.clone();
resumen.put("imagen", "/assets/images/imprimelibros/presupuestador/" + presupuesto.getTipoEncuadernacion() + ".png");
resumen.put("imagen_alt", messageSource.getMessage("presupuesto." + presupuesto.getTipoEncuadernacion(), null, locale));
boolean hayDepositoLegal = servicios != null && servicios.stream()
.map(m -> java.util.Objects.toString(m.get("id"), "")) // null-safe -> String
.map(String::trim)
@ -823,6 +826,18 @@ public class PresupuestoService {
counter++;
}
List<Map<String, Object>> serviciosExtras = new ArrayList<>();
if(servicios != null){
for (Map<String, Object> servicio : servicios) {
HashMap<String, Object> servicioData = new HashMap<>();
servicioData.put("descripcion", servicio.get("label"));
servicioData.put("precio", servicio.get("price"));
serviciosExtras.add(servicioData);
}
}
resumen.put("servicios", serviciosExtras);
return resumen;
}

View File

@ -160,6 +160,13 @@ presupuesto.calcular-presupuesto=Calcular presupuesto
presupuesto.consultar-soporte=Consultar con soporte
# Pestaña resumen del presupuesto
presupuesto.resumen.tabla.descripcion=Descripción
presupuesto.resumen.tabla.cantidad=Cantidad
presupuesto.resumen.tabla.precio-unidad=Precio/unidad
presupuesto.resumen.tabla.precio-total=Precio total
presupuesto.resumen.tabla.base=Base
presupuesto.resumen.tabla.iva=I.V.A. (4%)
presupuesto.resumen.tabla.total=Total presupuesto
presupuesto.resumen-texto=Impresion de {0} unidades encuadernadas en {1} en {2} con {3} páginas en formato {4} x {5} mm. \
<ul> \
<li>Papel interior {6} {7} gr.</li> \
@ -171,8 +178,10 @@ presupuesto.resumen-texto-acabado-cubierta= <li>Acabado {0}. </li>
presupuesto.resumen-texto-end=</ul>
presupuesto.resumen-texto-sobrecubierta=<li>Sobrecubierta impresa en {0} {1} gr. <ul><li>Acabado {2}</li><li>Solapas: {3} mm.</li></ul></li>
presupuesto.resumen-texto-faja=<li>Faja impresa en {0} {1} gr. con un alto de {2} mm. <ul><li>Acabado {3}</li><li>Solapas: {4} mm.</li></ul></li>
presupuesto.resumen-deposito-legal=4 ejemplares para el Depósito Legal
presupuesto.resumen-deposito-legal=Ejemplares para el Depósito Legal
presupuesto.volver-extras=Volver a extras
presupuesto.resumen.inicie-sesion=Inicie sesión para continuar
presupuesto.resumen.agregar-cesta=Agregar a la cesta
# Resumen del presupuesto
presupuesto.resumen-presupuesto=Resumen presupuesto

View File

@ -2,7 +2,7 @@ import imagen_presupuesto from "./imagen-presupuesto.js";
import ServiceOptionCard from "./service-option-card.js";
import TiradaCard from "./tirada-price-card.js";
import * as Summary from "./summary.js";
import { bracketPrefix, dotify } from "../utils.js";
import { formateaMoneda } from "../utils.js";
class PresupuestoCliente {
@ -157,6 +157,9 @@ class PresupuestoCliente {
// pestaña extras
this.divExtras = $('#div-extras');
// pestaña resumen
this.tablaResumen = $('#resumen-tabla-final');
// resumen
this.summaryTableInterior = $('#summary-interior');
this.summaryTableCubierta = $('#summary-cubierta');
@ -1394,16 +1397,17 @@ class PresupuestoCliente {
const servicios = [];
$('.service-checkbox:checked').each(function () {
const $servicio = $(this);
const $servicio = $(this);
servicios.push({
id: $servicio.attr('id') ?? $(`label[for="${$servicio.attr('id')}"] .service-title`).text().trim(),
label: $(`label[for="${$servicio.attr('id')}"] .service-title`).text().trim(),
price: $servicio.data('price') ?? $(`label[for="${$servicio.attr('id')}"] .service-price`).text().trim().replace(" " + self.divExtras.data('currency'), ''),
});
});
const body = {
presupuesto: this.#getPresupuestoData(),
servicios: servicios
presupuesto: this.#getPresupuestoData(),
servicios: servicios
};
$.ajax({
@ -1413,7 +1417,7 @@ class PresupuestoCliente {
data: JSON.stringify(body)
}).then((data) => {
$('#resumen-titulo').text(data.titulo);
$('#resumen-texto').html(data.texto);
this.#updateResumenTable(data);
}).catch((error) => {
console.error("Error obtener resumen: ", error);
});
@ -1505,6 +1509,52 @@ class PresupuestoCliente {
});
}
#updateResumenTable(data) {
this.tablaResumen.find('tbody').empty();
const lineas = Object.keys(data).filter(k => k.startsWith("linea")).sort((a, b) => {
const numA = parseInt(a.replace("linea", ""), 10);
const numB = parseInt(b.replace("linea", ""), 10);
return numA - numB;
});
const servicios = data.servicios || [];
let total = 0;
const locale = document.documentElement.lang || 'es-ES';
for (const l of lineas) {
const row = `
<tr>
<td>${l=="linea0" ? `<img style="max-width: 60px; height: auto;" src="${data.imagen}" alt="${data.imagen_alt}" class="img-fluid" />` : ''}</td>
<td>${data[l].descripcion}</td>
<td class="text-center">${data[l].cantidad}</td>
<td class="text-center">${formateaMoneda(data[l].precio_unitario, 4, locale)}</td>
<td class="text-end">${formateaMoneda(data[l].precio_total, 2, locale)}</td>
</tr>
`;
total += data[l].precio_total;
this.tablaResumen.find('tbody').append(row);
}
for (const s of servicios) {
const row = `
<tr>
<td></td>
<td>${s.descripcion}</td>
<td class="text-center">1</td>
<td class="text-center">${formateaMoneda(s.precio, 2, locale)}</td>
<td class="text-end">${formateaMoneda(s.precio, 2, locale)}</td>
</tr>
`;
total += s.precio;
this.tablaResumen.find('tbody').append(row);
}
$('#resumen-base').text(formateaMoneda(total, 2, locale));
$('#resumen-iva').text(formateaMoneda(total * 0.04, 2, locale));
$('#resumen-total').text(formateaMoneda(total * 1.04, 2, locale));
}
/******************************
* END RESUMEN
******************************/

View File

@ -16,7 +16,33 @@
<div class="col-9 mx-auto mt-4">
<h5 id="resumen-titulo" class="text-center"></h5>
<p id="resumen-texto"></p>
<table id="resumen-tabla-final" class="table table-borderless table-striped mt-3"
th:data-currency="#{app.currency}">
<thead>
<tr>
<th></th>
<th th:text="#{presupuesto.resumen.tabla.descripcion}">Descripción</th>
<th th:text="#{presupuesto.resumen.tabla.cantidad}">Cantidad</th>
<th th:text="#{presupuesto.resumen.tabla.precio-unidad}">Precio unitario</th>
<th th:text="#{presupuesto.resumen.tabla.precio-total}">Precio total</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr class="table-active">
<th colspan="4" class="text-end" th:text="#{presupuesto.resumen.tabla.base}">Total</th>
<th class="text-end" id="resumen-base">0,00 €</th>
</tr>
<tr class="table-active">
<th colspan="4" class="text-end" th:text="#{presupuesto.resumen.tabla.iva}">IVA (4%)</th>
<th class="text-end" id="resumen-iva">0,00 €</th>
</tr>
<tr class="table-active">
<th colspan="4" class="text-end" th:text="#{presupuesto.resumen.tabla.total}">Total con IVA</th>
<th class="text-end" id="resumen-total">0,00 €</th>
</tfoot>
</table>
</div>
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
@ -25,5 +51,20 @@
<i class=" ri-arrow-left-circle-line label-icon align-middle fs-16 me-2"></i>
<span th:text="#{presupuesto.volver-extras}">Volver a extras</span>
</button>
<div th:unless="${#authorization.expression('isAuthenticated()')}">
<button id="btn-add-cart" type="button"
class="btn btn-secondary d-flex align-items-center btn-change-tab-resumen">
<i class="mdi mdi-login label-icon align-middle fs-16 me-2"></i>
<span th:text="#{presupuesto.resumen.inicie-sesion}">Inicie sesión para continuar</span>
</button>
</div>
<div th:if="${#authorization.expression('isAuthenticated()')}">
<button id="btn-add-cart" type="button"
class="btn btn-secondary d-flex align-items-center">
<span th:text="#{presupuesto.resumen.agregar-cesta}">Agregar a la cesta</span>
<i class="ri-shopping-cart-2-line fs-16 ms-2"></i>
</button>
</div>
</div>
</div>