from flask import (request, render_template, redirect, url_for, send_from_directory, send_file, g) from .models import ModelForm, BondDeal, Counterparties from sqlalchemy import create_engine from sqlalchemy.exc import IntegrityError import pandas as pd import os import datetime import redis from .utils import load_counterparties, load_trades, add_triggers, bump_rev, simple_serialize from PyPDF2 import PdfFileMerger from io import BytesIO from Dawn import app def cp_choices(): return Counterparties.query.order_by('name').\ with_entities(Counterparties.code, Counterparties.name) def get_queue(): q = getattr(g, 'queue', None) if q is None: q = g.queue = redis.Redis(host='debian') return q class CounterpartyForm(ModelForm): class Meta: model = Counterparties class BondForm(ModelForm): class Meta: model = BondDeal include_foreign_keys = True exclude = ['dealid', 'lastupdate'] #we generate it with a trigger at the server level @app.route('/trades/', methods=['GET', 'POST']) @app.route('/trades/', defaults={'tradeid': None}, methods=['GET', 'POST']) def trade_manage(tradeid): if tradeid: trade = BondDeal.query.get(tradeid) bond_form = BondForm(obj = BondDeal.query.get(tradeid)) #we change the default to update bond_form.action.choices = [('UPDATE', 'UPDATE'), ('CANCEL', 'CANCEL')] old_ticket_name = trade.ticket else: trade = BondDeal() bond_form = BondForm() bond_form.cp_code.choices = cp_choices() if bond_form.is_submitted(): if bond_form.validate(): bond_form.populate_obj(trade) session = bond_form.get_session() ticket_file = trade.ticket trade.ticket = None if not tradeid: session.add(trade) if ticket_file.filename == '': if tradeid: trade.ticket = old_ticket_name else: if old_ticket_name: trade.ticket = bump_rev(old_ticket_name) else: trade.ticket = "{0} {1}.pdf".format(str(trade.trade_date), trade.description) ticket_file.save(os.path.join(app.config['TICKETS_FOLDER'], trade.ticket)) try: session.commit() except IntegrityError: print("TODO: fix this") finally: q = get_queue() q.rpush('trades', simple_serialize(trade)) return redirect(url_for('list_trades')) else: return str(bond_form.errors) return render_template('trade_entry.html', form=bond_form, trade_id=tradeid) @app.route('/blotter/') def list_trades(): trade_list = BondDeal.query.order_by(BondDeal.trade_date, BondDeal.id) return render_template('blotter.html', trades=trade_list.all()) @app.route('/tickets/') def download_ticket(tradeid): trade = BondDeal.query.get(tradeid) pdf = PdfFileMerger() pdf.append(os.path.join(app.config['TICKETS_FOLDER'], trade.ticket)) pdf.append(os.path.join(app.config['CP_FOLDER'], trade.counterparty.instructions)) fh = BytesIO() pdf.write(fh) pdf.close() fh.seek(0) return send_file(fh, mimetype='application/pdf') @app.route('/counterparties/', methods=['GET']) @app.route('/counterparties/', defaults={'instr': None}, methods=['GET']) def list_counterparties(instr): if instr: return send_from_directory(filename = instr, directory = app.config['CP_FOLDER'], mimetype='application/pdf') else: cp_list = Counterparties.query.order_by(Counterparties.name) return render_template('counterparties.html', counterparties = cp_list.all()) @app.route('/edit_cp/', methods=['GET', 'POST']) def edit_counterparty(cpcode): cp = Counterparties.query.get(cpcode) cp_form = CounterpartyForm(obj = cp) old_instructions = cp.instructions if cp_form.is_submitted(): if cp_form.validate(): cp_form.populate_obj(cp) session = cp_form.get_session() instructions = cp.instructions if instructions.filename == '': cp.instructions = old_instructions else: cp.instructions = cp.name + '.pdf' instructions.save(os.path.join(app.config['CP_FOLDER'], cp.instructions)) session.commit() return redirect(url_for('list_counterparties')) return render_template('edit_cp.html', form=cp_form, code=cpcode)