Initial commit
This commit is contained in:
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
8
.idea/New folder.iml
generated
Normal file
8
.idea/New folder.iml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
14
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
14
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="ignoredPackages">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="pandas" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
||||||
7
.idea/misc.xml
generated
Normal file
7
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Black">
|
||||||
|
<option name="sdkName" value="Python 3.13 (New folder)" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (New folder)" project-jdk-type="Python SDK" />
|
||||||
|
</project>
|
||||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/New folder.iml" filepath="$PROJECT_DIR$/.idea/New folder.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
BIN
__pycache__/config.cpython-313.pyc
Normal file
BIN
__pycache__/config.cpython-313.pyc
Normal file
Binary file not shown.
7
config.py
Normal file
7
config.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
db_config = {
|
||||||
|
'host': 'localhost',
|
||||||
|
'user': 'root',
|
||||||
|
'password': 'admin',
|
||||||
|
'database': 'income_tax',
|
||||||
|
'port': 3306
|
||||||
|
}
|
||||||
13
js/App.js
Normal file
13
js/App.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import FormPage from './components/FormPage';
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>Income Tax Entry Form</h2>
|
||||||
|
<FormPage table="cit" />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App;
|
||||||
50
js/FormPage.js
Normal file
50
js/FormPage.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
const FormPage = ({ table }) => {
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
gross_total_income: '',
|
||||||
|
net_taxable_income: '',
|
||||||
|
tax_payable: '',
|
||||||
|
total_tax_payable: '',
|
||||||
|
refund: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleChange = e => {
|
||||||
|
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async e => {
|
||||||
|
e.preventDefault();
|
||||||
|
await axios.post(`http://localhost:5000/add/${table}`, formData);
|
||||||
|
alert('Entry saved');
|
||||||
|
setFormData({
|
||||||
|
gross_total_income: '',
|
||||||
|
net_taxable_income: '',
|
||||||
|
tax_payable: '',
|
||||||
|
total_tax_payable: '',
|
||||||
|
refund: ''
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
{Object.keys(formData).map(key => (
|
||||||
|
<div key={key}>
|
||||||
|
<label>{key.replaceAll('_', ' ')}:</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
step="0.01"
|
||||||
|
name={key}
|
||||||
|
value={formData[key]}
|
||||||
|
onChange={handleChange}
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
<button type="submit">Save</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FormPage;
|
||||||
877
main.py
Normal file
877
main.py
Normal file
@@ -0,0 +1,877 @@
|
|||||||
|
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort
|
||||||
|
import os
|
||||||
|
import mysql.connector
|
||||||
|
from werkzeug.utils import secure_filename
|
||||||
|
from config import db_config
|
||||||
|
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
app.config['UPLOAD_FOLDER'] = os.path.join('static', 'uploads')
|
||||||
|
ALLOWED_EXTENSIONS = {'pdf', 'docx', 'doc', 'xlsx', 'xls'}
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def welcome():
|
||||||
|
return render_template('welcome.html')
|
||||||
|
|
||||||
|
@app.route('/dashboard')
|
||||||
|
def index():
|
||||||
|
return render_template('index.html') # Your dashboard page
|
||||||
|
|
||||||
|
# Ensure folder exists
|
||||||
|
os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True)
|
||||||
|
|
||||||
|
|
||||||
|
def allowed_file(filename):
|
||||||
|
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
||||||
|
|
||||||
|
|
||||||
|
# Upload route
|
||||||
|
@app.route('/upload', methods=['GET', 'POST'])
|
||||||
|
def upload_file():
|
||||||
|
if request.method == 'POST':
|
||||||
|
files = request.files.getlist('documents')
|
||||||
|
year = request.form['year']
|
||||||
|
stage = request.form['stage']
|
||||||
|
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
for file in files:
|
||||||
|
if file and allowed_file(file.filename):
|
||||||
|
filename = secure_filename(file.filename)
|
||||||
|
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
||||||
|
file.save(filepath)
|
||||||
|
|
||||||
|
cursor.execute("""
|
||||||
|
INSERT INTO documents (filename, filepath, filetype, year, stage)
|
||||||
|
VALUES (%s, %s, %s, %s, %s)
|
||||||
|
""", (filename, filepath, file.filename.rsplit('.', 1)[1], year, stage))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return redirect(url_for('view_documents'))
|
||||||
|
|
||||||
|
return render_template('upload.html')
|
||||||
|
|
||||||
|
|
||||||
|
# View all documents with filters
|
||||||
|
@app.route('/documents')
|
||||||
|
def view_documents():
|
||||||
|
year = request.args.get('year')
|
||||||
|
stage = request.args.get('stage')
|
||||||
|
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
query = "SELECT * FROM documents WHERE 1=1"
|
||||||
|
params = []
|
||||||
|
|
||||||
|
if year:
|
||||||
|
query += " AND year = %s"
|
||||||
|
params.append(year)
|
||||||
|
if stage:
|
||||||
|
query += " AND stage = %s"
|
||||||
|
params.append(stage)
|
||||||
|
|
||||||
|
cursor.execute(query, params)
|
||||||
|
documents = cursor.fetchall()
|
||||||
|
|
||||||
|
cursor.execute("SELECT DISTINCT year FROM documents ORDER BY year DESC")
|
||||||
|
years = [row['year'] for row in cursor.fetchall()]
|
||||||
|
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
return render_template('view_docs.html', documents=documents, years=years)
|
||||||
|
|
||||||
|
|
||||||
|
# Serve uploaded file
|
||||||
|
from flask import send_file
|
||||||
|
|
||||||
|
@app.route('/uploads/<filename>')
|
||||||
|
def uploaded_file(filename):
|
||||||
|
mode = request.args.get('mode', 'view')
|
||||||
|
filepath = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(filename))
|
||||||
|
|
||||||
|
if not os.path.exists(filepath):
|
||||||
|
abort(404)
|
||||||
|
|
||||||
|
file_ext = filename.rsplit('.', 1)[-1].lower()
|
||||||
|
|
||||||
|
# --- View Mode ---
|
||||||
|
if mode == 'view':
|
||||||
|
if file_ext == 'pdf':
|
||||||
|
return send_file(filepath, mimetype='application/pdf')
|
||||||
|
elif file_ext in ['xls', 'xlsx']:
|
||||||
|
# Excel cannot be rendered in-browser by Flask; trigger download instead
|
||||||
|
return send_file(filepath, as_attachment=False, download_name=filename, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
|
||||||
|
else:
|
||||||
|
return abort(415) # Unsupported type for viewing
|
||||||
|
|
||||||
|
# --- Download Mode ---
|
||||||
|
return send_file(filepath, as_attachment=True)
|
||||||
|
|
||||||
|
|
||||||
|
# (Keep all your other routes and imports as they are)
|
||||||
|
|
||||||
|
## 1. READ/DISPLAY all ITR records
|
||||||
|
# This page will show all records in a table with Edit and Delete buttons.
|
||||||
|
@app.route('/itr_records')
|
||||||
|
def display_itr():
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
cursor.execute("SELECT * FROM itr ORDER BY year DESC, id DESC")
|
||||||
|
records = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return render_template('display_itr.html', records=records)
|
||||||
|
|
||||||
|
|
||||||
|
## 2. CREATE/ADD a new ITR record
|
||||||
|
# This route handles both showing the blank form and saving the new data.
|
||||||
|
@app.route('/itr/add', methods=['GET', 'POST'])
|
||||||
|
def add_itr():
|
||||||
|
if request.method == 'POST':
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# A list of all columns in your form and database table
|
||||||
|
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'
|
||||||
|
]
|
||||||
|
|
||||||
|
query = f"INSERT INTO itr ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})"
|
||||||
|
values = [request.form.get(col, 0) for col in columns]
|
||||||
|
|
||||||
|
cursor.execute(query, tuple(values))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
# After adding, redirect to the page that shows all records
|
||||||
|
return redirect(url_for('display_itr'))
|
||||||
|
|
||||||
|
# If it's a GET request, just show the blank form to add a record
|
||||||
|
return render_template('add_itr.html')
|
||||||
|
|
||||||
|
|
||||||
|
## 3. UPDATE an existing ITR record
|
||||||
|
# This route needs an ID to know which record to edit.
|
||||||
|
@app.route('/itr/update/<int:id>', 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)
|
||||||
|
|
||||||
|
|
||||||
|
## 4. DELETE an ITR record
|
||||||
|
# This route also needs an ID to know which record to delete.
|
||||||
|
@app.route('/itr/delete/<int:id>', methods=['POST'])
|
||||||
|
def delete_itr(id):
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("DELETE FROM itr WHERE id = %s", (id,))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
# After deleting, redirect back to the display page
|
||||||
|
return redirect(url_for('display_itr'))
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/itr', methods=['GET', 'POST'])
|
||||||
|
def itr_form():
|
||||||
|
if request.method == 'POST':
|
||||||
|
data = {key: request.form.get(key, 0) for key in request.form}
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
query = """
|
||||||
|
INSERT INTO itr (
|
||||||
|
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 (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||||
|
"""
|
||||||
|
values = tuple([
|
||||||
|
int(data.get('year', 0))
|
||||||
|
] + [
|
||||||
|
float(data.get(col, 0)) for col in [
|
||||||
|
'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'
|
||||||
|
]
|
||||||
|
])
|
||||||
|
cursor.execute(query, values)
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
return render_template('itr_form.html')
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# ADD THESE NEW FUNCTIONS TO YOUR APP.PY FILE
|
||||||
|
#
|
||||||
|
|
||||||
|
## ===============================================
|
||||||
|
## AO (Assessing Officer) Routes
|
||||||
|
## ===============================================
|
||||||
|
|
||||||
|
# DISPLAY all AO records
|
||||||
|
@app.route('/ao_records')
|
||||||
|
def display_ao():
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
# Note: Querying the 'ao' table
|
||||||
|
cursor.execute("SELECT * FROM ao ORDER BY year DESC, id DESC")
|
||||||
|
records = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
# Note: Rendering the 'display_ao.html' template
|
||||||
|
return render_template('display_ao.html', records=records)
|
||||||
|
|
||||||
|
|
||||||
|
# ADD a new AO record
|
||||||
|
@app.route('/ao/add', methods=['GET', 'POST'])
|
||||||
|
def add_ao():
|
||||||
|
if request.method == 'POST':
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Define the columns for the 'ao' table
|
||||||
|
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'
|
||||||
|
] # Make sure these match your 'ao' table columns!
|
||||||
|
|
||||||
|
# Note: Inserting into the 'ao' table
|
||||||
|
query = f"INSERT INTO ao ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})"
|
||||||
|
values = [request.form.get(col, 0) for col in columns]
|
||||||
|
|
||||||
|
cursor.execute(query, tuple(values))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
# Note: Redirecting to the 'display_ao' function
|
||||||
|
return redirect(url_for('display_ao'))
|
||||||
|
|
||||||
|
# Note: Rendering the 'add_ao.html' template
|
||||||
|
return render_template('add_ao.html')
|
||||||
|
|
||||||
|
|
||||||
|
# (You will also need to add update_ao and delete_ao functions later)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/ao', methods=['GET', 'POST'])
|
||||||
|
def ao_form():
|
||||||
|
if request.method == 'POST':
|
||||||
|
data = {key: request.form.get(key, 0) for key in request.form}
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
query = """
|
||||||
|
INSERT INTO ao (
|
||||||
|
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 (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||||
|
"""
|
||||||
|
|
||||||
|
values = tuple([
|
||||||
|
data.get('year'),
|
||||||
|
float(data.get('gross_total_income', 0)),
|
||||||
|
float(data.get('disallowance_14a', 0)),
|
||||||
|
float(data.get('disallowance_37', 0)),
|
||||||
|
float(data.get('deduction_80ia_business', 0)),
|
||||||
|
float(data.get('deduction_sec37_disallowance', 0)),
|
||||||
|
float(data.get('deduction_80g', 0)),
|
||||||
|
float(data.get('net_taxable_income', 0)),
|
||||||
|
float(data.get('tax_30_percent', 0)),
|
||||||
|
float(data.get('tax_book_profit_18_5', 0)),
|
||||||
|
float(data.get('surcharge_12', 0)),
|
||||||
|
float(data.get('edu_cess_3', 0)),
|
||||||
|
float(data.get('total_tax_payable', 0)),
|
||||||
|
float(data.get('mat_credit', 0)),
|
||||||
|
float(data.get('interest_234c', 0)),
|
||||||
|
float(data.get('total_tax', 0)),
|
||||||
|
float(data.get('advance_tax', 0)),
|
||||||
|
float(data.get('tds', 0)),
|
||||||
|
float(data.get('tcs', 0)),
|
||||||
|
float(data.get('tax_on_assessment', 0)),
|
||||||
|
float(data.get('refund', 0)),
|
||||||
|
])
|
||||||
|
|
||||||
|
cursor.execute(query, values)
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
return render_template('ao_form.html')
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# ADD THESE NEW CIT FUNCTIONS TO YOUR APP.PY FILE
|
||||||
|
#
|
||||||
|
|
||||||
|
## =======================================================
|
||||||
|
## CIT (Commissioner of Income Tax) Routes
|
||||||
|
## =======================================================
|
||||||
|
|
||||||
|
# DISPLAY all CIT records
|
||||||
|
@app.route('/cit_records')
|
||||||
|
def display_cit():
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
# Querying the 'cit' table
|
||||||
|
cursor.execute("SELECT * FROM cit ORDER BY year DESC, id DESC")
|
||||||
|
records = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
# Rendering the 'display_cit.html' template
|
||||||
|
return render_template('display_cit.html', records=records)
|
||||||
|
|
||||||
|
|
||||||
|
# ADD a new CIT record
|
||||||
|
@app.route('/cit/add', methods=['GET', 'POST'])
|
||||||
|
def add_cit():
|
||||||
|
if request.method == 'POST':
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# IMPORTANT: These columns match your 'cit' table structure
|
||||||
|
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'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Inserting into the 'cit' table
|
||||||
|
query = f"INSERT INTO cit ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})"
|
||||||
|
values = [request.form.get(col, 0) for col in columns]
|
||||||
|
|
||||||
|
cursor.execute(query, tuple(values))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
# Redirecting to the 'display_cit' function
|
||||||
|
return redirect(url_for('display_cit'))
|
||||||
|
|
||||||
|
# Rendering the 'add_cit.html' template
|
||||||
|
return render_template('add_cit.html')
|
||||||
|
|
||||||
|
|
||||||
|
# (You will also need to add update_cit and delete_cit functions later)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# ADD THESE FINAL FUNCTIONS FOR ITAT TO YOUR APP.PY FILE
|
||||||
|
#
|
||||||
|
|
||||||
|
## =======================================================
|
||||||
|
## ITAT (Income Tax Appellate Tribunal) Routes
|
||||||
|
## =======================================================
|
||||||
|
|
||||||
|
# DISPLAY all ITAT records
|
||||||
|
@app.route('/itat_records')
|
||||||
|
def display_itat():
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
# Querying the 'itat' table
|
||||||
|
cursor.execute("SELECT * FROM itat ORDER BY year DESC, id DESC")
|
||||||
|
records = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
# Rendering the 'display_itat.html' template
|
||||||
|
return render_template('display_itat.html', records=records)
|
||||||
|
|
||||||
|
|
||||||
|
# ADD a new ITAT record
|
||||||
|
@app.route('/itat/add', methods=['GET', 'POST'])
|
||||||
|
def add_itat():
|
||||||
|
if request.method == 'POST':
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# NOTE: These are the specific columns for your 'itat' table
|
||||||
|
columns = [
|
||||||
|
'year', 'mat_tax_credit', 'surcharge', 'cess', 'total_credit'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Inserting into the 'itat' table
|
||||||
|
query = f"INSERT INTO itat ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})"
|
||||||
|
values = [request.form.get(col, 0) for col in columns]
|
||||||
|
|
||||||
|
cursor.execute(query, tuple(values))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
# Redirecting to the 'display_itat' function
|
||||||
|
return redirect(url_for('display_itat'))
|
||||||
|
|
||||||
|
# Rendering the 'add_itat.html' template
|
||||||
|
return render_template('add_itat.html')
|
||||||
|
|
||||||
|
|
||||||
|
# (You will also need to add update_itat and delete_itat functions later)
|
||||||
|
|
||||||
|
@app.route('/cit', methods=['GET', 'POST'])
|
||||||
|
def cit_form():
|
||||||
|
if request.method == 'POST':
|
||||||
|
data = {key: request.form.get(key, 0) for key in request.form}
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
query = """
|
||||||
|
INSERT INTO cit (
|
||||||
|
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
|
||||||
|
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
|
||||||
|
"""
|
||||||
|
|
||||||
|
values = (
|
||||||
|
data.get('year'), # Include 'year' as the first value
|
||||||
|
float(data.get('gross_total_income', 0)),
|
||||||
|
float(data.get('deduction_80ia_business', 0)),
|
||||||
|
float(data.get('deduction_sec37_disallowance', 0)),
|
||||||
|
float(data.get('deduction_80g', 0)),
|
||||||
|
float(data.get('net_taxable_income', 0)),
|
||||||
|
float(data.get('tax_30_percent', 0)),
|
||||||
|
float(data.get('tax_book_profit_18_5', 0)),
|
||||||
|
float(data.get('tax_payable', 0)),
|
||||||
|
float(data.get('surcharge_12', 0)),
|
||||||
|
float(data.get('edu_cess_3', 0)),
|
||||||
|
float(data.get('total_tax_payable', 0)),
|
||||||
|
float(data.get('mat_credit', 0)),
|
||||||
|
float(data.get('interest_234c', 0)),
|
||||||
|
float(data.get('total_tax', 0)),
|
||||||
|
float(data.get('advance_tax', 0)),
|
||||||
|
float(data.get('tds', 0)),
|
||||||
|
float(data.get('tcs', 0)),
|
||||||
|
float(data.get('tax_on_assessment', 0)),
|
||||||
|
float(data.get('refund', 0))
|
||||||
|
)
|
||||||
|
|
||||||
|
cursor.execute(query, values)
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
|
||||||
|
return render_template('cit_form.html')
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/itat', methods=['GET', 'POST'])
|
||||||
|
def itat_form():
|
||||||
|
if request.method == 'POST':
|
||||||
|
mat_tax_credit = request.form['mat_tax_credit']
|
||||||
|
surcharge = request.form['surcharge']
|
||||||
|
cess = request.form['cess']
|
||||||
|
total_credit = request.form['total_credit']
|
||||||
|
year=request.form['year']
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("""
|
||||||
|
INSERT INTO itat (year, mat_tax_credit, surcharge, cess, total_credit)
|
||||||
|
VALUES (%s,%s, %s, %s, %s)
|
||||||
|
""", (year,mat_tax_credit, surcharge, cess, total_credit))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return redirect(url_for('index'))
|
||||||
|
return render_template('itat_form.html')
|
||||||
|
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/itr_report', methods=['GET'])
|
||||||
|
def itr_report():
|
||||||
|
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('/ao_report', methods=['GET'])
|
||||||
|
def ao_report():
|
||||||
|
selected_year = request.args.get('year')
|
||||||
|
connection = pymysql.connect(**db_config)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if selected_year:
|
||||||
|
query = "SELECT * FROM ao WHERE year = %s"
|
||||||
|
df = pd.read_sql(query, connection, params=[selected_year])
|
||||||
|
|
||||||
|
if df.empty:
|
||||||
|
return "No records found for the selected year."
|
||||||
|
|
||||||
|
# Transpose the DataFrame: rows → fields, columns → records
|
||||||
|
df_transposed = df.transpose()
|
||||||
|
df_transposed.insert(0, 'Field', df_transposed.index)
|
||||||
|
|
||||||
|
# Rename columns to "Record 1", "Record 2", ...
|
||||||
|
for i in range(1, df_transposed.shape[1]):
|
||||||
|
df_transposed.rename(columns={df_transposed.columns[i]: f"Record {i}"}, 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='AO_Vertical')
|
||||||
|
|
||||||
|
# Optional: Adjust formatting
|
||||||
|
workbook = writer.book
|
||||||
|
worksheet = writer.sheets['AO_Vertical']
|
||||||
|
worksheet.set_column(0, 0, 30) # Widen 'Field' column
|
||||||
|
|
||||||
|
output.seek(0)
|
||||||
|
return send_file(
|
||||||
|
output,
|
||||||
|
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
as_attachment=True,
|
||||||
|
download_name=f"AO_Report_{selected_year}.xlsx"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute("SELECT DISTINCT year FROM ao ORDER BY year DESC")
|
||||||
|
years = [row[0] for row in cursor.fetchall()]
|
||||||
|
return render_template("ao_reports.html", years=years)
|
||||||
|
finally:
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/cit_report', methods=['GET'])
|
||||||
|
def cit_report():
|
||||||
|
selected_year = request.args.get('year')
|
||||||
|
connection = pymysql.connect(**db_config)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if selected_year:
|
||||||
|
# Fetch data from the `cit` table for the selected year
|
||||||
|
query = "SELECT * FROM cit WHERE year = %s"
|
||||||
|
df = pd.read_sql(query, connection, params=[selected_year])
|
||||||
|
|
||||||
|
output = io.BytesIO()
|
||||||
|
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
|
||||||
|
workbook = writer.book
|
||||||
|
|
||||||
|
# Write each row vertically on a separate sheet or below one another
|
||||||
|
for i, (_, row) in enumerate(df.iterrows(), start=1):
|
||||||
|
# Convert the row to vertical format
|
||||||
|
vertical_df = pd.DataFrame(row).reset_index()
|
||||||
|
vertical_df.columns = ['Field', 'Value']
|
||||||
|
|
||||||
|
# Write each vertical entry below the previous (e.g., block by block)
|
||||||
|
start_row = (i - 1) * (len(vertical_df) + 3) # 3-row gap between entries
|
||||||
|
vertical_df.to_excel(writer, sheet_name='CIT_Report', index=False, startrow=start_row)
|
||||||
|
|
||||||
|
output.seek(0)
|
||||||
|
|
||||||
|
return send_file(
|
||||||
|
output,
|
||||||
|
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
as_attachment=True,
|
||||||
|
download_name=f"CIT_Report_{selected_year}_Vertical.xlsx"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# Render dropdown for year selection
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute("SELECT DISTINCT year FROM cit ORDER BY year DESC")
|
||||||
|
years = [row[0] for row in cursor.fetchall()]
|
||||||
|
return render_template("cit_reports.html", years=years)
|
||||||
|
finally:
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
@app.route('/itat_report', methods=['GET'])
|
||||||
|
def itat_report():
|
||||||
|
selected_year = request.args.get('year')
|
||||||
|
connection = pymysql.connect(**db_config)
|
||||||
|
|
||||||
|
try:
|
||||||
|
if selected_year:
|
||||||
|
query = "SELECT * FROM itat WHERE year = %s"
|
||||||
|
df = pd.read_sql(query, connection, params=[selected_year])
|
||||||
|
|
||||||
|
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 send_file(
|
||||||
|
output,
|
||||||
|
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
as_attachment=True,
|
||||||
|
download_name=f"ITAT_Report_{selected_year}_Vertical.xlsx"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
with connection.cursor() as cursor:
|
||||||
|
cursor.execute("SELECT DISTINCT year FROM itat ORDER BY year DESC")
|
||||||
|
years = [row[0] for row in cursor.fetchall()]
|
||||||
|
return render_template("itat_reports.html", years=years)
|
||||||
|
finally:
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@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])
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/download/<int:doc_id>')
|
||||||
|
def download_report(doc_id):
|
||||||
|
conn = get_db_connection()
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
cursor.execute("SELECT * FROM documents WHERE id = %s", (doc_id,))
|
||||||
|
document = cursor.fetchone()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if not document:
|
||||||
|
return "Document not found", 404
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
if not year:
|
||||||
|
connection = pymysql.connect(**db_config)
|
||||||
|
try:
|
||||||
|
years = set()
|
||||||
|
for table in ['itr', 'ao', 'cit', 'itat']:
|
||||||
|
df = pd.read_sql(f"SELECT DISTINCT year FROM {table}", connection)
|
||||||
|
years.update(int(y) for y in df['year'].dropna().tolist())
|
||||||
|
return render_template('summary_reports.html', years=sorted(years), message="Please select a year to download.")
|
||||||
|
finally:
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
connection = pymysql.connect(**db_config)
|
||||||
|
try:
|
||||||
|
stages = ['itr', 'ao', 'cit', 'itat']
|
||||||
|
stage_data = {}
|
||||||
|
|
||||||
|
for stage in stages:
|
||||||
|
query = f"SELECT * FROM {stage} WHERE year = %s"
|
||||||
|
df = pd.read_sql(query, connection, params=[year])
|
||||||
|
stage_data[stage.upper()] = df
|
||||||
|
|
||||||
|
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", "Less: Deduction u/s 80G", "Net Taxable Income", "Tax @ 30%",
|
||||||
|
"Tax @ 18.5% on Book Profit", "Surcharge @ 12%", "Education Cess @ 3%", "Total Tax Payable",
|
||||||
|
"Less: MAT Credit", "Net Tax", "Add: Interest u/s 234C", "Total Tax",
|
||||||
|
"Advance Tax", "TDS", "TCS", "SAT", "Tax on Regular Assessment", "Refund"
|
||||||
|
]
|
||||||
|
|
||||||
|
columns = [
|
||||||
|
'gross_total_income', 'disallowance_14a', 'disallowance_37', 'gti',
|
||||||
|
'deduction_80ia', 'deduction_80g', 'net_taxable_income', 'tax_30',
|
||||||
|
'book_profit_tax', 'surcharge_12', 'education_cess', 'total_tax',
|
||||||
|
'mat_credit', 'net_tax', 'interest_234c', 'total_tax_payable',
|
||||||
|
'advance_tax', 'tds', 'tcs', 'sat', 'tax_regular', 'refund'
|
||||||
|
]
|
||||||
|
|
||||||
|
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(A)": [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)
|
||||||
|
|
||||||
|
# Export to Excel with formatting
|
||||||
|
output = io.BytesIO()
|
||||||
|
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
|
||||||
|
df.to_excel(writer, index=False, sheet_name=f'AY {year}')
|
||||||
|
workbook = writer.book
|
||||||
|
worksheet = writer.sheets[f'AY {year}']
|
||||||
|
|
||||||
|
# Format definitions
|
||||||
|
header_format = workbook.add_format({
|
||||||
|
'bold': True,
|
||||||
|
'text_wrap': True,
|
||||||
|
'valign': 'middle',
|
||||||
|
'align': 'center',
|
||||||
|
'bg_color': '#007bff',
|
||||||
|
'font_color': 'white',
|
||||||
|
'border': 1
|
||||||
|
})
|
||||||
|
|
||||||
|
cell_format = workbook.add_format({
|
||||||
|
'border': 1,
|
||||||
|
'valign': 'top',
|
||||||
|
'align': 'center',
|
||||||
|
})
|
||||||
|
|
||||||
|
# Apply formats
|
||||||
|
for col_num, value in enumerate(df.columns):
|
||||||
|
worksheet.write(0, col_num, value, header_format)
|
||||||
|
# Auto column width
|
||||||
|
max_len = max(df[value].astype(str).map(len).max(), len(str(value))) + 2
|
||||||
|
worksheet.set_column(col_num, col_num, max_len)
|
||||||
|
|
||||||
|
# Format data rows
|
||||||
|
for row_num in range(1, len(df) + 1):
|
||||||
|
for col_num in range(len(df.columns)):
|
||||||
|
worksheet.write(row_num, col_num, df.iloc[row_num - 1, col_num], cell_format)
|
||||||
|
|
||||||
|
output.seek(0)
|
||||||
|
|
||||||
|
return send_file(
|
||||||
|
output,
|
||||||
|
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||||
|
as_attachment=True,
|
||||||
|
download_name=f"Summary_Report_{year}.xlsx"
|
||||||
|
)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.run(host='0.0.0.0', port=5003, debug=True)
|
||||||
|
|
||||||
54
static/index.css
Normal file
54
static/index.css
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f2f6fc;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 40px auto;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form label {
|
||||||
|
display: block;
|
||||||
|
margin-top: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
form input[type="number"] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px 10px;
|
||||||
|
margin-top: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form button {
|
||||||
|
margin-top: 25px;
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
padding: 12px 20px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 100%;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
form button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
0
static/logo.png
Normal file
0
static/logo.png
Normal file
BIN
static/uploads/Contractor_Report_194.xlsx
Normal file
BIN
static/uploads/Contractor_Report_194.xlsx
Normal file
Binary file not shown.
BIN
static/uploads/Feedback_Report_Form.pdf
Normal file
BIN
static/uploads/Feedback_Report_Form.pdf
Normal file
Binary file not shown.
BIN
static/uploads/Rakesh_Kumar1.xlsx
Normal file
BIN
static/uploads/Rakesh_Kumar1.xlsx
Normal file
Binary file not shown.
19
templates/add_itr.html
Normal file
19
templates/add_itr.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="container">
|
||||||
|
<h2>Add New Income Tax Return Record</h2>
|
||||||
|
<form method="POST" action="{{ url_for('add_itr') }}">
|
||||||
|
<label>Year:</label>
|
||||||
|
<input type="number" name="year" required>
|
||||||
|
{% for field in [
|
||||||
|
"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"
|
||||||
|
] %}
|
||||||
|
<label>{{ field.replace("_", " ").title() }}:</label>
|
||||||
|
<input type="number" name="{{ field }}" step="any" value="0.00" required>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
127
templates/ao_form.html
Normal file
127
templates/ao_form.html
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>AO Form Entry</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
/* Reset and base styles */
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #333;
|
||||||
|
padding: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 90%;
|
||||||
|
max-width: 700px;
|
||||||
|
margin: auto;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-size: 28px;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"]:focus {
|
||||||
|
border-color: #007BFF;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
margin-top: 30px;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #007BFF;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: white;
|
||||||
|
font-size: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"]:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>AO Form Entry</h2>
|
||||||
|
<form method="POST" onsubmit="return showSuccessMessage()">
|
||||||
|
<label>Year:</label>
|
||||||
|
<input type="number" name="year" required>
|
||||||
|
{% for field in [
|
||||||
|
"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"
|
||||||
|
] %}
|
||||||
|
<label for="{{ field }}">{{ field.replace("_", " ").title() }}:</label>
|
||||||
|
<input type="number" name="{{ field }}" step="0.01" required>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- JavaScript Alert -->
|
||||||
|
<script>
|
||||||
|
function showSuccessMessage() {
|
||||||
|
alert("Form submitted successfully!");
|
||||||
|
return true; // allow form to submit after showing alert
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
74
templates/ao_reports.html
Normal file
74
templates/ao_reports.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Download AO Reports</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f4f7f9;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 60px auto;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Download AO Report</h2>
|
||||||
|
<form method="GET" action="{{ url_for('ao_report') }}" target="_blank">
|
||||||
|
|
||||||
|
<label for="year">Select Year:</label>
|
||||||
|
<br>
|
||||||
|
<select name="year" id="year" required>
|
||||||
|
<option value="">-- Select Year --</option>
|
||||||
|
{% for y in years %}
|
||||||
|
<option value="{{ y }}">{{ y }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<br><br>
|
||||||
|
<button type="submit">Download Excel</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
123
templates/cit_form.html
Normal file
123
templates/cit_form.html
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CIT Form Entry</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
/* ...existing styles... (no changes needed) */
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #333;
|
||||||
|
padding: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 90%;
|
||||||
|
max-width: 700px;
|
||||||
|
margin: auto;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-size: 28px;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"]:focus {
|
||||||
|
border-color: #007BFF;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
margin-top: 30px;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #007BFF;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: white;
|
||||||
|
font-size: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"]:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>CIT Form Entry</h2>
|
||||||
|
<form method="POST" onsubmit="return showSuccessMessage()">
|
||||||
|
<label>Year:</label>
|
||||||
|
<input type="number" name="year" required>
|
||||||
|
|
||||||
|
{% for field in [
|
||||||
|
"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"
|
||||||
|
] %}
|
||||||
|
<label for="{{ field }}">{{ field.replace("_", " ").title() }}:</label>
|
||||||
|
<input type="number" name="{{ field }}" step="0.01" required>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function showSuccessMessage() {
|
||||||
|
alert("Form submitted successfully!");
|
||||||
|
return true; // continue with form submission
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
74
templates/cit_reports.html
Normal file
74
templates/cit_reports.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Download CIT Reports</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f4f7f9;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 60px auto;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Download CIT Report</h2>
|
||||||
|
<form method="GET" action="{{ url_for('cit_report') }}" target="_blank">
|
||||||
|
|
||||||
|
<label for="year">Select Year:</label>
|
||||||
|
<br>
|
||||||
|
<select name="year" id="year" required>
|
||||||
|
<option value="">-- Select Year --</option>
|
||||||
|
{% for y in years %}
|
||||||
|
<option value="{{ y }}">{{ y }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<br><br>
|
||||||
|
<button type="submit">Download Excel</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
66
templates/display_itr.html
Normal file
66
templates/display_itr.html
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>ITR Records</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background-color: #f8f9fa; padding: 20px; color: #333; }
|
||||||
|
.container { max-width: 95%; margin: auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
|
||||||
|
h2 { text-align: center; margin-bottom: 20px; }
|
||||||
|
.btn { padding: 8px 15px; border-radius: 5px; text-decoration: none; color: white; border: none; cursor: pointer; font-size: 14px; }
|
||||||
|
.btn-add { background-color: #28a745; display: inline-block; margin-bottom: 20px; }
|
||||||
|
.btn-update { background-color: #007bff; }
|
||||||
|
.btn-delete { background-color: #dc3545; }
|
||||||
|
.action-cell form { display: inline-block; margin-left: 5px; }
|
||||||
|
.table-wrapper { overflow-x: auto; }
|
||||||
|
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
|
||||||
|
th, td { padding: 12px; border: 1px solid #dee2e6; text-align: right; white-space: nowrap; }
|
||||||
|
th { background-color: #343a40; color: white; text-align: center; }
|
||||||
|
tr:nth-child(even) { background-color: #f2f2f2; }
|
||||||
|
td:first-child, th:first-child { text-align: left; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Income Tax Return Records 🧾</h2>
|
||||||
|
<a href="{{ url_for('add_itr') }}" class="btn btn-add">➕ Add New Record</a>
|
||||||
|
|
||||||
|
{% if records %}
|
||||||
|
<div class="table-wrapper">
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Year</th>
|
||||||
|
<th>Gross Total Income</th>
|
||||||
|
<th>Net Taxable Income</th>
|
||||||
|
<th>Total Tax Payable</th>
|
||||||
|
<th>Refund</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for record in records %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ record.year }}</td>
|
||||||
|
<td>{{ "{:,.2f}".format(record.gross_total_income) }}</td>
|
||||||
|
<td>{{ "{:,.2f}".format(record.net_taxable_income) }}</td>
|
||||||
|
<td>{{ "{:,.2f}".format(record.total_tax_payable) }}</td>
|
||||||
|
<td>{{ "{:,.2f}".format(record.refund) }}</td>
|
||||||
|
<td class="action-cell">
|
||||||
|
<a href="{{ url_for('update_itr', id=record.id) }}" class="btn btn-update">Edit</a>
|
||||||
|
|
||||||
|
<form action="{{ url_for('delete_itr', id=record.id) }}" method="post" onsubmit="return confirm('Are you sure you want to delete this record?');">
|
||||||
|
<button type="submit" class="btn btn-delete">Delete</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<p style="text-align: center; margin-top: 20px;">No records found. Click the button above to add one!</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
129
templates/index.html
Normal file
129
templates/index.html
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Dashboard | Income Tax Utilities</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f4f7f6;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 750px;
|
||||||
|
margin: 50px auto;
|
||||||
|
padding: 40px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
font-size: 32px;
|
||||||
|
color: #2c3e50;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.section {
|
||||||
|
margin-bottom: 35px;
|
||||||
|
}
|
||||||
|
.section h3 {
|
||||||
|
font-size: 22px;
|
||||||
|
color: #0056b3;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
border-bottom: 2px solid #e9ecef;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
margin: 15px 0;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
padding: 14px 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 17px;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 123, 255, 0.1);
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
transform: translateY(-2px) scale(1.01);
|
||||||
|
box-shadow: 0 6px 12px rgba(0, 91, 179, 0.2);
|
||||||
|
}
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.container {
|
||||||
|
margin: 20px;
|
||||||
|
padding: 25px;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
font-size: 26px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2 class="header">Dashboard 🏛️</h2>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h3>ITR (Income Tax Return)</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{ url_for('add_itr') }}">➕ Add New ITR Record</a></li>
|
||||||
|
<li><a href="{{ url_for('display_itr') }}">🧾 View & Manage ITR Records</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h3>AO (Assessing Officer)</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{ url_for('add_ao') }}">➕ Add New AO Record</a></li>
|
||||||
|
<li><a href="{{ url_for('display_ao') }}">🧾 View & Manage AO Records</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h3>CIT (Commissioner of Income Tax)</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{ url_for('add_cit') }}">➕ Add New CIT Record</a></li>
|
||||||
|
<li><a href="{{ url_for('display_cit') }}">🧾 View & Manage CIT Records</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h3>ITAT (Income Tax Appellate Tribunal)</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="{{ url_for('add_itat') }}">➕ Add New ITAT Record</a></li>
|
||||||
|
<li><a href="{{ url_for('display_itat') }}">🧾 View & Manage ITAT Records</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h3>Documents & Reports 📂</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="/upload">→ Upload Documents</a></li>
|
||||||
|
<li><a href="/documents">→ View Documents</a></li>
|
||||||
|
<li><a href="/reports">→ Generate Reports</a></li>
|
||||||
|
<li><a href="/summary_report">→ Generate Summary Reports</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
126
templates/itat_form.html
Normal file
126
templates/itat_form.html
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>ITAT Form Entry</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
/* Same styling for layout */
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #333;
|
||||||
|
padding: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 90%;
|
||||||
|
max-width: 700px;
|
||||||
|
margin: auto;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-size: 28px;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"]:focus {
|
||||||
|
border-color: #007BFF;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
margin-top: 30px;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #007BFF;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: white;
|
||||||
|
font-size: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"]:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>ITAT Form Entry</h2>
|
||||||
|
<form method="POST" onsubmit="return showSuccessMessage()">
|
||||||
|
<label>Year:</label>
|
||||||
|
<input type="number" name="year" step="0.01" required>
|
||||||
|
|
||||||
|
<label>MAT Tax Credit:</label>
|
||||||
|
<input type="number" name="mat_tax_credit" step="0.01" required>
|
||||||
|
|
||||||
|
<label>Surcharge:</label>
|
||||||
|
<input type="number" name="surcharge" step="0.01" required>
|
||||||
|
|
||||||
|
<label>Cess:</label>
|
||||||
|
<input type="number" name="cess" step="0.01" required>
|
||||||
|
|
||||||
|
<label>Total Credit:</label>
|
||||||
|
<input type="number" name="total_credit" step="0.01" required>
|
||||||
|
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function showSuccessMessage() {
|
||||||
|
alert("Form submitted successfully!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
74
templates/itat_reports.html
Normal file
74
templates/itat_reports.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Download ITAT Reports</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f4f7f9;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 60px auto;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Download ITAT Report</h2>
|
||||||
|
<form method="GET" action="{{ url_for('itat_report') }}" target="_blank">
|
||||||
|
|
||||||
|
<label for="year">Select Year:</label>
|
||||||
|
<br>
|
||||||
|
<select name="year" id="year" required>
|
||||||
|
<option value="">-- Select Year --</option>
|
||||||
|
{% for y in years %}
|
||||||
|
<option value="{{ y }}">{{ y }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<br><br>
|
||||||
|
<button type="submit">Download Excel</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
251
templates/itr_form.html
Normal file
251
templates/itr_form.html
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
|
||||||
|
<title>ITR Form Entry</title>
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
|
||||||
|
/* Existing CSS here... */
|
||||||
|
|
||||||
|
* {
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
body {
|
||||||
|
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
|
||||||
|
color: #333;
|
||||||
|
|
||||||
|
padding: 30px 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.container {
|
||||||
|
|
||||||
|
width: 90%;
|
||||||
|
|
||||||
|
max-width: 700px;
|
||||||
|
|
||||||
|
margin: auto;
|
||||||
|
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
padding: 40px;
|
||||||
|
|
||||||
|
border-radius: 12px;
|
||||||
|
|
||||||
|
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
font-size: 28px;
|
||||||
|
|
||||||
|
color: #2c3e50;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
form {
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
label {
|
||||||
|
|
||||||
|
margin-top: 15px;
|
||||||
|
|
||||||
|
margin-bottom: 6px;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
|
||||||
|
padding: 10px 12px;
|
||||||
|
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
input[type="number"]:focus {
|
||||||
|
|
||||||
|
border-color: #007BFF;
|
||||||
|
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
|
||||||
|
margin-top: 30px;
|
||||||
|
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
background-color: #007BFF;
|
||||||
|
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
font-size: 18px;
|
||||||
|
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
button[type="submit"]:hover {
|
||||||
|
|
||||||
|
background-color: #0056b3;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
|
||||||
|
.container {
|
||||||
|
|
||||||
|
padding: 20px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
|
||||||
|
font-size: 22px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<h2>Income Tax Return Form</h2>
|
||||||
|
|
||||||
|
<form method="POST" onsubmit="showSuccessMessage()">
|
||||||
|
|
||||||
|
<label>Year:</label>
|
||||||
|
|
||||||
|
<input type="number" name="year" required>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
{% for field in [
|
||||||
|
|
||||||
|
"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"
|
||||||
|
|
||||||
|
] %}
|
||||||
|
|
||||||
|
<label>{{ field.replace("_", " ").title() }}:</label>
|
||||||
|
|
||||||
|
<input type="number" name="{{ field }}" step="0.01" required>
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<button type="submit">Submit</button>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- JavaScript to show popup -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function showSuccessMessage() {
|
||||||
|
|
||||||
|
alert("Form submitted successfully!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
74
templates/itr_reports.html
Normal file
74
templates/itr_reports.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Download ITR Reports</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f4f7f9;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 60px auto;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Download ITR Report</h2>
|
||||||
|
<form method="GET" action="{{ url_for('itr_report') }}" target="_blank">
|
||||||
|
|
||||||
|
<label for="year">Select Year:</label>
|
||||||
|
<br>
|
||||||
|
<select name="year" id="year" required>
|
||||||
|
<option value="">-- Select Year --</option>
|
||||||
|
{% for y in years %}
|
||||||
|
<option value="{{ y }}">{{ y }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<br><br>
|
||||||
|
<button type="submit">Download Excel</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
130
templates/reports.html
Normal file
130
templates/reports.html
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Reports Of Stages</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f4f7f9;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 900px;
|
||||||
|
margin: 40px auto;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 6px 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 6px 14px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
padding: 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even) td {
|
||||||
|
background-color: #eef3f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: center;
|
||||||
|
color: #777;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin-top: 30px;
|
||||||
|
list-style: none;
|
||||||
|
padding-left: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li a {
|
||||||
|
color: #007bff;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul li a:hover {
|
||||||
|
text-decorat
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Reports</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li><a href="/itr_report" >→ View ITR Reports</a></li>
|
||||||
|
<li><a href="/ao_report" >→ View AO Reports</a></li>
|
||||||
|
<li><a href="/cit_report" >→ View CIT Reports</a></li>
|
||||||
|
<li><a href="/itat_report" >→ View ITAT Reports</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
146
templates/stage_reports.html
Normal file
146
templates/stage_reports.html
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{ stage }} Reports</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f0f2f5;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 40px auto;
|
||||||
|
padding: 30px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 8px 14px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
outline: none;
|
||||||
|
transition: border 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
select:focus {
|
||||||
|
border-color: #007bff;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 12px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even) td {
|
||||||
|
background-color: #f9fbfc;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:hover td {
|
||||||
|
background-color: #eef5ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-download {
|
||||||
|
background-color: #28a745;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 7px 14px;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-download:hover {
|
||||||
|
background-color: #218838;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-data {
|
||||||
|
text-align: center;
|
||||||
|
color: #777;
|
||||||
|
font-size: 16px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>{{ stage }} Reports</h2>
|
||||||
|
|
||||||
|
<form method="GET">
|
||||||
|
<input type="hidden" name="stage" value="{{ stage }}">
|
||||||
|
<label for="year">Select Year:</label>
|
||||||
|
<select name="year" id="year" onchange="this.form.submit()">
|
||||||
|
<option value="">-- All Years --</option>
|
||||||
|
{% for y in years %}
|
||||||
|
<option value="{{ y }}" {% if y == request.args.get('year') %}selected{% endif %}>{{ y }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% if documents %}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Year</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for doc in documents %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ doc.year }}</td>
|
||||||
|
<td>
|
||||||
|
<a class="btn-download" href="{{ url_for('download_report', doc_id=doc.id) }}">Download</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% else %}
|
||||||
|
<p class="no-data">No reports found for this selection.</p>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
83
templates/summary_reports.html
Normal file
83
templates/summary_reports.html
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Download Summary Report</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
background-color: white;
|
||||||
|
padding: 30px 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px 16px;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
color: red;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Download Year-wise Summary Report</h2>
|
||||||
|
|
||||||
|
{% if message %}
|
||||||
|
<p class="message">{{ message }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form method="GET" action="{{ url_for('summary_report') }}">
|
||||||
|
<label for="year">Select Year:</label>
|
||||||
|
<select name="year" id="year" required>
|
||||||
|
<option value="">-- Select Year --</option>
|
||||||
|
{% for year in years %}
|
||||||
|
<option value="{{ year }}">{{ year }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<button type="submit">Download Summary Report</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
21
templates/update_itr.html
Normal file
21
templates/update_itr.html
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Update ITR Record</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style> /* ... your form styles ... */ </style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Update ITR Record for Year {{ record.year }}</h2>
|
||||||
|
<form method="POST" action="{{ url_for('update_itr', id=record.id) }}">
|
||||||
|
{% for field in record.keys() if field != 'id' %}
|
||||||
|
<label>{{ field.replace("_", " ").title() }}:</label>
|
||||||
|
<input type="number" name="{{ field }}" step="any" value="{{ record[field] }}" required>
|
||||||
|
{% endfor %}
|
||||||
|
<button type="submit">Update Record</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
123
templates/upload.html
Normal file
123
templates/upload.html
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Upload Documents</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
/* Reset and base styles */
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
color: #333;
|
||||||
|
padding: 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 90%;
|
||||||
|
max-width: 700px;
|
||||||
|
margin: auto;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
font-size: 28px;
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"],
|
||||||
|
select,
|
||||||
|
input[type="file"] {
|
||||||
|
padding: 10px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 16px;
|
||||||
|
transition: border-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="number"]:focus,
|
||||||
|
select:focus,
|
||||||
|
input[type="file"]:focus {
|
||||||
|
border-color: #007BFF;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
margin-top: 30px;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #007BFF;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
color: white;
|
||||||
|
font-size: 18px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"]:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input, select {
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button[type="submit"] {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Upload Income Tax Documents</h2>
|
||||||
|
<form method="POST" enctype="multipart/form-data">
|
||||||
|
<label for="year">Year:</label>
|
||||||
|
<input type="number" name="year" required>
|
||||||
|
|
||||||
|
<label for="stage">Stage:</label>
|
||||||
|
<select name="stage" required>
|
||||||
|
<option value="ITR">ITR</option>
|
||||||
|
<option value="AO">AO</option>
|
||||||
|
<option value="CIT">CIT</option>
|
||||||
|
<option value="ITAT">ITAT</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="documents">Select Documents:</label>
|
||||||
|
<input type="file" name="documents" multiple required>
|
||||||
|
|
||||||
|
<button type="submit">Upload</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
164
templates/view_docs.html
Normal file
164
templates/view_docs.html
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>View Documents</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
background-color: #f4f7f9;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 40px auto;
|
||||||
|
background: #fff;
|
||||||
|
padding: 30px 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
text-align: center;
|
||||||
|
color: #2c3e50;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #34495e;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 14px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #3498db;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #2980b9;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
background-color: #2c3e50;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 12px 15px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:nth-child(even) {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody tr:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #2980b9;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
form {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Document Records</h2>
|
||||||
|
|
||||||
|
<form method="GET">
|
||||||
|
<label for="year">Filter by Year:</label>
|
||||||
|
<select name="year">
|
||||||
|
<option value="">All</option>
|
||||||
|
{% for y in years %}
|
||||||
|
<option value="{{ y }}">{{ y }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="stage">Filter by Stage:</label>
|
||||||
|
<select name="stage">
|
||||||
|
<option value="">All</option>
|
||||||
|
<option value="ITR">ITR</option>
|
||||||
|
<option value="AO">AO</option>
|
||||||
|
<option value="CIT">CIT</option>
|
||||||
|
<option value="ITAT">ITAT</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button type="submit">Apply</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>File</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Stage</th>
|
||||||
|
<th>Year</th>
|
||||||
|
<th>Uploaded At</th>
|
||||||
|
<th>Download</th>
|
||||||
|
<th>View</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for doc in documents %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ doc.filename }}</td>
|
||||||
|
<td>{{ doc.filetype }}</td>
|
||||||
|
<td>{{ doc.stage }}</td>
|
||||||
|
<td>{{ doc.year }}</td>
|
||||||
|
<td>{{ doc.uploaded_at }}</td>
|
||||||
|
<td><a href="{{ url_for('uploaded_file', filename=doc.filename) }}?mode=download">Download</a></td>
|
||||||
|
<td><a href="{{ url_for('uploaded_file', filename=doc.filename) }}?mode=view" target="_blank">View</a></td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
55
templates/welcome.html
Normal file
55
templates/welcome.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<!-- templates/welcome.html -->
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Welcome - Laxmi Civil Engineering Pvt. Ltd</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #e8f0fe;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
padding: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
color: #333;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 18px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enter-btn {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
padding: 12px 25px;
|
||||||
|
font-size: 18px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enter-btn:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<img src="https://tse1.mm.bing.net/th/id/OIP.fc5NZer25Y3YeS3Fd0PO9gAAAA?pid=Api&rs=1&c=1&qlt=95&w=92&h=92" class="logo" alt="Company Logo">
|
||||||
|
<h1>Welcome to Laxmi Civil Engineering Pvt. Ltd</h1>
|
||||||
|
<p>Income Tax Filing and Compliance</p>
|
||||||
|
<a href="{{ url_for('index') }}" class="enter-btn">Go To Dashboard</a>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user