mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 10:43:18 +00:00
<!-- CURSOR_AGENT_PR_BODY_BEGIN --> ## Problema Tras cargar el programa, la pantalla pide en paralelo get / concepts / partidas / **vs-cost**. El vs-cost fallaba: `fn_work_program_vs_cost (sqlstate=42703): column m.project_id does not exist` `warehouse_movements` no tiene `project_id`. El proyecto está en `warehouses.project_id`. ## Cambio (changeset 038) - Salidas de almacén por `JOIN warehouses w ON w.id = m.warehouse_id WHERE w.project_id = …` - Ejecutado por partida **sin duplicar** al cruzar varias semanas (el join anterior multiplicaba el monto) ## Prueba local (hecha antes de pedir merge) En Postgres 16 corrí las **4 RPCs** que usa la página, con presupuesto, 2 semanas, gasto $50 y salida de almacén $25: - `fn_work_program_get` — curva 400 / 600 - `fn_work_program_list_concepts` — items - `fn_work_program_list_partidas` — A001 - `fn_work_program_vs_cost` — ejecutado semanal **75**, por partida **75** (no 150) Script: `scripts/verify-work-program-load.sh` ## Cómo probar en tu ambiente 1. Mergear y aplicar Liquibase (038). 2. Recargar Programa de obra en la obra ya importada. Sin toast rojo. 3. La pestaña / bloque de programado vs costo debe abrir. <!-- CURSOR_AGENT_PR_BODY_END --> <div><a href="https://cursor.com/agents/bc-d8a5d34a-ead9-4912-8296-322cff799783?cursor_ref=pr_footer&cursor_cta=open_in_web"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-web-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-web-light.png"><img alt="Open in Web" width="114" height="28" src="https://cursor.com/assets/images/open-in-web-dark.png"></picture></a> <a href="https://cursor.com/background-agent?bcId=bc-d8a5d34a-ead9-4912-8296-322cff799783&cursor_ref=pr_footer&cursor_cta=open_in_cursor"><picture><source media="(prefers-color-scheme: dark)" srcset="https://cursor.com/assets/images/open-in-cursor-dark.png"><source media="(prefers-color-scheme: light)" srcset="https://cursor.com/assets/images/open-in-cursor-light.png"><img alt="Open in Cursor" width="131" height="28" src="https://cursor.com/assets/images/open-in-cursor-dark.png"></picture></a> </div>
91 lines
4.2 KiB
SQL
91 lines
4.2 KiB
SQL
SET search_path = core;
|
|
|
|
INSERT INTO projects (name, start_date, end_date) VALUES ('Obra test', '2026-09-07', '2026-09-19');
|
|
-- id = 1
|
|
|
|
INSERT INTO budget_chapters (project_id, code, name, sort_order) VALUES (1, 'A001', 'PRELIMINARES', 1);
|
|
INSERT INTO budget_items (project_id, chapter_id, code, description, amount, sort_order)
|
|
VALUES (1, 1, '10301-001', 'Trazo', 1000, 1);
|
|
|
|
INSERT INTO work_programs (project_id, start_date, end_date, duration_days, source, status)
|
|
VALUES (1, '2026-09-07', '2026-09-19', 13, 'import', 'active');
|
|
|
|
INSERT INTO work_program_periods (program_id, period_index, label, start_date, end_date) VALUES
|
|
(1, 1, 'Sem 1', '2026-09-07', '2026-09-13'),
|
|
(1, 2, 'Sem 2', '2026-09-14', '2026-09-19');
|
|
|
|
INSERT INTO work_program_partida_amounts (program_id, budget_chapter_id, period_id, amount) VALUES
|
|
(1, 1, 1, 400.00),
|
|
(1, 1, 2, 600.00);
|
|
|
|
INSERT INTO work_program_concept_slots (program_id, budget_item_id, period_id, start_pct, end_pct)
|
|
VALUES (1, 1, 1, 0, 50);
|
|
|
|
INSERT INTO expense_entries (project_id, expense_date, subtotal, status, counts_toward_budget, budget_item_id)
|
|
VALUES (1, '2026-09-08', 50.00, 'confirmed', true, 1);
|
|
|
|
INSERT INTO warehouses (tenant_id, kind, project_id) VALUES (1, 'project', 1);
|
|
INSERT INTO warehouse_materials (tenant_id, code, name) VALUES (1, 'CEM', 'Cemento');
|
|
INSERT INTO warehouse_movements (tenant_id, warehouse_id, material_id, movement_type, movement_date, quantity, total_cost, budget_item_id)
|
|
VALUES (1, 1, 1, 'exit', '2026-09-09', 1, 25.00, 1);
|
|
|
|
DO $$
|
|
DECLARE
|
|
v_get jsonb;
|
|
v_concepts jsonb;
|
|
v_partidas jsonb;
|
|
v_vs jsonb;
|
|
v_broken jsonb;
|
|
BEGIN
|
|
v_get := fn_work_program_get(jsonb_build_object('project_id', 1));
|
|
IF NOT COALESCE((v_get->>'ok')::boolean, false) THEN
|
|
RAISE EXCEPTION 'fn_work_program_get failed: %', v_get->>'message';
|
|
END IF;
|
|
IF jsonb_array_length(v_get->'data'->'curve') <> 2 THEN
|
|
RAISE EXCEPTION 'curve expected 2 periods, got %', v_get->'data'->'curve';
|
|
END IF;
|
|
IF (v_get->'data'->'curve'->0->>'amount')::numeric <> 400 THEN
|
|
RAISE EXCEPTION 'curve week1 amount %, expected 400', v_get->'data'->'curve'->0->>'amount';
|
|
END IF;
|
|
IF (v_get->'data'->'curve'->1->>'amount')::numeric <> 600 THEN
|
|
RAISE EXCEPTION 'curve week2 amount %, expected 600', v_get->'data'->'curve'->1->>'amount';
|
|
END IF;
|
|
|
|
v_concepts := fn_work_program_list_concepts(jsonb_build_object('project_id', 1));
|
|
IF NOT COALESCE((v_concepts->>'ok')::boolean, false) THEN
|
|
RAISE EXCEPTION 'fn_work_program_list_concepts failed: %', v_concepts->>'message';
|
|
END IF;
|
|
IF jsonb_array_length(v_concepts->'data'->'items') < 1 THEN
|
|
RAISE EXCEPTION 'concepts empty: %', v_concepts;
|
|
END IF;
|
|
|
|
v_partidas := fn_work_program_list_partidas(jsonb_build_object('project_id', 1));
|
|
IF NOT COALESCE((v_partidas->>'ok')::boolean, false) THEN
|
|
RAISE EXCEPTION 'fn_work_program_list_partidas failed: %', v_partidas->>'message';
|
|
END IF;
|
|
IF (v_partidas->'data'->'chapters'->0->>'code') <> 'A001' THEN
|
|
RAISE EXCEPTION 'partida code %, expected A001', v_partidas->'data'->'chapters'->0->>'code';
|
|
END IF;
|
|
|
|
v_vs := fn_work_program_vs_cost(jsonb_build_object('project_id', 1));
|
|
IF NOT COALESCE((v_vs->>'ok')::boolean, false) THEN
|
|
RAISE EXCEPTION 'fn_work_program_vs_cost failed: %', v_vs->>'message';
|
|
END IF;
|
|
-- Sem 1: gasto 50 + salida almacén 25 = 75
|
|
IF (v_vs->'data'->'by_period'->0->>'executed_amount')::numeric <> 75 THEN
|
|
RAISE EXCEPTION 'vs-cost week1 executed %, expected 75. payload=%',
|
|
v_vs->'data'->'by_period'->0->>'executed_amount', v_vs;
|
|
END IF;
|
|
IF (v_vs->'data'->'by_period'->0->>'scheduled_amount')::numeric <> 400 THEN
|
|
RAISE EXCEPTION 'vs-cost week1 scheduled %, expected 400', v_vs->'data'->'by_period'->0->>'scheduled_amount';
|
|
END IF;
|
|
IF (v_vs->'data'->'by_chapter'->0->>'executed_amount')::numeric <> 75 THEN
|
|
RAISE EXCEPTION 'vs-cost chapter executed %, expected 75', v_vs->'data'->'by_chapter'->0->>'executed_amount';
|
|
END IF;
|
|
IF (v_vs->'data'->'by_chapter'->0->>'scheduled_amount')::numeric <> 1000 THEN
|
|
RAISE EXCEPTION 'vs-cost chapter scheduled %, expected 1000', v_vs->'data'->'by_chapter'->0->>'scheduled_amount';
|
|
END IF;
|
|
|
|
RAISE NOTICE 'OK get+concepts+partidas+vs-cost';
|
|
END;
|
|
$$;
|