assemblerpdf 1.0.6__tar.gz → 1.0.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. {assemblerpdf-1.0.6/src/assemblerpdf.egg-info → assemblerpdf-1.0.8}/PKG-INFO +1 -1
  2. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/pyproject.toml +1 -1
  3. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/assemblers/base.py +57 -1
  4. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/fields/checkbox.html +2 -1
  5. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/fields/radio.html +2 -1
  6. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/layout/style.html +121 -11
  7. assemblerpdf-1.0.8/src/assemblerpdf/templates/assemblerpdf/layout/table.html +33 -0
  8. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/tabla_matriz_riesgo.html +12 -12
  9. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8/src/assemblerpdf.egg-info}/PKG-INFO +1 -1
  10. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf.egg-info/SOURCES.txt +1 -0
  11. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/MANIFEST.in +0 -0
  12. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/README.md +0 -0
  13. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/setup.cfg +0 -0
  14. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/__init__.py +0 -0
  15. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/assemblers/__init__.py +0 -0
  16. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/assemblers/form.py +0 -0
  17. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/assemblers/report.py +0 -0
  18. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/core.py +0 -0
  19. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/fonts/Inter-Bold.ttf +0 -0
  20. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/fonts/Inter-Medium.ttf +0 -0
  21. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/fonts/Inter-Regular.ttf +0 -0
  22. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/img/Logo-unp-rojo.png +0 -0
  23. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/img/logo-mininterior-rojo.jpg +0 -0
  24. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/fields/field_input.html +0 -0
  25. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/fields/field_label.html +0 -0
  26. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/fields/input.html +0 -0
  27. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/fields/textarea.html +0 -0
  28. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/layout/footer.html +0 -0
  29. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/layout/footer_fixed.html +0 -0
  30. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/layout/grid_row.html +0 -0
  31. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/layout/header.html +0 -0
  32. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/layout/section.html +0 -0
  33. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/assemblerpdf/misc/signature.html +0 -0
  34. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/anexos.html +0 -0
  35. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/anexos_limpio.html +0 -0
  36. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/archivese.html +0 -0
  37. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/autoriza_envio.html +0 -0
  38. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/checkbox.html +0 -0
  39. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/control_cambios.html +0 -0
  40. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/datos_basicosinf.html +0 -0
  41. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/datos_ot.html +0 -0
  42. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/encaso_de.html +0 -0
  43. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fiila_dos_check.html +0 -0
  44. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_cinco_zona.html +0 -0
  45. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_cuatro.html +0 -0
  46. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_cuatro_si_no.html +0 -0
  47. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_cuatro_zona.html +0 -0
  48. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_dos.html +0 -0
  49. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_dos_zona.html +0 -0
  50. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_instructivo.html +0 -0
  51. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_tres.html +0 -0
  52. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_tres_checkbox.html +0 -0
  53. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_tres_zona.html +0 -0
  54. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/fila_uno.html +0 -0
  55. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/firma.html +0 -0
  56. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/firma_doble.html +0 -0
  57. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/firmaop2.html +0 -0
  58. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/firmas_oficializacion.html +0 -0
  59. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/hechos_sobrevinientes.html +0 -0
  60. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/hechos_sobrevinientes_vacio.html +0 -0
  61. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/iformfilacuatro.html +0 -0
  62. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/informacion_doble.html +0 -0
  63. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/input_2checks.html +0 -0
  64. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/input_check.html +0 -0
  65. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/input_checkbox.html +0 -0
  66. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/input_solitario.html +0 -0
  67. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/label_input_dos.html +0 -0
  68. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/leyenda_autoriza_correo.html +0 -0
  69. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/leyenda_superiol.html +0 -0
  70. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/logos.html +0 -0
  71. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/manifiesto.html +0 -0
  72. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/notificacion_correo.html +0 -0
  73. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/oficializacion.html +0 -0
  74. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/pregunta_si_no.html +0 -0
  75. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/pregunta_tresopciones.html +0 -0
  76. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/qr_oficializacion.html +0 -0
  77. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/situacion_amenaza.html +0 -0
  78. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/style.html +0 -0
  79. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/subtitulo_icono.html +0 -0
  80. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/subtitulo_icono_largo.html +0 -0
  81. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/tabla_doble.html +0 -0
  82. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/tabla_instructivo.html +0 -0
  83. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/tabla_proyeccion.html +0 -0
  84. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/tabla_simple.html +0 -0
  85. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/texarea.html +0 -0
  86. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/tipo_identificacion.html +0 -0
  87. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/tipos_checkbox.html +0 -0
  88. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/titulo.html +0 -0
  89. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/titulo_logo.html +0 -0
  90. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/templates/sistema/titulo_principal.html +0 -0
  91. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/utils/__init__.py +0 -0
  92. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf/utils/template_loader.py +0 -0
  93. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf.egg-info/dependency_links.txt +0 -0
  94. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf.egg-info/requires.txt +0 -0
  95. {assemblerpdf-1.0.6 → assemblerpdf-1.0.8}/src/assemblerpdf.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assemblerpdf
3
- Version: 1.0.6
3
+ Version: 1.0.8
4
4
  Summary: Generador de PDFs usando WeasyPrint, diseñado para formularios y reportes con componentes genéricos.
5
5
  Author-email: EcosistemaUNP <ecosistema@unp.gov.co>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "assemblerpdf"
7
- version = "1.0.6"
7
+ version = "1.0.8"
8
8
  description = "Generador de PDFs usando WeasyPrint, diseñado para formularios y reportes con componentes genéricos."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -2,7 +2,7 @@ import os
2
2
  from assemblerpdf.core import generate_pdf_from_string
3
3
 
4
4
  class BaseFormAssembler:
5
- def __init__(self, context=None, codigo=None, fecha=None, version=None, auto_decorations=True, custom_css_path=None, custom_css_content=None, pdf_forms=False):
5
+ def __init__(self, context=None, codigo=None, fecha=None, version=None, auto_decorations=True, custom_css_path=None, custom_css_content=None, pdf_forms=False, margin_top=None, margin_bottom=None, margin_left=None, margin_right=None, padding_top=None, padding_bottom=None, padding_left=None, padding_right=None):
6
6
  self.context = context or {}
7
7
  self.components = []
8
8
  self.codigo = codigo
@@ -12,6 +12,15 @@ class BaseFormAssembler:
12
12
  self.custom_css_path = custom_css_path
13
13
  self.custom_css_content = custom_css_content
14
14
  self.pdf_forms = pdf_forms
15
+ self.margin_top = margin_top
16
+ self.margin_bottom = margin_bottom
17
+ self.margin_left = margin_left
18
+ self.margin_right = margin_right
19
+ self.padding_top = padding_top
20
+ self.padding_bottom = padding_bottom
21
+ self.padding_left = padding_left
22
+ self.padding_right = padding_right
23
+ self._in_section_block = False
15
24
 
16
25
  def _get_img_base(self):
17
26
  import assemblerpdf
@@ -24,6 +33,7 @@ class BaseFormAssembler:
24
33
  """Renderiza un componente usando Jinja2 (motor nativo de la librería)."""
25
34
  # Unificar contexto
26
35
  full_context = {
36
+ 'interactive': self.pdf_forms,
27
37
  'img_base': self._get_img_base(),
28
38
  'auto_decorations': self.auto_decorations,
29
39
  'codigo': self.codigo,
@@ -31,6 +41,14 @@ class BaseFormAssembler:
31
41
  'version': self.version,
32
42
  'custom_css_path': self.custom_css_path,
33
43
  'custom_css_content': self.custom_css_content,
44
+ 'margin_top': self.margin_top,
45
+ 'margin_bottom': self.margin_bottom,
46
+ 'margin_left': self.margin_left,
47
+ 'margin_right': self.margin_right,
48
+ 'padding_top': self.padding_top,
49
+ 'padding_bottom': self.padding_bottom,
50
+ 'padding_left': self.padding_left,
51
+ 'padding_right': self.padding_right,
34
52
  **self.context,
35
53
  **(extra_context or {}),
36
54
  'disabled': extra_context.get('disabled', False) if extra_context else False,
@@ -50,6 +68,13 @@ class BaseFormAssembler:
50
68
  extra_context (dict): Contexto adicional para el template
51
69
  wrapper_html (str): HTML envolvente opcional
52
70
  """
71
+ if template_name == 'section.html':
72
+ if self._in_section_block:
73
+ self.components.append('</div>')
74
+ self._in_section_block = False
75
+ self.components.append('<div class="keep-together">')
76
+ self._in_section_block = True
77
+
53
78
  rendered = self._render(template_name, extra_context)
54
79
 
55
80
  if wrapper_html:
@@ -89,6 +114,30 @@ class BaseFormAssembler:
89
114
  self.components.append(row_html)
90
115
  return self
91
116
 
117
+ def add_table(self, headers=None, rows=None, titulo=None, class_group=None, style_group=None, extra_context=None):
118
+ """
119
+ Agrega una tabla genérica altamente dinámica y estilizada al documento.
120
+
121
+ Args:
122
+ headers (list): Lista de diccionarios que definen las columnas:
123
+ [{"text": "Col 1", "width": "30%", "align": "left"}, ...]
124
+ rows (list): Lista de diccionarios, cada uno con una lista de celdas:
125
+ [{"cells": [{"content": "Valor 1", "rowspan": 2}, {"content": "Valor 2"}]}]
126
+ titulo (str): Título superior opcional de la tabla.
127
+ class_group (str): Clase CSS adicional para la tabla.
128
+ style_group (str): Estilo inline adicional para la tabla.
129
+ extra_context (dict): Contexto extra
130
+ """
131
+ ctx = {
132
+ 'headers': headers or [],
133
+ 'rows': rows or [],
134
+ 'titulo': titulo,
135
+ 'class_group': class_group,
136
+ 'style_group': style_group,
137
+ **(extra_context or {})
138
+ }
139
+ return self.add_component('table.html', ctx)
140
+
92
141
  def add_raw_html(self, html):
93
142
  """Agrega HTML crudo al documento."""
94
143
  self.components.append(html)
@@ -96,11 +145,18 @@ class BaseFormAssembler:
96
145
 
97
146
  def add_page_break(self):
98
147
  """Inserta un salto de página."""
148
+ if self._in_section_block:
149
+ self.components.append('</div>')
150
+ self._in_section_block = False
99
151
  self.components.append('<div class="page-break"></div>')
100
152
  return self
101
153
 
102
154
  def build(self, pdf_forms=None):
103
155
  """Une todos los componentes renderizados y compila el PDF."""
156
+ if self._in_section_block:
157
+ self.components.append('</div>')
158
+ self._in_section_block = False
159
+
104
160
  # 1. Obtener estilos globales (style.html)
105
161
  head = self._render("style.html")
106
162
 
@@ -1,4 +1,5 @@
1
- <div class="choice-container {{ class_group|default('') }}" style="margin-bottom: {{ margin_bottom|default('8px') }}; {{ style_group|default('') }}">
1
+ {% set is_inline = inline if inline is defined else (opciones|length <= 3) %}
2
+ <div class="choice-container {{ class_group|default('') }} {% if is_inline %}inline-choice{% endif %}" style="margin-bottom: {{ margin_bottom|default('8px') }}; {{ style_group|default('') }}">
2
3
  {% if label %}
3
4
  <label class="form-label {{ class_label|default('') }}" style="{{ style_label|default('') }}">{{ label }}</label>
4
5
  {% endif %}
@@ -1,4 +1,5 @@
1
- <div class="choice-container {{ class_group|default('') }}" style="margin-bottom: {{ margin_bottom|default('8px') }}; {{ style_group|default('') }}">
1
+ {% set is_inline = inline if inline is defined else (opciones|length <= 3) %}
2
+ <div class="choice-container {{ class_group|default('') }} {% if is_inline %}inline-choice{% endif %}" style="margin-bottom: {{ margin_bottom|default('8px') }}; {{ style_group|default('') }}">
2
3
  {% if label %}
3
4
  <label class="form-label {{ class_label|default('') }}" style="{{ style_label|default('') }}">{{ label }}</label>
4
5
  {% endif %}
@@ -35,19 +35,22 @@
35
35
  {% if auto_decorations %}
36
36
  @page {
37
37
  size: letter;
38
- margin-top: 1.5cm;
39
- margin-bottom: 2.2cm; /* Espacio reservado para el footer fijo */
40
- margin-left: 1.2cm;
41
- margin-right: 1.2cm;
38
+ margin-top: {{ margin_top|default('1.5cm') }};
39
+ margin-bottom: {{ margin_bottom|default('2.2cm') }}; /* Espacio reservado para el footer fijo */
40
+ margin-left: {{ margin_left|default('1.2cm') }};
41
+ margin-right: {{ margin_right|default('1.2cm') }};
42
42
  border: 1px solid #303d50;
43
43
  border-radius: 5px;
44
- padding: 15px 15px 5px 15px; /* Espacio interno del borde */
44
+ padding-top: {{ padding_top|default('15px') }};
45
+ padding-bottom: {{ padding_bottom|default('5px') }};
46
+ padding-left: {{ padding_left|default('15px') }};
47
+ padding-right: {{ padding_right|default('15px') }};
45
48
  }
46
49
 
47
50
  /* Pie de página fijo de oficialización */
48
51
  .oficializacion-fija {
49
52
  position: fixed;
50
- bottom: -1.7cm; /* Posicionado dentro del margen inferior */
53
+ bottom: calc(-{{ margin_bottom|default('2.2cm') }} + 0.5cm); /* Posicionado dentro del margen inferior */
51
54
  left: 0;
52
55
  width: 100%;
53
56
  z-index: 9999;
@@ -62,16 +65,20 @@
62
65
  }
63
66
 
64
67
  /* Evitar saltos de página huérfanos dentro de grupos compactos */
65
- .signature-container, .form-group, .choice-container {
68
+ .signature-container, .form-group, .choice-container, .grid-row {
66
69
  page-break-inside: avoid;
67
70
  }
71
+ .keep-together {
72
+ page-break-inside: avoid !important;
73
+ break-inside: avoid !important;
74
+ }
68
75
  {% else %}
69
76
  @page {
70
77
  size: letter;
71
- margin-top: 1.5cm;
72
- margin-bottom: 1.5cm;
73
- margin-left: 1cm;
74
- margin-right: 1cm;
78
+ margin-top: {{ margin_top|default('1.5cm') }};
79
+ margin-bottom: {{ margin_bottom|default('1.5cm') }};
80
+ margin-left: {{ margin_left|default('1cm') }};
81
+ margin-right: {{ margin_right|default('1cm') }};
75
82
  }
76
83
  {% endif %}
77
84
 
@@ -150,6 +157,31 @@
150
157
  margin-bottom: 8px;
151
158
  }
152
159
 
160
+ .choice-container.inline-choice {
161
+ flex-direction: row !important;
162
+ align-items: center !important;
163
+ justify-content: flex-start !important;
164
+ gap: 15px !important;
165
+ }
166
+
167
+ .choice-container.inline-choice .form-label {
168
+ margin-bottom: 0 !important;
169
+ flex: 1 !important;
170
+ padding-right: 10px !important;
171
+ }
172
+
173
+ .choice-container.inline-choice .choice-group {
174
+ margin-top: 0 !important;
175
+ display: inline-block !important;
176
+ flex-shrink: 0 !important;
177
+ white-space: nowrap !important;
178
+ }
179
+
180
+ .choice-container.inline-choice .choice-item {
181
+ margin-bottom: 0 !important;
182
+ margin-right: 16px !important;
183
+ }
184
+
153
185
  .choice-group {
154
186
  display: block;
155
187
  margin-top: 4px;
@@ -159,7 +191,9 @@
159
191
  display: inline-block;
160
192
  vertical-align: middle;
161
193
  margin-right: 16px;
194
+ margin-bottom: 8px;
162
195
  font-size: 11px;
196
+ line-height: 1.6;
163
197
  }
164
198
 
165
199
  .choice-box {
@@ -280,6 +314,39 @@
280
314
  text-transform: uppercase;
281
315
  }
282
316
 
317
+ /* Preset de Título Principal (con fondo azul oscuro y texto blanco) */
318
+ .section-container.main-section-title {
319
+ background-color: #303d50 !important;
320
+ padding: 4px 10px !important;
321
+ border-radius: 4px !important;
322
+ margin-top: 12px !important;
323
+ margin-bottom: 6px !important;
324
+ border-bottom: none !important;
325
+ page-break-after: avoid !important;
326
+ page-break-inside: avoid !important;
327
+ display: block !important;
328
+ }
329
+
330
+ .section-container.main-section-title .section-title {
331
+ color: #ffffff !important;
332
+ font-size: 11px !important;
333
+ }
334
+
335
+ /* Preset de Subtítulo (con icono y espaciado compacto) */
336
+ .section-container.subtitle-section {
337
+ margin-top: 8px !important;
338
+ margin-bottom: 4px !important;
339
+ border-bottom: 1px solid #cbd5e1 !important;
340
+ padding-bottom: 4px !important;
341
+ page-break-after: avoid !important;
342
+ page-break-inside: avoid !important;
343
+ }
344
+
345
+ .section-container.subtitle-section .section-title {
346
+ color: #303d50 !important;
347
+ font-size: 10px !important;
348
+ }
349
+
283
350
  /* ✍️ Firma */
284
351
  .signature-container {
285
352
  display: flex;
@@ -342,6 +409,49 @@
342
409
  width: 20%;
343
410
  }
344
411
 
412
+ /* 📊 Tabla Genérica */
413
+ .table-container {
414
+ width: 100%;
415
+ margin-top: 10px;
416
+ margin-bottom: 10px;
417
+ }
418
+
419
+ .table-title-bar {
420
+ background-color: #303d50;
421
+ padding: 6px 12px;
422
+ border-radius: 4px 4px 0 0;
423
+ }
424
+
425
+ .assembler-table {
426
+ width: 100%;
427
+ border-collapse: collapse;
428
+ border: 1px solid #cbd5e1;
429
+ font-family: 'Inter', sans-serif;
430
+ font-size: 9.5px;
431
+ background-color: #ffffff;
432
+ }
433
+
434
+ .assembler-table th {
435
+ padding: 6px 10px;
436
+ font-weight: bold;
437
+ border: 1px solid #475569;
438
+ background-color: #303d50;
439
+ color: #ffffff;
440
+ font-size: 9.5px;
441
+ }
442
+
443
+ .assembler-table td {
444
+ padding: 6px 10px;
445
+ border: 1px solid #cbd5e1;
446
+ vertical-align: top;
447
+ font-size: 9.5px;
448
+ color: #334155;
449
+ }
450
+
451
+ .assembler-table tr {
452
+ page-break-inside: avoid;
453
+ }
454
+
345
455
  /* Saltos de Página */
346
456
  .page-break {
347
457
  page-break-before: always;
@@ -0,0 +1,33 @@
1
+ <div class="table-container {{ class_group|default('') }}" style="margin-top: {{ margin_top|default('10px') }}; margin-bottom: {{ margin_bottom|default('10px') }}; {{ style_group|default('') }}">
2
+ {% if titulo %}
3
+ <div class="table-title-bar" style="background-color: #303d50; padding: 6px 12px; border-radius: 4px 4px 0 0;">
4
+ <span style="font-size: 11px; font-weight: bold; color: #ffffff; text-transform: uppercase;">{{ titulo }}</span>
5
+ </div>
6
+ {% endif %}
7
+ <table class="assembler-table" style="width: 100%; border-collapse: collapse; border: 1px solid #cbd5e1; font-family: 'Inter', sans-serif; font-size: 9.5px; {% if titulo %}border-top: none; border-radius: 0 0 4px 4px;{% else %}border-radius: 4px;{% endif %} overflow: hidden;">
8
+ {% if headers %}
9
+ <thead>
10
+ <tr style="background-color: #303d50; color: #ffffff;">
11
+ {% for h in headers %}
12
+ <th style="padding: 6px 10px; font-weight: bold; text-align: {{ h.align|default('left') }}; font-size: 9.5px; border: 1px solid #cbd5e1; {% if h.width %}width: {{ h.width }};{% endif %} {{ h.style|default('') }}" {% if h.colspan %}colspan="{{ h.colspan }}"{% endif %} {% if h.rowspan %}rowspan="{{ h.rowspan }}"{% endif %}>
13
+ {{ h.text }}
14
+ </th>
15
+ {% endfor %}
16
+ </tr>
17
+ </thead>
18
+ {% endif %}
19
+ <tbody>
20
+ {% for row in rows %}
21
+ <tr style="{{ row.style|default('') }}">
22
+ {% for cell in row.cells %}
23
+ <td style="padding: 6px 10px; border: 1px solid #cbd5e1; vertical-align: top; text-align: {{ cell.align|default('left') }}; {{ cell.style|default('') }}"
24
+ {% if cell.rowspan %}rowspan="{{ cell.rowspan }}"{% endif %}
25
+ {% if cell.colspan %}colspan="{{ cell.colspan }}"{% endif %}>
26
+ {{ cell.content|safe }}
27
+ </td>
28
+ {% endfor %}
29
+ </tr>
30
+ {% endfor %}
31
+ </tbody>
32
+ </table>
33
+ </div>
@@ -1,6 +1,6 @@
1
- <table style="width: 100%; border-collapse: collapse; margin-top: 10px; page-break-inside: auto; orphans: 3; widows: 3;">
1
+ <table class="matriz-riesgo-table" style="width: 100%; border-collapse: collapse; margin-top: 10px; page-break-inside: auto; orphans: 3; widows: 3;">
2
2
  <!-- Fila de encabezados -->
3
- <tr style="background-color: #303d50; page-break-inside: avoid; break-inside: avoid; display: table-row;">
3
+ <tr class="row-header" style="background-color: #303d50; page-break-inside: avoid; break-inside: avoid; display: table-row;">
4
4
  <td class="celda-i" style="width: 14%; padding: 10px 5px 10px 20px; border: 1px solid #303d50;">
5
5
  <label style="margin-bottom: 0px; font-weight: bold; color: white; font-size: 13px;">Item</label>
6
6
  </td>
@@ -26,7 +26,7 @@
26
26
 
27
27
  <!-- Filas de datos -->
28
28
  {% for fila in filas %}
29
- <tr style="border-bottom: 1px solid #e0e0e0; {% if fila.es_subtotal %}background-color: #f9f9f9;{% endif %} page-break-inside: avoid; break-inside: avoid; display: table-row;">
29
+ <tr style="border-bottom: 1px solid #e0e0e0; {% if fila.es_subtotal %}background-color: #f9f9f9;{% endif %} page-break-inside: avoid; break-inside: avoid; display: table-row;" {% if fila.es_seccion_principal %}class="row-seccion"{% elif fila.es_subtotal %}class="row-subtotal"{% else %}class="row-data"{% endif %}>
30
30
  {% if fila.es_seccion_principal %}
31
31
  <!-- Fila principal que abarca todas las columnas -->
32
32
  <td colspan="7" style="padding: 10px 20px; background-color: #f5f5f5; border: 1px solid #e0e0e0;">
@@ -41,7 +41,7 @@
41
41
  {{ fila.item }}
42
42
  </p>
43
43
  </td>
44
- <td class="celda-c" style="width: 25%; padding: 10px 5px; vertical-align: middle; border: 1px solid #e0e0e0;">
44
+ <td class="celda-c" style="width: 20%; padding: 10px 5px; vertical-align: middle; border: 1px solid #e0e0e0;">
45
45
  <!-- Vacío para subtotal -->
46
46
  </td>
47
47
  <td class="celda-c" style="width: 5%; padding: 10px 5px; text-align: center; vertical-align: middle; border: 1px solid #e0e0e0;">
@@ -51,17 +51,17 @@
51
51
  </td>
52
52
  <td class="celda-c" style="width: 5%; padding: 10px 5px; text-align: center; vertical-align: middle; border: 1px solid #e0e0e0;">
53
53
  <p style="margin: 0; font-size: 13px; color: #002857; font-weight: bold;">
54
- {% if fila.escala33 %}{{ fila.escala33|floatformat:2 }}%{% else %}-{% endif %}
54
+ {% if fila.escala33 %}{{ "%.2f"|format(fila.escala33) }}%{% else %}-{% endif %}
55
55
  </p>
56
56
  </td>
57
57
  <td class="celda-c" style="width: 5%; padding: 10px 5px; text-align: center; vertical-align: middle; border: 1px solid #e0e0e0;">
58
58
  <p style="margin: 0; font-size: 13px; color: #002857; font-weight: bold;">
59
- {{ fila.valor_absoluto|default:'-' }}
59
+ {{ fila.valor_absoluto|default('-') }}
60
60
  </p>
61
61
  </td>
62
62
  <td class="celda-c" style="width: 12%; padding: 10px 5px; text-align: center; vertical-align: middle; border: 1px solid #e0e0e0;">
63
63
  <p style="margin: 0; font-size: 13px; color: #002857; font-weight: bold;">
64
- {{ fila.valor_relativo_ponderado|default:0|floatformat:2 }}
64
+ {{ "%.2f"|format(fila.valor_relativo_ponderado|default(0)) }}
65
65
  </p>
66
66
  </td>
67
67
  <td class="celda-d" style="width: 39%; padding: 10px 20px 10px 5px; vertical-align: middle; border: 1px solid #e0e0e0;">
@@ -98,35 +98,35 @@
98
98
  <!-- Columna Escala 100% -->
99
99
  <td class="celda-c" style="width: 5%; padding: 10px 5px; text-align: center; vertical-align: top; border: 1px solid #e0e0e0;">
100
100
  <p style="margin: 0; font-size: 13px; color: #002857;">
101
- {{ fila.escala100|default:'-' }}
101
+ {{ fila.escala100|default('-') }}
102
102
  </p>
103
103
  </td>
104
104
 
105
105
  <!-- Columna Escala 33% -->
106
106
  <td class="celda-c" style="width: 5%; padding: 10px 5px; text-align: center; vertical-align: top; border: 1px solid #e0e0e0;">
107
107
  <p style="margin: 0; font-size: 13px; color: #002857;">
108
- {{ fila.escala33|default:'-' }}
108
+ {{ fila.escala33|default('-') }}
109
109
  </p>
110
110
  </td>
111
111
 
112
112
  <!-- Columna Valor absoluto -->
113
113
  <td class="celda-c" style="width: 5%; padding: 10px 5px; text-align: center; vertical-align: top; border: 1px solid #e0e0e0;">
114
114
  <p style="margin: 0; font-size: 13px; color: #002857; font-weight: {% if fila.valor_absoluto %}bold{% endif %};">
115
- {{ fila.valor_absoluto|default:'-' }}
115
+ {{ fila.valor_absoluto|default('-') }}
116
116
  </p>
117
117
  </td>
118
118
 
119
119
  <!-- Columna Valor relativo ponderado -->
120
120
  <td class="celda-c" style="width: 12%; padding: 10px 5px; text-align: center; vertical-align: top; border: 1px solid #e0e0e0;">
121
121
  <p style="margin: 0; font-size: 13px; color: #002857;">
122
- {{ fila.valor_relativo_ponderado|default:'0'|floatformat:3 }}
122
+ {{ "%.2f"|format(fila.valor_relativo_ponderado|default(0)) }}
123
123
  </p>
124
124
  </td>
125
125
 
126
126
  <!-- Columna Fuentes de información -->
127
127
  <td class="celda-d" style="width: 39%; padding: 10px 20px 10px 5px; vertical-align: top; border: 1px solid #e0e0e0; page-break-inside: avoid; break-inside: avoid;">
128
128
  <p style="margin: 0; font-size: 11px; color: #002857; font-family: 'Roboto', sans-serif;">
129
- {{ fila.fuentes_informacion|default:'' }}
129
+ {{ fila.fuentes_informacion|default('') }}
130
130
  </p>
131
131
  </td>
132
132
  {% endif %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: assemblerpdf
3
- Version: 1.0.6
3
+ Version: 1.0.8
4
4
  Summary: Generador de PDFs usando WeasyPrint, diseñado para formularios y reportes con componentes genéricos.
5
5
  Author-email: EcosistemaUNP <ecosistema@unp.gov.co>
6
6
  License: MIT
@@ -29,6 +29,7 @@ src/assemblerpdf/templates/assemblerpdf/layout/grid_row.html
29
29
  src/assemblerpdf/templates/assemblerpdf/layout/header.html
30
30
  src/assemblerpdf/templates/assemblerpdf/layout/section.html
31
31
  src/assemblerpdf/templates/assemblerpdf/layout/style.html
32
+ src/assemblerpdf/templates/assemblerpdf/layout/table.html
32
33
  src/assemblerpdf/templates/assemblerpdf/misc/signature.html
33
34
  src/assemblerpdf/templates/sistema/anexos.html
34
35
  src/assemblerpdf/templates/sistema/anexos_limpio.html
File without changes
File without changes
File without changes