Files
IncomeTaxSystem/AppCode/DocumentHandler.py
2026-01-07 00:49:42 +05:30

222 lines
7.8 KiB
Python

import os
from AppCode.Config import DBConfig
from AppCode.FileHandler import FileHandler
from werkzeug.utils import secure_filename
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort, flash,send_file
import mysql.connector
import pandas as pd
import io
from AppCode.YearGet import YearGet
class DocumentHandler:
def __init__(self):
self.years = []
self.documents = []
self.isSuccess = False
self.resultMessage = ""
# VIEW DOCUMENTS
def View(self, request):
year = request.args.get('year', '')
stage = request.args.get('stage', '')
dbconfig = DBConfig()
connection = dbconfig.get_db_connection()
if not connection:
self.isSuccess = False
return
cursor = connection.cursor(dictionary=True)
# --- FILTER QUERY ---
cursor.callproc("GetDocuments", [year, stage])
# fetch first result set
for result in cursor.stored_results():
self.documents = result.fetchall()
break
# ---- GET YEARS FROM STORED PROCEDURE ----
cursor.callproc("GetYear")
for result in cursor.stored_results():
year_rows = result.fetchall()
break
self.years = [row['year'] for row in year_rows]
cursor.close()
connection.close()
self.isSuccess = True
# Upload Documents
def Upload(self, request):
dbconfig = DBConfig()
connection = dbconfig.get_db_connection()
if connection:
cursor = connection.cursor()
files = request.files.getlist('documents')
year = request.form['year']
stage = request.form['stage']
for file in files:
extension = file.filename.rsplit('.', 1)[1]
if extension not in FileHandler.ALLOWED_EXTENSIONS:
print("Skip invalid file type : ",extension)
continue
filename = secure_filename(file.filename)
filepath = os.path.join(FileHandler.UPLOAD_FOLDER, filename)
file.save(filepath)
cursor.callproc('InsertDocument', [ filename, filepath, extension, year, stage ])
connection.commit()
cursor.close()
connection.close()
# return redirect(url_for('view_documents'))
def Summary_report(self, request):
dbconfig = DBConfig()
connection = dbconfig.get_db_connection()
year_str = request.args.get('year')
# If year not selected
if not year_str or not year_str.isdigit():
yearGetter = YearGet()
allYears = yearGetter.get_year_by_model("AllYearsInAllModel")
yearGetter.close()
return render_template(
'summary_reports.html',
years=allYears,
message="Please select a valid year to download."
)
# Convert year to int (IMPORTANT FIX)
year = int(year_str)
try:
stages = {
"ITR": "itr",
"AO": "ao",
"CIT": "cit",
"ITAT": "itat",
}
stage_data = {}
for stage_name, table_name in stages.items():
cursor = connection.cursor(dictionary=True)
cursor.callproc("sp_get_stage_data", [table_name, year])
rows = []
for result in cursor.stored_results():
rows = result.fetchall()
stage_data[stage_name] = pd.DataFrame(rows) if rows else pd.DataFrame()
cursor.close()
def safe_get(df, col):
return df[col].values[0] if col in df.columns and not df.empty else "-"
particulars = [
"Gross Total Income", "Add: Disallowance u/s 14A", "Add: Disallowance u/s 37",
"GTI as per", "Less: Deduction u/s 80IA - On Business Income", "- On Misc Receipts",
"- On Other", "- On Sec 37 Disallowance", "Less: Deduction u/s 80G", " ",
"Net Taxable Income", "Tax @ 30%", "Tax @ 18.5% on Book Profit",
"Tax Payable", "Surcharge @ %", "Education Cess @ 3%", "Total Tax Payable",
"Less: MAT Credit Utilized", "Add: Interest u/s 234C", "Total Tax", " ",
"Advance Tax", "TDS", "TCS", "SAT",
"Tax on Regular Assessment", "Refund" , "Remarks"
]
columns = [
'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', 'sat',
'tax_on_assessment', 'refund', 'Remarks'
]
data = {
"Particulars": particulars,
"ITR": [safe_get(stage_data['ITR'], col) for col in columns],
"AO": [safe_get(stage_data['AO'], col) for col in columns],
"CIT": [safe_get(stage_data['CIT'], col) for col in columns],
"ITAT": [safe_get(stage_data['ITAT'], col) for col in columns],
}
df = pd.DataFrame(data)
# ===== Excel Export =====
output = io.BytesIO()
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
sheet_name = f"AY {year} - {year + 1}"
df.to_excel(writer, index=False, sheet_name=sheet_name, startrow=2)
workbook = writer.book
worksheet = writer.sheets[sheet_name]
# ===== Company Heading =====
company_heading = workbook.add_format({
'bold': True,
'font_size': 14,
'font_color': 'black',
'align': 'center',
'valign': 'middle'
})
worksheet.merge_range(
0, 0, 0, len(df.columns) - 1,
"Laxmi Civil Engineering Services Pvt Ltd",
company_heading
)
# ===== Header Format =====
header = workbook.add_format({
'bold': True,
'align': 'center',
'valign': 'middle',
'bg_color': '#007bff',
'font_color': 'white',
'border': 1
})
cell = workbook.add_format({
'border': 1,
'align': 'left',
'valign': 'middle'
})
# Write headers
for col_num, col_name in enumerate(df.columns):
worksheet.write(2, col_num, col_name, header)
max_len = max(df[col_name].astype(str).map(len).max(), len(col_name)) + 2
worksheet.set_column(col_num, col_num, max_len)
# Write data rows
for row in range(3, len(df) + 3):
for col in range(len(df.columns)):
worksheet.write(row, col, df.iloc[row - 3, col], cell)
worksheet.freeze_panes(3, 1)
output.seek(0)
return send_file(
output,
download_name=f"AY{year}-{year + 1}_Summary_Report.xlsx",
as_attachment=True,
mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
)
finally:
connection.close()