From 7cf8287b34aed0920a6eb6180b80efa087921c09 Mon Sep 17 00:00:00 2001 From: pjpatil12 Date: Mon, 1 Dec 2025 17:45:16 +0530 Subject: [PATCH] add itai model and irt report download code commit. --- AppCode/AOHandler.py | 32 +- AppCode/CITHandler.py | 29 +- AppCode/ITATHandler.py | 20 +- AppCode/ITRHandler.py | 84 +++- AppCode/YearGet.py | 28 ++ AppCode/__pycache__/AOHandler.cpython-313.pyc | Bin 2991 -> 3537 bytes .../__pycache__/CITHandler.cpython-313.pyc | Bin 3003 -> 3473 bytes .../DocumentHandler.cpython-313.pyc | Bin 3624 -> 3624 bytes .../__pycache__/ITATHandler.cpython-313.pyc | Bin 3418 -> 3391 bytes .../__pycache__/ITRHandler.cpython-313.pyc | Bin 3899 -> 5852 bytes AppCode/__pycache__/YearGet.cpython-313.pyc | Bin 0 -> 1826 bytes main.py | 425 ++++++++++-------- test.py | 120 +++++ 13 files changed, 503 insertions(+), 235 deletions(-) create mode 100644 AppCode/YearGet.py create mode 100644 AppCode/__pycache__/YearGet.cpython-313.pyc diff --git a/AppCode/AOHandler.py b/AppCode/AOHandler.py index f8e2b37..4f1e313 100644 --- a/AppCode/AOHandler.py +++ b/AppCode/AOHandler.py @@ -9,10 +9,8 @@ class AOHandler: self.conn = DBConfig.get_db_connection() self.cursor = self.conn.cursor(dictionary=True) - # GET ALL AO RECORDS using stored procedure "GetAllItr" def get_all_ao(self): - self.cursor.callproc("GetAllAO") records = [] @@ -25,7 +23,6 @@ class AOHandler: def get_ao_by_id(self, id): # Call stored procedure self.cursor.callproc('GetAOById', [id]) - # Fetch result records = [] for result in self.cursor.stored_results(): @@ -64,26 +61,23 @@ class AOHandler: # UPDATE ITR RECORD by AO id - # def update(self, id, data): + def update_ao(self, id, data): - # columns = [ - # 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', - # 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', - # 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', - # 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', - # 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', - # 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' - # ] + fields = [ + "year","gross_total_income", "disallowance_14a", "disallowance_37", + "deduction_80ia_business", "deduction_sec37_disallowance", "deduction_80g", + "net_taxable_income", "tax_30_percent", "tax_book_profit_18_5", + "surcharge_12", "edu_cess_3", "total_tax_payable", "mat_credit", + "interest_234c", "total_tax", "advance_tax", "tds", "tcs", + "tax_on_assessment", "refund" + ] - # set_clause = ", ".join([f"{col}=%s" for col in columns]) + values = [id] + [data.get(f, 0) for f in fields] - # query = f"UPDATE itr SET {set_clause} WHERE id = %s" + print("AO update values:", values) - # values = [data.get(col, 0) for col in columns] - # values.append(id) - - # self.cursor.execute(query, tuple(values)) - # self.conn.commit() + self.cursor.callproc("UpdateAOById", values) + self.conn.commit() # DELETE RECORD by AO id diff --git a/AppCode/CITHandler.py b/AppCode/CITHandler.py index af283ef..eba7500 100644 --- a/AppCode/CITHandler.py +++ b/AppCode/CITHandler.py @@ -45,23 +45,26 @@ class CITHandler: self.cursor.callproc("InsertCIT", values) self.conn.commit() + + # UPDATE CIT RECORD - # def update_cit(self, id, data): - # columns = [ - # "year", "gross_total_income", "deduction_80ia_business", "deduction_sec37_disallowance", - # "deduction_80g", "net_taxable_income", "tax_30_percent", "tax_book_profit_18_5", - # "tax_payable", "surcharge_12", "edu_cess_3", "total_tax_payable", "mat_credit", - # "interest_234c", "total_tax", "advance_tax", "tds", "tcs", "tax_on_assessment", "refund" - # ] + def update_cit(self, id, data): + columns = [ + "year", "gross_total_income", "deduction_80ia_business", + "deduction_sec37_disallowance", "deduction_80g", + "net_taxable_income", "tax_30_percent", "tax_book_profit_18_5", + "tax_payable", "surcharge_12", "edu_cess_3", + "total_tax_payable", "mat_credit", "interest_234c", + "total_tax", "advance_tax", "tds", "tcs", + "tax_on_assessment", "refund" + ] - # set_clause = ", ".join([f"{col}=%s" for col in columns]) - # query = f"UPDATE cit SET {set_clause} WHERE id=%s" + values = [id] + [data.get(col, 0) for col in columns] + + self.cursor.callproc("UpdateCITById", values) + self.conn.commit() - # values = [data.get(col, 0) for col in columns] - # values.append(id) - # self.cursor.execute(query, tuple(values)) - # self.conn.commit() # DELETE CIT RECORD def delete_cit(self, id): diff --git a/AppCode/ITATHandler.py b/AppCode/ITATHandler.py index 85ec3d4..8c71f1e 100644 --- a/AppCode/ITATHandler.py +++ b/AppCode/ITATHandler.py @@ -30,17 +30,15 @@ class ITATHandler: # INSERT ITAT (PROC) def add_itat(self, data): - values = [ - data.get("cit_id"), - data.get("year"), - data.get("mat_tax_credit"), - data.get("surcharge"), - data.get("cess"), - data.get("total_credit") - ] - self.cursor.callproc("InsertITAT", values) - self.conn.commit() - + values = [ + data.get("mat_tax_credit", 0), + data.get("surcharge", 0), + data.get("cess", 0), + data.get("total_credit", 0), + data.get("year", 0) + ] + self.cursor.callproc("InsertITAT", values) + self.conn.commit() # UPDATE ITAT (PROC) def update_itat(self, id, data): diff --git a/AppCode/ITRHandler.py b/AppCode/ITRHandler.py index c3d3c1c..9105348 100644 --- a/AppCode/ITRHandler.py +++ b/AppCode/ITRHandler.py @@ -1,5 +1,17 @@ from AppCode.Config import DBConfig import mysql.connector +from AppCode.YearGet import YearGet + +import pandas as pd +import pymysql +import io + +# new +from AppCode.Config import DBConfig +import mysql.connector +import pandas as pd +import io +from flask import send_file, render_template, request @@ -61,8 +73,24 @@ class ITRHandler: # UPDATE ITR RECORD by ITR id - def update(self, id, data): + # def update(self, id, data): + # columns = [ + # 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', + # 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', + # 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', + # 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', + # 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', + # 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' + # ] + # values = [data.get(col, 0) for col in columns] + # values.insert(0, id) # first argument is ID + + # print("values.insert(0, id)-->",values.insert(0, id)) + # self.cursor.callproc("UpdateITR", values) + # self.conn.commit() + + def update(self, id, data): columns = [ 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', @@ -72,14 +100,11 @@ class ITRHandler: 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' ] - set_clause = ", ".join([f"{col}=%s" for col in columns]) + values = [id] + [data.get(col, 0) for col in columns] - query = f"UPDATE itr SET {set_clause} WHERE id = %s" + print("Final values:", values) - values = [data.get(col, 0) for col in columns] - values.append(id) - - self.cursor.execute(query, tuple(values)) + self.cursor.callproc("UpdateITR", values) self.conn.commit() @@ -90,6 +115,51 @@ class ITRHandler: self.conn.commit() + + + def itr_report_download(self, selected_year): + + try: + # Call stored procedure + self.cursor.callproc("GetITRByYear", [selected_year]) + + rows = [] + for result in self.cursor.stored_results(): + rows = result.fetchall() + + if not rows: + return None + + # Convert SQL rows to DataFrame + df = pd.DataFrame(rows) + + # Transpose + df_transposed = df.transpose() + df_transposed.insert(0, 'Field', df_transposed.index) + + record_cols = { + i: f"Record {i}" + for i in df_transposed.columns if isinstance(i, int) + } + + df_transposed.rename(columns=record_cols, inplace=True) + df_transposed.reset_index(drop=True, inplace=True) + + # Save to Excel in memory + output = io.BytesIO() + with pd.ExcelWriter(output, engine='xlsxwriter') as writer: + df_transposed.to_excel(writer, index=False, sheet_name='ITR_Vertical') + worksheet = writer.sheets['ITR_Vertical'] + worksheet.set_column(0, 0, 30) + + output.seek(0) + return output + + except mysql.connector.Error as e: + print("MySQL Error →", e) + return None + + # CLOSE CONNECTION def close(self): self.cursor.close() diff --git a/AppCode/YearGet.py b/AppCode/YearGet.py new file mode 100644 index 0000000..5b79701 --- /dev/null +++ b/AppCode/YearGet.py @@ -0,0 +1,28 @@ +from AppCode.Config import DBConfig +import mysql.connector + +class YearGet: + + def __init__(self): + self.conn = DBConfig.get_db_connection() + self.cursor = self.conn.cursor(dictionary=True) + + def get_year_by_model(self, proc_name): + try: + self.cursor.callproc(proc_name) + + years = [] + + for result in self.cursor.stored_results(): + rows = result.fetchall() + years = [row["year"] for row in rows] + + return years + + except mysql.connector.Error as e: + print("MySQL Error:", e) + return [] + + def close(self): + self.cursor.close() + self.conn.close() diff --git a/AppCode/__pycache__/AOHandler.cpython-313.pyc b/AppCode/__pycache__/AOHandler.cpython-313.pyc index 895d00007ef85142165bb17b8cba1a026395e24e..fcb2feacecdc9a59e314bfc9a0a31bf8866be0d7 100644 GIT binary patch delta 702 zcmYL{&1(}u7{+JzE3>;v%vU#SQq!bTF+v*;M$-?gsg_2HrcF#d6qMLRDU?l_Z3U&+ z3L-5Yv#ql$yAFo} zXgnP5p8BM&I58Ytd34Sm09eV&SiP%6)#}DNXLnGId5K~XY}MxZc_{f=Cqw=TL4Mog ztA)g45WcAmNbewwk>9q-1)d7_1JQ)lyT2%2fEdWaacJ;47=t<93-W@=#em6qLCOa} zc_;(-jfdZykmcfBs~+R7Y5=GpOg)CsO`C=|aj-AT=fpTiKFA#;4t;KcRV`l_A8~G*R<#M>STK8{*_`>!o5`2 z6ld_1F^g4ZY-3=zi2Eq0f?XC4G4wMGFq~%?q%b9l@Lu2rC(WC3YvHXzx#>-&Qw5_q zUBW#F&5O)*n_>}Ig3Y5WNjo0kZF}ykYM=GQy0(^lt*`2pNM-z0sH)ZVMBSZOl71q` zM`xsRwt-GkzPmo7Zmtwso-d@DbhVpgUKF= zyyrDypjFsMkURpflQH>+HcF?>BZp_4oGzQC36fI!p`AQdhFuq^0AFTEF^rOi5|4Dz z^a(vXCnhY#Ci*R3n`pOAJH!sF(r|EZV_-WAaR9rOEEBKNvMP zJFx9!WHg%mi#>UA5!X6K%gKt|?u=2BGr1p$xdKhP#qa3vk(if~lUk&goReRinm9R; z$C{CQ@?0KQZabiYA}0{xI{6cisjMQ9*~ajRg^AVT6AuTg_$M(jR-R8rysYw{0vIQI w@VYblOrF3ip&0;F#|Xs5;y~g9Gb1D8T?Xab3}W9oVi_5wJ~4pEB0-=W0RGBFJ^%m! diff --git a/AppCode/__pycache__/CITHandler.cpython-313.pyc b/AppCode/__pycache__/CITHandler.cpython-313.pyc index 37a8c98a4567955de6e2a2a275bd41dcf6718e1d..6adc0a6ec63646f5ba31ebaf5713531c3ce239c7 100644 GIT binary patch delta 571 zcmdljK2e(YGcPX}0}xCK(an^c$Xm>4H?h&2M~b0{E10v0JDp3Dd*i-2tc)u+N3+>7 zGOnCFll`JKGe`pzZ~$o#|MNK@F_l4|A(%0cF^@TvQJ*oCS(qV=rI<;dp_oaS!9#?B zA>V28MpjXImS84RCW!t3CSNfI25trgpqe}uU7%nd>*V{ax{R!odD-0SS<)CZS^SEW zfZ|0U9k+Nx3sMqGQk^|RoGLw2iY$O)nruZpAbB|uVGSZ|K!h!bumcjsY(PQ*42t-G z%v)TgU^C*AGfQrX0!{Kr%uC5hEz&~>8-uh(FfgPtG%$Q(;t=NQVE-V(AS^mTWMlYc z3ENHKE0X6+%#>K5yrA%!q~^x(ixRdM1#LUn9&qsVb9ZuI=a9L`Au}U>McNe((;GlB z&Q8wj91<5fB(8Eu{rtqvAZb_33bdkI+EIxunQ7uhk;(NOvly)=OL5vUx=oJcd?M}z za;N~34F|pB{t%xg~Q0$i_6+ez%uC5hEz(QQ$uCazn5@WS&B#4DmdBOb z7O0}g5k$C5-o#@ns|aMaF??cSX0`al!_F%HNra14pJK?u_1(19&Ag n{ekKjfw)*4NPJ*sWMsU{pnRJ_>^qAaBcs$O1`t^!2$TZ=gHSL| diff --git a/AppCode/__pycache__/DocumentHandler.cpython-313.pyc b/AppCode/__pycache__/DocumentHandler.cpython-313.pyc index 2153fb1eadc4b8ba1b995ceacd219b45297ee12a..cdbe22f3bd4f86e87aba6058381be5ea07c751a1 100644 GIT binary patch delta 20 acmZ1>vqFaZGcPX}0}$Lu*WJi1%Lf2D7zF+R delta 20 acmZ1>vqFaZGcPX}0}vE`)!N7{%Lf2Dj0GY9 diff --git a/AppCode/__pycache__/ITATHandler.cpython-313.pyc b/AppCode/__pycache__/ITATHandler.cpython-313.pyc index e748652cc607709c27a946abec2e55c668753593..04e27a1330f48140798193dc309d84b229c3adad 100644 GIT binary patch delta 433 zcmca5wO@+&GcPX}0}!l_(ajXv$Xme5C^xx|RhA`~$&_jGURF5><1UQx7silflM@1| z0qJF6&}YqK3S|glnyknuJox~J$mAk6cM-na#FF@u#ESUjqSTbkk|L1W$=BEvSXnAl z6N@H)Wh<;N0}3@TJP;6>&M}eWf~4jO!^;A?Hz3>@(hCwV3uwT2VhaQ>3n;^Qaw~v5 zZ5R(C_ko*DjIYD(10MsgV83^#_jMkHi#!SoWLA`2;W4|xBhc^J>3N+;<|2>GRUWw_ zL7>%}pR=1V+Nc3pMM@w-8APan2vs0)iz~DsC9x#cGsH2ZNCPOK$x_4%l9U4x+8{z_ zayX|sqt51jPF+Sut;u`2d>Jh#b8|mtw3z&!Ta3|uG8<2$fG$X-A&4*q5f+oD^Z2lG vvdVvwnEZmr6sSm!S3<=RD8&fG#X>;h12ZEd<5LFZ?`$@VQlA)r1lYL%vqfy= delta 355 zcmdllbxVr(GcPX}0}wng)Xikt$Xme5XfnBuRd#X%6UXG^tm4c}ri_yhvdS_ugK0S! zmlYz+&1T97(#^o2&o)_~twfeBIkO}_GvyXbWoly4Exz2ulK7IuiumNB)RfGU$=lf! zCf{W%5UK!bXkd82Bhc^B=`kVVGLPKkM$UrGXW5MzZIpp>MJgad6-20k2z4NFiz~Ds zC9x#cGsH2ZNE0Za$x_4%l9U4xIv_%KvJIy>qu%BcPF+Su?a7O{d>O4Lf8cs7VF{GI zB?!{#k(if~lUk&goReRi>Nxo|ccXwFNUITuFar^mlWTZz|6?V_>@8UJDVM&)F%cY0oDTmQdw7n diff --git a/AppCode/__pycache__/ITRHandler.cpython-313.pyc b/AppCode/__pycache__/ITRHandler.cpython-313.pyc index a32745120d5a88f55970e10df2909ce85f88d9cd..4a43b758d50cddb3c27d1e41fa00648d97ac8449 100644 GIT binary patch delta 2979 zcmZuzU2GHC6}~g$`LW02*s+}-Cw3f?4KWZX-iE&=fJ5SiP_m0BUbYRza_wIgMly8*4N;g16P`Xn zV+LC0gl&k$?3#?jyrmPcV6}E^hxU1P^ojMcwK296jv*0?Lr&}*lCTs;O=t^}*#MHy zalJH22qEkmqa*xd!bT`l80bH$sk!{vFm(8DDrx+(Qi?F9U02j>Dwi)PW*r7r!Ksom zUM!?bipgW;!i1uiGQ`I^QESZVz}#DXfdImy?7+@3G2%2G$43&!(rUJ#;K%hh7ha?& z-v=DcQdFJcWVTTrV=oh=>Ww7RO$ChaGsBesgFi7&>OdX1#7zX62?PL4wutj;DPqGO z(xdZP+(LA%0J;qz420_qFS~>4GLEo$@bwFJiVke}auGu=qm7T}OA!`(jDx~9h(0ES zsr|-`fOiWpfPw$&KLIYIT~PW{l*%NjT~w0sqStIXy$k8I7aj8WCKDX3d1PX)&pKtc9eLuNM@33FKxUcwHXH~-wQU(;O47YBj*x0g+7c4fK2TQKB%2_~Jwq~0mNVggMhx9vk^&GcDx0XU z@tYAg5~tH&t8Jt(1mi}@Oe{)rqp*Q$WNnUJz;~|+vM|?^a2ArBY)f)3^dg<2Pj0F0 zHygDaMh7?B(^?BOG7cGjk3X&2fs~cLr6rP zXSKdsWe6*DLOrch!sSpq+ObhISkfG5+F(7xXt=A7X+t@x9gS{VcbV9+&TX`bog4f* z$D=f?jVg}rUYE$OqzGx2tv(4MgE}UTt+hEShic&>b;G6;u2(pk{nO;Cwa%}}#`8)c zdy!8l84YK{BN5sfG;g{c zHm+K_m^JMK=~6n5!P>N!a9Y)iny#2!UezHIejR+(a&_eOG6+j)HKUje+|VWmuLdy_ zv7$o)wQT6TX7c^hB}G5}iYX3GWt75cYbvHt(ozcPo1B%g4w-{lMk`E=tENp?l=CJ# zKCNFUnD&gOs!FD$VUxAyU|n#Lva|LkNV-x0t&&YmLy1ir)+Tl9eK6^4&Xlsb)YFM% zO)5_kBy}gDbd%F2O2rAtzE)w=KB?jJRzfDF=uVg~T!v2xZbeuTZ@z?6SSc4ZTuNoN zNwuJ*vu0@H(c4)Y@D=?OSn5B7UHK+jwslFZkKDd1;+(kX?yR~y=g;04zmdA{9(>f; zJZoDDZMlB_+WE!MzG`US$DsqW@uimb>xZu$zSpwj(!gg7YJ2J59BL}JF156M&Y^~; zD`zg9neV*k-#SY#bEv)Jedl}5pSfnGC3kSm|EUUpBe=MGpt^eiqAUw2w0$ucT?j^3 zS*ET2(_r)}^{aEYJRcoh+;eP|LH-wJV^$P5Mlg8UfjlAN zw(Rb#jNaxa|=t=9uT3H-EmmV4-LymI!^+4=a5gA4v6 zx8h5__C?>es&89m&xig$9J)*RZ!Lwp-k08!Drz;{H+y`^7hLppSAE?TPbF5t_kGbP zJZgwhB!Nb#U0J*u`>|`OF*qyzXQdr7d*UPNKl_h-`MDeUny(z5JG|)au6nyy5iPYo zbo=i%Y^`|iySG1VZ25AT1=)Y~S7BM+jy1*^^xHtp1I_QYHxKsMelIu(*2kP6`Y81E z!6$tMUV zZ-x#V0FlQP`WFFA_oiKAjs3atM=9bZF9Tc)mK||49FYv(wWrfd41)wZ2*e2t5f~;g zN#LS!#uXeP4r*cSgd;$L>g3XU2d&s>cHfHA&Ni+zNvv*q0f4>0-4z~s@k(!y^M?rFZJaBy79P85_wcm@=tUiw~uWrm`tPf%~i1Jv*d>i9eI jK0vMq$o>U~s7{bQAOibeQEwIXJ`qM}DzJhGTAu$84%(p{ delta 1293 zcmZ8h%}*Ow5PxrX-+KLxKjYXTY^XpiB1DO0KothZ1&IcQBsNY&qo$&^v0NG3d25S= z3q4eokt(IuYd+MItF&s`Q&NsS^bhC-1TE3FmC_@()TpYWTsm*Tb=#5r+j%o@X5Rc} zo#9{1YKZ?EB#SX+FK(DlbJzL9?1HWm9bkxrwz##}=kSZ;fYnnuz{3H}} z^aS^X0CWjJ1)(nXH5tKSwnvJPYf8Q&guA&o35J}ltgaSo8lg_Mtqeom*NTeIvQt*N zVSx)G{0^@}Kljl&;O81Hi)kU%=?|P8$%sC5UDAbfNEdu)4q_`aF5oUIToo=`5war{ zJY^|%99t%7DMR1}iHc?Uf6>ruB`Kst_JcKmW!98^y_T|+v7|_+T=$#7G0gVm3lkan zCU4G^jHOejGdC4wP|DHqcfTn&`@`vD38#hiIHV0-IC|y^Jhr20mIc}m5$nQ;x-P~C z^mTXU>deK(S+!WBYI=52U3aNB=4Ml1$f%d1r;{Y3)Vh)s^=9VcA(;N~2hE31c-piJj>pBG9uIK4pdJ*ip z0>H=3g}V4nxn9jJLwZkl<3^862_EnO;6v1wEIwPq^3scf;fG7jrDtoqeH+u?tvwZ6 z11P3;*ox|EAE8 zw>@Le71urIrt{PH_mq<_6vsXLrhQ+D>?n~(vtP!Z1Ruxul=IKQZr!x*E1?}F^pg^P z)%GAYfnT*1qmOWj~LTep3Hwh*=9E4EUIGTj=(CX;2D#fh^s^vRd2kkEaK^L!>H1Vl#2pYd$yk}+yiopj@vS-e@=i{DxzV@i4 zr3o0^_Fggfd4Qjh2|;WSM;92e0V=56B)rKHE`u~b$rGUq&VwqXK@|s?H3AVA_?+|% z$s9-J@zF8Iu9yqcI-Z2UHHf2rMr=R{2&V$!RgMTMpJqPLCy`W<;fN}c=t3kHrO|hd zGI_)Bo?&2m=mTBhfxv!89zz>2%WwcQji^E%zvp4F!4|JyJmRS6 z8dk-{_hjhhvEkA?4tc*cZhT-^&SKTDz0wU^cdEv%@<(dT^^9t1WN~rKnKw#}d=wUI zRMs@pHa$(FZQ*Hn5@C+rJVVQ{pX{k83*ROSJIPBc;%BivCH=X1->fVB+e-ge*)64i zOS!Tl-fKQ$>YyJdhcW2IPw{mY=mzuxOBgEs3uca!av~^lgNci!3sm2xTf?jD*90?{)ceY+UTfNF>|%R=5hh zCY*x`$J&O9HP+Q1$ERxQ+cz^4gg9h4CzEF8j>>x3vKEP>(^l7Wh%v7b!(FmGm&z5x z)8AuKDphOl9gD^q{pAoU`A(>`NKD(yMM(>~ilH0LE>{gI;e{@Z1iq+9oDW?pFibha z#eUBOKw8nz?_adg=4x7%b)7|1VTWOBpAuox+;xVQ;ec<6DSPp@waL}VdOWio&upf4 z+$u8t)8L#6Te8%edR!gWNPK+pNA5>IQ+-2GPHHB-Cey~Ph__f*(2a%%6`0ky|CH0 z8_(`_bl$u1_kqL?|8g&}pgtLC9m&Jvw$_pU$m8B9()|+ReD7$V@FdnU+9NzsIHY?d zhEJ^+oCUxCEkLx}HMW*mO?)S(NIO%?@quIPyy={b8wJ~i zZImVr3%_I`9oMuwOJ%DeNoZQdB(7(fwqZM(MsNy9A0j`VPEB*YvS;dA+4G1wx8xbF zrac1x!XR!OPJ#$i<6', methods=['GET', 'POST']) -def update_itr(id): - conn = get_db_connection() - - if request.method == 'POST': - cursor = conn.cursor() - columns = [ - 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', - 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', - 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', - 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', - 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', - 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' - ] - - # Create the "SET column = %s" part of the query - set_clause = ', '.join([f"{col} = %s" for col in columns]) - query = f"UPDATE itr SET {set_clause} WHERE id = %s" - - values = [request.form.get(col, 0) for col in columns] - values.append(id) # Add the ID for the WHERE clause at the end - - cursor.execute(query, tuple(values)) - conn.commit() - cursor.close() - conn.close() - return redirect(url_for('display_itr')) - - # For a GET request, fetch the existing data and show it in the form - cursor = conn.cursor(dictionary=True) - cursor.execute("SELECT * FROM itr WHERE id = %s", (id,)) - record = cursor.fetchone() - cursor.close() - conn.close() - return render_template('update_itr.html', record=record) @@ -155,7 +126,6 @@ def update_itr(id): ## ITR (Income Tax Return) Routes ## =============================================== - ## 1. READ/DISPLAY all ITR records @app.route('/itr_records') def display_itr(): @@ -186,6 +156,61 @@ def delete_itr(id): itr.close() return redirect(url_for('display_itr')) +## 3. UPDATE an existing ITR record +@app.route('/itr/update/', methods=['GET', 'POST']) +def update_itr(id): + itr = ITRHandler() + + if request.method == 'POST': + data = {k: request.form.get(k, 0) for k in request.form} + print("itr data-->",data) + + itr.update(id, data=data) + itr.close() + return redirect(url_for('display_itr')) + + record = itr.get_itr_by_id(id) + itr.close() + return render_template('update_itr.html', record=record) + + + +## 3. UPDATE an existing ITR record +# @app.route('/itr/update/', methods=['GET', 'POST']) +# def update_itr(id): +# conn = get_db_connection() + +# if request.method == 'POST': +# cursor = conn.cursor() +# columns = [ +# 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', +# 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', +# 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', +# 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', +# 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', +# 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' +# ] + +# # Create the "SET column = %s" part of the query +# set_clause = ', '.join([f"{col} = %s" for col in columns]) +# query = f"UPDATE itr SET {set_clause} WHERE id = %s" + +# values = [request.form.get(col, 0) for col in columns] +# values.append(id) # Add the ID for the WHERE clause at the end + +# cursor.execute(query, tuple(values)) +# conn.commit() +# cursor.close() +# conn.close() +# return redirect(url_for('display_itr')) + +# # For a GET request, fetch the existing data and show it in the form +# cursor = conn.cursor(dictionary=True) +# cursor.execute("SELECT * FROM itr WHERE id = %s", (id,)) +# record = cursor.fetchone() +# cursor.close() +# conn.close() +# return render_template('update_itr.html', record=record) @@ -213,6 +238,25 @@ def add_ao(): return redirect(url_for('display_ao')) return render_template('add_ao.html') +# 3. UPDATE AO record +@app.route('/ao/update/', methods=['GET', 'POST']) +def update_ao(id): + ao = AOHandler() + record = ao.get_ao_by_id(id) + + if not record: + return "AO record not found", 404 + + if request.method == 'POST': + data = request.form.to_dict() + ao.update_ao(id, data) + ao.close() + flash("AO record updated successfully!", "success") + return redirect(url_for('display_ao')) + + ao.close() + return render_template("update_ao.html", record=record) + # 4. DELETE AO record safely @app.route('/ao/delete/', methods=['POST']) @@ -224,41 +268,43 @@ def delete_ao(id): return redirect(url_for('display_ao')) + + # 3. UPDATE AO record -@app.route('/ao/update/', methods=['GET', 'POST']) -def update_ao(id): - conn = get_db_connection() - cursor = conn.cursor(dictionary=True) - cursor.execute("SELECT * FROM ao WHERE id = %s", (id,)) - ao_record = cursor.fetchone() +# @app.route('/ao/update/', methods=['GET', 'POST']) +# def update_ao(id): +# conn = get_db_connection() +# cursor = conn.cursor(dictionary=True) +# cursor.execute("SELECT * FROM ao WHERE id = %s", (id,)) +# ao_record = cursor.fetchone() - if not ao_record: - cursor.close() - conn.close() - return "AO record not found", 404 +# if not ao_record: +# cursor.close() +# conn.close() +# return "AO record not found", 404 - if request.method == 'POST': - columns = [ - 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', - 'deduction_80ia_business', 'deduction_sec37_disallowance', 'deduction_80g', - 'net_taxable_income', 'tax_30_percent', 'tax_book_profit_18_5', - 'surcharge_12', 'edu_cess_3', 'total_tax_payable', 'mat_credit', - 'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', - 'tax_on_assessment', 'refund' - ] - values = [request.form.get(col, 0) for col in columns] - set_clause = ", ".join([f"{col}=%s" for col in columns]) - query = f"UPDATE ao SET {set_clause} WHERE id=%s" - cursor.execute(query, tuple(values) + (id,)) - conn.commit() - cursor.close() - conn.close() - flash("AO record updated successfully!", "success") - return redirect(url_for('display_ao')) +# if request.method == 'POST': +# columns = [ +# 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', +# 'deduction_80ia_business', 'deduction_sec37_disallowance', 'deduction_80g', +# 'net_taxable_income', 'tax_30_percent', 'tax_book_profit_18_5', +# 'surcharge_12', 'edu_cess_3', 'total_tax_payable', 'mat_credit', +# 'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', +# 'tax_on_assessment', 'refund' +# ] +# values = [request.form.get(col, 0) for col in columns] +# set_clause = ", ".join([f"{col}=%s" for col in columns]) +# query = f"UPDATE ao SET {set_clause} WHERE id=%s" +# cursor.execute(query, tuple(values) + (id,)) +# conn.commit() +# cursor.close() +# conn.close() +# flash("AO record updated successfully!", "success") +# return redirect(url_for('display_ao')) - cursor.close() - conn.close() - return render_template('update_ao.html', record=ao_record) +# cursor.close() +# conn.close() +# return render_template('update_ao.html', record=ao_record) @@ -297,27 +343,28 @@ def delete_cit(id): return redirect(url_for('display_cit')) -# @app.route('/cit/update/', methods=['GET', 'POST']) -# def update_cit(id): -# handler = CITHandler() -# record = handler.get_cit_by_id(id) - -# if not record: -# handler.close() -# return "CIT record not found", 404 - -# if request.method == 'POST': -# handler.update_cit(id, request.form) -# handler.close() -# return redirect(url_for('display_cit')) - -# handler.close() -# return render_template('add_cit.html', record=record) - - - @app.route('/cit/update/', methods=['GET', 'POST']) def update_cit(id): + cit = CITHandler() + record = cit.get_cit_by_id(id) + + if not record: + cit.close() + return "CIT record not found", 404 + + if request.method == 'POST': + data = {k: request.form.get(k, 0) for k in request.form} + cit.update_cit(id, data) + cit.close() + return redirect(url_for('display_cit')) + + cit.close() + return render_template('update_cit.html', record=record) + + + +# @app.route('/cit/update/', methods=['GET', 'POST']) +# def update_cit(id): conn = get_db_connection() cursor = conn.cursor(dictionary=True) cursor.execute("SELECT * FROM cit WHERE id=%s", (id,)) @@ -495,35 +542,52 @@ def update_itat(id): # ADD a new ITAT record +# @app.route('/itat/add', methods=['GET', 'POST']) +# def add_itat(): +# conn = get_db_connection() +# cursor = conn.cursor(dictionary=True) + +# # Fetch all CIT records to choose from +# cursor.execute("SELECT id, year FROM cit ORDER BY year DESC") +# cit_records = cursor.fetchall() + +# if request.method == 'POST': +# cit_id = request.form.get('cit_id') # selected parent CIT id +# columns = ['id', 'year','mat_tax_credit', 'surcharge', 'cess', 'total_credit'] +# values = [cit_id, +# request.form.get('year', 0), +# request.form.get('mat_tax_credit', 0), +# request.form.get('surcharge', 0), +# request.form.get('cess', 0), +# request.form.get('total_credit', 0)] +# query = f"INSERT INTO itat ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})" +# cursor.execute(query, tuple(values)) +# conn.commit() +# cursor.close() +# conn.close() +# flash("ITAT record added successfully!", "success") +# return redirect(url_for('display_itat')) + +# cursor.close() +# conn.close() +# return render_template('add_itat.html', cit_records=cit_records) + + + + @app.route('/itat/add', methods=['GET', 'POST']) def add_itat(): - conn = get_db_connection() - cursor = conn.cursor(dictionary=True) - - # Fetch all CIT records to choose from - cursor.execute("SELECT id, year FROM cit ORDER BY year DESC") - cit_records = cursor.fetchall() + itat = ITATHandler() if request.method == 'POST': - cit_id = request.form.get('cit_id') # selected parent CIT id - columns = ['id', 'year','mat_tax_credit', 'surcharge', 'cess', 'total_credit'] - values = [cit_id, - request.form.get('year', 0), - request.form.get('mat_tax_credit', 0), - request.form.get('surcharge', 0), - request.form.get('cess', 0), - request.form.get('total_credit', 0)] - query = f"INSERT INTO itat ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})" - cursor.execute(query, tuple(values)) - conn.commit() - cursor.close() - conn.close() + data = {k: request.form.get(k, 0) for k in request.form} + itat.add_itat(data) + itat.close() flash("ITAT record added successfully!", "success") return redirect(url_for('display_itat')) - cursor.close() - conn.close() - return render_template('add_itat.html', cit_records=cit_records) + itat.close() + return render_template('add_itat.html') # @app.route('/itat/update/', methods=['GET', 'POST']) @@ -651,64 +715,60 @@ def get_db_connection(): connection = mysql.connector.connect(**db_config) return connection -import pandas as pd -import pymysql -import io @app.route('/reports') def reports(): return render_template("reports.html") - +# new new @app.route('/itr_report', methods=['GET']) def itr_report(): - connection = pymysql.connect(**db_config) - try: - selected_year = request.args.get('year') + yearGetter = YearGet() + selected_year = request.args.get('year') - if selected_year: - # Fetch ITR data for the selected year - query = "SELECT * FROM itr WHERE year = %s" - df = pd.read_sql(query, connection, params=[selected_year]) + if selected_year: + itr = ITRHandler() + output = itr.itr_report_download(selected_year) + itr.close() - if df.empty: - return "No records found for the selected year." + if output is None: + return "No records found for the selected year." - # Transpose DataFrame: vertical fields, horizontal records - df_transposed = df.transpose() - df_transposed.insert(0, 'Field', df_transposed.index) + return send_file( + output, + mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + as_attachment=True, + download_name=f"ITR_Report_{selected_year}.xlsx" + ) - # Rename columns as Record 1, Record 2, etc. - record_cols = {i: f'Record {i}' for i in df_transposed.columns if isinstance(i, int)} - df_transposed.rename(columns=record_cols, inplace=True) - df_transposed.reset_index(drop=True, inplace=True) + else: + years = yearGetter.get_year_by_model("GetITRYears") + yearGetter.close() + return render_template("itr_reports.html", years=years) - output = io.BytesIO() - with pd.ExcelWriter(output, engine='xlsxwriter') as writer: - df_transposed.to_excel(writer, index=False, sheet_name='ITR_Vertical') + - # Format for better readability (optional) - workbook = writer.book - worksheet = writer.sheets['ITR_Vertical'] - worksheet.set_column(0, 0, 30) # Field column wider +# @app.route('/itr/reports', methods=['GET', 'POST']) +# def itr_reports(): +# yearGetter = YearGet() - output.seek(0) - return send_file( - output, - mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - as_attachment=True, - download_name=f"ITR_Report_{selected_year}.xlsx" - ) +# if request.method == "POST": +# selected_year = request.form.get("year") +# itr=ITRHandler() + + +# yearGetter.close() +# return redirect(url_for("itr_report_result", year=selected_year)) + +# # GET method → fetch all distinct years through procedure +# years = yearGetter.get_year_by_model("GetITRYears") +# yearGetter.close() + +# print("---- year --",years) + +# return render_template("itr_reports.html", years=years) - else: - # Render dropdown form with available years - with connection.cursor() as cursor: - cursor.execute("SELECT DISTINCT year FROM itr ORDER BY year DESC") - years = [row[0] for row in cursor.fetchall()] - return render_template("itr_reports.html", years=years) - finally: - connection.close() @app.route('/ao_report', methods=['GET']) @@ -832,35 +892,35 @@ def itat_report(): -@app.route('/itr_report_download', methods=['GET']) -def itr_report_download(): - connection = pymysql.connect(**db_config) - try: - selected_year = request.args.get('year') +# @app.route('/itr_report_download', methods=['GET']) +# def itr_report_download(): +# connection = pymysql.connect(**db_config) +# try: +# selected_year = request.args.get('year') - if selected_year: - query = "SELECT * FROM itr WHERE year = %s" - df = pd.read_sql(query, connection, params=[selected_year]) +# if selected_year: +# query = "SELECT * FROM itr WHERE year = %s" +# df = pd.read_sql(query, connection, params=[selected_year]) - output = io.BytesIO() - with pd.ExcelWriter(output, engine='xlsxwriter') as writer: - df.to_excel(writer, index=False, sheet_name=f"ITR {selected_year}") - output.seek(0) +# output = io.BytesIO() +# with pd.ExcelWriter(output, engine='xlsxwriter') as writer: +# df.to_excel(writer, index=False, sheet_name=f"ITR {selected_year}") +# output.seek(0) - return send_file( - output, - download_name=f"ITR_Report_{selected_year}.xlsx", - as_attachment=True, - mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - ) - else: - # If no year is selected, show dropdown - with connection.cursor() as cursor: - cursor.execute("SELECT DISTINCT year FROM itr ORDER BY year DESC") - years = [row[0] for row in cursor.fetchall()] - return render_template('itr_reports.html', years=years) - finally: - connection.close() +# return send_file( +# output, +# download_name=f"ITR_Report_{selected_year}.xlsx", +# as_attachment=True, +# mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' +# ) +# else: +# # If no year is selected, show dropdown +# with connection.cursor() as cursor: +# cursor.execute("SELECT DISTINCT year FROM itr ORDER BY year DESC") +# years = [row[0] for row in cursor.fetchall()] +# return render_template('itr_reports.html', years=years) +# finally: +# connection.close() @app.route('/download/') @@ -878,12 +938,7 @@ def download_report(doc_id): file_path = os.path.join('static', 'uploads', document['filename']) # adjust as per your storage return send_from_directory(directory='static/uploads', path=document['filename'], as_attachment=True) -# main.py -from flask import Flask, send_file -import pandas as pd -import io -import pymysql # or use mysql.connector if preferred -from config import db_config + @app.route('/summary_report', methods=['GET']) def summary_report(): year = request.args.get('year') diff --git a/test.py b/test.py index f9ddca0..f9cd8a6 100644 --- a/test.py +++ b/test.py @@ -101,3 +101,123 @@ class DocumentHandler: # return redirect(url_for('view_documents')) #return render_template('upload.html') + + + + + + + +# old itr report code +@app.route('/itr_report', methods=['GET']) +def itr_report(): + yearGetter = YearGet() + + connection = pymysql.connect(**db_config) + try: + selected_year = request.args.get('year') + + if selected_year: + # Fetch ITR data for the selected year + query = "SELECT * FROM itr WHERE year = %s" + df = pd.read_sql(query, connection, params=[selected_year]) + + if df.empty: + return "No records found for the selected year." + + # Transpose DataFrame: vertical fields, horizontal records + df_transposed = df.transpose() + df_transposed.insert(0, 'Field', df_transposed.index) + + # Rename columns as Record 1, Record 2, etc. + record_cols = {i: f'Record {i}' for i in df_transposed.columns if isinstance(i, int)} + df_transposed.rename(columns=record_cols, inplace=True) + df_transposed.reset_index(drop=True, inplace=True) + + output = io.BytesIO() + with pd.ExcelWriter(output, engine='xlsxwriter') as writer: + df_transposed.to_excel(writer, index=False, sheet_name='ITR_Vertical') + + # Format for better readability (optional) + workbook = writer.book + worksheet = writer.sheets['ITR_Vertical'] + worksheet.set_column(0, 0, 30) # Field column wider + + output.seek(0) + return send_file( + output, + mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + as_attachment=True, + download_name=f"ITR_Report_{selected_year}.xlsx" + ) + + else: + # Render dropdown form with available years + with connection.cursor() as cursor: + cursor.execute("SELECT DISTINCT year FROM itr ORDER BY year DESC") + years = [row[0] for row in cursor.fetchall()] + return render_template("itr_reports.html", years=years) + + finally: + connection.close() + + + +# --------------\ + +@app.route('/itr_report', methods=['GET']) +def itr_report(): + yearGetter = YearGet() + + + selected_year = request.args.get('year') + + if selected_year: + # Fetch ITR data for the selected year + query = "SELECT * FROM itr WHERE year = %s" + df = pd.read_sql(query, connection, params=[selected_year]) + + if df.empty: + return "No records found for the selected year." + + + + # Transpose DataFrame: vertical fields, horizontal records + df_transposed = df.transpose() + df_transposed.insert(0, 'Field', df_transposed.index) + + # Rename columns as Record 1, Record 2, etc. + record_cols = {i: f'Record {i}' for i in df_transposed.columns if isinstance(i, int)} + df_transposed.rename(columns=record_cols, inplace=True) + df_transposed.reset_index(drop=True, inplace=True) + + output = io.BytesIO() + with pd.ExcelWriter(output, engine='xlsxwriter') as writer: + df_transposed.to_excel(writer, index=False, sheet_name='ITR_Vertical') + + # Format for better readability (optional) + workbook = writer.book + worksheet = writer.sheets['ITR_Vertical'] + worksheet.set_column(0, 0, 30) # Field column wider + + output.seek(0) + return send_file( + output, + mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + as_attachment=True, + download_name=f"ITR_Report_{selected_year}.xlsx" + ) + + else: + # Render dropdown form with available years + with connection.cursor() as cursor: + # cursor.execute("SELECT DISTINCT year FROM itr ORDER BY year DESC") + # years = [row[0] for row in cursor.fetchall()] + + years = yearGetter.get_year_by_model("GetITRYears") + yearGetter.close() + + print("---- year --",years) + + + return render_template("itr_reports.html", years=years)