mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 12:43:18 +00:00
fix: curva del programa de obra sin agregados SQL anidados
Tras importar Excel el GET /work-program fallaba con 42803 porque fn_work_program_get hacía jsonb_agg(... SUM(...)). El SUM queda en una subquery y jsonb_agg afuera. Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
This commit is contained in:
parent
4750dab95f
commit
8617bdfecf
2 changed files with 93 additions and 0 deletions
|
|
@ -45,5 +45,6 @@
|
||||||
<include file="changesets/033-catalog-suppliers-units.sql" relativeToChangelogFile="true"/>
|
<include file="changesets/033-catalog-suppliers-units.sql" relativeToChangelogFile="true"/>
|
||||||
<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"/>
|
||||||
|
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|
|
||||||
92
db/core/changesets/036-fn-work-program-get-curve.sql
Normal file
92
db/core/changesets/036-fn-work-program-get-curve.sql
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
--liquibase formatted sql
|
||||||
|
-- PANELS · core · fn_work_program_get: jsonb_agg no puede anidar SUM (42803)
|
||||||
|
|
||||||
|
--changeset panel:core-036-fn-work-program-get-curve 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_scheduled jsonb;
|
||||||
|
v_cumulative numeric := 0;
|
||||||
|
v_row jsonb;
|
||||||
|
v_arr jsonb := '[]'::jsonb;
|
||||||
|
v_pct_period numeric;
|
||||||
|
v_pct_cum numeric;
|
||||||
|
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;
|
||||||
|
|
||||||
|
-- SUM va en la subquery; jsonb_agg afuera. Postgres no permite agregados anidados
|
||||||
|
-- (sqlstate 42803) y esto petaba el GET justo después de importar por partida.
|
||||||
|
SELECT COALESCE(jsonb_agg(to_jsonb(x) ORDER BY x.period_index), '[]'::jsonb)
|
||||||
|
INTO v_scheduled
|
||||||
|
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;
|
||||||
|
|
||||||
|
FOR v_row IN SELECT value FROM jsonb_array_elements(v_scheduled) LOOP
|
||||||
|
v_pct_period := CASE WHEN v_budget_total > 0
|
||||||
|
THEN round((v_row.value->>'amount')::numeric / v_budget_total, 6) ELSE 0 END;
|
||||||
|
v_cumulative := v_cumulative + (v_row.value->>'amount')::numeric;
|
||||||
|
v_pct_cum := CASE WHEN v_budget_total > 0 THEN round(v_cumulative / v_budget_total, 6) ELSE 0 END;
|
||||||
|
v_arr := v_arr || jsonb_build_array(jsonb_build_object(
|
||||||
|
'period_index', v_row.value->'period_index',
|
||||||
|
'label', v_row.value->'label',
|
||||||
|
'amount', v_row.value->'amount',
|
||||||
|
'pct_period', v_pct_period,
|
||||||
|
'pct_cumulative', v_pct_cum
|
||||||
|
));
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
RETURN core.rpc_ok(
|
||||||
|
jsonb_build_object(
|
||||||
|
'program', v_program,
|
||||||
|
'periods', v_periods,
|
||||||
|
'budget_subtotal', v_budget_total,
|
||||||
|
'curve', v_arr
|
||||||
|
),
|
||||||
|
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;
|
||||||
|
$$;
|
||||||
Loading…
Reference in a new issue