Guía de Administrador — Renglones Presupuestarios y Centros de Costo
Cambio importante (mayo 2026): Tras el Sub-proyecto 1, los antiguos "centros de costo" se separaron en tres tablas independientes. Esta guía cubre la administración de las 3:
- Renglones presupuestarios (
budget_positions, excost_centers) — partidas presupuestarias.- Áreas funcionales (
functional_areas) — clasificador PDVSA (26 códigos).- Centros de costo (
cost_centersnuevo) — unidades organizacionales (22 con responsable y departamento).
Guía técnica para administradores de las dimensiones contables del ERP del Consorcio Alvorada & Cladoca.
Configuración Inicial
1. Crear un Renglón Presupuestario
Acceda a Presupuesto → Renglones Presupuestarios o use la API:
POST /api/budget/positions
Content-Type: application/json
{
"code": "ACE-1-1AL-LEV",
"name": "Levantamiento Topográfico - Proyecto Norte",
"description": "Servicios de levantamiento topográfico OPEX",
"costType": "OPEX",
"functionalAreaId": "<UUID del área 'LEV'>",
"category": "Servicios Técnicos",
"subCategory": "Levantamiento",
"status": "ACTIVE"
}
Campos requeridos:
code— Código único en el sistema (patrónACE-{Cat}-{Sub}-{Área}).name— Nombre descriptivo.costType—OPEXoCAPEX.functionalAreaId— FK NOT NULL al área funcional PDVSA.
2. Crear un Centro de Costo (organizacional)
POST /api/accounting/cost-centers
Content-Type: application/json
{
"code": "CC-OPS-NORTE",
"name": "Operaciones Norte",
"type": "PRODUCTIVE",
"departmentId": "<UUID departamento OPS>",
"parentId": "<UUID CC-OPS>",
"managerId": "<UUID empleado responsable>",
"status": "ACTIVE"
}
3. Crear un Área Funcional
POST /api/accounting/functional-areas
Content-Type: application/json
{
"code": "WELL",
"name": "Pozos Especiales",
"description": "Servicios a pozos no clasificados en LEV/SCT/SST",
"category": "UPSTREAM_OPERATIONS",
"status": "ACTIVE"
}
Las 26 áreas funcionales iniciales se cargan automáticamente con la migración
20260501000001-create-functional-areas-table.js.
4. Importación Masiva de Renglones
Para cargar múltiples renglones use el endpoint de importación:
POST /api/budget/positions/import
Content-Type: multipart/form-data
file: renglones-presupuestarios.xlsx
Formato del archivo Excel:
| code | name | costType | functionalAreaCode | category | subCategory |
|---|---|---|---|---|---|
| ACE-1-1AL-LEV | Alimentación Levantamiento | OPEX | LEV | Logística | Alimentación |
| ACE-CAPEX-INPR | Inversión Producción 2026 | CAPEX | INPR | Construcción | Producción |
El sistema resuelve
functionalAreaCode→functionalAreaIddurante la importación.
Configuración de Permisos
Permisos del Módulo
| Permiso | Descripción | Quién debe tenerlo |
|---|---|---|
budget:read | Ver dashboards y reportes de presupuesto | Todos los usuarios con acceso a presupuestos |
budget:positions:read | Ver renglones presupuestarios | Todos los usuarios |
budget:positions:write | Crear y editar renglones | Administradores y Jefes de Área |
accounting:cost-centers:read | Ver centros de costo | Todos los usuarios |
accounting:cost-centers:write | Crear/editar CCs | Administradores |
accounting:functional-areas:read | Ver áreas funcionales | Todos los usuarios |
accounting:functional-areas:write | Crear/editar áreas | Administradores y Gerencia Finanzas |
accounting:mappings:read | Ver mapeos cuenta↔renglón | Contabilidad y Finanzas |
accounting:mappings:write | Crear/editar mapeos | Contadores |
Permisos legacy DEPRECATED:
cost-centers:read|writeredirigen abudget:positions:read|writedurante 1 release.
Asignar Permisos en el Sistema
POST /api/roles/{roleId}/permissions
{
"permissions": [
"budget:positions:read",
"accounting:cost-centers:read",
"budget:read"
]
}
GET /api/users/{userId}/permissions
Vinculación con Planes Presupuestarios
Crear un Plan con Renglones y Centros de Costo
- Crear el
BudgetPlanconbudgetType: "OPEX"o"CAPEX". - Crear
BudgetLinereferenciandobudgetPositionIdycostCenterId.
# 1. Crear plan OPEX
POST /api/budget/plans
{
"fiscalYear": 2026,
"budgetType": "OPEX",
"departmentId": "<UUID dept>",
"description": "Presupuesto Operacional 2026"
}
# 2. Crear línea con renglón + CC
POST /api/budget/lines
{
"budgetPlanId": "<UUID plan>",
"budgetPositionId": "<UUID renglón>",
"costCenterId": "<UUID CC>",
"categoryId": "<UUID categoría>",
"description": "Servicios de levantamiento Q1",
"plannedAmount": 150000
}
functional_area_id se infiere automáticamente desde budget_position.functional_area_id si no se proporciona.
Importante:
BudgetLineno tiene columnabudgetType. El tipo OPEX/CAPEX se determina siempre a través delBudgetPlanasociado. Nunca filtre directamente enBudgetLine.budgetType.Validación:
budget_position.cost_typedebe coincidir conBudgetPlan.budgetType. Si no coinciden, la creación de la línea falla con 422.
Configurar Mapeos Cuenta ↔ Renglón
Reemplaza el JSONB cost_centers.accounting_accounts viejo. Use:
POST /api/accounting/account-position-links
{
"accountId": "<UUID cuenta 6.3.01.018>",
"budgetPositionId": "<UUID ACE-1-1AL-LEV>",
"role": "DEBIT_DEFAULT"
}
Reglas:
- Sólo un
DEBIT_DEFAULTpor cuenta. - Sólo un
CREDIT_DEFAULTpor cuenta. - Múltiples
ALLOWEDpor cuenta (whitelist amplia).
Migración de Datos Existentes
Los datos del modelo viejo se migraron automáticamente con las migraciones M1-M9 del Sub-proyecto 1. Snapshot del proceso:
| Migración | Acción |
|---|---|
| M1 | CREATE functional_areas + seed 26 áreas |
| M2 | RENAME cost_centers → budget_positions (preserva UUIDs) |
| M3 | ARCHIVE columnas mensuales en budget_positions_legacy_excel |
| M4 | UPDATE budget_positions.functional_area_id desde pdvsa_code |
| M5 | CREATE nueva cost_centers (organizacional) + seed 22 CCs |
| M6 | CREATE account_budget_position_links |
| M7 | EXTEND journal_entry_lines con dimensiones |
| M8 | EXTEND budget_lines, budget_commitments, afe_expenses con dimensiones |
| M9 | DROP columnas DEPRECATED |
Si necesita reasignar áreas funcionales o renglones a CCs después del Sub-proyecto 1, use los endpoints PUT correspondientes — la lógica viene en journalEntryService y budgetLineService.
Configuración de Alertas Presupuestarias
Las alertas se generan automáticamente cuando la ejecución supera umbrales configurados. Para ajustar los umbrales, modifique las constantes en:
backend_erp/src/modules/budget/services/budgetAlertService.js
const ALERT_THRESHOLDS = {
WARNING: 0.80, // Alerta amarilla al 80%
CRITICAL: 0.95, // Alerta roja al 95%
};
Monitoreo y Resolución de Problemas
Verificar endpoint de ejecución por renglón
curl -H "Authorization: Bearer {token}" \
"http://localhost:5001/api/budget/dashboard/execution-by-position?fiscalYear=2026&costType=opex"
Respuesta esperada:
{
"fiscalYear": 2026,
"costType": "opex",
"positions": [
{
"budgetPositionId": "bp-...",
"code": "ACE-1-1AL-LEV",
"name": "Levantamiento - Alimentación",
"functionalAreaCode": "LEV",
"costType": "OPEX",
"totalPlanned": 150000,
"totalCommitted": 45000,
"totalExecuted": 80000,
"totalAvailable": 25000,
"executionPercentage": "53.33"
}
]
}
Problemas Comunes
Error: "column BudgetLine.budgetType does not exist"
Este error ocurre si el código intenta filtrar directamente en BudgetLine por budgetType. La columna no existe en esa tabla. El filtro debe aplicarse en el include de BudgetPlan:
// ❌ Incorrecto
where: { budgetType: 'OPEX' } // en BudgetLine
// ✅ Correcto
include: [{
model: BudgetPlan,
where: { budgetType: 'OPEX' },
attributes: []
}]
Error 422 al crear JournalEntryLine: "cost_center_id requerido para cuenta EXPENSE"
journalEntryService.create() valida que toda línea cuya cuenta sea EXPENSE o REVENUE lleve cost_center_id. Para FIXED_ASSET o INTANGIBLE_ASSET exige project_id. Asegure que los formularios y servicios upstream propaguen las dimensiones correctas.
Error 422: "no existe link en account_budget_position_links"
Si una línea trae budget_position_id, debe existir un link configurado para esa cuenta. Cree el link con POST /api/accounting/account-position-links.
Dashboard no muestra datos de renglones o CCs
- Verificar permisos:
budget:positions:read,accounting:cost-centers:read. - Verificar que las
BudgetLinestienenbudgetPositionIdycostCenterIdasignados. - Revisar los logs del backend.
Respaldo y Mantenimiento
Tablas involucradas en el módulo
| Tabla | Descripción |
|---|---|
budget_positions | Renglones presupuestarios (149 en producción) |
budget_positions_legacy_excel | Archivo histórico de columnas mensuales |
cost_centers | Centros de costo organizacionales (22) |
functional_areas | Áreas funcionales PDVSA (26) |
account_budget_position_links | Mapeo cuenta ↔ renglón con rol |
budget_plans | Planes presupuestarios (tiene budget_type) |
budget_lines | Líneas con budget_position_id, cost_center_id, functional_area_id |
budget_executions | Ejecuciones registradas |
budget_commitments | Compromisos con dimensiones propagadas |
journal_entry_lines | 5 dimensiones contables por línea |
Índices recomendados
-- Acelerar consultas de dashboard por dimensión
CREATE INDEX IF NOT EXISTS idx_budget_lines_position
ON budget_lines(budget_position_id);
CREATE INDEX IF NOT EXISTS idx_budget_lines_cost_center
ON budget_lines(cost_center_id);
CREATE INDEX IF NOT EXISTS idx_budget_positions_functional_area
ON budget_positions(functional_area_id) WHERE status = 'ACTIVE';
CREATE INDEX IF NOT EXISTS idx_je_lines_dim_combo
ON journal_entry_lines(cost_center_id, functional_area_id);