diff --git a/src/main/java/com/imprimelibros/erp/pdf/TemplateRegistry.java b/src/main/java/com/imprimelibros/erp/pdf/TemplateRegistry.java
index 71f19c1..12008f7 100644
--- a/src/main/java/com/imprimelibros/erp/pdf/TemplateRegistry.java
+++ b/src/main/java/com/imprimelibros/erp/pdf/TemplateRegistry.java
@@ -8,7 +8,6 @@ public class TemplateRegistry {
public TemplateRegistry(PdfModuleConfig config) {
this.config = config;
- System.out.println("PDF templates registrados => " + config.getTemplates());
}
public String resolve(DocumentType type, String templateId) {
diff --git a/src/main/resources/i18n/pdf_en.properties b/src/main/resources/i18n/pdf_en.properties
new file mode 100644
index 0000000..e69de29
diff --git a/src/main/resources/i18n/pdf_es.properties b/src/main/resources/i18n/pdf_es.properties
new file mode 100644
index 0000000..4b71644
--- /dev/null
+++ b/src/main/resources/i18n/pdf_es.properties
@@ -0,0 +1,21 @@
+pdf.company.name=Impresión ImprimeLibros S.L.
+pdf.company.address=C/ José Picón, 28 local A
+pdf.company.postalcode=28028
+pdf.company.city=Madrid
+pdf.company.phone=+34 910052574
+
+pdf.presupuesto=PRESUPUESTO
+pdf.factura=FACTURA
+pdf.pedido=PEDIDO
+
+# Presupuesto
+pdf.presupuesto.number=PRESUPUESTO Nº:
+pdf.presupuesto.client=CLIENTE:
+pdf.presupuesto.date=FECHA:
+
+pdf.presupuesto.titulo=Título:
+
+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
+pdf.politica-privacidad.aviso=Le comunicamos que los datos que usted nos facilite quedarán incorporados en nuestro registro interno de actividades de tratamiento con el fin de llevar a cabo una adecuada gestión fiscal y contable. Los datos proporcionados se conservarán mientras se mantenga la relación comercial o durante los años necesarios para cumplir con las obligaciones legales. Así mismo, los datos no serán cedidos a terceros salvo en aquellos casos en que exista una obligación legal. Tiene derecho a acceder a sus datos personales, rectificar los datos inexactos, solicitar su supresión, limitar alguno de los tratamientos u oponerse a algún uso vía e-mail, personalmente o mediante correo postal.
\ No newline at end of file
diff --git a/src/main/resources/i18n/presupuesto_es.properties b/src/main/resources/i18n/presupuesto_es.properties
index f6d2736..f05835b 100644
--- a/src/main/resources/i18n/presupuesto_es.properties
+++ b/src/main/resources/i18n/presupuesto_es.properties
@@ -72,6 +72,15 @@ presupuesto.espiral-descripcion=Espiral (a partir de 20 páginas)
presupuesto.wire-o=Wire-O
presupuesto.wireo=Wire-O
presupuesto.wire-o-descripcion=Wire-O (a partir de 20 páginas)
+presupuesto.informacion-adicional=Información adicional
+presupuesto.informacion-adicional-descripcion=Datos adicionales
+presupuesto.iva-reducido=I.V.A reducido
+presupuesto.iva-reducido-descripcion=Se verificará que el pedido cumpla con los requisitos establecidos en el Artículo 91 de la Ley 37/1992, sobre inserción de publicidad, antes de proceder con su producción, lo que garantiza la aplicación del IVA reducido del 4%.
+presupuesto.entrega=Entrega
+presupuesto.entrega.peninsula=Península y Baleares
+presupuesto.entrega.canarias=Canarias
+presupuesto.entrega.paises-ue=Países UE
+
presupuesto.encuadernacion-descripcion=Seleccione la encuadernación del libro
presupuesto.continuar-interior=Continuar a diseño interior
diff --git a/src/main/resources/static/assets/css/bootstrap-for-pdf.css b/src/main/resources/static/assets/css/bootstrap-for-pdf.css
new file mode 100644
index 0000000..598f91e
--- /dev/null
+++ b/src/main/resources/static/assets/css/bootstrap-for-pdf.css
@@ -0,0 +1,59 @@
+/* =======================
+ Bootstrap for PDF (compatible con OpenHTMLtoPDF)
+ ======================= */
+
+/* -- TEXT ALIGN -- */
+.text-start { text-align: left !important; }
+.text-center { text-align: center !important; }
+.text-end { text-align: right !important; }
+
+/* -- FONT WEIGHT -- */
+.fw-normal { font-weight: 400 !important; }
+.fw-semibold { font-weight: 600 !important; }
+.fw-bold { font-weight: 700 !important; }
+
+/* -- SPACING (margin/padding) -- */
+.mt-1 { margin-top: 0.25rem !important; }
+.mt-2 { margin-top: 0.5rem !important; }
+.mt-3 { margin-top: 1rem !important; }
+.mb-1 { margin-bottom: 0.25rem !important; }
+.mb-2 { margin-bottom: 0.5rem !important; }
+.mb-3 { margin-bottom: 1rem !important; }
+
+.p-1 { padding: 0.25rem !important; }
+.p-2 { padding: 0.5rem !important; }
+.p-3 { padding: 1rem !important; }
+
+/* -- TABLE -- */
+.table {
+ width: 100%;
+ border-collapse: collapse;
+ font-size: 10.5pt;
+}
+
+.table th,
+.table td {
+ padding: 6px;
+ border: 1px solid #dee2e6;
+}
+
+.table thead th {
+ background-color: #f8f9fa;
+ font-weight: 700;
+}
+
+/* -- BORDER -- */
+.border {
+ border: 1px solid #dee2e6 !important;
+}
+
+.border-0 { border: 0 !important; }
+
+/* -- BACKGROUND -- */
+.bg-light { background-color: #f8f9fa !important; }
+.bg-white { background-color: #fff !important; }
+
+/* -- DISPLAY UTILS (limited) -- */
+.d-block { display: block !important; }
+.d-inline { display: inline !important; }
+.d-inline-block { display: inline-block !important; }
diff --git a/src/main/resources/static/assets/css/presupuestador.css b/src/main/resources/static/assets/css/presupuestador.css
index 6d6a116..060f000 100644
--- a/src/main/resources/static/assets/css/presupuestador.css
+++ b/src/main/resources/static/assets/css/presupuestador.css
@@ -414,6 +414,7 @@
.form-switch-presupuesto .form-check-input:checked {
border-color: #92b2a7;
+ background-color: #cbcecd;
}
.form-switch-custom.form-switch-presupuesto .form-check-input:checked::before {
diff --git a/src/main/resources/static/assets/css/presupuestopdf.css b/src/main/resources/static/assets/css/presupuestopdf.css
index 1b1063a..165d183 100644
--- a/src/main/resources/static/assets/css/presupuestopdf.css
+++ b/src/main/resources/static/assets/css/presupuestopdf.css
@@ -1,54 +1,169 @@
+:root {
+ --verde: #92b2a7;
+ --letterspace: 8px;
+ /* ← puedes ajustar este valor en el root */
+ -ink: #1b1e28;
+ --muted: #5b6472;
+ --accent: #0ea5e9;
+ /* azul tira a cyan */
+ --line: #e6e8ef;
+ --bg-tag: #f4f7fb;
+}
+
/* Open Sans (rutas relativas desde css → fonts) */
@font-face {
font-family: "Open Sans";
src: url("../fonts/OpenSans-Regular.ttf") format("truetype");
font-weight: 400;
}
+
@font-face {
font-family: "Open Sans";
src: url("../fonts/OpenSans-SemiBold.ttf") format("truetype");
font-weight: 600;
}
+
@font-face {
font-family: "Open Sans";
src: url("../fonts/OpenSans-Bold.ttf") format("truetype");
font-weight: 700;
}
-:root {
- --ink: #1b1e28;
- --muted: #5b6472;
- --accent: #0ea5e9; /* azul tira a cyan */
- --line: #e6e8ef;
- --bg-tag: #f4f7fb;
-}
@page {
size: A4;
- margin: 15mm 14mm 18mm 14mm;
- @bottom-right { content: "Página " counter(page) " / " counter(pages); }
+ margin: 0;
}
-html, body {
- font-family: "Open Sans", Arial, sans-serif;
+html,
+body {
+ font-family: "Open Sans" !important;
color: var(--ink);
font-size: 11pt;
line-height: 1.35;
}
-/* Top band */
-.topbar {
- display: table;
- width: 100%;
- border-bottom: 2px solid var(--accent);
- padding-bottom: 6mm;
- margin-bottom: 6mm;
+.page-content {
+ padding: 15mm 14mm 28mm 14mm; /* ↑ deja 10mm extra para no pisar el footer */
+ box-sizing: border-box; /* para que el padding no desborde */
}
-.brand { display: table-cell; width: 60%; vertical-align: top; }
-.logo { height: 30px; display: block; margin-bottom: 4px; }
-.brand-name { font-weight: 700; }
-.brand-meta { color: var(--muted); font-size: 9.5pt; }
-.doc-title { display: table-cell; width: 40%; text-align: right; font-weight: 700; letter-spacing: 3px; }
+
+
+body.has-watermark {
+ background-image: none !important;
+}
+
+/* ====== HEADER (tabla) ====== */
+.il-header {
+ width: 100%;
+ border-collapse: collapse;
+ margin: 0 0 8mm 0;
+ /* ↓ espacio bajo el header */
+}
+
+.il-left,
+.il-right {
+ vertical-align: middle;
+}
+
+.il-left {
+ width: 50%;
+}
+
+.il-right {
+ width: 50%;
+ text-align: right;
+}
+
+.il-logo {
+ height: 70px;
+}
+
+/* ← tamaño logo */
+
+/* Caja superior derecha con esquinas */
+.il-company-box {
+ display: inline-block;
+ align-items: end;
+ /* para alinear a la derecha sin ocupar todo */
+ position: relative;
+ padding: 4mm 4mm;
+ /* ← espacio texto ↔ esquinas */
+ color: #000;
+ font-size: 10.5pt;
+ /* ← tamaño de letra */
+ line-height: 1;
+ /* ← separación entre líneas */
+ max-width: 75mm;
+ /* ← ancho máximo de la caja */
+ text-align: center;
+}
+
+/* Esquinas */
+.il-company-box .corner {
+ position: absolute;
+ width: 20px;
+ /* ← anchura esquina */
+ height: 20px;
+ /* ← altura esquina */
+ border-color: #92b2a7;
+ /* ← color esquina */
+}
+
+.corner.tl {
+ top: 0;
+ left: 0;
+ border-top: 2px solid #92b2a7;
+ border-left: 2px solid #92b2a7;
+}
+
+.corner.tr {
+ top: 0;
+ right: 0;
+ border-top: 2px solid #92b2a7;
+ border-right: 2px solid #92b2a7;
+}
+
+.corner.bl {
+ bottom: 0;
+ left: 0;
+ border-bottom: 2px solid #92b2a7;
+ border-left: 2px solid #92b2a7;
+}
+
+.corner.br {
+ bottom: 0;
+ right: 0;
+ border-bottom: 2px solid #92b2a7;
+ border-right: 2px solid #92b2a7;
+}
+
+
+.company-line {
+ margin: 1.5mm 0;
+}
+
+
+
+/* Nueva banda verde PRESUPUESTO */
+.doc-banner {
+ width: 100%;
+ background-color: #92b2a7 !important; /* ← tu verde corporativo */
+ color: white;
+ text-align: center;
+ padding: 2mm 0;
+ margin-bottom: 4mm;
+ display: block; /* evita conflictos */
+}
+
+.banner-text {
+ font-family: "Open Sans", Arial, sans-serif !important;
+ font-weight: 400;
+ font-size: 20pt;
+ letter-spacing: 8px; /* ← configurable */
+}
+
+
/* ficha superior */
.sheet-info {
@@ -57,41 +172,99 @@ html, body {
margin: 4mm 0 6mm 0;
font-size: 10.5pt;
}
+
.sheet-info td {
border: 1px solid var(--line);
padding: 4px 6px;
}
-.sheet-info .lbl { color: var(--muted); margin-right: 4px; }
-.sheet-info .val { font-weight: 700; }
+
+.sheet-info .lbl {
+ color: var(--muted);
+ margin-right: 4px;
+}
+
+/*.sheet-info .val {
+}*/
/* Línea título libro */
.line-title {
+ font-family: "Open Sans", Arial, sans-serif !important;
margin: 3mm 0 5mm 0;
- padding: 4px 6px;
- background: var(--bg-tag);
- border-left: 3px solid var(--accent);
+ padding: 2px 4px;
font-size: 10.5pt;
+ font-weight: 600;
+ color: #5c5c5c;
+}
+
+.line-title .lbl {
+ margin-right: 6px;
+ font-weight: 600;
}
-.line-title .lbl { color: var(--muted); margin-right: 6px; font-weight: 600; }
/* Specs 2 columnas */
-.specs { display: table; width: 100%; table-layout: fixed; margin-bottom: 6mm; }
-.specs .col { display: table-cell; width: 50%; padding-right: 6mm; vertical-align: top; }
-.specs .col:last-child { padding-right: 0; }
+.specs-wrapper {
+ width: 180mm;
+ margin-left: 15mm; /* ← margen izquierdo real del A4 */
+ margin-right: auto; /* opcional */
+ color: #5c5c5c;
+}
+
+.align-with-text {
+ margin-left: 1mm;
+ margin-right: 0;
+ width: auto;
+}
+
+.specs {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ margin-bottom: 6mm;
+}
+.specs .col {
+ display: table-cell;
+ width: 50%;
+ padding-right: 6mm;
+ vertical-align: top;
+}
+.specs .col:last-child {
+ padding-right: 0;
+}
+
.block-title {
text-transform: uppercase;
font-weight: 700;
color: var(--accent);
- font-size: 10pt;
+ font-size: 8pt;
margin: 2mm 0 1mm 0;
}
-.kv { margin: 1mm 0; }
-.kv span { color: var(--muted); display: inline-block; min-width: 55%; }
-.kv b { font-weight: 600; }
-.subblock { margin-top: 3mm; }
-.services { margin: 0; padding-left: 14px; }
-.services li { margin: 1mm 0; }
+.kv {
+ margin: 1mm 0;
+}
+
+.kv span {
+ color: var(--muted);
+ display: inline-block;
+ min-width: 55%;
+}
+
+.kv b {
+ font-weight: 600;
+}
+
+.subblock {
+ margin-top: 3mm;
+}
+
+.services {
+ margin: 0;
+ padding-left: 14px;
+}
+
+.services li {
+ margin: 1mm 0;
+}
/* Bloque marcapáginas */
.bookmark {
@@ -100,8 +273,10 @@ html, body {
padding: 3mm;
background: #fff;
}
+
.bookmark .bk-title {
- font-weight: 700; margin-bottom: 2mm;
+ font-weight: 700;
+ margin-bottom: 2mm;
}
/* Tabla de precios (tiradas) */
@@ -111,6 +286,7 @@ html, body {
margin-top: 6mm;
font-size: 10.5pt;
}
+
.prices thead th {
text-align: left;
padding: 6px;
@@ -118,27 +294,81 @@ html, body {
background: #eef8fe;
font-weight: 700;
}
+
.prices tbody td {
border-bottom: 1px solid var(--line);
padding: 6px;
}
-.prices .col-tirada { width: 22%; font-weight: 700; }
+
+.prices .col-tirada {
+ width: 22%;
+ font-weight: 700;
+}
/* Footer */
+
.footer {
- margin-top: 8mm;
+ position: fixed;
+ left: 14mm;
+ right: 14mm;
+ bottom: 18mm;
border-top: 1px solid var(--line);
padding-top: 4mm;
- display: table;
- width: 100%;
- font-size: 9.5pt;
+ font-size: 7.5pt;
+ color: var(--muted);
+ z-index: 10; /* sobre la marca */
+ background: transparent;
+}
+
+
+.footer .address {
+ display: table-cell;
+ width: 45%;
+}
+
+.footer .privacy {
+ display: table-cell;
+ width: 55%;
+}
+
+.pv-title {
+ font-weight: 700;
+ margin-bottom: 1mm;
+ color: var(--ink);
+}
+
+.pv-text {
+ line-height: 1.25;
+}
+
+.page-count {
+ margin-top: 2mm;
+ text-align: right;
+ font-size: 9pt;
color: var(--muted);
}
-.footer .address { display: table-cell; width: 45%; }
-.footer .privacy { display: table-cell; width: 55%; }
-.pv-title { font-weight: 700; margin-bottom: 1mm; color: var(--ink); }
-.pv-text { line-height: 1.25; }
-.page-count { margin-top: 2mm; text-align: right; font-size: 9pt; color: var(--muted); }
-.page::after { content: counter(page); }
-.pages::after { content: counter(pages); }
+.page::after {
+ content: counter(page);
+}
+
+.pages::after {
+ content: counter(pages);
+}
+
+/* Caja a página completa SIN vw/vh y SIN z-index negativo */
+.watermark {
+ position: fixed;
+ top: 0; left: 0; right: 0; bottom: 0; /* ocupa toda la HOJA */
+ pointer-events: none;
+ z-index: 0; /* debajo del contenido */
+}
+
+.watermark img {
+ position: absolute;
+ top: 245mm; /* baja/sube (70–85%) */
+ left: 155mm; /* desplaza a la derecha si quieres */
+ transform: translate(-50%, -50%) rotate(-15deg);
+ width: 60%; /* tamaño grande, ya no hay recorte por márgenes */
+ max-width: none;
+}
diff --git a/src/main/resources/static/assets/images/logo-watermark.png b/src/main/resources/static/assets/images/logo-watermark.png
new file mode 100644
index 0000000..87a3522
Binary files /dev/null and b/src/main/resources/static/assets/images/logo-watermark.png differ
diff --git a/src/main/resources/templates/imprimelibros/pdf/presupuesto-a4.html b/src/main/resources/templates/imprimelibros/pdf/presupuesto-a4.html
index 6e58aeb..06f4e45 100644
--- a/src/main/resources/templates/imprimelibros/pdf/presupuesto-a4.html
+++ b/src/main/resources/templates/imprimelibros/pdf/presupuesto-a4.html
@@ -1,142 +1,199 @@
+
Presupuesto
+
-
-
-
-
-

-
-
ImprimeLibros ERP
-
- C. José Picón, 28 local A · 28028 Madrid
- · 910052574
- · info@imprimelibros.com
- · B04998886
-
-
-
-
P R E S U P U E S T O
+
+
+
+
+
-
-
-
- | PRESUPUESTO Nº: 153153 |
- CLIENTE: JUAN JOSÉ MÉNDEZ |
- FECHA: 10/10/2025 |
-
-
+
+
-
-
- Título:
- Libro de prueba
-
-
-
-
-
-
Encuadernación
-
Encuadernación:Fresado
-
Formato:
- 148x210 mm
-
-
Páginas:132
-
Páginas Negro:100
-
Páginas Color:32
-
-
-
Interior
-
Tipo de impresión:Color Premium
-
Papel interior:Estucado Mate
-
Gramaje interior:115
-
-
-
-
-
-
Cubierta
-
Tipo de cubierta:Tapa blanda
-
Solapas:Sí
-
Tamaño solapas:80 mm
-
Impresión:Una cara
-
Papel cubierta:Estucado mate
-
Gramaje cubierta:250
-
Acabado:Plastificado Brillo 1/C
-
-
-
-
Servicios Extras
-
-
-
- -
- Ferro Digital
- 0,00 €
-
-
-
-
-
-
-
Marcapáginas
-
Tamaño:50x210
-
Papel:Estucado mate 300 g
-
Impresión:Una cara
-
Plastificado:Brillo 1/C
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ | PRESUPUESTO Nº: 153153 |
+ CLIENTE: JUAN JOSÉ
+ MÉNDEZ |
+ FECHA: 10/10/2025 |
-
-
+
+
+
+
+ Título:
+ Libro de prueba
+
+
+
+
+
+
+
Encuadernación
+
Encuadernación:Fresado
+
Formato:
+ 148x210 mm
+
+
Páginas:132
+
Páginas Negro:100
+
Páginas Color:32
+
+
+
Interior
+
Tipo de impresión:Color
+ Premium
+
Papel interior:Estucado
+ Mate
+
+
Gramaje interior:115
+
+
+
+
+
+
Cubierta
+
Tipo de cubierta:Tapa
+ blanda
+
+
Solapas:Sí
+
Tamaño solapas:80 mm
+
Impresión:Una cara
+
Papel cubierta:Estucado
+ mate
+
+
Gramaje cubierta:250
+
Acabado:Plastificado
+ Brillo 1/C
+
+
+
+
Servicios Extras
+
+
+
+ -
+ Ferro Digital
+ 0,00 €
+
+
+
+
+
+
+
Marcapáginas
+
Tamaño:50x210
+
Papel:Estucado
+ mate
+ 300 g
+
Impresión:Una cara
+
+
Plastificado:Brillo
+ 1/C
+
+
+
+
+
+
+
+
+
+
+ | TIRADA |
+ IMPRESIÓN |
+ IVA |
+ TOTAL |
+ UNIDAD |
+
+
+
+
+ | 100 uds. |
+ 152,15€ |
+ 7,68€ |
+ 159,99€ |
+ 1,52€ |
+
+
+
+
+
+
+ | Sin datos de tiradas. |
+
+
+
+
+
+