From 1a217321742a22569e4bf8612a9a51ecfeb835b0 Mon Sep 17 00:00:00 2001 From: pjpatil12 Date: Sat, 24 Jan 2026 18:22:28 +0530 Subject: [PATCH] report formate changes all model --- AppCode/AOHandler.py | 162 ++++++++++++----- AppCode/CITHandler.py | 166 +++++++++++++----- AppCode/ITATHandler.py | 133 +++++++++++--- AppCode/ITRHandler.py | 137 +++++++++++---- AppCode/__pycache__/AOHandler.cpython-313.pyc | Bin 5491 -> 7576 bytes .../__pycache__/CITHandler.cpython-313.pyc | Bin 5236 -> 7619 bytes .../DocumentHandler.cpython-313.pyc | Bin 9535 -> 9535 bytes .../__pycache__/ITATHandler.cpython-313.pyc | Bin 4839 -> 7630 bytes .../__pycache__/ITRHandler.cpython-313.pyc | Bin 5738 -> 7802 bytes 9 files changed, 452 insertions(+), 146 deletions(-) diff --git a/AppCode/AOHandler.py b/AppCode/AOHandler.py index 24a21bc..86b0820 100644 --- a/AppCode/AOHandler.py +++ b/AppCode/AOHandler.py @@ -71,49 +71,127 @@ class AOHandler: self.cursor.callproc('DeleteAOById', [id]) self.conn.commit() + # report download by year + def ao_report_download(self, selected_year): + try: + # AY calculation (2020 -> AY 2020-2021) + ay_start = int(selected_year) + ay_end = ay_start + 1 + assessment_year = f"AY {ay_start}-{ay_end}" + + # Fetch AO records + self.cursor.callproc("GetAOByYear", [selected_year]) + + rows = [] + for result in self.cursor.stored_results(): + rows = result.fetchall() + + if not rows: + return None + + # Remove id column if exists + for row in rows: + row.pop("id", None) + + # Mapping DB fields → readable Excel labels + field_mapping = { + "gross_total_income": "Gross Total Income", + "disallowance_14a": "Add: Disallowance u/s 14A", + "disallowance_37": "Add: Disallowance u/s 37", + "deduction_80ia_business": "Less: Deduction u/s 80IA - On Business Income", + "deduction_80ia_misc": "On Misc Receipts", + "deduction_80ia_other": "On Other", + "deduction_sec37_disallowance": "On Sec 37 Disallowance", + "deduction_80g": "Less: Deduction u/s 80G", + "net_taxable_income": "Net Taxable Income", + "tax_30_percent": "Tax @ 30%", + "tax_book_profit_18_5": "Tax @ 18.5% on Book Profit", + "tax_payable": "Tax Payable", + "surcharge_12": "Surcharge @ 12%", + "edu_cess_3": "Education Cess @ 3%", + "total_tax_payable": "Total Tax Payable", + "mat_credit": "Less: MAT Credit Utilized", + "interest_234c": "Add: Interest u/s 234C", + "total_tax": "Total Tax", + "advance_tax": "Advance Tax", + "tds": "TDS", + "tcs": "TCS", + "sat": "SAT", + "tax_on_assessment": "Tax on Regular Assessment", + "refund": "Refund", + "Remarks": "Remarks" + } + + # Vertical AO structure + data = [] + for key, label in field_mapping.items(): + value = rows[0].get(key, 0) + data.append([label, value]) + + df = pd.DataFrame(data, columns=["Particulars", "AO"]) + + # Excel output + output = io.BytesIO() + with pd.ExcelWriter(output, engine="xlsxwriter") as writer: + workbook = writer.book + worksheet = workbook.add_worksheet("AO Report") + writer.sheets["AO Report"] = worksheet + + # Formats + title_fmt = workbook.add_format({ + "bold": True, + "align": "center", + "font_size": 14 + }) + header_fmt = workbook.add_format({ + "bold": True, + "border": 1, + "align": "center" + }) + text_fmt = workbook.add_format({"border": 1}) + num_fmt = workbook.add_format({ + "border": 1, + "num_format": "#,##0.00" + }) + + # Company Name + worksheet.merge_range( + "A1:B1", + "Laxmi Civil Engineering Services Pvt Ltd", + title_fmt + ) + + # Assessment Year + worksheet.merge_range( + "A2:B2", + f"Assessment Year : {assessment_year}", + workbook.add_format({"bold": True, "align": "center"}) + ) + + # Header + worksheet.write_row("A4", ["Particulars", "AO"], header_fmt) + + # Data rows + row_no = 4 + for _, row in df.iterrows(): + worksheet.write(row_no, 0, row["Particulars"], text_fmt) + worksheet.write(row_no, 1, row["AO"], num_fmt) + row_no += 1 + + # Column width + worksheet.set_column("A:A", 45) + worksheet.set_column("B:B", 20) + + 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() - self.conn.close() - - # report download by year - def ao_report_download(self, selected_year): - try: - # Call stored proc to fetch year-wise records - self.cursor.callproc("GetAOByYear", [selected_year]) - - rows = [] - for result in self.cursor.stored_results(): - rows = result.fetchall() - - if not rows: - return None - - df = pd.DataFrame(rows) - - # TRANSPOSE - df_transposed = df.transpose() - df_transposed.insert(0, 'Field', df_transposed.index) - - # Rename columns: Record 1, 2, 3... - 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) - - # Excel Output - output = io.BytesIO() - with pd.ExcelWriter(output, engine="xlsxwriter") as writer: - df_transposed.to_excel(writer, index=False, sheet_name="AO_Vertical") - worksheet = writer.sheets["AO_Vertical"] - worksheet.set_column(0, 0, 30) - - output.seek(0) - return output - - except mysql.connector.Error as e: - print("MySQL Error:", e) - return None \ No newline at end of file + self.conn.close() \ No newline at end of file diff --git a/AppCode/CITHandler.py b/AppCode/CITHandler.py index 1612d8a..a1d9ca0 100644 --- a/AppCode/CITHandler.py +++ b/AppCode/CITHandler.py @@ -4,7 +4,6 @@ import pandas as pd import io - class CITHandler: def __init__(self): @@ -51,8 +50,6 @@ class CITHandler: self.cursor.callproc("InsertCIT", values) self.conn.commit() - - # UPDATE CIT RECORD def update_cit(self, id, data): columns = [ @@ -69,53 +66,130 @@ class CITHandler: self.cursor.callproc("UpdateCITById", values) self.conn.commit() - - # DELETE CIT RECORD def delete_cit(self, id): self.cursor.callproc("DeleteCITById", [id]) self.conn.commit() + # + def cit_report_download(self, selected_year): + try: + # AY calculation (2020 -> AY 2020-2021) + ay_start = int(selected_year) + ay_end = ay_start + 1 + assessment_year = f"AY {ay_start}-{ay_end}" - # CLOSE CONNECTION + # Fetch CIT records + self.cursor.callproc("GetCITByYear", [selected_year]) + + rows = [] + for result in self.cursor.stored_results(): + rows = result.fetchall() + + if not rows: + return None + + # Remove id column if exists + for row in rows: + row.pop("id", None) + + # Mapping DB fields → readable Excel labels + field_mapping = { + "gross_total_income": "Gross Total Income", + "disallowance_14a": "Add: Disallowance u/s 14A", + "disallowance_37": "Add: Disallowance u/s 37", + "deduction_80ia_business": "Less: Deduction u/s 80IA - On Business Income", + "deduction_80ia_misc": "On Misc Receipts", + "deduction_80ia_other": "On Other", + "deduction_sec37_disallowance": "On Sec 37 Disallowance", + "deduction_80g": "Less: Deduction u/s 80G", + "net_taxable_income": "Net Taxable Income", + "tax_30_percent": "Tax @ 30%", + "tax_book_profit_18_5": "Tax @ 18.5% on Book Profit", + "tax_payable": "Tax Payable", + "surcharge_12": "Surcharge @ 12%", + "edu_cess_3": "Education Cess @ 3%", + "total_tax_payable": "Total Tax Payable", + "mat_credit": "Less: MAT Credit Utilized", + "interest_234c": "Add: Interest u/s 234C", + "total_tax": "Total Tax", + "advance_tax": "Advance Tax", + "tds": "TDS", + "tcs": "TCS", + "sat": "SAT", + "tax_on_assessment": "Tax on Regular Assessment", + "refund": "Refund", + "Remarks": "Remarks" + } + + # Vertical CIT structure (single record per year) + data = [] + for key, label in field_mapping.items(): + value = rows[0].get(key, 0) + data.append([label, value]) + + df = pd.DataFrame(data, columns=["Particulars", "CIT"]) + + # Excel output + output = io.BytesIO() + with pd.ExcelWriter(output, engine="xlsxwriter") as writer: + workbook = writer.book + worksheet = workbook.add_worksheet("CIT Report") + writer.sheets["CIT Report"] = worksheet + + # Formats + title_fmt = workbook.add_format({ + "bold": True, + "align": "center", + "font_size": 14 + }) + header_fmt = workbook.add_format({ + "bold": True, + "border": 1, + "align": "center" + }) + text_fmt = workbook.add_format({"border": 1}) + num_fmt = workbook.add_format({ + "border": 1, + "num_format": "#,##0.00" + }) + + # Company Name + worksheet.merge_range( + "A1:B1", + "Laxmi Civil Engineering Services Pvt Ltd", + title_fmt + ) + + # Assessment Year + worksheet.merge_range( + "A2:B2", + f"Assessment Year : {assessment_year}", + workbook.add_format({"bold": True, "align": "center"}) + ) + + # Header + worksheet.write_row("A4", ["Particulars", "CIT"], header_fmt) + + # Data rows + row_no = 4 + for _, row in df.iterrows(): + worksheet.write(row_no, 0, row["Particulars"], text_fmt) + worksheet.write(row_no, 1, row["CIT"], num_fmt) + row_no += 1 + + # Column widths + worksheet.set_column("A:A", 45) + worksheet.set_column("B:B", 20) + + 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() - self.conn.close() - - - def cit_report_download(self, selected_year): - try: - # Call stored procedure - self.cursor.callproc("GetCITByYear", [selected_year]) - - rows = [] - for result in self.cursor.stored_results(): - rows = result.fetchall() - - if not rows: - return None - - df = pd.DataFrame(rows) - - # Excel output - output = io.BytesIO() - with pd.ExcelWriter(output, engine="xlsxwriter") as writer: - - for i, (_, row) in enumerate(df.iterrows(), start=1): - # Convert row to vertical format - vertical_df = pd.DataFrame(row).reset_index() - vertical_df.columns = ['Field', 'Value'] - - start_row = (i - 1) * (len(vertical_df) + 3) # gap between blocks - vertical_df.to_excel( - writer, - sheet_name='CIT_Report', - index=False, - startrow=start_row - ) - - output.seek(0) - return output - - except mysql.connector.Error as e: - print("MySQL Error:", e) - return None \ No newline at end of file + self.conn.close() \ No newline at end of file diff --git a/AppCode/ITATHandler.py b/AppCode/ITATHandler.py index b810bd5..f714e5f 100644 --- a/AppCode/ITATHandler.py +++ b/AppCode/ITATHandler.py @@ -65,32 +65,123 @@ class ITATHandler: self.conn.commit() - def itat_report_download(self, selected_year): - try: - # Call stored procedure - self.cursor.callproc("GetITATByYear", [selected_year]) - rows = [] - for result in self.cursor.stored_results(): - rows = result.fetchall() + try: + # AY calculation (2020 -> AY 2020-2021) + ay_start = int(selected_year) + ay_end = ay_start + 1 + assessment_year = f"AY {ay_start}-{ay_end}" - if not rows: - return None + # Fetch ITAT data + self.cursor.callproc("GetITATByYear", [selected_year]) + rows = [] + for result in self.cursor.stored_results(): + rows = result.fetchall() - df = pd.DataFrame(rows) - - # Excel output - output = io.BytesIO() - with pd.ExcelWriter(output, engine="xlsxwriter") as writer: - df.T.to_excel(writer, header=False, sheet_name="ITAT_Report") - - output.seek(0) - return output - - except mysql.connector.Error as e: - print("MySQL Error:", e) + if not rows: return None + # Remove id column if exists + for row in rows: + row.pop("id", None) + + # Mapping DB fields → readable Excel labels + field_mapping = { + "gross_total_income": "Gross Total Income", + "disallowance_14a": "Add: Disallowance u/s 14A", + "disallowance_37": "Add: Disallowance u/s 37", + "deduction_80ia_business": "Less: Deduction u/s 80IA - On Business Income", + "deduction_80ia_misc": "On Misc Receipts", + "deduction_80ia_other": "On Other", + "deduction_sec37_disallowance": "On Sec 37 Disallowance", + "deduction_80g": "Less: Deduction u/s 80G", + "net_taxable_income": "Net Taxable Income", + "tax_30_percent": "Tax @ 30%", + "tax_book_profit_18_5": "Tax @ 18.5% on Book Profit", + "tax_payable": "Tax Payable", + "surcharge_12": "Surcharge @ 12%", + "edu_cess_3": "Education Cess @ 3%", + "total_tax_payable": "Total Tax Payable", + "mat_credit": "Less: MAT Credit Utilized", + "interest_234c": "Add: Interest u/s 234C", + "total_tax": "Total Tax", + "advance_tax": "Advance Tax", + "tds": "TDS", + "tcs": "TCS", + "sat": "SAT", + "tax_on_assessment": "Tax on Regular Assessment", + "refund": "Refund", + "Remarks": "Remarks" + } + + # Vertical ITAT structure + data = [] + for key, label in field_mapping.items(): + value = rows[0].get(key, 0) + data.append([label, value]) + + df = pd.DataFrame(data, columns=["Particulars", "ITAT"]) + + # Excel output + output = io.BytesIO() + with pd.ExcelWriter(output, engine="xlsxwriter") as writer: + workbook = writer.book + worksheet = workbook.add_worksheet("ITAT Report") + writer.sheets["ITAT Report"] = worksheet + + # Formats + title_fmt = workbook.add_format({ + "bold": True, + "align": "center", + "font_size": 14 + }) + header_fmt = workbook.add_format({ + "bold": True, + "border": 1, + "align": "center" + }) + text_fmt = workbook.add_format({"border": 1}) + num_fmt = workbook.add_format({ + "border": 1, + "num_format": "#,##0.00" + }) + + # Company Name + worksheet.merge_range( + "A1:B1", + "Laxmi Civil Engineering Services Pvt Ltd", + title_fmt + ) + + # Assessment Year + worksheet.merge_range( + "A2:B2", + f"Assessment Year : {assessment_year}", + workbook.add_format({"bold": True, "align": "center"}) + ) + + # Header + worksheet.write_row("A4", ["Particulars", "ITAT"], header_fmt) + + # Data rows + row_no = 4 + for _, row in df.iterrows(): + worksheet.write(row_no, 0, row["Particulars"], text_fmt) + worksheet.write(row_no, 1, row["ITAT"], num_fmt) + row_no += 1 + + # Column widths + worksheet.set_column("A:A", 45) + worksheet.set_column("B:B", 20) + + 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/ITRHandler.py b/AppCode/ITRHandler.py index 87091ec..3731c99 100644 --- a/AppCode/ITRHandler.py +++ b/AppCode/ITRHandler.py @@ -81,48 +81,111 @@ class ITRHandler: self.conn.commit() - # report download by year + # # report download by year def itr_report_download(self, selected_year): - try: - # Call stored procedure - self.cursor.callproc("GetITRByYear", [selected_year]) + try: + # Call stored procedure + self.cursor.callproc("GetITRByYear", [selected_year]) - rows = [] - for result in self.cursor.stored_results(): - rows = result.fetchall() + 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) + if not rows: return None + for row in rows: + row.pop('id', None) + + # Mapping DB fields → Excel labels (NO underscores) + field_mapping = { + "gross_total_income": "Gross Total Income", + "disallowance_14a": "Add: Disallowance u/s 14A", + "disallowance_37": "Add: Disallowance u/s 37", + "deduction_80ia_business": "Less: Deduction u/s 80IA - On Business Income", + "deduction_80ia_misc": "On Misc Receipts", + "deduction_80ia_other": "On Other", + "deduction_sec37_disallowance": "On Sec 37 Disallowance", + "deduction_80g": "Less: Deduction u/s 80G", + "net_taxable_income": "Net Taxable Income", + "tax_30_percent": "Tax @ 30%", + "tax_book_profit_18_5": "Tax @ 18.5% on Book Profit", + "tax_payable": "Tax Payable", + "surcharge_12": "Surcharge @ 12%", + "edu_cess_3": "Education Cess @ 3%", + "total_tax_payable": "Total Tax Payable", + "mat_credit": "Less: MAT Credit Utilized", + "interest_234c": "Add: Interest u/s 234C", + "total_tax": "Total Tax", + "advance_tax": "Advance Tax", + "tds": "TDS", + "tcs": "TCS", + "sat": "SAT", + "tax_on_assessment": "Tax on Regular Assessment", + "refund": "Refund" + } + + # Convert to vertical structure + data = [] + for key, label in field_mapping.items(): + value = rows[0].get(key, 0) + data.append([label, value]) + + df = pd.DataFrame(data, columns=["Particulars", "ITR"]) + + # Excel output + output = io.BytesIO() + with pd.ExcelWriter(output, engine="xlsxwriter") as writer: + workbook = writer.book + worksheet = workbook.add_worksheet("ITR Report") + writer.sheets["ITR Report"] = worksheet + + # Formats + title_fmt = workbook.add_format({ + "bold": True, "align": "center", "valign": "vcenter", + "font_size": 14 + }) + header_fmt = workbook.add_format({ + "bold": True, "border": 1, "align": "center" + }) + cell_fmt = workbook.add_format({"border": 1}) + num_fmt = workbook.add_format({"border": 1, "num_format": "#,##0.00"}) + + # Company name + worksheet.merge_range("A1:B1", "Laxmi Civil Engineering Services Pvt Ltd", title_fmt) + + ay_start = int(selected_year) + ay_end = ay_start + 1 + assessment_year = f"AY {ay_start}-{ay_end}" + + # Assessment Year + worksheet.merge_range( + "A2:B2", + f"Assessment Year : {assessment_year}", + workbook.add_format({"align": "center", "bold": True}) + ) + + # Headers + worksheet.write_row("A4", ["Particulars", "ITR"], header_fmt) + + # Data rows + row_no = 4 + for _, row in df.iterrows(): + worksheet.write(row_no, 0, row["Particulars"], cell_fmt) + worksheet.write(row_no, 1, row["ITR"], num_fmt) + row_no += 1 + + # Column widths + worksheet.set_column("A:A", 45) + worksheet.set_column("B:B", 20) + + 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() - self.conn.close() + self.conn.close() \ No newline at end of file diff --git a/AppCode/__pycache__/AOHandler.cpython-313.pyc b/AppCode/__pycache__/AOHandler.cpython-313.pyc index 1f472ea885a517d352958146830fe83425258126..f533e36f2a7658c7785b2cef0410bbf7ee7a2006 100644 GIT binary patch delta 3583 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 delta 20 acmdn*wcm^TGcPX}0}zA=6>a1;Q3U`${skfc diff --git a/AppCode/__pycache__/ITATHandler.cpython-313.pyc b/AppCode/__pycache__/ITATHandler.cpython-313.pyc index cd0d19ba09e0a4408982967c5e9443d4d3433131..4f59d0e3bd1d5afe9ea2635a261377a65c7618f5 100644 GIT binary patch delta 3586 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 KuMwpcrT+m3U$+DR delta 1673 zcmY*ZU2qds6u!IL-Ta57-6S-B-P9BsS{NHCf)?6f8$gATEWyz*&18}dM$%2Zn+`2A z7{_rOXM71=oq|5Jj1T0oI*!9*RbYH<08QNK1H+p>Rf;mgjN`c}OY~;;oNvE#?z!Kb zbF+`fejm1P+H7V7Ypxp?PCCD~ziCy6I1^oA)Ux%vJt-rJk(Fp?ZDHN^qa-~_ZN14| z$u8Al=hZ`IV^wC8Y+{?9*6|`OG7xce7#)o=TS!0<@7CFl??IbPqZzAS81s zmmW=WDYuSCX+TwY2A?uHAdY(xN^)XXlCz^1=rn!2A0Z18kZh1SIIdUU-0?|+$co$n zx-G}o;dKO2Ry2@!%CB>YppMj8im%GX|1?j~LmdyzGm1vhbbzLjYyuh2bz(Y7nnbf` z5v>Op5MoM%b-v?83kxr@IcZMp?681H4-kTe)1s}@ToI99yGam*qQ*p|o%lZ^KAS4Z z2t(5acw{b*LTI?tS(tntB7IOtKqqz_WcpB^3Zc|4Qj8-eF|0P|9%_$j?e48wQX_;T zOSC5~9T9yXNw&l+XP^2!l}B5}BHK=A)+18o*r~+f`M0DD#$>!28!t%3+yz5I%9e0W zI2ECBobZN%TrOs^QiRsJa=28+rwMDGD=Ks6akWs9aD>u0Nj_VUrMPB=s_D}bt`xGF zB5Yv`a!#7l%*s2GR7uO38R<7N(OGhjkI#!IUl*n@E@9#R#|x2OOjx{~7;=3u+%Tlk z<(y`k%v3UQ47)W`1!rWXTv8;BE695lI0~moa$BsqpcG`Kl998L#uVg=#$kyZs#&n4 zfPl6db&uQUG*(J!X)Y@jHLk5qQJ35!lvQoGg(*6h*KE0b`q@!AjVh25q%-MksiWd;R7WP^j140S4mAVO z+kxmN%k*{M4@56h-@d!*yzxqN-_cD5xdv*n%bsQDGE=*Fn-BjQh;FdR>EA$*ykSPp z;8xvwYBjt@#;h%%SRs>kUK^Z z0Upx1%dyYwEl;3k`};u%ggxR(^k>(^lZOt(_b!fK8gKRtHhKm(5pDCYJ6vn-oz=SY zu48E3<9o8f0{K{Z0|xV9%oAtO_uiNj+z&&&Q@guTc;0q`v*7=Mwu6|%;o%&jO3I14j=w#Z+JfoHP_=5zHQ-vV_}z2tXM@2l6K zF&BWv7uAD-QEEt40t4I**8gXMQkMcD{|v-5uAGr`83j+17eje|W?p%(i1X@t;8pKO kWHb3dWAZK6jAJvU+-y-ggg;d$f