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

@ -1,5 +1,7 @@
<!-- _cartItem.html -->
<div th:fragment="cartItem(item)" class="card product mb-3 shadow-sm">
<div th:fragment="cartItem(item)" class="card product mb-3 shadow-sm" th:attr="data-iva-4=${item.iva4},
data-iva-21=${item.iva21},
data-base=${item.base}">
<div class="card-body">
<div class="row gy-3">
@ -25,20 +27,44 @@
</h5>
<!-- Detalles opcionales (ej: cliente, fecha, etc.) -->
<ul class="list-inline text-muted mb-2">
<div th:each="linea : ${item.lineas}">
<ul class="list-inline text-muted mb-1">
<div th:each="linea : ${item.resumen.lineas}">
<li class="list-inline-item me-3">
<div th:utext="${linea['descripcion']}"></div>
</li>
</div>
</ul>
<ul class="list-inline text-muted mb-1" th:if="${item.resumen.servicios != null}">
<span th:utext="#{pdf.servicios-adicionales}">Servicios adicionales</span>
<span class="spec-label" th:text="${item.resumen.servicios}"></span>
</ul>
<ul class="list-inline text-muted mb-1" th:if="${item.resumen != null
and #maps.containsKey(item.resumen, 'datosMaquetacion')
and item.resumen['datosMaquetacion'] != null}">
<li class="list-inline-item spec-row mb-1">
<span th:text="#{pdf.datos-maquetacion}">Datos de maquetación:</span>
<span th:utext="${item.resumen.datosMaquetacion}"></span>
</li>
</ul>
<ul class="list-inline text-muted mb-1" th:if="${item.resumen != null
and #maps.containsKey(item.resumen, 'datosMarcapaginas')
and item.resumen['datosMarcapaginas'] != null}">
<li class="list-inline-item spec-row mb-1">
<span th:text="#{pdf.datos-marcapaginas}">Datos de marcapáginas:</span>
<span th:utext="${item.resumen.datosMarcapaginas}"></span>
</li>
</ul>
</div>
<!-- Precio o totales (si los tienes) -->
<div class="col-sm-auto text-end">
<p class="text-muted mb-1" th:text="#{cart.precio}">Precio</p>
<h5 class="fs-14 mb-0">
<span th:text="${item.total != null ? item.total : '-'}">0,00</span>
<span th:text="${item.baseTotal != null ? item.baseTotal : '-'}">0,00</span>
</h5>
</div>
</div>
@ -50,14 +76,10 @@
<div class="d-flex flex-wrap my-n1">
<!-- Botón eliminar -->
<div>
<form th:action="@{|/cart/${item.cartItemId}/remove|}" method="post" class="d-inline">
<input type="hidden" name="_method" value="delete" />
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<a href="#" class="d-block text-body p-1 px-2"
onclick="this.closest('form').submit(); return false;">
<i class="ri-delete-bin-fill text-muted align-bottom me-1"></i> Eliminar
</a>
</form>
<a href="javascript:void(0);" class="d-block text-body p-1 px-2 delete-item"
th:attr="data-cart-item-id=${item.cartItemId}">
<i class="ri-delete-bin-fill text-muted align-bottom me-1"></i> Eliminar
</a>
</div>
</div>
</div>

View File

@ -32,18 +32,67 @@
</nav>
</div>
<div class="container-fluid">
<div class="container-fluid row gy-4">
<div th:if="${items.isEmpty()}">
<div class="alert alert-info" role="alert" th:text="#{cart.empty}"></div>
</div>
<div th:unless="${#lists.isEmpty(items)}">
<div class="col-xl-8 col-12">
<div th:each="item : ${items}" th:insert="~{imprimelibros/cart/_cartItem :: cartItem(${item})}">
</div>
</div>
<div class="col-xl-4">
<div class="sticky-side-div">
<div class="card">
<div class="card-header border-bottom-dashed">
<h5 th:text="#{cart.resumen.title}" class="card-title mb-0"></h5>
</div>
<div class="card-body pt-2">
<div class="table-responsive">
<table class="table table-borderless mb-0">
<tbody>
<tr>
<td><span th:text="#{cart.resumen.base}"></span></td>
<td class="text-end" id="base-cesta"></td>
</tr>
<tr id="tr-iva-4">
<td><span th:text="#{cart.resumen.iva-4}"></span> : </td>
<td class="text-end" id="iva-4-cesta"></td>
</tr>
<tr id="tr-iva-21">
<td><span th:text="#{cart.resumen.iva-21}"></span> : </td>
<td class="text-end" id="iva-21-cesta"></td>
</tr>
<tr class="table-active">
<th><span th:text="#{cart.resumen.total}"></span>:</th>
<td class="text-end">
<span id="total-cesta" class="fw-semibold">
</span>
</td>
</tr>
</tbody>
</table>
<button type="button" class="btn btn-secondary w-100 mt-2"
th:text="#{cart.resumen.tramitar}">Checkout</button>
</div>
<!-- end table-responsive -->
</div>
</div>
<div class="alert border-dashed alert-danger" role="alert">
<div class="d-flex align-items-center">
<div class="ms-2">
<h5 class="fs-14 text-danger fw-semibold" th:text="#{cart.resumen.fidelizacion}"></h5>
</div>
</div>
</div>
</div>
<!-- end stickey -->
</div>
</div>
</th:block>
<th:block th:replace="~{theme/partials/vendor-scripts :: scripts}" />
@ -51,6 +100,8 @@
<script th:inline="javascript">
window.languageBundle = /*[[${languageBundle}]]*/ {};
</script>
<script type="module" th:src="@{/assets/js/pages/imprimelibros/cart/cart.js}"></script>
</th:block>
</body>

View File

@ -54,9 +54,12 @@
<tr>
<td class="text-start"><span th:text="#{'pdf.presupuesto.number'}" class="lbl">PRESUPUESTO Nº:</span> <span
class="val" th:text="${numero}">153153</span></td>
<td class="text-center"><span th:text="#{pdf.presupuesto.client}" class="lbl">CLIENTE:</span> <span class="val"
<td class="text-center">
<span th:if="${cliente?.nombre} != ''" th:text="#{pdf.presupuesto.client}" class="lbl">CLIENTE:</span> <span class="val"
th:text="${cliente?.nombre} ?: '-'">JUAN JOSÉ
MÉNDEZ</span></td>
MÉNDEZ
</span>
</td>
<td class="text-end"><span class="lbl" th:text="#{pdf.presupuesto.date}">FECHA:</span> <span class="val"
th:text="${#temporals.format(fecha, 'dd/MM/yyyy')}">10/10/2025</span></td>
</tr>
@ -69,9 +72,6 @@
</div>
<!-- DATOS TÉCNICOS -->
<div class="line-title">
<span class="lbl" th:text="#{pdf.presupuesto.descripcion}">Descripción:</span>
</div>
<div class="specs-wrapper align-with-text ">
<div class="specs">
<div th:if="${specs} == null">
@ -85,11 +85,15 @@
<span th:utext="#{pdf.servicios-adicionales}">Servicios adicionales</span>
<span class="spec-label" th:text="${specs.servicios}"></span>
</div>
<div th:if="${specs.datosMaquetacion != null}" class="spec-row mb-1">
<div th:if="${specs != null
and #maps.containsKey(specs, 'datosMaquetacion')
and specs['datosMaquetacion'] != null}" class="spec-row mb-1">
<span th:text="#{pdf.datos-maquetacion}">Datos de maquetación:</span>
<span th:utext="${specs.datosMaquetacion}"></span>
</div>
<div th:if="${specs.datosMarcapaginas != null}" class="spec-row mb-1">
<div th:if="${specs != null
and #maps.containsKey(specs, 'datosMarcapaginas')
and specs['datosMarcapaginas'] != null}" class="spec-row mb-1">
<span th:text="#{pdf.datos-marcapaginas}">Datos de marcapáginas:</span>
<span th:utext="${specs.datosMarcapaginas}"></span>
</div>
@ -98,7 +102,7 @@
</div>
<!-- TABLA TIRADAS -->
<table class="prices" class="align-items-center">
<table class="prices align-items-center">
<thead>
<tr>
<th class="text-center col-tirada" th:text="#{pdf.table.tirada}">TIRADA</th>
@ -133,6 +137,8 @@
<!-- PIE -->
<div class="footer">
<div class="fw-bold fs-6 mb-1" th:text="#{pdf.incluye-envio}">El presupuesto incluye el envío a una dirección de la
península.</div>
<div class="privacy">
<div class="pv-title" th:text="#{pdf.politica-privacidad}">Política de privacidad</div>
<div class="pv-text" th:text="#{pdf.politica-privacidad.responsable}">Responsable: Impresión Imprime Libros -

View File

@ -1,4 +1,4 @@
<div th:fragment="buttons(appMode, btnClass, showPrev, showNext, showActions, showCart)" class="buttons-bar mt-2">
<div th:fragment="buttons(appMode, btnClass, showPrev, showNext, showActions, showCart, showPrint)" class="buttons-bar mt-2">
<!-- Fila 1: ACCIONES, centradas -->
<div class="buttons-row center" th:if="${showActions}">
@ -8,7 +8,7 @@
<span th:text="#{presupuesto.guardar}">Guardar</span>
</button>
<button type="button" class="btn btn-secondary d-flex align-items-center mx-2 btn-imprimir">
<button th:if="${showPrint}" type="button" class="btn btn-secondary d-flex align-items-center mx-2 btn-imprimir">
<i class="ri-printer-line me-2"></i>
<span th:text="#{app.imprimir}">Imprimir</span>
</button>

View File

@ -408,6 +408,11 @@
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-cubierta', true, true, true, false)}"></div>
<div sec:authorize="isAuthenticated()"
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-cubierta', true, true, true, false, true)}">
</div>
<div sec:authorize="!isAuthenticated()"
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-cubierta', true, true, false, false, false)}">
</div>
</div>
</div>

View File

@ -299,7 +299,7 @@
<div
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-datos-generales', false, true, false, false)}">
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-datos-generales', false, true, false, false, false)}">
</div>

View File

@ -17,6 +17,9 @@
<!-- End Ribbon Shape -->
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-extras', true, true, true, false)}"></div>
<div sec:authorize="isAuthenticated()"
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-extras', true, true, true, false, true)}"></div>
<div sec:authorize="!isAuthenticated()"
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-extras', true, true, false, false, false)}"></div>
</div>
</div>

View File

@ -57,8 +57,11 @@
</div>
</div>
<div
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-interior', true, true, true, false)}">
<div sec:authorize="!isAuthenticated()"
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-interior', true, true, false, false, false)}">
</div>
<div sec:authorize="isAuthenticated()"
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-interior', true, true, true, false, true)}">
</div>

View File

@ -51,7 +51,7 @@
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
<div
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-resumen', true, false, true, true)}">
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-resumen', true, false, true, true, true)}">
</div>
</div>
</div>

View File

@ -11,12 +11,10 @@
</div>
<div class="ribbon-content mt-4">
<div id="div-tiradas-error"
class="d-flex justify-content-center mt-4 w-100 d-none">
<div id="div-tiradas-error" class="d-flex justify-content-center mt-4 w-100 d-none">
</div>
<div id="div-tiradas"
class="row row-cols-auto justify-content-center g-4 mx-auto mb-4"
<div id="div-tiradas" class="row row-cols-auto justify-content-center g-4 mx-auto mb-4"
style="max-width:1120px" th:data-per-unit="#{presupuesto.precio-unidad}"
th:data-total="#{presupuesto.total}" th:data-select="#{presupuesto.seleccionar-tirada}"
th:data-selected="#{presupuesto.tirada-seleccionada}" th:data-units="#{presupuesto.unidades}">
@ -27,6 +25,11 @@
<!-- End Ribbon Shape -->
<div class="d-flex justify-content-between align-items-center mt-4 w-100">
<div th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-seleccion-tirada', true, true, true, false)}"></div>
<div sec:authorize="isAuthenticated()"
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-seleccion-tirada', true, true, true, false, true)}">
</div>
<div sec:authorize="!isAuthenticated()"
th:replace="~{imprimelibros/presupuestos/presupuestador-items/_buttons :: buttons(${appMode}, 'btn-change-tab-seleccion-tirada', true, true, false, false, false)}">
</div>
</div>
</div>