mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 13:23:17 +00:00
Reutiliza el catálogo de proveedores y agrega carga de facturas, conceptos de la semana, préstamos editables, finiquitos, dispersión, historial de personal, reportes y jornal de cotización. Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
129 lines
7 KiB
PL/PgSQL
129 lines
7 KiB
PL/PgSQL
--liquibase formatted sql
|
|
-- PANELS · core · jornal IMSS y consulta de cuotas
|
|
|
|
--changeset panel:core-050a-columns endDelimiter:; splitStatements:true
|
|
ALTER TABLE core.workers ADD COLUMN IF NOT EXISTS imss_daily_wage NUMERIC(12,2);
|
|
ALTER TABLE core.payroll_settings ADD COLUMN IF NOT EXISTS imss_rate_enfermedad NUMERIC(8,6) NOT NULL DEFAULT 0.020000;
|
|
ALTER TABLE core.payroll_settings ADD COLUMN IF NOT EXISTS imss_rate_invalidez NUMERIC(8,6) NOT NULL DEFAULT 0.017500;
|
|
ALTER TABLE core.payroll_settings ADD COLUMN IF NOT EXISTS imss_rate_retiro NUMERIC(8,6) NOT NULL DEFAULT 0.020000;
|
|
ALTER TABLE core.payroll_settings ADD COLUMN IF NOT EXISTS imss_rate_cesantia NUMERIC(8,6) NOT NULL DEFAULT 0.031500;
|
|
ALTER TABLE core.payroll_settings ADD COLUMN IF NOT EXISTS imss_rate_infonavit NUMERIC(8,6) NOT NULL DEFAULT 0.050000;
|
|
ALTER TABLE core.payroll_settings ADD COLUMN IF NOT EXISTS imss_rate_riesgo NUMERIC(8,6) NOT NULL DEFAULT 0.005433;
|
|
ALTER TABLE core.payroll_settings ADD COLUMN IF NOT EXISTS settlement_aguinaldo_days NUMERIC(6,2) NOT NULL DEFAULT 15;
|
|
ALTER TABLE core.payroll_settings ADD COLUMN IF NOT EXISTS settlement_prima_pct NUMERIC(6,2) NOT NULL DEFAULT 25;
|
|
|
|
--changeset panel:core-050b-fn-settings-save splitStatements:false
|
|
CREATE OR REPLACE FUNCTION core.fn_payroll_settings_save(payload jsonb)
|
|
RETURNS jsonb
|
|
LANGUAGE plpgsql
|
|
SECURITY INVOKER
|
|
SET search_path = core
|
|
AS $$
|
|
DECLARE
|
|
v_tid integer := core._payroll_tenant_id(payload);
|
|
v_cur payroll_settings%ROWTYPE;
|
|
v_settings jsonb;
|
|
BEGIN
|
|
PERFORM core._payroll_seed_defaults(v_tid);
|
|
SELECT * INTO v_cur FROM payroll_settings WHERE tenant_id = v_tid;
|
|
UPDATE payroll_settings SET
|
|
loan_commission_enabled = COALESCE((payload->>'loan_commission_enabled')::boolean, v_cur.loan_commission_enabled),
|
|
loan_commission_pct = COALESCE((payload->>'loan_commission_pct')::numeric, v_cur.loan_commission_pct, 0),
|
|
loan_small_max = COALESCE((payload->>'loan_small_max')::numeric, v_cur.loan_small_max, 0),
|
|
imss_rate_enfermedad = COALESCE((payload->>'imss_rate_enfermedad')::numeric, v_cur.imss_rate_enfermedad),
|
|
imss_rate_invalidez = COALESCE((payload->>'imss_rate_invalidez')::numeric, v_cur.imss_rate_invalidez),
|
|
imss_rate_retiro = COALESCE((payload->>'imss_rate_retiro')::numeric, v_cur.imss_rate_retiro),
|
|
imss_rate_cesantia = COALESCE((payload->>'imss_rate_cesantia')::numeric, v_cur.imss_rate_cesantia),
|
|
imss_rate_infonavit = COALESCE((payload->>'imss_rate_infonavit')::numeric, v_cur.imss_rate_infonavit),
|
|
imss_rate_riesgo = COALESCE((payload->>'imss_rate_riesgo')::numeric, v_cur.imss_rate_riesgo),
|
|
settlement_aguinaldo_days = COALESCE((payload->>'settlement_aguinaldo_days')::numeric, v_cur.settlement_aguinaldo_days),
|
|
settlement_prima_pct = COALESCE((payload->>'settlement_prima_pct')::numeric, v_cur.settlement_prima_pct)
|
|
WHERE tenant_id = v_tid;
|
|
SELECT to_jsonb(s) INTO v_settings FROM payroll_settings s WHERE tenant_id = v_tid;
|
|
RETURN core.rpc_ok(jsonb_build_object('settings', v_settings), 'Configuración de nómina guardada',
|
|
jsonb_build_object('fn', 'fn_payroll_settings_save', 'tenant_id', v_tid));
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RETURN core.rpc_from_exception('fn_payroll_settings_save', SQLSTATE, SQLERRM);
|
|
END;
|
|
$$;
|
|
|
|
--changeset panel:core-050c-fn-imss-quote splitStatements:false
|
|
CREATE OR REPLACE FUNCTION core.fn_imss_quote(payload jsonb)
|
|
RETURNS jsonb
|
|
LANGUAGE plpgsql
|
|
SECURITY INVOKER
|
|
SET search_path = core
|
|
AS $$
|
|
DECLARE
|
|
v_tid integer := core._payroll_tenant_id(payload);
|
|
v_worker_id bigint := NULLIF(payload->>'worker_id', '')::bigint;
|
|
v_from date := NULLIF(payload->>'date_from', '')::date;
|
|
v_to date := NULLIF(payload->>'date_to', '')::date;
|
|
v_settings payroll_settings%ROWTYPE;
|
|
v_rows jsonb;
|
|
BEGIN
|
|
IF v_from IS NULL OR v_to IS NULL THEN
|
|
RETURN core.rpc_err('VALIDATION', 'fn_imss_quote: indique el periodo',
|
|
jsonb_build_object('fn', 'fn_imss_quote'));
|
|
END IF;
|
|
PERFORM core._payroll_seed_defaults(v_tid);
|
|
SELECT * INTO v_settings FROM payroll_settings WHERE tenant_id = v_tid;
|
|
SELECT COALESCE(jsonb_agg(to_jsonb(x) ORDER BY x.last_name_p), '[]'::jsonb) INTO v_rows
|
|
FROM (
|
|
SELECT w.id AS worker_id, w.first_name, w.last_name_p, w.nss, w.daily_wage,
|
|
w.imss_daily_wage,
|
|
COALESCE(w.imss_daily_wage, w.daily_wage) AS wage_used,
|
|
(w.imss_daily_wage IS NULL) AS used_real_wage,
|
|
COALESCE(d.days, 0) AS days,
|
|
core.round_money(COALESCE(d.days, 0) * COALESCE(w.imss_daily_wage, w.daily_wage)) AS sbc,
|
|
core.round_money(COALESCE(d.days, 0) * COALESCE(w.imss_daily_wage, w.daily_wage) * v_settings.imss_rate_enfermedad) AS cuota_enfermedad,
|
|
core.round_money(COALESCE(d.days, 0) * COALESCE(w.imss_daily_wage, w.daily_wage) * v_settings.imss_rate_invalidez) AS cuota_invalidez,
|
|
core.round_money(COALESCE(d.days, 0) * COALESCE(w.imss_daily_wage, w.daily_wage) * v_settings.imss_rate_retiro) AS cuota_retiro,
|
|
core.round_money(COALESCE(d.days, 0) * COALESCE(w.imss_daily_wage, w.daily_wage) * v_settings.imss_rate_cesantia) AS cuota_cesantia,
|
|
core.round_money(COALESCE(d.days, 0) * COALESCE(w.imss_daily_wage, w.daily_wage) * v_settings.imss_rate_infonavit) AS cuota_infonavit,
|
|
core.round_money(COALESCE(d.days, 0) * COALESCE(w.imss_daily_wage, w.daily_wage) * v_settings.imss_rate_riesgo) AS cuota_riesgo
|
|
FROM workers w
|
|
LEFT JOIN (
|
|
SELECT worker_id, COUNT(*)::numeric AS days
|
|
FROM attendance
|
|
WHERE present = true AND work_date BETWEEN v_from AND v_to
|
|
GROUP BY worker_id
|
|
) d ON d.worker_id = w.id
|
|
WHERE w.tenant_id = v_tid
|
|
AND (v_worker_id IS NULL OR w.id = v_worker_id)
|
|
) x;
|
|
RETURN core.rpc_ok(
|
|
jsonb_build_object('quotes', v_rows, 'rates', to_jsonb(v_settings)),
|
|
'Consulta de cuotas IMSS',
|
|
jsonb_build_object('fn', 'fn_imss_quote')
|
|
);
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RETURN core.rpc_from_exception('fn_imss_quote', SQLSTATE, SQLERRM);
|
|
END;
|
|
$$;
|
|
|
|
--changeset panel:core-050d-fn-imss-wage splitStatements:false
|
|
CREATE OR REPLACE FUNCTION core.fn_worker_imss_wage_set(payload jsonb)
|
|
RETURNS jsonb
|
|
LANGUAGE plpgsql
|
|
SECURITY INVOKER
|
|
SET search_path = core
|
|
AS $$
|
|
DECLARE
|
|
v_id bigint := NULLIF(payload->>'id', '')::bigint;
|
|
v_wage numeric := NULLIF(payload->>'imss_daily_wage', '')::numeric;
|
|
BEGIN
|
|
UPDATE workers SET imss_daily_wage = v_wage, updated_at = now() WHERE id = v_id;
|
|
IF NOT FOUND THEN
|
|
RETURN core.rpc_err('NOT_FOUND', 'Trabajador no encontrado', jsonb_build_object('fn', 'fn_worker_imss_wage_set', 'id', v_id));
|
|
END IF;
|
|
RETURN core.rpc_ok(jsonb_build_object('id', v_id, 'imss_daily_wage', v_wage), 'Jornal IMSS actualizado',
|
|
jsonb_build_object('fn', 'fn_worker_imss_wage_set', 'id', v_id));
|
|
EXCEPTION WHEN OTHERS THEN
|
|
RETURN core.rpc_from_exception('fn_worker_imss_wage_set', SQLSTATE, SQLERRM);
|
|
END;
|
|
$$;
|
|
|
|
--changeset panel:core-050e-grants endDelimiter:; splitStatements:true
|
|
GRANT EXECUTE ON FUNCTION core.fn_imss_quote(jsonb) TO panels_core_app;
|
|
GRANT EXECUTE ON FUNCTION core.fn_worker_imss_wage_set(jsonb) TO panels_core_app;
|