Files
MBS/PROYECTO/addir/adprmt017_desvinculacion.sql

140 lines
6.8 KiB
Transact-SQL

/* ------------------------------------------------------------------
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