Browse Source

Budget template now includes 'Fond' column

main
Holger Frey 5 months ago
parent
commit
34318d94ec
  1. 12
      superx_budget/budget.py
  2. 16
      superx_budget/overview.py
  3. 6
      superx_budget/pyramid/templates.py
  4. 2
      superx_budget/superx.py
  5. BIN
      test_data/Budget-Vorlage-2024.xlsx
  6. BIN
      test_data/Verwendungsnachweis_und_Kassenstand_SAP.xlsx
  7. 2
      tests/conftest.py
  8. 27
      tests/test_budget_parser.py
  9. 1
      tests/test_helpers.py
  10. 10
      tests/test_overview.py
  11. 13
      tests/test_superx_parser.py

12
superx_budget/budget.py

@ -10,11 +10,13 @@ EXPECTED_TABLE_HEADERS = [ @@ -10,11 +10,13 @@ EXPECTED_TABLE_HEADERS = [
"Projekt",
"Laufzeit",
"BA",
"Fond",
"Budget",
"Ausgaben",
"Rest",
]
NUM_EXPECTED_HEADERS = len(EXPECTED_TABLE_HEADERS)
ExcelRow = namedtuple("ExcelRow", ["row", "data"])
@ -26,6 +28,7 @@ BudgetData = namedtuple( @@ -26,6 +28,7 @@ BudgetData = namedtuple(
"project_name",
"period",
"project",
"fond",
"budget",
"expenses",
"rest",
@ -34,7 +37,9 @@ BudgetData = namedtuple( @@ -34,7 +37,9 @@ BudgetData = namedtuple(
def _check_table_header(xl_row):
fields_ignore_none = (("" if c is None else c) for c in xl_row.data[:7])
fields_ignore_none = (
("" if c is None else c) for c in xl_row.data[:NUM_EXPECTED_HEADERS]
)
fields_str = (str(c) for c in fields_ignore_none)
fields = [c.strip() for c in fields_str]
if fields != EXPECTED_TABLE_HEADERS:
@ -51,7 +56,10 @@ def _skip_empty_lines(rows): @@ -51,7 +56,10 @@ def _skip_empty_lines(rows):
def _parse_data_table(rows):
for xl_row in _skip_empty_lines(rows):
data = [strip_excel_value(value) for value in xl_row.data[:7]]
data = [
strip_excel_value(value)
for value in xl_row.data[:NUM_EXPECTED_HEADERS]
]
yield BudgetData(xl_row.row, *data)

16
superx_budget/overview.py

@ -34,6 +34,11 @@ class ProjectOverview: @@ -34,6 +34,11 @@ class ProjectOverview:
"""returns the excel row number"""
return self.budget_data.row
@property
def budget(self):
"""returns the budget"""
return self.budget_data.budget
@property
def expenses(self):
"""returns the accumulated expenses"""
@ -43,14 +48,21 @@ class ProjectOverview: @@ -43,14 +48,21 @@ class ProjectOverview:
@property
def available(self):
"""returns the still available budget"""
return self.budget_data.budget - self.expenses
"""returns the still available rest budget"""
return (self.budget_data.budget or 0) - self.expenses
def add(self, description, kind, amount):
"""adds an entry that modifies the available budget"""
entry = OverviewBudgetEntry(description, kind, amount)
self.entries.append(entry)
def __repr__(self):
"""returns an informative string representation"""
return (
f"<ProjectOverview {self.project}:"
f"{self.budget} - {self.expenses} = {self.available}>"
)
def _create_overview_map(budget_list):
"""returns a dictonary with project as key and overview as value"""

6
superx_budget/pyramid/templates.py

@ -32,9 +32,9 @@ def templates(context, request): @@ -32,9 +32,9 @@ def templates(context, request):
cache_max_age=0,
content_type=XLSX_CONTENT_TYPE,
)
response.headers[
"Content-Disposition"
] = f"attachment;filename={file_name}"
response.headers["Content-Disposition"] = (
f"attachment;filename={file_name}"
)
return response
tmp = list_budget_files(request.budgets_dir)

2
superx_budget/superx.py

@ -27,7 +27,7 @@ SuperXData = namedtuple( @@ -27,7 +27,7 @@ SuperXData = namedtuple(
"expenses",
"revenue_actual",
"revenue_target",
"acutal_value",
"actual_value",
],
)

BIN
test_data/Budget-Vorlage-2024.xlsx

Binary file not shown.

BIN
test_data/Verwendungsnachweis_und_Kassenstand_SAP.xlsx

Binary file not shown.

2
tests/conftest.py

@ -22,7 +22,7 @@ def example_root(request): @@ -22,7 +22,7 @@ def example_root(request):
@pytest.fixture
def budget_example_file(example_root):
return example_root / "Budget-Vorlage-2020.xlsx"
return example_root / "Budget-Vorlage-2024.xlsx"
@pytest.fixture

27
tests/test_budget_parser.py

@ -32,9 +32,9 @@ def test_parse_data_table(): @@ -32,9 +32,9 @@ def test_parse_data_table():
from superx_budget.budget import ExcelRow, _parse_data_table
rows = [
ExcelRow(2, list("ABCDEFG")),
ExcelRow(3, [None for i in range(7)]),
ExcelRow(4, list("tuvwxyzX")), # one item more
ExcelRow(2, list("ABCDEFGH")),
ExcelRow(3, [None for i in range(8)]),
ExcelRow(4, list("stuvwxyzX")), # one item more
]
result = _parse_data_table(rows)
@ -42,9 +42,9 @@ def test_parse_data_table(): @@ -42,9 +42,9 @@ def test_parse_data_table():
assert first.row == 2
assert first.number == "A"
assert first.rest == "G"
assert first.rest == "H"
assert last.row == 4
assert last.number == "t"
assert last.number == "s"
assert last.rest == "z"
@ -54,15 +54,12 @@ def test_parse_budget_data(budget_example_sheet): @@ -54,15 +54,12 @@ def test_parse_budget_data(budget_example_sheet):
result = parse_budget_data(budget_example_sheet)
first, last = result[0], result[-1]
assert len(result) == 18
assert len(result) == 20
assert first.row == 3
assert first.number == 1
assert first.project_name == "Safegurard I (neu)"
assert first.rest == "=E3-F3"
assert last.row == 54
assert last.number == "=A51+1"
assert last.project_name == "ZIM Microcoat II"
assert last.rest == "=E54-F54"
assert first.project_name == "Safeguard IV"
assert first.rest == "=F3-G3"
assert last.row == 61
def test_parse_budget_file(budget_example_file):
@ -71,8 +68,8 @@ def test_parse_budget_file(budget_example_file): @@ -71,8 +68,8 @@ def test_parse_budget_file(budget_example_file):
result = parse_budget_file(budget_example_file)
first = result[0]
assert len(result) == 18
assert len(result) == 20
assert first.row == 3
assert first.number == 1
assert first.project_name == "Safegurard I (neu)"
assert first.rest == "=E3-F3"
assert first.project_name == "Safeguard IV"
assert first.rest == "=F3-G3"

1
tests/test_helpers.py

@ -109,6 +109,7 @@ def test_list_budget_files(example_root): @@ -109,6 +109,7 @@ def test_list_budget_files(example_root):
assert sorted(r.name for r in result) == [
"Budget-Vorlage-2019.xlsx",
"Budget-Vorlage-2020.xlsx",
"Budget-Vorlage-2024.xlsx",
]

10
tests/test_overview.py

@ -11,6 +11,7 @@ def example_budget_data(): @@ -11,6 +11,7 @@ def example_budget_data():
"Safegurard I",
"01.08.2019-31.07.2020",
"1100000102",
"3210",
5000,
0,
0,
@ -85,8 +86,8 @@ def test_create_overview_map(budget_example_file): @@ -85,8 +86,8 @@ def test_create_overview_map(budget_example_file):
budget_data = parse_budget_file(budget_example_file)
result = _create_overview_map(budget_data)
assert len(result) == 18
assert "2100276501" in result
assert len(result) == 20
assert "1083013701" in result
for key, value in result.items():
assert key == str(value.project)
@ -105,7 +106,8 @@ def test_create_entries_from_export(budget_example_file, superx_example_file): @@ -105,7 +106,8 @@ def test_create_entries_from_export(budget_example_file, superx_example_file):
_create_entries_from_superx(budget_map, superx_data.data)
assert budget_map["1100000102"].available == 5000 - 0.01 - 1000 - 1 - 1001
expenses = 0.01 + 1000 + 1 + 1001
assert budget_map["1100068704"].available == 2000 - expenses
def test_filter_superx_material_expenses(superx_example_file):
@ -132,4 +134,4 @@ def test_create_overview(budget_example_file, superx_example_file): @@ -132,4 +134,4 @@ def test_create_overview(budget_example_file, superx_example_file):
budget_data = parse_budget_file(budget_example_file)
budget_map = create_overview(budget_data, superx_data)
assert budget_map["1100000102"].available == 5000 - 1 - 1001
assert budget_map["1100068704"].available == 2000 - 1 - 1001

13
tests/test_superx_parser.py

@ -1,6 +1,5 @@ @@ -1,6 +1,5 @@
""" Stub file for testing the project """
import pytest
@ -83,9 +82,9 @@ def test_parse_data_table(): @@ -83,9 +82,9 @@ def test_parse_data_table():
assert first_value.cost_center == "A"
assert first_value.fonds == "B"
assert first_value.acutal_value == "J"
assert first_value.actual_value == "J"
assert second_value.cost_center == "q"
assert second_value.acutal_value == "z"
assert second_value.actual_value == "z"
def test_parse_export_data(superx_example_workbook):
@ -102,14 +101,14 @@ def test_parse_export_data(superx_example_workbook): @@ -102,14 +101,14 @@ def test_parse_export_data(superx_example_workbook):
first, last = result.data[0], result.data[-1]
assert first.cost_center == "1110200121"
assert first.fonds == "3310"
assert first.project == "1100000102"
assert first.project == "1100068704"
assert first.kind == "1 - Personal"
assert first.budget_year is None
assert first.obligo == 0.01
assert first.expenses == 1000
assert first.revenue_actual == 2000
assert first.revenue_target == 3000
assert first.acutal_value == 4000
assert first.actual_value == 4000
assert last.cost_center == "1110200121"
assert last.fonds == "1123"
assert last.project == "8200062807"
@ -119,7 +118,7 @@ def test_parse_export_data(superx_example_workbook): @@ -119,7 +118,7 @@ def test_parse_export_data(superx_example_workbook):
assert last.expenses == 1236
assert last.revenue_actual == 2236
assert last.revenue_target == 3236
assert last.acutal_value == 4236
assert last.actual_value == 4236
def test_parse_exported_file(superx_example_file):
@ -131,5 +130,5 @@ def test_parse_exported_file(superx_example_file): @@ -131,5 +130,5 @@ def test_parse_exported_file(superx_example_file):
assert len(result.data) == 212
assert first.cost_center == "1110200121"
assert first.fonds == "3310"
assert first.project == "1100000102"
assert first.project == "1100068704"
assert first.kind == "1 - Personal"

Loading…
Cancel
Save