update itr and ao from and auto save mat ceadit and utility
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort, flash,send_file
|
||||
from flask import (
|
||||
render_template, request, send_file, jsonify
|
||||
)
|
||||
from werkzeug.utils import secure_filename
|
||||
import pandas as pd
|
||||
import os
|
||||
@@ -17,11 +19,40 @@ class DocumentHandler:
|
||||
self.isSuccess = False
|
||||
self.resultMessage = ""
|
||||
|
||||
# VIEW DOCUMENTS
|
||||
# =========================
|
||||
# Utility: Parse Year
|
||||
# =========================
|
||||
def parse_year(self, year_value):
|
||||
"""
|
||||
Accepts:
|
||||
- '2026'
|
||||
- 'AY 2026-2027'
|
||||
Returns:
|
||||
- 2026 (int)
|
||||
"""
|
||||
if not year_value:
|
||||
return None
|
||||
|
||||
year_value = year_value.strip()
|
||||
|
||||
if year_value.isdigit():
|
||||
return int(year_value)
|
||||
|
||||
try:
|
||||
# "AY 2026-2027" → 2026
|
||||
return int(year_value.split()[1].split('-')[0])
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
# =========================
|
||||
# View Documents
|
||||
# =========================
|
||||
def View(self, request):
|
||||
year = request.args.get('year', '')
|
||||
year_raw = request.args.get('year', '')
|
||||
stage = request.args.get('stage', '')
|
||||
|
||||
year = self.parse_year(year_raw)
|
||||
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
|
||||
@@ -30,15 +61,13 @@ class DocumentHandler:
|
||||
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():
|
||||
@@ -49,55 +78,72 @@ class DocumentHandler:
|
||||
|
||||
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']
|
||||
if not connection:
|
||||
return
|
||||
|
||||
for file in files:
|
||||
extension = file.filename.rsplit('.', 1)[1]
|
||||
if extension not in FileHandler.ALLOWED_EXTENSIONS:
|
||||
print("Skip invalid file type : ",extension)
|
||||
continue
|
||||
cursor = connection.cursor()
|
||||
|
||||
filename = secure_filename(file.filename)
|
||||
filepath = os.path.join(FileHandler.UPLOAD_FOLDER, filename)
|
||||
file.save(filepath)
|
||||
files = request.files.getlist('documents')
|
||||
year_raw = request.form.get('year')
|
||||
stage = request.form.get('stage')
|
||||
|
||||
cursor.callproc('InsertDocument', [ filename, filepath, extension, year, stage ])
|
||||
year = self.parse_year(year_raw)
|
||||
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
connection.close()
|
||||
# return redirect(url_for('view_documents'))
|
||||
if not year:
|
||||
self.resultMessage = "Invalid year selected."
|
||||
return
|
||||
|
||||
def Summary_report(self, request):
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
for file in files:
|
||||
if '.' not in file.filename:
|
||||
continue
|
||||
|
||||
year_str = request.args.get('year')
|
||||
extension = file.filename.rsplit('.', 1)[1].lower()
|
||||
|
||||
# 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."
|
||||
if extension not in FileHandler.ALLOWED_EXTENSIONS:
|
||||
print("Skipping invalid file:", 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]
|
||||
)
|
||||
|
||||
# Convert year to int (IMPORTANT FIX)
|
||||
year = int(year_str)
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
# =========================
|
||||
# Summary Preview (JSON)
|
||||
# =========================
|
||||
def Summary_preview(self, request):
|
||||
"""
|
||||
Returns JSON preview of summary report for selected year.
|
||||
"""
|
||||
year_raw = request.args.get("year")
|
||||
year = self.parse_year(year_raw)
|
||||
|
||||
if not year:
|
||||
return jsonify([])
|
||||
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
if not connection:
|
||||
return jsonify([])
|
||||
|
||||
try:
|
||||
stages = {
|
||||
@@ -112,11 +158,111 @@ class DocumentHandler:
|
||||
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()
|
||||
|
||||
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',
|
||||
'edu_cess', 'total_tax_payable',
|
||||
'mat_credit_created',
|
||||
'mat_credit_utilized',
|
||||
'interest_234c', 'total_tax',
|
||||
'-', 'advance_tax', 'tds',
|
||||
'tcs', 'sat',
|
||||
'tax_on_assessment',
|
||||
'refund', 'Remarks'
|
||||
]
|
||||
|
||||
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 @ %", "Total Tax Payable",
|
||||
"Add: MAT Credit Created",
|
||||
"Less: MAT Credit Utilized",
|
||||
"Add: Interest u/s 234C",
|
||||
"Total Tax", " ",
|
||||
"Advance Tax", "TDS", "TCS", "SAT",
|
||||
"Tax on Regular Assessment",
|
||||
"Refund", "Remarks"
|
||||
]
|
||||
|
||||
def safe_get(df, col):
|
||||
return df[col].values[0] if col in df.columns and not df.empty else 0
|
||||
|
||||
preview = []
|
||||
for i, part in enumerate(particulars):
|
||||
preview.append({
|
||||
"Particular": part,
|
||||
"ITR": safe_get(stage_data['ITR'], columns[i]),
|
||||
"AO": safe_get(stage_data['AO'], columns[i]),
|
||||
"CIT": safe_get(stage_data['CIT'], columns[i]),
|
||||
"ITAT": safe_get(stage_data['ITAT'], columns[i]),
|
||||
})
|
||||
|
||||
return jsonify(preview)
|
||||
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
def Summary_report(self, request):
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
|
||||
year_raw = request.args.get('year')
|
||||
|
||||
# Safely parse year to int
|
||||
try:
|
||||
year = int(year_raw)
|
||||
except (TypeError, ValueError):
|
||||
year = None
|
||||
|
||||
if not year:
|
||||
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."
|
||||
)
|
||||
|
||||
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()
|
||||
|
||||
@@ -124,25 +270,45 @@ class DocumentHandler:
|
||||
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 @ %", "Total Tax Payable","Add: MAT Credit Created",
|
||||
"Less: MAT Credit Utilized", "Add: Interest u/s 234C", "Total Tax", " ",
|
||||
"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 @ %", "Total Tax Payable",
|
||||
"Add: MAT Credit Created",
|
||||
"Less: MAT Credit Utilized",
|
||||
"Add: Interest u/s 234C",
|
||||
"Total Tax", " ",
|
||||
"Advance Tax", "TDS", "TCS", "SAT",
|
||||
"Tax on Regular Assessment", "Refund" , "Remarks"
|
||||
"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', 'edu_cess', 'total_tax_payable',
|
||||
'mat_credit_created','mat_credit_utilized' , 'interest_234c','total_tax', '-',
|
||||
'advance_tax', 'tds', 'tcs', 'sat',
|
||||
'tax_on_assessment', 'refund', 'Remarks'
|
||||
'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',
|
||||
'edu_cess', 'total_tax_payable',
|
||||
'mat_credit_created',
|
||||
'mat_credit_utilized',
|
||||
'interest_234c', 'total_tax',
|
||||
'-', 'advance_tax', 'tds',
|
||||
'tcs', 'sat',
|
||||
'tax_on_assessment',
|
||||
'refund', 'Remarks'
|
||||
]
|
||||
|
||||
data = {
|
||||
@@ -155,56 +321,44 @@ class DocumentHandler:
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
|
||||
# ===== Excel Export =====
|
||||
output = io.BytesIO()
|
||||
|
||||
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
|
||||
sheet_name = f"AY {year} - {year + 1}"
|
||||
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({
|
||||
title = workbook.add_format({
|
||||
'bold': True,
|
||||
'font_size': 14,
|
||||
'font_color': 'black',
|
||||
'align': 'center',
|
||||
'valign': 'middle'
|
||||
'align': 'center'
|
||||
})
|
||||
|
||||
worksheet.merge_range(
|
||||
0, 0, 0, len(df.columns) - 1,
|
||||
"Laxmi Civil Engineering Services Pvt Ltd",
|
||||
company_heading
|
||||
title
|
||||
)
|
||||
|
||||
# ===== 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'
|
||||
})
|
||||
cell = workbook.add_format({'border': 1})
|
||||
|
||||
# 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)
|
||||
worksheet.set_column(col_num, col_num, 25)
|
||||
|
||||
# Write data rows
|
||||
for row in range(3, len(df) + 3):
|
||||
for row in range(len(df)):
|
||||
for col in range(len(df.columns)):
|
||||
worksheet.write(row, col, df.iloc[row - 3, col], cell)
|
||||
worksheet.write(row + 3, col, df.iloc[row, col], cell)
|
||||
|
||||
worksheet.freeze_panes(3, 1)
|
||||
|
||||
@@ -219,3 +373,4 @@ class DocumentHandler:
|
||||
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user