/* ------------------------------------------------------------------ ADPRMT017 - Accion de Personal: DESVINCULAR (indicador de Rotacion) Fecha : 2026-10-05 Crea : adtb00061 (catalogo de causas de salida) adtb00062 (detalle de desvinculacion por accion) vista vw_rotacion_mensual La desactivacion (adtb00003.status_t = 'D') pasa a hacerse SOLO por la accion de personal; noprmt016 ya no desactiva. Idempotente. ------------------------------------------------------------------- */ SET NOCOUNT ON; /* 1. Catalogo de causas clase: V = voluntaria, I = involuntaria, O = otra cuenta_rotacion: 'N' para traslados dentro del grupo (no es salida real) */ IF OBJECT_ID('dbo.adtb00061') IS NULL BEGIN CREATE TABLE dbo.adtb00061 ( cod_causa SMALLINT NOT NULL CONSTRAINT pk_adtb00061 PRIMARY KEY, desc_causa VARCHAR(60) NOT NULL, clase CHAR(1) NOT NULL CONSTRAINT ck_adtb00061_clase CHECK (clase IN ('V','I','O')), cuenta_rotacion CHAR(1) NOT NULL CONSTRAINT df_adtb00061_cuenta DEFAULT 'S', status_t CHAR(1) NULL, us_crea VARCHAR(50) NULL, fech_crea DATETIME NULL ); INSERT INTO dbo.adtb00061 (cod_causa, desc_causa, clase, cuenta_rotacion, us_crea, fech_crea) VALUES ( 1, 'RENUNCIA', 'V', 'S', SUSER_SNAME(), GETDATE()), ( 2, 'ABANDONO DE TRABAJO', 'V', 'S', SUSER_SNAME(), GETDATE()), ( 3, 'DIMISION', 'V', 'S', SUSER_SNAME(), GETDATE()), ( 4, 'DESAHUCIO', 'I', 'S', SUSER_SNAME(), GETDATE()), ( 5, 'DESPIDO', 'I', 'S', SUSER_SNAME(), GETDATE()), ( 6, 'CIERRE DE OPERACION / MINA', 'I', 'S', SUSER_SNAME(), GETDATE()), ( 7, 'FIN DE CONTRATO / TEMPORADA', 'I', 'S', SUSER_SNAME(), GETDATE()), ( 8, 'NO SUPERO PERIODO DE PRUEBA', 'I', 'S', SUSER_SNAME(), GETDATE()), ( 9, 'MUTUO ACUERDO', 'O', 'S', SUSER_SNAME(), GETDATE()), (10, 'PENSION / RETIRO', 'O', 'S', SUSER_SNAME(), GETDATE()), (11, 'FALLECIMIENTO', 'O', 'S', SUSER_SNAME(), GETDATE()), (12, 'TRASLADO A OTRA EMPRESA DEL GRUPO', 'O', 'N', SUSER_SNAME(), GETDATE()), (99, 'OTRA', 'O', 'S', SUSER_SNAME(), GETDATE()); END GO /* 2. Detalle de desvinculacion (una fila por accion DESVINCULAR) */ IF OBJECT_ID('dbo.adtb00062') IS NULL BEGIN CREATE TABLE dbo.adtb00062 ( id_desv INT IDENTITY(1,1) NOT NULL CONSTRAINT pk_adtb00062 PRIMARY KEY, num_trx INT NULL, -- adtb00020.num_trx (NULL = historico) num_emp INT NOT NULL, fecha_salida DATE NOT NULL, cod_causa SMALLINT NOT NULL CONSTRAINT fk_adtb00062_causa REFERENCES dbo.adtb00061(cod_causa), recontratable CHAR(1) NULL, -- S / N detalle VARCHAR(200) NULL, departamento SMALLINT NULL, -- foto al momento de la salida cod_puesto SMALLINT NULL, tipo_empleado VARCHAR(20) NULL, -- NORMAL / TEMPORERO fech_ingreso DATE NULL, origen CHAR(1) NOT NULL CONSTRAINT df_adtb00062_origen DEFAULT 'A', -- A accion, H historico status_t CHAR(1) NULL, -- 'E' anulada us_crea VARCHAR(50) NULL, fech_crea DATETIME NULL, us_mod VARCHAR(50) NULL, fech_mod DATETIME NULL ); CREATE INDEX ix_adtb00062_fecha ON dbo.adtb00062(fecha_salida) INCLUDE (num_emp, cod_causa, departamento, tipo_empleado, status_t); CREATE INDEX ix_adtb00062_emp ON dbo.adtb00062(num_emp); CREATE INDEX ix_adtb00062_trx ON dbo.adtb00062(num_trx); END GO /* 3. El movimiento 4 DESVINCULAR queda con tipo_mov 'CANCELAR' (adprmt017 reconoce CANCELAR, DESVINCULAR y TERMINO). No se cambia. */ /* 4. Rotacion mensual por departamento y tipo de empleado. salidas_rotacion excluye causas con cuenta_rotacion = 'N'. Plantilla = empleados con ingreso <= inicio de mes y sin salida antes del inicio. */ IF OBJECT_ID('dbo.vw_rotacion_mensual') IS NOT NULL DROP VIEW dbo.vw_rotacion_mensual; GO CREATE VIEW dbo.vw_rotacion_mensual AS WITH meses AS ( SELECT CAST('2022-01-01' AS DATE) AS ini UNION ALL SELECT DATEADD(MONTH, 1, ini) FROM meses WHERE ini < DATEADD(MONTH, -1, CAST(GETDATE() AS DATE)) ), emp AS ( SELECT a.num_emp, a.departamento, ISNULL(a.tipo_empleado,'NORMAL') AS tipo_empleado, a.fech_efec, a.fecha_salida FROM dbo.adtb00003 a WHERE a.num_emp >= 39 -- fichas < 39 no son empleados reales AND (a.status_t IS NULL OR a.status_t = 'D') ), sal AS ( SELECT d.num_emp, d.fecha_salida, d.departamento, ISNULL(d.tipo_empleado,'NORMAL') AS tipo_empleado, c.clase, c.cuenta_rotacion FROM dbo.adtb00062 d JOIN dbo.adtb00061 c ON c.cod_causa = d.cod_causa WHERE d.status_t IS NULL ) SELECT m.ini AS mes, YEAR(m.ini) AS anio, MONTH(m.ini) AS mes_num, g.departamento, dp.nom_dpto, g.tipo_empleado, g.plantilla_inicio, ISNULL(i.ingresos,0) AS ingresos, ISNULL(s.salidas,0) AS salidas, ISNULL(s.salidas_rotacion,0) AS salidas_rotacion, ISNULL(s.voluntarias,0) AS voluntarias, ISNULL(s.involuntarias,0) AS involuntarias, ISNULL(s.otras,0) AS otras, CASE WHEN g.plantilla_inicio > 0 THEN CAST(100.0 * ISNULL(s.salidas_rotacion,0) / g.plantilla_inicio AS DECIMAL(6,2)) END AS rotacion_pct FROM meses m CROSS APPLY ( SELECT e.departamento, e.tipo_empleado, COUNT(*) AS plantilla_inicio FROM emp e WHERE e.fech_efec <= m.ini AND (e.fecha_salida IS NULL OR e.fecha_salida >= m.ini) GROUP BY e.departamento, e.tipo_empleado ) g OUTER APPLY ( SELECT COUNT(*) AS ingresos FROM emp e WHERE e.departamento = g.departamento AND e.tipo_empleado = g.tipo_empleado AND e.fech_efec >= m.ini AND e.fech_efec < DATEADD(MONTH,1,m.ini) ) i OUTER APPLY ( SELECT COUNT(*) AS salidas, SUM(CASE WHEN x.cuenta_rotacion = 'S' THEN 1 ELSE 0 END) AS salidas_rotacion, SUM(CASE WHEN x.clase = 'V' THEN 1 ELSE 0 END) AS voluntarias, SUM(CASE WHEN x.clase = 'I' THEN 1 ELSE 0 END) AS involuntarias, SUM(CASE WHEN x.clase = 'O' THEN 1 ELSE 0 END) AS otras FROM sal x WHERE x.departamento = g.departamento AND x.tipo_empleado = g.tipo_empleado AND x.fecha_salida >= m.ini AND x.fecha_salida < DATEADD(MONTH,1,m.ini) ) s LEFT JOIN dbo.adtb00001 dp ON dp.departamento = g.departamento; GO