primera version final del presupuesto

This commit is contained in:
2025-10-17 09:21:31 +02:00
parent ea8a005cde
commit 46715d1017
11 changed files with 323 additions and 73 deletions

View File

@ -14,6 +14,7 @@ pdf.presupuesto.client=CLIENTE:
pdf.presupuesto.date=FECHA:
pdf.presupuesto.titulo=Título:
pdf.presupuesto.descripcion=Descripción:
pdf.table.tirada=TIRADA
pdf.table.impresion=IMPRESIÓN
@ -22,6 +23,11 @@ pdf.table.iva-4=IVA 4%
pdf.table.iva-21=IVA 21%
pdf.table.precio-total=PRECIO TOTAL
pdf.servicios-adicionales=<u>Servicios adicionales:</u>
pdf.ejemplares-deposito-legal=Impresión de {0} ejemplares de depósito legal<br />
pdf.datos-maquetacion=Datos de maquetación:
pdf.datos-marcapaginas=Datos de marcapáginas:
pdf.politica-privacidad=Política de privacidad
pdf.politica-privacidad.responsable=Responsable: Impresión Imprime Libros - CIF: B04998886 - Teléfono de contacto: 910052574
pdf.politica-privacidad.correo-direccion=Correo electrónico: info@imprimelibros.com - Dirección postal: Calle José Picón, Nº 28 Local A, 28028, Madrid

View File

@ -187,6 +187,7 @@ presupuesto.extras=Servicios Extras
presupuesto.extras-descripcion=Seleccione los servicios adicionales que desea añadir al presupuesto
presupuesto.extras-retractilado=Retractilado
presupuesto.extras-isbn=ISBN
presupuesto.extras-service-isbn=ISBN
presupuesto.extras-deposito-legal=Depósito Legal
presupuesto.extras-deposito-legal-descripcion=Se añadirán 4 ejemplares a la tirada
presupuesto.extras-revision-archivos=Revisión de archivos

View File

@ -207,6 +207,7 @@ body.has-watermark {
margin-left: 15mm; /* ← margen izquierdo real del A4 */
margin-right: auto; /* opcional */
color: #5c5c5c;
font-size: 9pt;
}
.align-with-text {
@ -231,6 +232,26 @@ body.has-watermark {
padding-right: 0;
}
/* Listas sin margen superior por defecto */
ul, ol {
margin-top: 0;
margin-bottom: 0rem; /* si quieres algo abajo */
padding-left: 1.25rem; /* sangría */
}
/* Párrafos con menos margen inferior */
p {
margin: 0 0 .5rem;
}
/* Si una lista va justo después de un texto o título, que no tenga hueco arriba */
p + ul, p + ol,
h1 + ul, h2 + ul, h3 + ul, h4 + ul, h5 + ul, h6 + ul,
div + ul, div + ol {
margin-top: 0;
}
.block-title {
text-transform: uppercase;
font-weight: 700;
@ -289,20 +310,20 @@ body.has-watermark {
.prices thead th {
text-align: left;
padding: 6px;
padding: 3px;
border-bottom: 2px solid var(--accent);
background: #eef8fe;
font-weight: 700;
font-weight: 500;
}
.prices tbody td {
border-bottom: 1px solid var(--line);
padding: 6px;
padding: 3px;
}
.prices .col-tirada {
width: 22%;
font-weight: 700;
font-weight: 500;
}
/* Footer */

View File

@ -68,17 +68,37 @@
<span class="val" th:text="${titulo} ?: '-'">Libro de prueba</span>
</div>
<!-- DATOS TÉCNICOS EN 2 COLUMNAS -->
<!-- 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:utext="${especificaciones} ?: '<em>Sin especificaciones técnicas.</em>'">
<div th:if="${specs} == null">
<em>Sin especificaciones técnicas.</em>
</div>
</div>
</div> <!-- .specs-wrapper -->
<div th:if="${specs} != null">
<div th:each="spec : ${specs.lineas}" class="spec-row mb-1">
<span class="spec-label" th:utext="${spec.descripcion}"></span>
</div>
<div th:if="${specs.servicios != null}" class="spec-row mb-1">
<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">
<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">
<span th:text="#{pdf.datos-marcapaginas}">Datos de marcapáginas:</span>
<span th:utext="${specs.datosMarcapaginas}"></span>
</div>
</div> <!-- .specs -->
</div> <!-- .specs-wrapper -->
</div>
<!-- TABLA TIRADAS -->
<table class="prices">
<table class="prices" class="align-items-center">
<thead>
<tr>
<th class="text-center col-tirada" th:text="#{pdf.table.tirada}">TIRADA</th>

View File

@ -1,57 +1,46 @@
<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)" class="buttons-bar mt-2">
<!-- Fila 1: ACCIONES, centradas -->
<div class="buttons-row center" th:if="${showActions}">
<button th:if="${appMode == 'add' or appMode == 'edit'}"
type="button"
class="btn btn-secondary d-flex align-items-center mx-2 guardar-presupuesto">
<button th:if="${appMode == 'add' or appMode == 'edit'}" type="button"
class="btn btn-secondary d-flex align-items-center mx-2 guardar-presupuesto">
<i class="ri-save-3-line me-2"></i>
<span th:text="#{presupuesto.guardar}">Guardar</span>
</button>
<button th:if="${appMode == 'add' or appMode == 'edit'}"
type="button"
class="btn btn-secondary d-flex align-items-center mx-2 add-cart-btn">
<i class="ri-shopping-cart-line me-2"></i>
<span th:text="#{presupuesto.add-to-cart}">Añadir a la cesta</span>
</button>
<button type="button"
class="btn btn-secondary d-flex align-items-center mx-2 btn-imprimir">
<button 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>
<!-- Alternativa cuando no está autenticado -->
<button sec:authorize="!isAuthenticated()"
type="button"
class="btn btn-secondary d-flex align-items-center btn-login-required ms-2">
<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>
<button th:if="${appMode == 'add' or appMode == 'edit'}" type="button"
class="btn btn-secondary d-flex align-items-center mx-2 add-cart-btn">
<i class="ri-shopping-cart-line me-2"></i>
<span th:text="#{presupuesto.add-to-cart}">Añadir a la cesta</span>
</button>
<!-- Alternativa cuando no está autenticado -->
<button sec:authorize="!isAuthenticated()" type="button"
class="btn btn-secondary d-flex align-items-center btn-login-required ms-2">
<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>
<!-- Fila 2: PREV (izq) / NEXT o LOGIN (dcha) -->
<div class="buttons-row split">
<button th:if="${showPrev}"
th:id="|${btnClass}-prev|"
data-btn-action="previous"
th:class="'btn btn-light ' + ${btnClass}"
type="button">
<button th:if="${showPrev}" th:id="|${btnClass}-prev|" data-btn-action="previous"
th:class="'btn btn-light ' + ${btnClass}" type="button">
<i class="ri-arrow-left-circle-line label-icon align-middle fs-16 me-2"></i>
<span th:text="#{app.acciones.anterior}">Anterior</span>
</button>
<div class="right-slot d-flex align-items-center">
<button th:if="${showNext}"
data-btn-action="next"
th:id="|${btnClass}-next|"
th:class="'btn btn-secondary d-flex align-items-center ' + ${btnClass}"
type="button">
<button th:if="${showNext}" data-btn-action="next" th:id="|${btnClass}-next|"
th:class="'btn btn-secondary d-flex align-items-center ' + ${btnClass}" type="button">
<span th:text="#{app.acciones.siguiente}">Siguiente</span>
<i class="ri-arrow-right-circle-line fs-16 ms-2"></i>
</button>
</div>
</div>
</div>
</div>