diff --git a/cli/OverheadAccounts.py b/cli/OverheadAccounts.py index 192f799..71080fa 100644 --- a/cli/OverheadAccounts.py +++ b/cli/OverheadAccounts.py @@ -6,164 +6,186 @@ from utils import getParam from Cheetah.Template import Template + +EPSILON = Decimal('0.000000001') + def perform(dbh, params): year = getParam(params, 'year', datetime.datetime.today().year) startDate = datetime.datetime(year, 1, 1, 0, 0, 0) endDate = datetime.datetime(year, 12, 31, 23, 59, 59) premises = (1, 2) - # get overhead sums by object, category and timespan - overheadSums = dbGetMany( - dbh, - { - "statement": - """ - select sum(ae.amount) as sum, - aec.description as category, - p.id as house_id, - p.description as house, - aec.considerminusarea as considerminusarea - from account_t a, - premise_t p, - account_entry_t ae, - account_entry_category_t aec - where p.account = a.id and - ae.account = a.id and - aec.overhead_relevant = 't' and - ae.account_entry_category = aec.id and - ae.fiscal_year = %(year)s and - p.id in %(premises)s - group by house_id, house, category, considerminusarea - union - select 0 as sum, - aec.description as category, - p.id as house_id, - p.description as house, - aec.considerminusarea as considerminusarea - from account_t a, - premise_t p, - account_entry_t ae, - account_entry_category_t aec - where p.account = a.id and - ae.account = a.id and - aec.overhead_relevant = 't' and - aec.id not in (select distinct account_entry_category from account_entry_t) and - ae.fiscal_year = %(year)s and - p.id in %(premises)s - group by house_id, house, category, considerminusarea - union - select 120 as sum, - 'Waschmaschine' as category, - id as house_id, - description as house, - false as considerminusarea - from premise_t - where id in %(premises)s - order by house_id, category - """, - "params": { - "year": year, - "premises": premises - } - } - ) - # logger.info(f"{overheadSums=}") - for overheadSum in overheadSums: - logger.info(f"house: {overheadSum['house']}, considerMinusArea: {overheadSum['considerminusarea']}, category: {overheadSum['category']}, sum: {overheadSum['sum']}") - - #subtotal = {} - #for premise in premises: - # v = [ x['sum'] for x in overheadSums if x['house_id'] == premise ] - # logger.info(f"{v=}") - # subtotal[premise] = sum(v) - # logger.info(f"{subtotal=}") - - # get areas and factors - totalAreas = {} - flatAreas = dbGetMany( - dbh, - { - "statement": - """ - select - p.id as house_id, - p.description as house, - sum(f.area) as flat_area - from - premise_t p, - flat_t f - where - f.premise = p.id and - p.id in %(premises)s - group by house_id - """, - "params": { - "premises": premises - } - } - ) - - for area in flatAreas: - logger.info(f"{area['house']=}, {area['flat_area']=}") - totalAreas[area['house_id']] = { 'flat_area': area['flat_area'] } - - commercialAreas = dbGetMany( - dbh, - { - "statement": - """ - select - p.id as house_id, - p.description as house, - coalesce(sum(c.area), 0) as commercial_area - from - premise_t p full outer join commercial_premise_t c on c.premise = p.id - where - p.id in %(premises)s - group by house_id - """, - "params": { - "premises": premises - } - } - ) - - for area in commercialAreas: - logger.info(f"{area['house']=}, {area['commercial_area']=}") - totalAreas[area['house_id']] |= { 'commercial_area': area['commercial_area'] } - - minusAreas = dbGetMany( - dbh, - { - "statement": - """ - select - p.id as house_id, - p.description as house, - p.minus_area as minus_area - from - premise_t p - where - p.id in %(premises)s - group by house_id - """, - "params": { - "premises": premises - } - } - ) - - for area in minusAreas: - logger.info(f"{area['house']=}, {area['minus_area']=}") - totalAreas[area['house_id']] |= { 'minus_area': area['minus_area'] } - + houses = {} for premise in premises: - totalAreas[premise]['other_area'] = totalAreas[premise]['commercial_area'] + totalAreas[premise]['minus_area'] - totalAreas[premise]['total_area'] = totalAreas[premise]['flat_area'] + totalAreas[premise]['other_area'] - totalAreas[premise]['flat_factor'] = totalAreas[premise]['flat_area'] / totalAreas[premise]['total_area'] - totalAreas[premise]['other_factor'] = totalAreas[premise]['other_area'] / totalAreas[premise]['total_area'] - totalAreas[premise]['factor_check'] = totalAreas[premise]['flat_factor'] + totalAreas[premise]['other_factor'] - logger.info(f"{totalAreas=}") + # get overhead sums by object, category and timespan + overheadItems = dbGetMany( + dbh, + { + "statement": + """ + select sum(ae.amount) as sum, + aec.description as category, + aec.considerminusarea as considerminusarea + from account_t a, + premise_t p, + account_entry_t ae, + account_entry_category_t aec + where p.account = a.id and + ae.account = a.id and + aec.overhead_relevant = 't' and + ae.account_entry_category = aec.id and + ae.fiscal_year = %(year)s and + p.id = %(premise)s + group by category, considerminusarea + union + select 0 as sum, + aec.description as category, + aec.considerminusarea as considerminusarea + from account_t a, + premise_t p, + account_entry_t ae, + account_entry_category_t aec + where p.account = a.id and + ae.account = a.id and + aec.overhead_relevant = 't' and + aec.id not in (select distinct account_entry_category from account_entry_t) and + ae.fiscal_year = %(year)s and + p.id = %(premise)s + group by category, considerminusarea + union + select 120 as sum, + 'Waschmaschine' as category, + false as considerminusarea + from premise_t + where id = %(premise)s + order by category + """, + "params": { + "year": year, + "premise": premise + } + } + ) + + # get areas and factors + totalArea = {} + flatArea = dbGetOne( + dbh, + { + "statement": + """ + select + sum(f.area) as flat_area + from + premise_t p, + flat_t f + where + f.premise = p.id and + p.id = %(premise)s + """, + "params": { + "premise": premise + } + } + ) + totalArea['flat_area'] = flatArea['flat_area'] + + commercialArea = dbGetOne( + dbh, + { + "statement": + """ + select + coalesce(sum(c.area), 0) as commercial_area + from + premise_t p full outer join commercial_premise_t c on c.premise = p.id + where + p.id = %(premise)s + """, + "params": { + "premise": premise + } + } + ) + totalArea['commercial_area'] = commercialArea['commercial_area'] + + minusAreaAndDetails = dbGetOne( + dbh, + { + "statement": + """ + select + p.minus_area as minus_area, + p.id as house_id, + p.description as house + from + premise_t p + where + p.id = %(premise)s + """, + "params": { + "premise": premise + } + } + ) + totalArea['minus_area'] = minusAreaAndDetails['minus_area'] + details = { 'id': minusAreaAndDetails['house_id'], 'description': minusAreaAndDetails['house'] } + + totalArea['other_area'] = totalArea['commercial_area'] + totalArea['minus_area'] + totalArea['total_area'] = totalArea['flat_area'] + totalArea['other_area'] + totalArea['flat_factor'] = totalArea['flat_area'] / totalArea['total_area'] + totalArea['other_factor'] = totalArea['other_area'] / totalArea['total_area'] + totalArea['factor_check'] = totalArea['flat_factor'] + totalArea['other_factor'] + + totalSum = Decimal('0') + flatSum = Decimal('0') + otherSum = Decimal('0') + for overheadItem in overheadItems: + totalSum += overheadItem['sum'] + overheadItem['flat_part'] = overheadItem['sum'] * totalArea['flat_factor'] if overheadItem['considerminusarea'] else overheadItem['sum'] + flatSum += overheadItem['flat_part'] + overheadItem['other_part'] = overheadItem['sum'] * totalArea['other_factor'] if overheadItem['considerminusarea'] else Decimal('0') + otherSum += overheadItem['other_part'] + + verifyDifference = totalSum - flatSum - otherSum + logger.debug(f"{totalSum=}, {verifyDifference=}") + if abs(verifyDifference) > EPSILON: + raise Exception(f"Verify Difference is too large: {premise=}, {verifyDifference=}") + + umlageAusfallWagnis = flatSum * Decimal('0.02') + flatSum2 = flatSum + umlageAusfallWagnis + + partByMonthArea = flatSum2 / Decimal('12') / totalArea['flat_area'] + + houses[details['id']] = { + 'details': details, + 'areas': totalArea, + 'overhead_items': overheadItems, + 'flat_sum': flatSum, + 'flat_sum_2': flatSum2, + 'other_sum': otherSum, + 'total_sum': totalSum, + 'umlage_ausfall_wagnis': umlageAusfallWagnis, + 'part_by_montharea': partByMonthArea, + 'year': year } + + + logger.info(f"{houses=}") + + + printOverviews = getParam(params, 'printOverviews', True) + if printOverviews: + overviewTemplate = getParam(params, 'overviewTemplate', 'betriebskostenuebersicht.tmpl') + overviewPrefix = getParam(params, 'overviewPrefix', 'overview') + overviewSuffix = getParam(params, 'overviewSuffix', 'tex') + + for house in houses.values(): + logger.debug(f"Processing item: {house}") + outputFile = f"{overviewPrefix}-{house['details']['id']}.{overviewSuffix}" + tmpl = Template(file=overviewTemplate, searchList=[ house ]) + logger.debug(tmpl) + with open(outputFile, 'w') as f: + f.write(str(tmpl)) diff --git a/cli/betriebskostenuebersicht.tmpl b/cli/betriebskostenuebersicht.tmpl new file mode 100644 index 0000000..95d6fa0 --- /dev/null +++ b/cli/betriebskostenuebersicht.tmpl @@ -0,0 +1,19 @@ +Haus: $details['description'] +Jahr: $year + + +Art | Wohnungen | andere Flächen | gesamt + +Fläche | $areas['flat_area'] | $areas['other_area'] +Faktor | $areas['flat_factor'] | $areas['other_factor'] + + +#for $item in $overhead_items +$item['category'] | $item['flat_part'] | $item['other_part'] | $item['sum'] +#end for + +Zwischensumme | $flat_sum | $other_sum | $total_sum +Umlageausfallwagnis | $umlage_ausfall_wagnis +Summe | $flat_sum_2 + +Anteil / Monat / m2 | $part_by_montharea