1515
1616from . import __version__ , read_cas_pdf
1717from .analysis .gains import CapitalGainsReport
18- from .enums import CASFileType
18+ from .enums import CASFileType , FileType
1919from .exceptions import GainsError , IncompleteCASError , ParserException
2020from .parsers .utils import cas2csv , cas2csv_summary , cas2json , is_close
21- from .types import CASData
21+ from .types import CASData , NSDLCASData
2222
2323CONTEXT_SETTINGS = dict (help_option_names = ["-h" , "--help" ])
2424console = Console ()
@@ -55,6 +55,99 @@ def get_color(amount: Union[Decimal, float, int]):
5555 return "white"
5656
5757
58+ def print_nsdl (parsed_data : NSDLCASData ):
59+ """Print summary of parsed data."""
60+
61+ count = 0
62+ err = 0
63+
64+ data = parsed_data .model_dump (by_alias = True )
65+ # console.print(data)
66+
67+ summary_table = Table .grid (expand = True )
68+ summary_table .add_column (justify = "right" )
69+ summary_table .add_column (justify = "left" )
70+ spacing = (0 , 1 )
71+ summary_table .add_row (
72+ Padding ("Statement Period :" , spacing ),
73+ f"[bold green]{ data ['statement_period' ]['from' ]} [/] To "
74+ f"[bold green]{ data ['statement_period' ]['to' ]} [/]" ,
75+ )
76+ summary_table .add_row (Padding ("File Type :" , spacing ), f"[bold]{ data ['file_type' ]} [/]" )
77+ # summary_table.add_row(Padding("CAS Type :", spacing), f"[bold]{data['cas_type']}[/]")
78+ for key , value in data ["investor_info" ].items ():
79+ summary_table .add_row (
80+ Padding (f"{ key .capitalize ()} :" , spacing ), re .sub (r"[^\S\r\n]+" , " " , value )
81+ )
82+ console .print (summary_table )
83+ console .print ("" )
84+
85+ table = Table (title = "Portfolio Summary" , show_lines = True )
86+ table .add_column ("Name" )
87+ table .add_column ("ISIN" )
88+ table .add_column ("Units" )
89+ table .add_column ("Price" )
90+ table .add_column ("Value" )
91+
92+ value = Decimal (0 )
93+
94+ for account in parsed_data .accounts :
95+ balance = account .balance
96+ value += balance
97+ running_balance = 0
98+ table_rows = []
99+ if len (account .equities ) > 0 :
100+ table_rows .append (["[italic]Equities[/]" ])
101+ for equity in account .equities :
102+ running_balance += equity .num_shares * equity .price
103+ table_rows .append (
104+ [
105+ equity .name ,
106+ equity .isin ,
107+ format_number (equity .num_shares ),
108+ formatINR (equity .price ),
109+ formatINR (equity .value ),
110+ ]
111+ )
112+ if len (account .mutual_funds ) > 0 :
113+ table_rows .append (["[italic]Mutual Funds[/]" ])
114+ for mf in account .mutual_funds :
115+ running_balance += mf .nav * mf .balance
116+ table_rows .append (
117+ [
118+ mf .name ,
119+ mf .isin ,
120+ format_number (mf .balance ),
121+ formatINR (mf .nav ),
122+ formatINR (mf .value ),
123+ ]
124+ )
125+ if is_close (balance , running_balance , tol = float (balance or 1 ) * 0.01 ):
126+ status = "️✅"
127+ else :
128+ status = "❗️"
129+ err += 1
130+ count += 1
131+ table .add_row (
132+ f"[bold]{ account .name } \n { account .dp_id } - { account .client_id } [/]" , "" , "" , "" , status
133+ )
134+
135+ for row in table_rows :
136+ table .add_row (* row )
137+
138+ console .print (table )
139+
140+ console .print (
141+ f"Portfolio Valuation : [bold green]{ formatINR (value )} [/] "
142+ f"[As of { data ['statement_period' ]['to' ]} ]"
143+ )
144+
145+ console .print ("[bold]Summary[/]" )
146+ console .print (f"{ 'Total' :8s} : [bold white]{ count :4d} [/] accounts" )
147+ console .print (f"{ 'Matched' :8s} : [bold green]{ count - err :4d} [/] accounts" )
148+ console .print (f"{ 'Error' :8s} : [bold red]{ err :4d} [/] accounts" )
149+
150+
58151def print_summary (parsed_data : CASData , output_filename = None , include_zero_folios = False ):
59152 """Print summary of parsed data."""
60153 count = 0
@@ -348,15 +441,20 @@ def cli(output, summary, password, include_all, gains, gains_112a, force_pdfmine
348441 except ParserException as exc :
349442 console .print (f"Error parsing pdf file :: [bold red]{ str (exc )} [/]" )
350443 sys .exit (1 )
351- if summary :
444+ if isinstance (data , NSDLCASData ):
445+ print_nsdl (data )
446+ elif summary :
352447 print_summary (
353448 data ,
354449 include_zero_folios = include_all ,
355450 output_filename = None if output_ext in (".csv" , ".json" ) else output ,
356451 )
357452
358453 if output_ext in (".csv" , ".json" ):
359- if output_ext == ".csv" :
454+ if output_ext == ".csv" and data .file_type in (
455+ FileType .CAMS .value ,
456+ FileType .KFINTECH .value ,
457+ ):
360458 if summary or data .cas_type == CASFileType .SUMMARY .name :
361459 description = "Generating summary CSV file..."
362460 conv_fn = cas2csv_summary
@@ -370,7 +468,7 @@ def cli(output, summary, password, include_all, gains, gains_112a, force_pdfmine
370468 with open (output , "w" , newline = "" , encoding = "utf-8" ) as fp :
371469 fp .write (conv_fn (data ))
372470 console .print (f"File saved : [bold]{ output } [/]" )
373- if gains or gains_112a :
471+ if data . file_type in ( FileType . CAMS . value , FileType . KFINTECH . value ) and ( gains or gains_112a ) :
374472 try :
375473 print_gains (
376474 data ,
0 commit comments