Pre-computed merge for change #22

This commit is contained in:
Cursor Origin 1970-01-01 00:00:00 +00:00
commit 43165024eb
2 changed files with 86 additions and 0 deletions

View file

@ -46,5 +46,6 @@
<include file="changesets/034-fn-expense-update-reclassify.sql" relativeToChangelogFile="true"/> <include file="changesets/034-fn-expense-update-reclassify.sql" relativeToChangelogFile="true"/>
<include file="changesets/035-warehouse-materials-catalog.sql" relativeToChangelogFile="true"/> <include file="changesets/035-warehouse-materials-catalog.sql" relativeToChangelogFile="true"/>
<include file="changesets/036-fn-work-program-get-curve.sql" relativeToChangelogFile="true"/> <include file="changesets/036-fn-work-program-get-curve.sql" relativeToChangelogFile="true"/>
<include file="changesets/037-fn-work-program-get-curve-vrow.sql" relativeToChangelogFile="true"/>
</databaseChangeLog> </databaseChangeLog>

View file

@ -0,0 +1,85 @@
--liquibase formatted sql
-- PANELS · core · fn_work_program_get: v_row es jsonb, no un record (.value = 42P01)
--changeset panel:core-037-fn-work-program-get-curve-vrow splitStatements:false
CREATE OR REPLACE FUNCTION core.fn_work_program_get(payload jsonb)
RETURNS jsonb
LANGUAGE plpgsql
SECURITY INVOKER
SET search_path = core
AS $$
DECLARE
v_project_id bigint := NULLIF(payload->>'project_id', '')::bigint;
v_program jsonb;
v_periods jsonb;
v_budget_total numeric(14,2);
v_curve jsonb;
BEGIN
IF v_project_id IS NULL THEN
RETURN core.rpc_err('VALIDATION', 'fn_work_program_get: project_id es obligatorio',
jsonb_build_object('fn', 'fn_work_program_get'));
END IF;
SELECT to_jsonb(wp) INTO v_program
FROM work_programs wp WHERE wp.project_id = v_project_id;
IF v_program IS NULL THEN
SELECT COALESCE(SUM(amount), 0) INTO v_budget_total FROM budget_items WHERE project_id = v_project_id;
RETURN core.rpc_ok(
jsonb_build_object(
'program', NULL,
'periods', '[]'::jsonb,
'budget_subtotal', v_budget_total,
'curve', '[]'::jsonb
),
format('Proyecto %s sin programa de obra', v_project_id),
jsonb_build_object('fn', 'fn_work_program_get', 'project_id', v_project_id)
);
END IF;
SELECT COALESCE(jsonb_agg(to_jsonb(p) ORDER BY p.period_index), '[]'::jsonb) INTO v_periods
FROM work_program_periods p WHERE p.program_id = (v_program->>'id')::bigint;
SELECT COALESCE(SUM(amount), 0) INTO v_budget_total FROM budget_items WHERE project_id = v_project_id;
-- Sin FOR + v_row.value (eso lo toma Postgres como tabla.columna → 42P01).
-- SUM de montos en subquery; jsonb_agg y el acumulado van en capas distintas
-- para no anidar agregados (42803).
SELECT COALESCE(jsonb_agg(to_jsonb(y) ORDER BY y.period_index), '[]'::jsonb)
INTO v_curve
FROM (
SELECT
x.period_index,
x.label,
x.amount,
CASE WHEN v_budget_total > 0 THEN round(x.amount / v_budget_total, 6) ELSE 0 END AS pct_period,
CASE WHEN v_budget_total > 0
THEN round(SUM(x.amount) OVER (ORDER BY x.period_index) / v_budget_total, 6)
ELSE 0
END AS pct_cumulative
FROM (
SELECT
pr.period_index,
pr.label,
round(COALESCE(SUM(pa.amount), 0), 2) AS amount
FROM work_program_periods pr
LEFT JOIN work_program_partida_amounts pa ON pa.period_id = pr.id
WHERE pr.program_id = (v_program->>'id')::bigint
GROUP BY pr.period_index, pr.label
) x
) y;
RETURN core.rpc_ok(
jsonb_build_object(
'program', v_program,
'periods', v_periods,
'budget_subtotal', v_budget_total,
'curve', v_curve
),
format('Programa de obra del proyecto %s', v_project_id),
jsonb_build_object('fn', 'fn_work_program_get', 'project_id', v_project_id)
);
EXCEPTION WHEN OTHERS THEN
RETURN core.rpc_from_exception('fn_work_program_get', SQLSTATE, SQLERRM);
END;
$$;