diff --git a/src/lib/server/controldesk-pg.ts b/src/lib/server/controldesk-pg.ts index bc59c87..bd11f69 100644 --- a/src/lib/server/controldesk-pg.ts +++ b/src/lib/server/controldesk-pg.ts @@ -172,7 +172,8 @@ const ROW_DATABASE_NODE = ` notification_email AS "CorreoNotificacion", server_name AS "ServerName", database_name AS "BDName", - restore_target_id AS "RestoreTargetId" + restore_target_id AS "RestoreTargetId", + anexo24c_aviso_fecha AS "Anexo24CAvisoFecha" `; const ROW_PORTAL_USER = ` @@ -377,6 +378,7 @@ export async function insertDatabaseNode(row: { bdName: string; activo: number; restoreTargetId?: number | null; + anexo24CAvisoFecha?: string | null; }): Promise { // server_name y sql_password se derivan del servidor de restauración asignado (su IP y su // credencial SQL cifrada); si el target aún no tiene IP, se conserva el serverName recibido. @@ -385,12 +387,13 @@ export async function insertDatabaseNode(row: { INSERT INTO ${qNodes()} ( node_subnode_key, rfc, legal_name, branch_name, notification_email, server_name, database_name, is_active, restore_target_id, - sql_password + sql_password, anexo24c_aviso_fecha ) VALUES ( $1, $2, $3, $4, $5, COALESCE((SELECT server_ip FROM ${qRestoreTargets()} WHERE id = $9), $6), $7, $8, $9, - (SELECT sql_password_encrypted FROM ${qRestoreTargets()} WHERE id = $9) + (SELECT sql_password_encrypted FROM ${qRestoreTargets()} WHERE id = $9), + $10 ) `, [ @@ -402,7 +405,8 @@ export async function insertDatabaseNode(row: { row.serverName, row.bdName, row.activo, - row.restoreTargetId ?? null + row.restoreTargetId ?? null, + row.anexo24CAvisoFecha ?? null ] ); } @@ -419,6 +423,7 @@ export async function updateDatabaseNode( bdName: string; activo: number; restoreTargetId?: number | null; + anexo24CAvisoFecha?: string | null; } ): Promise { await pgPool.query( @@ -433,8 +438,9 @@ export async function updateDatabaseNode( database_name = $7, is_active = $8, restore_target_id = $9, - sql_password = (SELECT sql_password_encrypted FROM ${qRestoreTargets()} WHERE id = $9) - WHERE id = $10 + sql_password = (SELECT sql_password_encrypted FROM ${qRestoreTargets()} WHERE id = $9), + anexo24c_aviso_fecha = $10 + WHERE id = $11 `, [ row.nodoSubNodo, @@ -446,6 +452,7 @@ export async function updateDatabaseNode( row.bdName, row.activo, row.restoreTargetId ?? null, + row.anexo24CAvisoFecha ?? null, id ] ); diff --git a/src/lib/server/db.ts b/src/lib/server/db.ts index 552dacf..5836837 100644 --- a/src/lib/server/db.ts +++ b/src/lib/server/db.ts @@ -1,7 +1,12 @@ import pkg from 'pg'; -const { Pool } = pkg; +const { Pool, types } = pkg; import { env } from '$env/dynamic/private'; +// DATE (OID 1082): devolver el string 'YYYY-MM-DD' crudo. Por default pg lo parsea +// como Date en hora LOCAL del proceso, y un uso posterior de .toISOString() puede +// desfasar el dia segun el timezone del servidor (afecta a24c.database_nodes.anexo24c_aviso_fecha). +types.setTypeParser(1082, (val: string) => val); + // Pool de PostgreSQL para usuarios y permisos const pgPool = new Pool({ host: env.DB_POSTGRES_HOST || '10.0.20.152', diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts index 4f691d6..79c3400 100644 --- a/src/routes/+page.server.ts +++ b/src/routes/+page.server.ts @@ -495,6 +495,9 @@ export const actions: Actions = { String(formData.get('ServerName') || '').trim() || DEFAULT_DATABASE_SERVER; const bdName = nodoSubNodo; const activo = parseActivoField(formData); + // Fecha de aviso SAT Anexo 24C (T2026-06-111), opcional: vacio = sin fecha. + const anexo24CAvisoFechaRaw = String(formData.get('Anexo24CAvisoFecha') || '').trim(); + const anexo24CAvisoFecha = anexo24CAvisoFechaRaw || null; if (!nodoSubNodo || !rfc || !nombre || !correo) { return { success: false, message: 'Faltan campos requeridos' }; @@ -509,7 +512,8 @@ export const actions: Actions = { serverName, bdName, activo, - restoreTargetId + restoreTargetId, + anexo24CAvisoFecha }); return { success: true }; @@ -536,6 +540,9 @@ export const actions: Actions = { String(formData.get('ServerName') || '').trim() || DEFAULT_DATABASE_SERVER; const bdName = nodoSubNodo; const activo = parseActivoField(formData); + // Fecha de aviso SAT Anexo 24C (T2026-06-111), opcional: vacio = sin fecha. + const anexo24CAvisoFechaRaw = String(formData.get('Anexo24CAvisoFecha') || '').trim(); + const anexo24CAvisoFecha = anexo24CAvisoFechaRaw || null; if (!id || !nodoSubNodo || !rfc || !nombre || !correo) { return { success: false, message: 'Faltan campos requeridos' }; @@ -550,7 +557,8 @@ export const actions: Actions = { serverName, bdName, activo, - restoreTargetId + restoreTargetId, + anexo24CAvisoFecha }); return { success: true }; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 9e5f437..0912166 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -503,7 +503,8 @@ ServerName: DEFAULT_DATABASE_SERVER, BDName: '', Activo: true, - RestoreTargetId: null + RestoreTargetId: null, + Anexo24CAvisoFecha: '' }); const openCreateDbModal = () => { @@ -520,7 +521,8 @@ ServerName: DEFAULT_DATABASE_SERVER, BDName: suggestedNodo, Activo: true, - RestoreTargetId: null + RestoreTargetId: null, + Anexo24CAvisoFecha: '' }; showDbCrudModal = true; }; @@ -541,7 +543,8 @@ ServerName: bd.ServerName ?? '', BDName: bd.BDName ?? '', Activo: !!bd.Activo, - RestoreTargetId: bd.RestoreTargetId ?? null + RestoreTargetId: bd.RestoreTargetId ?? null, + Anexo24CAvisoFecha: bd.Anexo24CAvisoFecha ?? '' }; showDbCrudModal = true; }; @@ -568,6 +571,7 @@ if (formDb.RestoreTargetId != null) { form.append('restore_target_id', String(formDb.RestoreTargetId)); } + form.append('Anexo24CAvisoFecha', formDb.Anexo24CAvisoFecha ?? ''); try { const res = await fetch(`?/${action}`, { @@ -2496,6 +2500,23 @@ Activo + + +
+ + +

+ Opcional. Si se captura, el login de SCAII Web muestra la leyenda de aviso + con esta fecha cuando el cliente está desactivado; en blanco no se incluye fecha. +

+