55
66from .exceptions import HeaderParseError , CASParseError
77from .regex import FOLIO_RE , HEADER_RE , SCHEME_RE
8- from .regex import CLOSE_UNITS_RE , NAV_RE , OPEN_UNITS_RE , VALUATION_RE , TRANSACTION_RE
8+ from .regex import CLOSE_UNITS_RE , NAV_RE , OPEN_UNITS_RE , VALUATION_RE
9+ from .regex import DESCRIPTION_TAIL_RE , DIVIDEND_RE , TRANSACTION_RE
910
1011
1112def parse_header (text ):
@@ -31,8 +32,14 @@ def process_cas_text(text):
3132 current_folio = None
3233 current_amc = None
3334 curr_scheme_data = {}
35+ balance = Decimal (0.0 )
3436 lines = text .split ("\u2029 " )
3537 for line in lines :
38+ if m := re .search (DESCRIPTION_TAIL_RE , line , re .I | re .DOTALL ):
39+ description_tail = m .group (1 ).rstrip ()
40+ line = line .replace (description_tail , "" )
41+ else :
42+ description_tail = ""
3643 if amc_match := re .search (r"^(.+?)\s+(MF|Mutual\s+Fund)$" , line , re .I | re .DOTALL ):
3744 current_amc = amc_match .group (0 )
3845 elif m := re .search (FOLIO_RE , line , re .I ):
@@ -70,6 +77,7 @@ def process_cas_text(text):
7077 "valuation" : {"date" : None , "value" : 0 , "nav" : 0 },
7178 "transactions" : [],
7279 }
80+ balance = Decimal (0.0 )
7381 if not curr_scheme_data :
7482 continue
7583 if m := re .search (OPEN_UNITS_RE , line ):
@@ -90,11 +98,23 @@ def process_cas_text(text):
9098 continue
9199 if m := re .search (TRANSACTION_RE , line , re .DOTALL ):
92100 date = date_parser .parse (m .group (1 )).date ()
101+ desc = m .group (2 ).strip () + description_tail
93102 amt = Decimal (m .group (3 ).replace ("," , "_" ).replace ("(" , "-" ))
94- units = Decimal (m .group (4 ).replace ("," , "_" ).replace ("(" , "-" ))
95- nav = Decimal (m .group (5 ).replace ("," , "_" ))
96- balance = Decimal (m .group (6 ).replace ("," , "_" ))
97- desc = m .group (2 ).strip ()
103+ if m .group (4 ) is None :
104+ units = None
105+ nav = None
106+ else :
107+ units = Decimal (m .group (4 ).replace ("," , "_" ).replace ("(" , "-" ))
108+ nav = Decimal (m .group (5 ).replace ("," , "_" ))
109+ balance = Decimal (m .group (6 ).replace ("," , "_" ))
110+ if div_match := re .search (DIVIDEND_RE , desc , re .I | re .DOTALL ):
111+ reinvest_flag , rate = div_match .groups ()
112+ is_dividend_payout = reinvest_flag is None
113+ is_dividend_reinvestment = not is_dividend_payout
114+ dividend_rate = Decimal (rate )
115+ else :
116+ is_dividend_payout = is_dividend_reinvestment = False
117+ dividend_rate = None
98118 curr_scheme_data ["transactions" ].append (
99119 {
100120 "date" : date ,
@@ -103,6 +123,9 @@ def process_cas_text(text):
103123 "units" : units ,
104124 "nav" : nav ,
105125 "balance" : balance ,
126+ "is_dividend_payout" : is_dividend_payout ,
127+ "is_dividend_reinvestment" : is_dividend_reinvestment ,
128+ "dividend_rate" : dividend_rate ,
106129 }
107130 )
108131 if curr_scheme_data :
0 commit comments