mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 10:43:18 +00:00
fix: importar programa de obra sin jsonb_object_length
Postgres no tiene jsonb_object_length; fn_work_program_replace tronaba al confirmar el Excel. El conteo de semanas ahora usa un contador en el loop de periodos. Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
This commit is contained in:
parent
b0a1a3147c
commit
b7bd167e08
2 changed files with 124 additions and 0 deletions
|
|
@ -38,5 +38,6 @@
|
|||
<include file="changesets/029-schema-work-program.sql" relativeToChangelogFile="true"/>
|
||||
<include file="changesets/030-rpc-work-program.sql" relativeToChangelogFile="true"/>
|
||||
<include file="changesets/031-project-doc-types-technical.sql" relativeToChangelogFile="true"/>
|
||||
<include file="changesets/032-fix-work-program-jsonb-object-length.sql" relativeToChangelogFile="true"/>
|
||||
|
||||
</databaseChangeLog>
|
||||
|
|
|
|||
123
db/core/changesets/032-fix-work-program-jsonb-object-length.sql
Normal file
123
db/core/changesets/032-fix-work-program-jsonb-object-length.sql
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
--liquibase formatted sql
|
||||
-- PANELS · core · fn_work_program_replace: jsonb_object_length no existe en PostgreSQL
|
||||
|
||||
--changeset panel:core-032a-fn-work-program-replace-period-count splitStatements:false
|
||||
CREATE OR REPLACE FUNCTION core.fn_work_program_replace(payload jsonb)
|
||||
RETURNS jsonb
|
||||
LANGUAGE plpgsql
|
||||
SECURITY INVOKER
|
||||
SET search_path = core
|
||||
AS $$
|
||||
DECLARE
|
||||
v_project_id bigint := NULLIF(payload->>'project_id', '')::bigint;
|
||||
v_source text := COALESCE(nullif(btrim(payload->>'source'), ''), 'import');
|
||||
v_status text := COALESCE(nullif(btrim(payload->>'status'), ''), 'active');
|
||||
v_start date;
|
||||
v_end date;
|
||||
v_program_id bigint;
|
||||
v_period jsonb;
|
||||
v_period_id bigint;
|
||||
v_period_map jsonb := '{}'::jsonb;
|
||||
v_period_count integer := 0;
|
||||
v_slot jsonb;
|
||||
v_partida jsonb;
|
||||
v_chapter jsonb;
|
||||
v_ch jsonb;
|
||||
v_slot_count integer := 0;
|
||||
v_partida_count integer := 0;
|
||||
v_err jsonb;
|
||||
BEGIN
|
||||
IF v_project_id IS NULL THEN
|
||||
RETURN core.rpc_err('VALIDATION', 'fn_work_program_replace: project_id es obligatorio',
|
||||
jsonb_build_object('fn', 'fn_work_program_replace'));
|
||||
END IF;
|
||||
|
||||
v_err := core._wp_assert_project_ready(v_project_id);
|
||||
IF v_err IS NOT NULL THEN RETURN v_err; END IF;
|
||||
|
||||
SELECT start_date, end_date INTO v_start, v_end FROM projects WHERE id = v_project_id;
|
||||
|
||||
DELETE FROM work_programs WHERE project_id = v_project_id;
|
||||
|
||||
INSERT INTO work_programs (project_id, start_date, end_date, duration_days, source, status)
|
||||
VALUES (v_project_id, v_start, v_end, (v_end - v_start + 1), v_source, v_status)
|
||||
RETURNING id INTO v_program_id;
|
||||
|
||||
FOR v_period IN SELECT * FROM jsonb_array_elements(core._wp_generate_periods(v_start, v_end)) LOOP
|
||||
INSERT INTO work_program_periods (program_id, period_index, label, start_date, end_date)
|
||||
VALUES (
|
||||
v_program_id,
|
||||
(v_period->>'period_index')::integer,
|
||||
v_period->>'label',
|
||||
(v_period->>'start_date')::date,
|
||||
(v_period->>'end_date')::date
|
||||
)
|
||||
RETURNING id INTO v_period_id;
|
||||
v_period_map := v_period_map || jsonb_build_object(v_period->>'period_index', v_period_id);
|
||||
v_period_count := v_period_count + 1;
|
||||
END LOOP;
|
||||
|
||||
FOR v_slot IN SELECT * FROM jsonb_array_elements(COALESCE(payload->'concept_slots', '[]'::jsonb)) LOOP
|
||||
v_period_id := (v_period_map->>(v_slot->>'period_index'))::bigint;
|
||||
IF v_period_id IS NULL THEN CONTINUE; END IF;
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM budget_items bi
|
||||
WHERE bi.id = (v_slot->>'budget_item_id')::bigint AND bi.project_id = v_project_id
|
||||
) THEN CONTINUE; END IF;
|
||||
IF core._wp_slot_weight((v_slot->>'start_pct')::numeric, (v_slot->>'end_pct')::numeric) <= 0 THEN CONTINUE; END IF;
|
||||
INSERT INTO work_program_concept_slots (program_id, budget_item_id, period_id, start_pct, end_pct)
|
||||
VALUES (
|
||||
v_program_id,
|
||||
(v_slot->>'budget_item_id')::bigint,
|
||||
v_period_id,
|
||||
COALESCE((v_slot->>'start_pct')::numeric, 0),
|
||||
COALESCE((v_slot->>'end_pct')::numeric, 0)
|
||||
);
|
||||
v_slot_count := v_slot_count + 1;
|
||||
END LOOP;
|
||||
|
||||
FOR v_ch IN SELECT * FROM jsonb_array_elements(COALESCE(payload->'chapters_to_create', '[]'::jsonb)) LOOP
|
||||
INSERT INTO budget_chapters (project_id, parent_id, code, name, wbs, sort_order)
|
||||
VALUES (
|
||||
v_project_id,
|
||||
NULLIF(v_ch->>'parent_id', '')::bigint,
|
||||
upper(COALESCE(nullif(btrim(v_ch->>'code'), ''), '')),
|
||||
COALESCE(nullif(btrim(v_ch->>'name'), ''), 'Partida'),
|
||||
COALESCE(nullif(btrim(v_ch->>'wbs'), ''), ''),
|
||||
COALESCE((v_ch->>'sort_order')::integer, 0)
|
||||
);
|
||||
END LOOP;
|
||||
|
||||
FOR v_partida IN SELECT * FROM jsonb_array_elements(COALESCE(payload->'partida_amounts', '[]'::jsonb)) LOOP
|
||||
v_period_id := (v_period_map->>(v_partida->>'period_index'))::bigint;
|
||||
IF v_period_id IS NULL THEN CONTINUE; END IF;
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM budget_chapters bc
|
||||
WHERE bc.id = (v_partida->>'budget_chapter_id')::bigint AND bc.project_id = v_project_id
|
||||
) THEN CONTINUE; END IF;
|
||||
IF COALESCE((v_partida->>'amount')::numeric, 0) = 0 THEN CONTINUE; END IF;
|
||||
INSERT INTO work_program_partida_amounts (program_id, budget_chapter_id, period_id, amount)
|
||||
VALUES (
|
||||
v_program_id,
|
||||
(v_partida->>'budget_chapter_id')::bigint,
|
||||
v_period_id,
|
||||
round(COALESCE((v_partida->>'amount')::numeric, 0), 2)
|
||||
);
|
||||
v_partida_count := v_partida_count + 1;
|
||||
END LOOP;
|
||||
|
||||
RETURN core.rpc_ok(
|
||||
jsonb_build_object(
|
||||
'program_id', v_program_id,
|
||||
'concept_slots', v_slot_count,
|
||||
'partida_amounts', v_partida_count,
|
||||
'period_count', v_period_count
|
||||
),
|
||||
format('Programa de obra del proyecto %s reemplazado (%s slots, %s erogaciones)',
|
||||
v_project_id, v_slot_count, v_partida_count),
|
||||
jsonb_build_object('fn', 'fn_work_program_replace', 'project_id', v_project_id)
|
||||
);
|
||||
EXCEPTION WHEN OTHERS THEN
|
||||
RETURN core.rpc_from_exception('fn_work_program_replace', SQLSTATE, SQLERRM);
|
||||
END;
|
||||
$$;
|
||||
Loading…
Reference in a new issue