Partidas y capítulos (BudgetItem)
Fichero: backend/app/models/budget_item.py.
BudgetItem representa cualquier línea del presupuesto: capítulos, partidas, subtotales (Ʃ) y porcentajes (%). Se organiza como un árbol mediante parent_id.
Campos principales
Sección titulada «Campos principales»| Campo | Tipo | Descripción |
|---|---|---|
id |
UUID | PK |
budget_id |
UUID | FK a budgets. |
parent_id |
UUID | FK a sí mismo; raíz si es null. |
codigo |
string(20) | Código del concepto. |
codigo_origen |
string(40) | Código original (BC3). |
descripcion |
string(500) | Descripción corta. |
descripcion_larga |
text | Descripción larga. |
unidad |
string(20) | Unidad de medida. |
cantidad |
Numeric(18,4) | Cantidad presupuestada. |
precio_unitario |
Numeric(18,4) | Precio unitario. |
importe |
Numeric(18,4) | Importe calculado. |
precio_venta |
Numeric(18,4) | Precio de venta final. |
beneficio_industrial_pct |
Numeric(5,2) | BI propio. |
gastos_generales_pct |
Numeric(5,2) | GG propio. |
iva_pct |
Numeric(5,2) | IVA propio. |
tipo |
string(20) | partida, capitulo, gg, bi, etc. |
tipo_concepto |
string(20) | partida, subtotal, porcentaje. |
orden |
int | Orden dentro del padre. |
porcentaje |
Numeric(5,2) | Valor del porcentaje (%). |
es_ajuste |
bool | Indica si es un ajuste. |
cantidad_inicial / importe_inicial |
Numeric | Valores previos a cambios (liquidación). |
precio_ajustado_manual |
bool | Precio venta editado manualmente. |
precio_calculado |
Numeric | Precio calculado por el motor. |
formula_cantidad / formula_precio |
string | Fórmulas con variables. |
grupo |
string(100) | Lote / familia de compras. |
supplier_id |
UUID | Proveedor asignado. |
Tipos de concepto Presto
Sección titulada «Tipos de concepto Presto»El campo tipo_concepto distingue tres semánticas:
partida: concepto normal. Importe = cantidad × precio unitario, o Σ recursos.subtotal: código que empieza porƩ. Suma importes anteriores del mismo nivel.porcentaje: código con%. Importe = base × pct / 100.
La detección automática se hace en BudgetItem.detectar_tipo_concepto (backend/app/models/budget_item.py:115):
@staticmethoddef detectar_tipo_concepto(codigo: str, unidad: str | None = None) -> str: if codigo.startswith("Ʃ"): return "subtotal" if "%" in codigo or unidad == "%": return "porcentaje" return "partida"Relaciones
Sección titulada «Relaciones»budget: Mapped["Budget"]supplier: Mapped["Supplier | None"]parent: Mapped["BudgetItem | None"]children: Mapped[list["BudgetItem"]]breakdowns: Mapped[list["BudgetBreakdown"]]measurements: Mapped[list["BudgetMeasurement"]]scenarios: Mapped[list["BudgetItemScenario"]]Restricciones
Sección titulada «Restricciones»uq_budget_item_codigo: código único dentro de un presupuesto.ondelete="CASCADE": al borrar un padre se borran sus hijos.
Ejemplo de árbol
Sección titulada «Ejemplo de árbol»C-01 Capítulo 1 P-01 Partida A P-02 Partida B Ʃ-01 Subtotal capítuloC-02 Capítulo 2Ʃ-02 Subtotal obraVéase también Motor de cálculo para entender cómo se calculan los importes.