feat(escrituras): añadir columna "Entrada" (########/####)

* SQL: nueva migración 003 que añade `entrada VARCHAR(13)` después de
  `estatus` en `escrituras_tramites`. Aplicada en producción.
* API: INSERT/UPDATE persisten el campo; auditoría lo registra con
  label "Entrada" en el historial.
* Frontend:
  - Nueva columna en el header entre Estatus y Últ. Actualización
  - Input con `pattern=^\d{1,8}/\d{4}$`, `maxlength=13`, placeholder
    "########/####" y validación nativa del navegador
  - newRow() y duplicateRow() incluyen `entrada:''` por defecto
  - exportHeaders / rowToArray / Excel widths actualizados
  - pdfCols renumerado para incluir Entrada en el PDF
This commit is contained in:
Soporte ZH Consultores
2026-05-11 19:31:22 +00:00
parent 4ee32aec6d
commit 81a909a1ec
3 changed files with 30 additions and 9 deletions
+17 -6
View File
@@ -459,6 +459,7 @@ tr.editing-row td textarea.editable {
<th>Instrucciones Especiales</th>
<th>Fecha de Solicitud</th>
<th>Estatus</th>
<th>Entrada</th>
<th>Últ. Actualización</th>
<th>Actualizado por</th>
<th>Observaciones</th>
@@ -641,7 +642,7 @@ function newRow() {
allRows.unshift({ id:null, tramite:'', cliente:'', abogado:'Abrego', notaria:'',
inscribe:'Sí', altera_turno:'No', instrucciones:'',
fecha_solicitud: new Date().toISOString(), estatus:'Solicitado',
observaciones:'', creado_por: authUser.email });
entrada:'', observaciones:'', creado_por: authUser.email });
render();
setTimeout(()=>{
const inp = document.querySelector('tr.data-row [data-field="tramite"]');
@@ -716,6 +717,12 @@ function render() {
</select><br>
<span class="badge ${badgeClass(r.estatus)}">${esc(r.estatus)}</span>
</td>
<td style="min-width:110px;">
<input class="editable" data-field="entrada" value="${esc(r.entrada||'')}"
placeholder="########/####" pattern="^\\d{1,8}/\\d{4}$" maxlength="13"
title="Hasta 8 dígitos, slash, y año de 4 dígitos. Ej: 12345678/2026"
style="min-width:100px;font-variant-numeric:tabular-nums;" ${dis}>
</td>
<td class="ts">${fmtDate(r.ultima_actualizacion)}</td>
<td class="user-col" title="${esc(r.actualizado_por||'')}">${esc(r.actualizado_por ? r.actualizado_por.split('@')[0] : '—')}</td>
<td style="min-width:140px;max-width:180px;">
@@ -952,14 +959,14 @@ function getExportRows() {
function exportHeaders() {
return ['#','Nombre del Trámite','Cliente','Abogado Solicitante','Notaría',
'Se Inscribe','Alt. de Turno','Instrucciones Especiales',
'Fecha de Solicitud','Estatus','Últ. Actualización','Observaciones','Creado por'];
'Fecha de Solicitud','Estatus','Entrada','Últ. Actualización','Observaciones','Creado por'];
}
function rowToArray(r, i) {
return [
i+1, r.tramite, r.cliente, r.abogado, r.notaria,
r.inscribe, r.altera_turno, r.instrucciones,
fmtDate(r.fecha_solicitud), r.estatus,
fmtDate(r.fecha_solicitud), r.estatus, r.entrada || '',
fmtDate(r.ultima_actualizacion), r.observaciones, r.creado_por
];
}
@@ -973,10 +980,13 @@ function exportExcel() {
const data = [exportHeaders(), ...rows.map(rowToArray)];
const ws = XLSX.utils.aoa_to_sheet(data);
// Column widths
// Column widths (#, Trámite, Cliente, Abogado, Notaría,
// Inscribe, Altera, Instrucciones, Fecha, Estatus,
// Entrada, Últ.Act., Observaciones, Creado por)
ws['!cols'] = [
{wch:4},{wch:30},{wch:22},{wch:18},{wch:12},
{wch:10},{wch:12},{wch:35},{wch:18},{wch:16},{wch:18},{wch:30},{wch:22}
{wch:10},{wch:12},{wch:35},{wch:18},{wch:16},
{wch:14},{wch:18},{wch:30},{wch:22}
];
// Header style (row 1)
@@ -1007,7 +1017,8 @@ function exportPDF() {
const headers = exportHeaders();
// Columnas a mostrar en PDF (subset para que quepa en landscape)
const pdfCols = [0,1,2,3,4,5,6,9,11];
// [#, Trámite, Cliente, Abogado, Notaría, Inscribe, Altera, Estatus, Entrada, Observaciones]
const pdfCols = [0,1,2,3,4,5,6,9,10,12];
const pdfHeaders = pdfCols.map(i=>headers[i]);
const win = window.open('','_blank');