Flatten budget-app contents into repo root

This commit is contained in:
jpmvaz
2026-10-29 20:41:01 +00:00
parent c9fd26f1c7
commit 93f2696764
95 changed files with 184 additions and 187 deletions
+71
View File
@@ -0,0 +1,71 @@
from decimal import Decimal
from io import BytesIO
import openpyxl
from app.calc import selected_spread
def test_selected_spread_in_cents():
months = selected_spread(Decimal("1000.00"), [1, 2, 3])
assert months[:3] == [Decimal("333.33"), Decimal("333.33"), Decimal("333.34")]
assert sum(months) == Decimal("1000.00") and months[3:] == [0] * 9
assert selected_spread(Decimal("120"), [4, 1, 3, 2, 2]) == [30, 30, 30, 30] + [0] * 8
assert selected_spread(Decimal("12"), []) == [1] * 12
def _first_line(client, year_id):
return client.get(f"/api/years/{year_id}").json()["categories"][0]["lines"][0]
def test_line_split_over_chosen_months(client, imported):
line = _first_line(client, imported)
r = client.put(f"/api/lines/{line['id']}", json={"monthly_kind": "selected", "monthly_months": [4, 1, 2, 3, 3]})
assert r.status_code == 200, r.text
after = _first_line(client, imported)
assert after["monthly_kind"] == "selected" and after["monthly_months"] == [1, 2, 3, 4]
assert after["adjusted"] == line["adjusted"] # the year total does not change, only when it is spent
share = round(line["adjusted"] / 4, 2)
assert after["months"][0] == share and after["months"][4:] == [0] * 8
assert round(sum(after["months"]), 2) == line["adjusted"]
# the year's monthly totals follow; the monthly budget report shows the months
year = client.get(f"/api/years/{imported}").json()
assert year["costs"]["adjusted"] == client.get(f"/api/years/{imported}").json()["costs"]["adjusted"]
assert client.get(f"/api/years/{imported}/reports/budget.xlsx").status_code == 200
assert client.put(f"/api/lines/{line['id']}", json={"monthly_kind": "selected", "monthly_months": []}).status_code == 400
assert client.put(f"/api/lines/{line['id']}", json={"monthly_months": [13]}).status_code == 400
# rolling over to next year keeps the chosen months
nxt = client.post("/api/years", json={"year": 2028, "copy_from_id": imported}).json()
copied = _first_line(client, nxt["id"])
assert copied["monthly_kind"] == "selected" and copied["monthly_months"] == [1, 2, 3, 4]
# back to 12 months
client.put(f"/api/lines/{line['id']}", json={"monthly_kind": "even", "monthly_months": None})
assert _first_line(client, imported)["months"][11] != 0
def test_template_keeps_chosen_months(client, imported):
line = _first_line(client, imported)
client.put(f"/api/lines/{line['id']}", json={"monthly_kind": "selected", "monthly_months": [1, 2, 3, 4, 7]})
dept = client.get("/api/departments").json()[0]["id"]
r = client.get(f"/api/departments/{dept}/template.xlsx?lang=pt&from_year_id={imported}&year=2030")
ws = openpyxl.load_workbook(BytesIO(r.content))["Linhas"]
assert ws.cell(8, 23).value == "Dividir pelos meses"
assert "1-4, 7" in [ws.cell(row, 23).value for row in range(9, 70)]
# a hand-written month list on a row without typed months
free = next(r for r in range(9, 70) if ws.cell(r, 2).value and ws.cell(r, 23).value is None
and all(ws.cell(r, c).value is None for c in range(11, 23)))
ws.cell(free, 23, "Set-Dez")
buf = BytesIO()
ws.parent.save(buf)
res = client.post("/api/years/import", files={"file": ("t.xlsx", buf.getvalue())},
data={"department_id": str(dept)}).json()
lines = [ln for c in client.get(f"/api/years/{res['year']['id']}").json()["categories"] for ln in c["lines"]]
picked = [ln["monthly_months"] for ln in lines if ln["monthly_kind"] == "selected"]
assert [1, 2, 3, 4, 7] in picked and [9, 10, 11, 12] in picked
a = client.get(f"/api/years/{imported}").json()["costs"]
b = client.get(f"/api/years/{res['year']['id']}").json()["costs"]
assert abs(a["adjusted"] - b["adjusted"]) < 0.01