Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ElthonJohan/Sistema-MRP/llms.txt

Use this file to discover all available pages before exploring further.

The budget service manages the project layer of Sistema MRP. Each project (Budget) defines cost targets in both soles and dollars and acts as the grouping key for inventory records, requirements, and dispatches. Deleting a project cascades: pending requirements are cancelled, their stock reservations are released, and all linked inventory records are frozen. Cost reporting aggregates dispatch quantities multiplied by material unit prices, giving a real-time view of spending versus budget for every project.

create_budget

create_budget(db, name, budget_soles, budget_dolares, notes=None) -> Budget
Creates a new active project with the given name and cost targets. Negative values for budget_soles or budget_dolares are clamped to 0.0.
db
Session
required
Active SQLAlchemy session. Commits internally.
name
str
required
Project name displayed throughout the application.
budget_soles
float
required
Cost target in Peruvian soles. Clamped to 0.0 if negative or None.
budget_dolares
float
required
Cost target in US dollars. Clamped to 0.0 if negative or None.
notes
str
Optional free-text notes for the project.
return
Budget
The newly created and refreshed Budget ORM object.
from services.budget_service import create_budget

project = create_budget(
    db,
    name="Centro Comercial Norte",
    budget_soles=250000.0,
    budget_dolares=65000.0,
    notes="Q1 2025 construction phase",
)
print(f"Created project #{project.id}: {project.name}")

get_budgets

get_budgets(db) -> list
Returns all budget records ordered by created_at descending. No filtering or pagination is applied.
db
Session
required
Active SQLAlchemy session.
return
list
List of all Budget ORM objects, newest first.
from services.budget_service import get_budgets

projects = get_budgets(db)
for p in projects:
    print(f"#{p.id} {p.name} — active: {p.is_active}")

update_budget

update_budget(db, budget_id, name, budget_soles, budget_dolares, notes, is_active) -> bool
Updates one or more fields on an existing project. Any parameter passed as None is skipped, leaving the current value unchanged. Negative numeric values are clamped to 0.0.
db
Session
required
Active SQLAlchemy session. Commits internally.
budget_id
int
required
ID of the project to update.
name
str
New project name. Pass None to leave unchanged.
budget_soles
float
Updated target in soles. Clamped to 0.0 if negative.
budget_dolares
float
Updated target in dollars. Clamped to 0.0 if negative.
notes
str
Updated notes text.
is_active
bool
Set project active or inactive.
return
bool
True when the project was found and updated; False when not found.
from services.budget_service import update_budget

ok = update_budget(
    db,
    budget_id=7,
    name="Centro Comercial Norte — Revised",
    budget_soles=275000.0,
    budget_dolares=None,    # unchanged
    notes=None,             # unchanged
    is_active=None,         # unchanged
)

delete_budget

delete_budget(db, budget_id) -> tuple[bool, int]
Deletes a project and cascades the following side effects:
  1. Cancels all requirements with status pending or partial that are linked to this project (via cancel_requirement, which also releases their stock reservations).
  2. Freezes all inventory records linked to the project by setting is_active=False.
  3. Deletes the Budget record.
db
Session
required
Active SQLAlchemy session. Commits internally at the end.
budget_id
int
required
ID of the project to delete.
[0]
bool
True when the project was found and deleted; False when not found.
[1]
int
Number of requirements that were cancelled as part of the deletion. 0 when the project was not found.
from services.budget_service import delete_budget

ok, cancelled = delete_budget(db, budget_id=7)
if ok:
    print(f"Project deleted. {cancelled} requirement(s) were cancelled.")
else:
    print("Project not found")

finish_budget

finish_budget(db, budget_id) -> bool
Marks a project as finished by setting is_finished=True, is_active=False, and finished_at=datetime.utcnow(). A finished project’s inventory and history remain intact and visible; it is simply no longer accepting new requirements or dispatches.
db
Session
required
Active SQLAlchemy session. Commits internally.
budget_id
int
required
ID of the project to finish.
return
bool
True when the project was found and marked finished; False otherwise.
from services.budget_service import finish_budget

ok = finish_budget(db, budget_id=7)
if not ok:
    print("Project not found")

reactivate_budget

reactivate_budget(db, budget_id) -> bool
Reverses a finish_budget call. Sets is_finished=False, is_active=True, and clears finished_at. Does not restore frozen inventory records — those must be redirected or unfrozen separately via the inventory service.
db
Session
required
Active SQLAlchemy session. Commits internally.
budget_id
int
required
ID of the finished project to reactivate.
return
bool
True when the project was found and reactivated; False otherwise.
from services.budget_service import reactivate_budget

ok = reactivate_budget(db, budget_id=7)
if not ok:
    print("Project not found")

get_dispatch_costs

get_dispatch_costs(db, since=None, until=None) -> tuple[list, float, float]
Aggregates dispatched quantities by material and calculates cost as total_qty × unit_price. Results are sorted by total_cost descending. Optionally filtered by Dispatch.dispatch_date.
db
Session
required
Active SQLAlchemy session.
since
datetime
Return only dispatches on or after this datetime.
until
datetime
Return only dispatches on or before this datetime.
[0]
list
List of dicts, one per material, sorted by total_cost descending.
[1]
float
Sum of all total_cost values (grand total in soles).
[2]
float
Sum of all total_cost_dolares values (grand total in dollars).
from services.budget_service import get_dispatch_costs
from datetime import datetime

costs, total_soles, total_dollars = get_dispatch_costs(
    db,
    since=datetime(2025, 1, 1),
    until=datetime(2025, 3, 31),
)

print(f"Grand total: S/ {total_soles:,.2f} | $ {total_dollars:,.2f}")
for row in costs:
    print(f"  {row['material']:30s} qty={row['total_qty']:>6}  S/ {row['total_cost']:>10,.2f}")

get_all_projects_cost_summary

get_all_projects_cost_summary(db) -> list
Returns a summary dict for every project, combining budget targets with actual dispatch costs since the project’s created_at date. This function calls get_dispatch_costs once per budget, so performance scales linearly with the number of projects.
db
Session
required
Active SQLAlchemy session.
return
list
List of dicts, one per project.
from services.budget_service import get_all_projects_cost_summary

summaries = get_all_projects_cost_summary(db)
for s in summaries:
    remaining = s["budget_soles"] - s["cost_soles"]
    print(f"{s['name']}: S/ {s['cost_soles']:,.2f} spent of S/ {s['budget_soles']:,.2f} (remaining: S/ {remaining:,.2f})")

Build docs developers (and LLMs) love