""" Views for the create overview part """ from tempfile import NamedTemporaryFile from pyramid.view import view_config from pyramid.httpexceptions import HTTPFound from pyramid_mailer.message import Message, Attachment from . import XLSX_CONTENT_TYPE, Root from ..budget import parse_budget_file from ..superx import parse_exported_file from ..helpers import find_recipients, find_budget_file, get_sheet_of_file from ..overview import create_overview # noqa: F401 from ..exceptions import BudgetParserError, SuperXParserError # noqa: F401 MAIL_MESSAGE_BODY = """Hallo an Alle, anbei ist eine aktuelle Übersicht unserer Verbrauchsmittel-Budgets. Frohes Bestellen! -- Dies ist eine automatisch generierte Email, bei Fragen bitte an Holgi wenden """ @view_config( context=Root, request_method="GET", renderer="superx_budget:pyramid/templates/start.jinja2", permission="view", ) def index(context, request): return {} @view_config( context=Root, request_method="POST", renderer="superx_budget:pyramid/templates/overview.jinja2", permission="view", ) def superx_upload(context, request): upload = request.POST.get("superx") if upload == b"" or not upload.filename.endswith(".xlsx"): request.session.flash("No Excel file uploaded.", "error") return HTTPFound("/") try: superx_export = parse_exported_file(upload.file) except SuperXParserError: request.session.flash( "File does not appear to be the required SuperX export.", "error" ) return HTTPFound("/") budget_file = find_budget_file( request.budgets_dir, superx_export.account_year ) if budget_file is None: request.session.flash( f"No budget file for year {superx_export.account_year} found.", "error", ) return HTTPFound("/") try: budget_data = parse_budget_file(budget_file) except BudgetParserError: request.session.flash( "Budget File does not appear to be in the required format.", "error", ) return HTTPFound("/") overview_map = create_overview(budget_data, superx_export) overview = sorted(overview_map.values(), key=lambda i: i.row) if any(not (item.found) for item in overview): request.session.flash( ( "Some projects in the budget template were not in the SuperX " "export. Please adjust their expenses manually." ), "info", ) recipients = find_recipients(request.budgets_dir) return { "account_year": superx_export.account_year, "export_date": superx_export.export_date.strftime("%Y-%m-%d"), "overview": overview, "template": budget_file.name, "recipients": recipients, } @view_config( context=Root, name="send", request_method="POST", renderer="superx_budget:pyramid/templates/sent.jinja2", permission="view", ) def send_overview(context, request): export_date = request.POST.get("export_date").strip() tmp_recipients = request.POST.get("recipients").strip() recipients = tmp_recipients.splitlines() budget_template = request.POST.get("template") budget_file = request.budgets_dir / budget_template expenses = {} for key, value in request.POST.items(): if key.startswith("expense-"): row_str = key.split("-")[-1] row = int(row_str) try: value = float(value) except ValueError: value = 0 expenses[row] = value # sanity check if ( not export_date or not recipients or not expenses or not budget_file.is_file() ): request.session.flash( f"There was an error with your submisssion, please try again.", "error", ) return HTTPFound("/") sheet = get_sheet_of_file(budget_file) for row, value in expenses.items(): cell = f"F{row}" sheet[cell] = value budget_year = budget_file.stem.split("-")[-1] message = Message( subject=f"Budget Übersicht {budget_year}, Stand {export_date}", sender="cpiserver@imtek.uni-freiburg.de", recipients=recipients, body=MAIL_MESSAGE_BODY, ) xls_name = f"{export_date}-Budget-Overview-{budget_year}.xlsx" with NamedTemporaryFile() as tmp: sheet._parent.save(tmp.name) tmp.seek(0) attachment = Attachment(xls_name, XLSX_CONTENT_TYPE, tmp) message.attach(attachment) request.mailer.send_immediately(message, fail_silently=False) return {"recipients": recipients, "xls_name": xls_name}