def _generateReport(self, session): """Generates pdf and html reports from the database.""" logging.info("Generate Flash PnL V2 Report") self.report_control = ReportsDBFlash(session=session, outputdir=self.output_dir, book='Whiteclif', book_code='WC', asofdate=self.asofdate, reportsurl=self.reports_url) self.docs = self.report_control.render()
class DailyFlashV2(IOService): """ Class representing the daily flash extract ioservice.""" #NB all defaults are handled in DailyFlashProcessFeed def __init__(self, props, working_path, output_dir, asofdate, lib_path, java_path, reports_url): datetoday = datetime.date.today() self.asofdate = asofdate self.reports_url = reports_url self.working_path = os.path.join(working_path, datetoday.strftime("%Y%m%d"), "flashpnl") self.output_dir = output_dir try: os.makedirs(self.working_path) except: pass self.log_file = os.path.join(self.working_path, "%s_daily_flash_v2.log" % self.asofdate) self.input_file = os.path.join(self.working_path, "%s_daily_flash_v2_input.txt" % self.asofdate) self.output_file = os.path.join(self.working_path, "%s_daily_flash_v2_output.csv" % self.asofdate) IOService.__init__(self, service="printPortfolio", props=props, input_file=self.input_file, output_file=self.output_file, log_file=self.log_file, outDelim=",", columms=None, lib_path=lib_path, java_path=java_path, trans='ioservice.ReportTranslator', aggreg=False) def _buildInputFile(self): """builds the input file for flash pnl i/o services.""" logging.info("Building input file %s" % self.input_file) with open(self.input_file, "wb") as inF: # Replace the date keys in the input file, with the correct date range inF.write("""portName,portType,format,systemAsOfDate,asOfDate,asOfTime,totalOnly,calcVar,varIncIntRate,varIncVega,varIncRlzd,subtractMean,varIncSectorSprd,varIncIssSprd,varTimeHorizon,varDayType,varConfLevel,varMRatio,varTvolCol,volTerm,volScale,corrScale RISK_FREE_CASH,book,titledCsv,{0},{0},1700,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 RISK_DAILY_FLASH,book,titledCsv,{0},{0},1700,1,1,1,1,1,0,0,0,1,1,99,1,1,365,1,1 RISK_DAILY_FLASH,book,titledCsv,{0},{0},1700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0""".format(self.asofdate.strftime("%Y%m%d"))) inF.close() def _loadDatabase(self, session): """loads the flash p&l output into the database.""" logging.info("Load Flash PnL Report into database") flash_control = ReportsDBFlashControl(None, None) flash_control.extracted = self.output_file flash_control.load(session, self.asofdate) flash_control.navload(session, self.asofdate) def _generateReport(self, session): """Generates pdf and html reports from the database.""" logging.info("Generate Flash PnL V2 Report") self.report_control = ReportsDBFlash(session=session, outputdir=self.output_dir, book='Whiteclif', book_code='WC', asofdate=self.asofdate, reportsurl=self.reports_url) self.docs = self.report_control.render() def _emailReport(self, server, email_from, email_to): """Generates daily flash report email in html format.""" if self.docs: # Get data for header headers = self.report_control.model.fund.columns data = {} for row in self.report_control.model.fund.data: row = dict(zip(headers, row)) if row['Deals'] == 'Whiteclif': data = row navstring = '${:,.0f}M'.format(data['Total Value']/1000000) if abs(data['Day P&L']) < 1000000: pnl_string = '${:.0f}K'.format(abs(data['Day P&L']/1000)) else: pnl_string = '${:,.2f}M'.format(abs(data['Day P&L']/1000000)) if data['Day P&L'] < 0 : pnl_string = '(' + pnl_string + ')' subject = 'Whiteclif Valuation {0} / Day P&L {1} / Prior Period Adjustment $0K'.format(navstring, pnl_string) # Get attachments html = [doc[1] for doc in self.docs if doc[0]=='html'][0] pdf = [doc[1] for doc in self.docs if doc[0]=='pdf'][0] logging.info("Convert html to image") name = os.path.splitext(os.path.split(html)[1])[0] imagefile = os.path.join(self.working_path, '{}.png'.format(name)) convert(html, imagefile, ["--width","800","--quality","50"]) message = "Flash PnL attachments can also be accessed here: \n\n" tail, head = os.path.split(pdf) href = os.path.join(self.reports_url, self.asofdate.strftime("%Y/%B/%d"), head) message = '%s\t<a href="%s">%s</a>\n' % (message, href, head) message = """<img src="%s"/> %s\n\nLinks to Operation's files: <a href="file:///\\corp.local\shared\Company%%20Shared\Kew%%20Portal\WhiteclifPnL">S:\Kew Portal\Whiteclif P&L</a> <a href="file:///\\corp.local\shared\Company%%20Shared\Kew%%20Portal\Trade%%20Extract">S:\Kew Portal\Trade Extract</a> """ % (imagefile, message) message = "<pre>\n\n%s</pre>" % message logging.info("Sending email to {}".format(email_to)) send_email(server, email_from, email_to, subject, body='', attachments={tail:head}, html=message) else: raise Exception, "No report files produced for Flash Report" def run(self, retry, smtpServer, emailFrom, emailTo, reports_db): """Runs the service to generate the flash report from Imagine.""" try: #Run print portfolio i/o service self._buildInputFile() result = IOService.run(self, retry) if result != 0: raise Exception, "IO Service failure" logging.info("Establishing session with database %s" % reports_db) engine = create_engine(reports_db) Session = sessionmaker(bind=engine) session = Session() self._loadDatabase(session) self._generateReport(session) self._emailReport(smtpServer, emailFrom, emailTo) except Exception, e: logging.exception("The Daily Flash extract failed with error %s" % e) subject = 'Daily Flash extract failed' body = 'The Daily Flash service failed with error message "%s". Imagine logfile attached.' % e send_email(smtpServer, emailFrom, emailTo, subject, body, {os.path.dirname(self.log_file):os.path.basename(self.log_file)}) return else: