mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 12:03:17 +00:00
- Añade cost_modules_test.ts con CRUD de gastos, almacén, control presupuestal e IAM - Amplía crud-smoke-test.sh para cubrir todos los endpoints HTTP nuevos - Corrige migración IAM: grants de core.rpc_* movidos a changeset core-027 - Corrige ambigüedad PL/pgSQL en _cost_settings que rompía fn_expense_create Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
88 lines
2.5 KiB
PL/PgSQL
88 lines
2.5 KiB
PL/PgSQL
--liquibase formatted sql
|
|
-- PANELS · core · fix ambigüedad de columnas en _cost_settings (RETURNS TABLE vs tenant_cost_settings)
|
|
|
|
--changeset panel:core-028a-fix-cost-settings splitStatements:false
|
|
CREATE OR REPLACE FUNCTION core._cost_settings(p_tenant_id integer)
|
|
RETURNS TABLE (
|
|
budget_warn_pct numeric,
|
|
budget_critical_pct numeric,
|
|
default_iva_rate numeric
|
|
)
|
|
LANGUAGE plpgsql
|
|
STABLE
|
|
SET search_path = core
|
|
AS $$
|
|
BEGIN
|
|
RETURN QUERY
|
|
SELECT
|
|
COALESCE(s.budget_warn_pct, 85::numeric),
|
|
COALESCE(s.budget_critical_pct, 100::numeric),
|
|
COALESCE(s.default_iva_rate, 0.16::numeric)
|
|
FROM (
|
|
SELECT t.budget_warn_pct, t.budget_critical_pct, t.default_iva_rate
|
|
FROM tenant_cost_settings t
|
|
WHERE t.tenant_id = p_tenant_id
|
|
) s
|
|
UNION ALL
|
|
SELECT 85::numeric, 100::numeric, 0.16::numeric
|
|
WHERE NOT EXISTS (SELECT 1 FROM tenant_cost_settings WHERE tenant_id = p_tenant_id)
|
|
LIMIT 1;
|
|
END;
|
|
$$;
|
|
|
|
--changeset panel:core-028b-fix-cost-budget-warning splitStatements:false
|
|
CREATE OR REPLACE FUNCTION core._cost_budget_warning(
|
|
p_tenant_id integer,
|
|
p_budget_item_id bigint,
|
|
p_add_subtotal numeric DEFAULT 0,
|
|
p_add_qty numeric DEFAULT 0
|
|
)
|
|
RETURNS jsonb
|
|
LANGUAGE plpgsql
|
|
STABLE
|
|
SET search_path = core
|
|
AS $$
|
|
DECLARE
|
|
v_item record;
|
|
v_warn numeric;
|
|
v_critical numeric;
|
|
v_exec_amt numeric;
|
|
v_exec_qty numeric;
|
|
v_pct numeric;
|
|
v_level text;
|
|
BEGIN
|
|
IF p_budget_item_id IS NULL THEN
|
|
RETURN NULL;
|
|
END IF;
|
|
SELECT id, description, amount, quantity INTO v_item
|
|
FROM budget_items WHERE id = p_budget_item_id;
|
|
IF NOT FOUND OR COALESCE(v_item.amount, 0) <= 0 THEN
|
|
RETURN NULL;
|
|
END IF;
|
|
SELECT cs.budget_warn_pct, cs.budget_critical_pct INTO v_warn, v_critical
|
|
FROM core._cost_settings(p_tenant_id) cs;
|
|
v_exec_amt := core._cost_executed_amount(p_budget_item_id) + COALESCE(p_add_subtotal, 0);
|
|
v_exec_qty := core._cost_executed_qty(p_budget_item_id) + COALESCE(p_add_qty, 0);
|
|
v_pct := round(v_exec_amt / v_item.amount * 100, 1);
|
|
IF v_pct > v_critical THEN
|
|
v_level := 'critical';
|
|
ELSIF v_pct > v_warn THEN
|
|
v_level := 'warn';
|
|
ELSE
|
|
RETURN NULL;
|
|
END IF;
|
|
RETURN jsonb_build_object(
|
|
'level', v_level,
|
|
'budget_item_id', p_budget_item_id,
|
|
'pct_after', v_pct,
|
|
'executed_amount', v_exec_amt,
|
|
'budget_amount', v_item.amount,
|
|
'executed_qty', v_exec_qty,
|
|
'budget_qty', v_item.quantity,
|
|
'message', format(
|
|
'Esta operación dejará el concepto "%s" al %s%% del presupuesto (importe)',
|
|
left(v_item.description, 80), v_pct
|
|
)
|
|
);
|
|
END;
|
|
$$;
|