227 lines
11 KiB
Transact-SQL
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
|