from collections import namedtuple from .helpers import excel_value_as_number KIND_OBLIGO = "obligo" KIND_EXPENSES = "expenses" VALID_MATERIAL_IDS = { "0216 - Sachmittel", "0227 - Verbrauchsmaterial", "0843 - Verbrauch/Stoffe", "2 - Sachmittel", } OverviewBudgetEntry = namedtuple( "OverviewBudgetEntry", ["description", "kind", "amount"] ) class ProjectOverview: def __init__(self, budget_data): """ initializes the class """ self.budget_data = budget_data self.entries = [] self.found = False @property def project(self): """ returns the project number """ return self.budget_data.project @property def row(self): """ returns the excel row number """ return self.budget_data.row @property def expenses(self): """ returns the accumulated expenses """ numbers = (excel_value_as_number(e.amount) for e in self.entries) values = (abs(entry) for entry in numbers) return sum(values) @property def available(self): """ returns the still available budget """ return self.budget_data.budget - 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 _create_overview_map(budget_list): """ returns a dictonary with project as key and overview as value """ map = {} for budget_data in budget_list: overview = ProjectOverview(budget_data) map[str(overview.project)] = overview return map def _filter_superx_material_expenses(superx_export): """ filters superx data to only contain material entries """ return (i for i in superx_export.data if i.kind in VALID_MATERIAL_IDS) def _create_entries_from_superx(overview_map, superx_export_data): """ adds overview entries from superx data """ for line in superx_export_data: if line.project in overview_map: overview = overview_map[line.project] overview.add(line.kind, KIND_OBLIGO, line.obligo) overview.add(line.kind, KIND_EXPENSES, line.expenses) return overview_map def _set_found_state(overview_map, superx_export): superx_projects = {line.project for line in superx_export.data} found_projects = superx_projects.intersection(set(overview_map.keys())) for project in found_projects: overview_map[project].found = True return overview_map def create_overview(budget_list, superx_export): """ create a overview map with budget entries from the parsed raw data """ tmp_map = _create_overview_map(budget_list) overview_map = _set_found_state(tmp_map, superx_export) material_expenses = _filter_superx_material_expenses(superx_export) return _create_entries_from_superx(overview_map, material_expenses)