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 download_messages(em, counterparty, start, end, auto=False): for msg in em.get_msgs( 20, path=["Interest", counterparty], ): if not auto: if counterparty == "CITI": base_dir = DAILY_DIR / f"{counterparty}_reports" / "Interest Statements" elif counterparty == "BAML": base_dir = ( DAILY_DIR / "Serenitas" / f"BoA_reports" / "Interest Statements" ) else: base_dir = ( DAILY_DIR / "Serenitas" / f"{counterparty}_reports" / "Interest Statements" ) else: base_dir = ( DAILY_DIR / "Serenitas" / "MonthlyInterest" / f"{counterparty}_reports" ) 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 g: if "This interest, margin" in e.text: 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 "TOTAL INTEREST" in e.text: next(g) 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 start_end(year, month): start = datetime.date(year, month, 1) end = start + relativedelta(months=1) end -= datetime.timedelta(days=1) return start, end def get_interest(delete=False): interest_amounts = defaultdict(float) counterparties = ["BNP", "CITI", "CS", "GS", "MS", "BAML"] for cp in counterparties: try: func = globals()[f"get_{cp}"] except KeyError: continue 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)) amount = func(g) interest_amounts[cp] = interest_amounts[cp] + amount if delete: try: shutil.rmtree( f"/home/serenitas/Daily/Serenitas/MonthlyInterest/{cp}_reports" ) except FileNotFoundError: pass return pd.DataFrame(interest_amounts, index=[0]).T.rename( index={"BAML": "BAML_ISDA"}, columns={0: "monthly_statement"} ) em = ExchangeMessage() counterparties = ["BNP", "CITI", "CS", "GS", "MS", "BAML"] parser = argparse.ArgumentParser(description="determine sender destination") parser.add_argument("start") parser.add_argument("end", default=datetime.date.today()) parser.add_argument("--auto", action="store_true", help="for automation or for monthly") parser.add_argument( "--delete", action="store_true", default=True, help="for automation or for monthly" ) args = parser.parse_args() for cp in counterparties: if args.auto: download_messages(em, cp, args.start, args.end, auto=args.auto) else: download_messages(em, cp, args.start, args.end) if args.auto: df = get_interest(delete=args.delete) start, end = start_end( datetime.datetime.today().year, datetime.datetime.today().month - 1 ) new_df = pd.merge( export_data(start, end).groupby("broker").sum(), df, how="outer", left_index=True, right_index=True, ) new_df["difference"] = new_df["amount"] - new_df["monthly_statement"]