Files
MBS/Dashboards MARMOTECH/SQL_Vistas_Presidencia.sql
T

227 lines
11 KiB
Transact-SQL

/* ============================================================================
MarmotechBI — Vistas para el Dashboard Ejecutivo de Presidencia
----------------------------------------------------------------------------
Autor : Juan F. Soto (jsoto)
Fecha : 2026-08-26
Servidor : 192.168.40.8 (SQL Server 2016)
Base : MarmotechBI (capa semantica; los datos viven en marmotech.dbo.*)
Objetivo : Radiografia financiera para el Presidente, a partir del
Mayor General Analitico (cgprrp008) y el Analisis de Gastos
por Departamento (cgprrp009).
Fuente de datos:
marmotech.dbo.cgtb00004 = transacciones contables (debito/credito por cuenta/fecha)
marmotech.dbo.cgtb00001 = catalogo de cuentas (nivel, descripcion)
marmotech.dbo.prdtable = periodos contables (ano, mes -> rango de fechas)
marmotech.dbo.mestable = nombres de meses
marmotech.dbo.adtb00001 = departamentos (nom_dpto)
Reglas de negocio (validadas contra cgprrp008 / cgprrp009):
* Estado de Resultados por PRIMER DIGITO de la cuenta:
4 = VENTAS NETA (naturaleza credito)
5 = COSTO DE VENTAS (naturaleza debito)
7 = GASTOS (naturaleza debito)
8 = OTROS INGRESOS Y GASTOS (incluye 88 = IMPUESTO S/RENTA)
* resultado (aporte a la utilidad) = credito - debito
-> Ventas suma positivo; Costo/Gastos/ISR restan; la suma de todas
las lineas = Utilidad Neta del periodo.
* Solo transacciones activas: status_t IS NULL.
* Se EXCLUYE el asiento de cierre anual (ref 'ED.99-001/12YY' y
'ED.99-002/12YY'); de lo contrario cada ano cerrado netearia a 0 porque
el cierre revierte las cuentas de resultado contra Utilidades Retenidas.
(2026 aun no tiene cierre, por eso muestra saldo operativo real.)
Seguridad (requisito): estas vistas solo deben ser legibles por jsoto.
Se crean en el esquema [presidencia] y se hace DENY SELECT a [public].
jsoto (MARMOTECH\jsoto y login SQL jsoto) es sysadmin/db_owner, por lo que
ignora el DENY y conserva acceso; el resto del equipo (db_datareader) queda
bloqueado a nivel de esquema.
============================================================================ */
USE MarmotechBI;
GO
/* ---- 1. Esquema dedicado ------------------------------------------------- */
IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = 'presidencia')
EXEC('CREATE SCHEMA presidencia AUTHORIZATION dbo;');
GO
/* ---- 2. Estado de Resultados mensual (cgprrp008) ------------------------- */
/* Grano: ano x mes x cuenta. Un renglon por cuenta contable de resultado. */
IF OBJECT_ID('presidencia.vwPLMensual','V') IS NOT NULL
DROP VIEW presidencia.vwPLMensual;
GO
CREATE VIEW presidencia.vwPLMensual
AS
WITH mov AS (
SELECT p.ano,
p.mes AS numero_mes,
b.cuenta_no,
SUM(b.debito) AS debito,
SUM(b.credito) AS credito
FROM marmotech.dbo.cgtb00004 b
INNER JOIN marmotech.dbo.prdtable p
ON b.fecha BETWEEN p.fecha_inicio AND p.fecha_corte
WHERE b.status_t IS NULL
AND LEFT(b.cuenta_no,1) IN ('4','5','7','8')
AND b.ref NOT LIKE 'ED.99-001/12%' -- asiento de cierre anual
AND b.ref NOT LIKE 'ED.99-002/12%' -- asiento de cierre anual (variante)
GROUP BY p.ano, p.mes, b.cuenta_no
)
SELECT
m.ano,
m.numero_mes,
ms.descrip AS mes,
RIGHT('0000'+CONVERT(varchar(4),m.ano),4) + '-' +
RIGHT('00'+CONVERT(varchar(2),m.numero_mes),2) AS AnoMes,
DATEFROMPARTS(m.ano, m.numero_mes, 1) AS fecha_mes,
LEFT(m.cuenta_no,1) AS grupo,
CASE LEFT(m.cuenta_no,1)
WHEN '4' THEN 1 WHEN '5' THEN 2 WHEN '7' THEN 3
WHEN '8' THEN CASE WHEN m.cuenta_no LIKE '88%' THEN 5 ELSE 4 END
END AS orden_linea,
CASE LEFT(m.cuenta_no,1)
WHEN '4' THEN 'Ventas Netas'
WHEN '5' THEN 'Costo de Ventas'
WHEN '7' THEN 'Gastos Operativos'
WHEN '8' THEN CASE WHEN m.cuenta_no LIKE '88%'
THEN 'Impuesto sobre la Renta'
ELSE 'Otros Ingresos y Gastos' END
END AS linea,
LEFT(m.cuenta_no,2) AS subgrupo_cod,
sg.descripcion AS subgrupo_desc,
m.cuenta_no AS cuenta,
ct.descripcion AS cuenta_desc,
ct.nivel,
m.debito,
m.credito,
CAST(m.credito - m.debito AS decimal(19,2)) AS resultado, -- + = aporta utilidad
CAST(m.debito - m.credito AS decimal(19,2)) AS costo_gasto -- + = costo/gasto
FROM mov m
LEFT JOIN marmotech.dbo.cgtb00001 ct ON ct.cuenta_no = m.cuenta_no
LEFT JOIN marmotech.dbo.cgtb00001 sg ON sg.cuenta_no = LEFT(m.cuenta_no,2)
LEFT JOIN marmotech.dbo.mestable ms ON ms.mes = m.numero_mes;
GO
/* ---- 3. Analisis de Gastos por Departamento (cgprrp009) ------------------ */
/* Grano: ano x mes x departamento x cuenta. Solo grupo 7 (GASTOS). */
IF OBJECT_ID('presidencia.vwGastosDepto','V') IS NOT NULL
DROP VIEW presidencia.vwGastosDepto;
GO
CREATE VIEW presidencia.vwGastosDepto
AS
WITH mov AS (
SELECT p.ano,
p.mes AS numero_mes,
ISNULL(b.departamento,0) AS departamento,
b.cuenta_no,
SUM(b.debito) AS debito,
SUM(b.credito) AS credito
FROM marmotech.dbo.cgtb00004 b
INNER JOIN marmotech.dbo.prdtable p
ON b.fecha BETWEEN p.fecha_inicio AND p.fecha_corte
WHERE b.status_t IS NULL
AND LEFT(b.cuenta_no,1) = '7'
AND b.ref NOT LIKE 'ED.99-001/12%'
AND b.ref NOT LIKE 'ED.99-002/12%'
GROUP BY p.ano, p.mes, ISNULL(b.departamento,0), b.cuenta_no
)
SELECT
m.ano,
m.numero_mes,
ms.descrip AS mes,
RIGHT('0000'+CONVERT(varchar(4),m.ano),4) + '-' +
RIGHT('00'+CONVERT(varchar(2),m.numero_mes),2) AS AnoMes,
DATEFROMPARTS(m.ano, m.numero_mes, 1) AS fecha_mes,
LEFT(CONVERT(varchar(4),m.departamento),1) AS gerencia_cod,
CASE LEFT(CONVERT(varchar(4),m.departamento),1)
WHEN '1' THEN 'Gerencia General'
WHEN '2' THEN 'Administracion y Materiales'
WHEN '3' THEN 'Gestion Humana'
WHEN '4' THEN 'Ventas y Mercadeo'
WHEN '5' THEN 'Canteras'
WHEN '6' THEN 'Planta / Produccion'
WHEN '7' THEN 'Planta Agregados'
WHEN '8' THEN 'Marmotech en Caribbean'
ELSE 'Sin Departamento'
END AS gerencia,
m.departamento,
ISNULL(ad.nom_dpto,'SIN DEPARTAMENTO') AS depto_nombre,
LEFT(m.cuenta_no,2) AS subgrupo_cod,
sg.descripcion AS subgrupo_desc,
m.cuenta_no AS cuenta,
ct.descripcion AS cuenta_desc,
m.debito,
m.credito,
CAST(m.debito - m.credito AS decimal(19,2)) AS gasto -- + = gasto neto
FROM mov m
LEFT JOIN marmotech.dbo.cgtb00001 ct ON ct.cuenta_no = m.cuenta_no
LEFT JOIN marmotech.dbo.cgtb00001 sg ON sg.cuenta_no = LEFT(m.cuenta_no,2)
LEFT JOIN marmotech.dbo.adtb00001 ad ON ad.departamento = m.departamento
LEFT JOIN marmotech.dbo.mestable ms ON ms.mes = m.numero_mes;
GO
/* ---- 4. Balance General / Estructura financiera (saldo acumulado) -------- */
/* Grano: ano x mes x cuenta, grupos 1 (Activos) 2 (Pasivos) 3 (Capital). */
/* saldo_acumulado = saldo contable al cierre del mes (deb-cred acumulado). */
IF OBJECT_ID('presidencia.vwBalanceMensual','V') IS NOT NULL
DROP VIEW presidencia.vwBalanceMensual;
GO
CREATE VIEW presidencia.vwBalanceMensual
AS
WITH mov AS (
SELECT p.ano,
p.mes AS numero_mes,
b.cuenta_no,
SUM(b.debito - b.credito) AS movimiento
FROM marmotech.dbo.cgtb00004 b
INNER JOIN marmotech.dbo.prdtable p
ON b.fecha BETWEEN p.fecha_inicio AND p.fecha_corte
WHERE b.status_t IS NULL
AND LEFT(b.cuenta_no,1) IN ('1','2','3')
GROUP BY p.ano, p.mes, b.cuenta_no
),
acum AS (
SELECT m.*,
SUM(m.movimiento) OVER (PARTITION BY m.cuenta_no
ORDER BY m.ano, m.numero_mes
ROWS UNBOUNDED PRECEDING) AS saldo_acumulado
FROM mov m
)
SELECT
a.ano,
a.numero_mes,
ms.descrip AS mes,
RIGHT('0000'+CONVERT(varchar(4),a.ano),4) + '-' +
RIGHT('00'+CONVERT(varchar(2),a.numero_mes),2) AS AnoMes,
DATEFROMPARTS(a.ano, a.numero_mes, 1) AS fecha_mes,
LEFT(a.cuenta_no,1) AS grupo,
CASE LEFT(a.cuenta_no,1) WHEN '1' THEN 'Activos'
WHEN '2' THEN 'Pasivos'
WHEN '3' THEN 'Capital' END AS grupo_desc,
LEFT(a.cuenta_no,2) AS subgrupo_cod,
sg.descripcion AS subgrupo_desc,
a.cuenta_no AS cuenta,
ct.descripcion AS cuenta_desc,
CAST(a.movimiento AS decimal(19,2)) AS movimiento_mes,
CAST(a.saldo_acumulado AS decimal(19,2)) AS saldo_natural, -- deb-cred
/* Presentacion: Activos positivos por debito; Pasivos/Capital por credito */
CAST(CASE WHEN LEFT(a.cuenta_no,1) = '1' THEN a.saldo_acumulado
ELSE -a.saldo_acumulado END AS decimal(19,2)) AS saldo_presentacion
FROM acum a
LEFT JOIN marmotech.dbo.cgtb00001 ct ON ct.cuenta_no = a.cuenta_no
LEFT JOIN marmotech.dbo.cgtb00001 sg ON sg.cuenta_no = LEFT(a.cuenta_no,2)
LEFT JOIN marmotech.dbo.mestable ms ON ms.mes = a.numero_mes;
GO
/* ---- 5. Seguridad: solo jsoto ------------------------------------------- */
DENY SELECT ON SCHEMA::presidencia TO [public];
GO
/* Concesion explicita (documenta la intencion; jsoto ya es db_owner/sysadmin) */
IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = 'MARMOTECH\jsoto')
GRANT SELECT ON SCHEMA::presidencia TO [MARMOTECH\jsoto];
GO
IF EXISTS (SELECT 1 FROM sys.database_principals WHERE name = 'jsoto')
GRANT SELECT ON SCHEMA::presidencia TO [jsoto];
GO