from serenitas.utils.env import DAILY_DIR from serenitas.utils.exchange import ExchangeMessage import datetime from collateral.baml_isda import download_from_secure_id from bs4 import BeautifulSoup from urllib.parse import urlsplit, parse_qs, urlunsplit import logging import argparse from collateral.common import load_pdf from pathlib import Path import pandas as pd from collections import defaultdict import shutil from interest_statement import export_data from dateutil.relativedelta import relativedelta logger = logging.getLogger(__name__) def get_fpath(counterparty, save=False): if not save: return DAILY_DIR / "Serenitas" / "MonthlyInterest" / f"{counterparty}_reports" elif counterparty == "CITI": return DAILY_DIR / f"{counterparty}_reports" / "Interest Statements" elif counterparty == "BAML": return DAILY_DIR / "Serenitas" / f"BoA_reports" / "Interest Statements" else: return ( DAILY_DIR / "Serenitas" / f"{counterparty}_reports" / "Interest Statements" ) def download_messages(em, counterparty, start, end, save=False): for msg in em.get_msgs( 20, path=["Interest", counterparty], ): base_dir = get_fpath(counterparty, save) if (msg.datetime_sent.date() >= datetime.date.fromisoformat(start)) and ( msg.datetime_sent.date() <= datetime.date.fromisoformat(end) ): if counterparty == "BAML": soup = BeautifulSoup(msg.body, features="lxml") a = soup.find("a") url = urlsplit(a["href"]) query = parse_qs(url.query) base_url = urlunsplit(url[:2] + ("",) * 3) try: download_from_secure_id( query["id"][0], query["brand"][0], base_dir, base_url ) except ValueError as e: logging.error(e) continue continue for attach in msg.attachments: fname = attach.name if (counterparty == "CS") and not ("Interest" in fname): continue p = base_dir / fname if not p.parent.exists(): p.parent.mkdir(parents=True) if not p.exists(): p.write_bytes(attach.content) def get_CS(g): for e in list(g)[-1]: if "This interest, margin" in e.text: if value == "No Accruals to Report": return 0 return float(value) value = e.text def get_BNP(g): for e in g: if "Due to" in e.text: value = next(g).text.replace(",", "") return -float(value) def get_CITI(path): df = pd.read_excel(path) for row in df.itertuples(): if "Net Interest Due To CP" in row: return -row._6 def get_GS(g): for e in g: if "due to" in e.text: return float(next(g).text.replace("USD", "").replace(",", "")) def get_MS(path): df = pd.read_excel(path) return -round(df["LOCAL_ACCRUAL"].sum(), 2) def get_BAML(g): for e in g: if "Net interest Amount" in e.text: return -float(next(g).text.replace("(", "-").replace(")", "")) def get_JPM(g): for e in g: if "Page" in e.text: return float(value.replace(",", "")) value = e.text def start_end(date): date = date - relativedelta(months=1) start = datetime.date(date.year, date.month, 1) end = start + relativedelta(months=1) end -= datetime.timedelta(days=1) return start, end def get_interest(counterparties, save=False): interest_amounts = defaultdict(float) for cp in counterparties: try: func = globals()[f"get_{cp}"] except KeyError: print(f"Missing cp {cp}") if cp in ("CITI", "MS"): for file in Path( f"/home/serenitas/Daily/Serenitas/MonthlyInterest/{cp}_reports" ).glob("*.xls*"): amount = func(file) interest_amounts[cp] = interest_amounts[cp] + amount else: for file in Path( f"/home/serenitas/Daily/Serenitas/MonthlyInterest/{cp}_reports" ).glob("*.pdf"): g = iter(load_pdf(file, pages=True if cp == "CS" else False)) amount = func(g) interest_amounts[cp] = interest_amounts[cp] + amount return pd.DataFrame(interest_amounts, index=[0]).T.rename( index={"BAML": "BAML_ISDA"}, columns={0: "monthly_statement"} ) def main(): em = ExchangeMessage() counterparties = ["BNP", "CITI", "CS", "GS", "MS", "BAML", "JPM"] parser = argparse.ArgumentParser(description="determine sender destination") parser.add_argument( "date", default=datetime.date.today() ) parser.add_argument( "--save", action="store_true", default=False, help="for automation or for monthly", ) parser.add_argument( "--accept", action="store_true", default=False, help="for automation or for monthly", ) args = parser.parse_args() start = datetime.date(args.date.year, args.date.month, 1) for cp in counterparties: download_messages(em, cp, start, args.date, args.save) df = get_interest(counterparties, save=args.save) start, end = start_end( args.date ) global interest_recon interest_recon = pd.merge( export_data(start, end).groupby("broker").sum(), df, how="outer", left_index=True, right_index=True, ) interest_recon["difference"] = ( interest_recon["amount"] - interest_recon["monthly_statement"] ) if args.accept: df = export_data(start, end) for k, v in interest_recon["difference"].items(): df.loc[k].loc["CSH_CASH"] -= v df.to_csv("/home/serenitas/flint/interest_recon.csv") if __name__ == "__main__": main()