Compare commits
25 Commits
40fc148287
...
pankaj-dev
| Author | SHA1 | Date | |
|---|---|---|---|
| 2058cfed95 | |||
| e5c349bbf4 | |||
| 4d26ee4f0f | |||
| 6e4efad834 | |||
| 64fc455f5c | |||
| 33e27f73b5 | |||
| eb12d4cd2e | |||
|
|
32b6ab9b10 | ||
|
|
b8d540263b | ||
| 9b1b8732ef | |||
| ded8d1f3b2 | |||
| 1819c49433 | |||
| aaab008a9d | |||
| a9af2cde8a | |||
| a0f4568ba2 | |||
|
|
a8e47af61c | ||
| 438f84e284 | |||
| a7eec85b8f | |||
| 4592113f76 | |||
| 1a21732174 | |||
| 30a7a4287e | |||
| 50f0e77f77 | |||
| 539561c8d8 | |||
| 2a9a29d4cd | |||
| 7bdcee0656 |
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.git
|
||||
.idea
|
||||
venv
|
||||
26
.env
Normal file
26
.env
Normal file
@@ -0,0 +1,26 @@
|
||||
# -----------------------------
|
||||
# Flask App Configuration
|
||||
# -----------------------------
|
||||
FLASK_ENV=development
|
||||
FLASK_DEBUG=true
|
||||
FLASK_HOST=0.0.0.0
|
||||
FLASK_PORT=5010
|
||||
|
||||
# -----------------------------
|
||||
# Security
|
||||
# -----------------------------
|
||||
SECRET_KEY=secret1234
|
||||
|
||||
# -----------------------------
|
||||
# Database Configuration
|
||||
# -----------------------------
|
||||
DB_DIALECT=mysql
|
||||
# DB_DRIVER=pymysql
|
||||
DB_HOST=127.0.0.1
|
||||
# DB_HOST=db # this is production for use docker
|
||||
DB_NAME=income_tax_db
|
||||
DB_PORT=3306
|
||||
# DB_NAME=test_income_taxdb
|
||||
DB_USER=root
|
||||
DB_PASSWORD=root
|
||||
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@@ -3,6 +3,7 @@
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
__pycache__
|
||||
|
||||
# Ingnor upload files
|
||||
static/uploads/
|
||||
@@ -15,3 +16,13 @@ logs/
|
||||
|
||||
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
|
||||
# Python cache
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# OS / Editor
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
@@ -3,9 +3,6 @@ import mysql.connector
|
||||
import pandas as pd
|
||||
import io
|
||||
|
||||
|
||||
|
||||
|
||||
class AOHandler:
|
||||
|
||||
def __init__(self):
|
||||
@@ -35,38 +32,39 @@ class AOHandler:
|
||||
|
||||
# Add AO record
|
||||
def add_ao(self, data):
|
||||
fields = [
|
||||
"year","gross_total_income", "disallowance_14a", "disallowance_37",
|
||||
"deduction_80ia_business", "deduction_sec37_disallowance", "deduction_80g",
|
||||
"net_taxable_income", "tax_30_percent", "tax_book_profit_18_5",
|
||||
"surcharge_12", "edu_cess_3", "total_tax_payable", "mat_credit",
|
||||
"interest_234c", "total_tax", "advance_tax", "tds", "tcs","sat",
|
||||
"tax_on_assessment", "refund","Remarks"
|
||||
]
|
||||
|
||||
|
||||
try:
|
||||
fields= [ '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', 'per_tax_a', 'tax_a_cal', 'per_surcharge_a', 'surcharge_a_cal', 'per_cess_a', 'edu_cess_a_cal', 'sum_of_a',
|
||||
'per_tax_b', 'tax_b_cal', 'per_surcharge_b', 'surcharge_b_cal', 'per_cess_b', 'edu_cess_b_cal', 'sum_of_b',
|
||||
'tax_payable','total_tax_payable', 'opening_balance', 'mat_credit_created', 'mat_credit_utilized', 'closing_balance',
|
||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'sat', 'tax_on_assessment', 'refund',
|
||||
'interest_244a_per143', 'refund_received', 'balance_receivable', 'remarks', 'created_at'
|
||||
]
|
||||
values = [data.get(f, 0) for f in fields]
|
||||
print("---- values ---- ",values)
|
||||
|
||||
self.cursor.callproc("InsertAO", values)
|
||||
self.cursor.callproc("InsertAO", values)
|
||||
self.conn.commit()
|
||||
except Exception as e:
|
||||
self.conn.rollback()
|
||||
raise e
|
||||
finally:
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
|
||||
|
||||
# UPDATE AO RECORD by AO id
|
||||
def update_ao(self, id, data):
|
||||
|
||||
fields = [
|
||||
"year","gross_total_income", "disallowance_14a", "disallowance_37",
|
||||
"deduction_80ia_business", "deduction_sec37_disallowance", "deduction_80g",
|
||||
"net_taxable_income", "tax_30_percent", "tax_book_profit_18_5",
|
||||
"surcharge_12", "edu_cess_3", "total_tax_payable", "mat_credit",
|
||||
"interest_234c", "total_tax", "advance_tax", "tds", "tcs","sat",
|
||||
"tax_on_assessment", "refund","Remarks"
|
||||
]
|
||||
fields= [ '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', 'per_tax_a', 'tax_a_cal', 'per_surcharge_a', 'surcharge_a_cal', 'per_cess_a', 'edu_cess_a_cal', 'sum_of_a',
|
||||
'per_tax_b', 'tax_b_cal', 'per_surcharge_b', 'surcharge_b_cal', 'per_cess_b', 'edu_cess_b_cal', 'sum_of_b',
|
||||
'tax_payable','total_tax_payable', 'opening_balance', 'mat_credit_created', 'mat_credit_utilized', 'closing_balance',
|
||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'sat', 'tax_on_assessment', 'refund',
|
||||
'interest_244a_per143', 'refund_received', 'balance_receivable', 'remarks', 'updated_at'
|
||||
]
|
||||
|
||||
values = [id] + [data.get(f, 0) for f in fields]
|
||||
|
||||
print("AO update values:", values)
|
||||
|
||||
self.cursor.callproc("UpdateAOById", values)
|
||||
self.conn.commit()
|
||||
|
||||
@@ -76,49 +74,144 @@ class AOHandler:
|
||||
self.cursor.callproc('DeleteAOById', [id])
|
||||
self.conn.commit()
|
||||
|
||||
# report download by year
|
||||
def ao_report_download(self, selected_year):
|
||||
try:
|
||||
# AY calculation (2020 -> AY 2020-2021)
|
||||
ay_start = int(selected_year)
|
||||
ay_end = ay_start + 1
|
||||
assessment_year = f"AY {ay_start}-{ay_end}"
|
||||
|
||||
# Fetch AO records
|
||||
self.cursor.callproc("GetAOByYear", [selected_year])
|
||||
|
||||
rows = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
|
||||
if not rows:
|
||||
return None
|
||||
|
||||
# Remove id column if exists
|
||||
for row in rows:
|
||||
row.pop("id", None)
|
||||
|
||||
# Mapping DB fields → readable Excel labels
|
||||
field_mapping = {
|
||||
"gross_total_income": "Gross Total Income",
|
||||
"disallowance_14a": "Add: Disallowance u/s 14A",
|
||||
"disallowance_37": "Add: Disallowance u/s 37",
|
||||
"-" : "-",
|
||||
"deduction_80ia_business": "Less: Deduction u/s 80IA - On Business Income",
|
||||
"deduction_80ia_misc": "On Misc Receipts",
|
||||
"deduction_80ia_other": "On Other",
|
||||
"deduction_sec37_disallowance": "On Sec 37 Disallowance",
|
||||
"deduction_80g": "Less: Deduction u/s 80G",
|
||||
"net_taxable_income": "Net Taxable Income",
|
||||
"-" : "-",
|
||||
"per_tax_a" : "Per% Tax @(A)",
|
||||
"tax_a_cal" : "Tax cal(A)",
|
||||
"per_surcharge_a" : "Per% surcharge @(A)",
|
||||
"surcharge_a_cal" : "Surcharge cal (A)",
|
||||
"per_cess_a" : "Per% cess(A)",
|
||||
"edu_cess_a_cal" : "Edu cess cal(A)",
|
||||
"sum_of_a" : "Sum of tax_cal(A)",
|
||||
"-" : "-",
|
||||
"per_tax_b" : "Per% Tax @(B)",
|
||||
"tax_b_cal" : "Tax cal(B)",
|
||||
"per_surcharge_b" : "Per% surcharge @(B)",
|
||||
"surcharge_b_cal" : "Surcharge cal (B)",
|
||||
"per_cess_b" : "Per% cess(B)",
|
||||
"edu_cess_b_cal" : "Edu cess cal(B)",
|
||||
"sum_of_b" : "Sum of tax_cal(B)",
|
||||
"tax_payable": "Tax Payable",
|
||||
"total_tax_payable": "Total Tax Payable",
|
||||
"opening_balance": "Opening Balance",
|
||||
"mat_credit_created": "Add: MAT Credit Created",
|
||||
"mat_credit_utilized": "Less: MAT Credit Utilized",
|
||||
"closing_balance": "Closing Balance",
|
||||
"interest_234c": "Add: Interest u/s 234C",
|
||||
"total_tax": "Total Tax",
|
||||
"advance_tax": "Advance Tax",
|
||||
"tds": "TDS",
|
||||
"tcs": "TCS",
|
||||
"sat": "SAT",
|
||||
"tax_on_assessment": "Tax on Regular Assessment",
|
||||
"refund" : "Refund",
|
||||
"interest_244a_per143" : "Add : Interest u/s 244A as per 143",
|
||||
"refund_received" : "Less : Refund Received on",
|
||||
"balance_receivable" : "Balance Receivable",
|
||||
"Remarks" : "Remarks"
|
||||
}
|
||||
|
||||
# Vertical AO structure
|
||||
data = []
|
||||
for key, label in field_mapping.items():
|
||||
value = rows[0].get(key, 0)
|
||||
data.append([label, value])
|
||||
|
||||
df = pd.DataFrame(data, columns=["Particulars", "AO"])
|
||||
|
||||
# Excel output
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
|
||||
workbook = writer.book
|
||||
worksheet = workbook.add_worksheet("AO Report")
|
||||
writer.sheets["AO Report"] = worksheet
|
||||
|
||||
# Formats
|
||||
title_fmt = workbook.add_format({
|
||||
"bold": True,
|
||||
"align": "center",
|
||||
"font_size": 14
|
||||
})
|
||||
header_fmt = workbook.add_format({
|
||||
"bold": True,
|
||||
"border": 1,
|
||||
"align": "center"
|
||||
})
|
||||
text_fmt = workbook.add_format({"border": 1})
|
||||
num_fmt = workbook.add_format({
|
||||
"border": 1,
|
||||
"num_format": "#,##0.00"
|
||||
})
|
||||
|
||||
# Company Name
|
||||
worksheet.merge_range(
|
||||
"A1:B1",
|
||||
"Laxmi Civil Engineering Services Pvt Ltd",
|
||||
title_fmt
|
||||
)
|
||||
|
||||
# Assessment Year
|
||||
worksheet.merge_range(
|
||||
"A2:B2",
|
||||
f"Assessment Year : {assessment_year}",
|
||||
workbook.add_format({"bold": True, "align": "center"})
|
||||
)
|
||||
|
||||
# Header
|
||||
worksheet.write_row("A4", ["Particulars", "AO"], header_fmt)
|
||||
|
||||
# Data rows
|
||||
row_no = 4
|
||||
for _, row in df.iterrows():
|
||||
worksheet.write(row_no, 0, row["Particulars"], text_fmt)
|
||||
worksheet.write(row_no, 1, row["AO"], num_fmt)
|
||||
row_no += 1
|
||||
|
||||
# Column width
|
||||
worksheet.set_column("A:A", 45)
|
||||
worksheet.set_column("B:B", 20)
|
||||
|
||||
output.seek(0)
|
||||
return output
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error →", e)
|
||||
return None
|
||||
|
||||
# CLOSE CONNECTION
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
|
||||
# report download by year
|
||||
def ao_report_download(self, selected_year):
|
||||
try:
|
||||
# Call stored proc to fetch year-wise records
|
||||
self.cursor.callproc("GetAOByYear", [selected_year])
|
||||
|
||||
rows = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
|
||||
if not rows:
|
||||
return None
|
||||
|
||||
df = pd.DataFrame(rows)
|
||||
|
||||
# TRANSPOSE
|
||||
df_transposed = df.transpose()
|
||||
df_transposed.insert(0, 'Field', df_transposed.index)
|
||||
|
||||
# Rename columns: Record 1, 2, 3...
|
||||
record_cols = {
|
||||
i: f"Record {i}"
|
||||
for i in df_transposed.columns if isinstance(i, int)
|
||||
}
|
||||
df_transposed.rename(columns=record_cols, inplace=True)
|
||||
df_transposed.reset_index(drop=True, inplace=True)
|
||||
|
||||
# Excel Output
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
|
||||
df_transposed.to_excel(writer, index=False, sheet_name="AO_Vertical")
|
||||
worksheet = writer.sheets["AO_Vertical"]
|
||||
worksheet.set_column(0, 0, 30)
|
||||
|
||||
output.seek(0)
|
||||
return output
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error:", e)
|
||||
return None
|
||||
self.conn.close()
|
||||
@@ -3,8 +3,6 @@ import mysql.connector
|
||||
import pandas as pd
|
||||
import io
|
||||
|
||||
|
||||
|
||||
class CITHandler:
|
||||
|
||||
def __init__(self):
|
||||
@@ -37,85 +35,179 @@ class CITHandler:
|
||||
|
||||
# INSERT CIT RECORD
|
||||
def add_cit(self, data):
|
||||
columns = [
|
||||
'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37',
|
||||
'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other',
|
||||
'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income',
|
||||
'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12',
|
||||
'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c',
|
||||
'total_tax', 'advance_tax', 'tds', 'tcs','sat', 'tax_on_assessment', 'refund', 'Remarks'
|
||||
]
|
||||
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', 'per_tax_a', 'tax_a_cal', 'per_surcharge_a', 'surcharge_a_cal', 'per_cess_a', 'edu_cess_a_cal', 'sum_of_a',
|
||||
'per_tax_b', 'tax_b_cal', 'per_surcharge_b', 'surcharge_b_cal', 'per_cess_b', 'edu_cess_b_cal', 'sum_of_b',
|
||||
'tax_payable','total_tax_payable', 'opening_balance', 'mat_credit_created', 'mat_credit_utilized', 'closing_balance',
|
||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'sat', 'tax_on_assessment', 'refund',
|
||||
'interest_244a_per143', 'refund_received', 'balance_receivable', 'remarks', 'created_at'
|
||||
]
|
||||
|
||||
values = [data.get(col, 0) for col in columns]
|
||||
|
||||
self.cursor.callproc("InsertCIT", values)
|
||||
self.conn.commit()
|
||||
|
||||
|
||||
|
||||
# UPDATE CIT RECORD
|
||||
def update_cit(self, id, data):
|
||||
columns = [
|
||||
'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37',
|
||||
'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other',
|
||||
'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income',
|
||||
'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12',
|
||||
'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c',
|
||||
'total_tax', 'advance_tax', 'tds', 'tcs','sat', 'tax_on_assessment', 'refund', 'Remarks'
|
||||
]
|
||||
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', 'per_tax_a', 'tax_a_cal', 'per_surcharge_a', 'surcharge_a_cal', 'per_cess_a', 'edu_cess_a_cal', 'sum_of_a',
|
||||
'per_tax_b', 'tax_b_cal', 'per_surcharge_b', 'surcharge_b_cal', 'per_cess_b', 'edu_cess_b_cal', 'sum_of_b',
|
||||
'tax_payable','total_tax_payable', 'opening_balance', 'mat_credit_created', 'mat_credit_utilized', 'closing_balance',
|
||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'sat', 'tax_on_assessment', 'refund',
|
||||
'interest_244a_per143', 'refund_received', 'balance_receivable', 'remarks', 'updated_at'
|
||||
]
|
||||
|
||||
values = [id] + [data.get(col, 0) for col in columns]
|
||||
|
||||
self.cursor.callproc("UpdateCITById", values)
|
||||
self.conn.commit()
|
||||
|
||||
|
||||
|
||||
# DELETE CIT RECORD
|
||||
def delete_cit(self, id):
|
||||
self.cursor.callproc("DeleteCITById", [id])
|
||||
self.conn.commit()
|
||||
#
|
||||
def cit_report_download(self, selected_year):
|
||||
try:
|
||||
# AY calculation (2020 -> AY 2020-2021)
|
||||
ay_start = int(selected_year)
|
||||
ay_end = ay_start + 1
|
||||
assessment_year = f"AY {ay_start}-{ay_end}"
|
||||
|
||||
# CLOSE CONNECTION
|
||||
# Fetch CIT records
|
||||
self.cursor.callproc("GetCITByYear", [selected_year])
|
||||
|
||||
rows = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
|
||||
if not rows:
|
||||
return None
|
||||
|
||||
# Remove id column if exists
|
||||
for row in rows:
|
||||
row.pop("id", None)
|
||||
|
||||
# Mapping DB fields → readable Excel labels
|
||||
field_mapping = {
|
||||
"gross_total_income": "Gross Total Income",
|
||||
"disallowance_14a": "Add: Disallowance u/s 14A",
|
||||
"disallowance_37": "Add: Disallowance u/s 37",
|
||||
"-" : "-",
|
||||
"deduction_80ia_business": "Less: Deduction u/s 80IA - On Business Income",
|
||||
"deduction_80ia_misc": "On Misc Receipts",
|
||||
"deduction_80ia_other": "On Other",
|
||||
"deduction_sec37_disallowance": "On Sec 37 Disallowance",
|
||||
"deduction_80g": "Less: Deduction u/s 80G",
|
||||
"net_taxable_income": "Net Taxable Income",
|
||||
"-" : "-",
|
||||
"per_tax_a" : "Per% Tax @(A)",
|
||||
"tax_a_cal" : "Tax cal(A)",
|
||||
"per_surcharge_a" : "Per% surcharge @(A)",
|
||||
"surcharge_a_cal" : "Surcharge cal (A)",
|
||||
"per_cess_a" : "Per% cess(A)",
|
||||
"edu_cess_a_cal" : "Edu cess cal(A)",
|
||||
"sum_of_a" : "Sum of tax_cal(A)",
|
||||
"-" : "-",
|
||||
"per_tax_b" : "Per% Tax @(B)",
|
||||
"tax_b_cal" : "Tax cal(B)",
|
||||
"per_surcharge_b" : "Per% surcharge @(B)",
|
||||
"surcharge_b_cal" : "Surcharge cal (B)",
|
||||
"per_cess_b" : "Per% cess(B)",
|
||||
"edu_cess_b_cal" : "Edu cess cal(B)",
|
||||
"sum_of_b" : "Sum of tax_cal(B)",
|
||||
"tax_payable": "Tax Payable",
|
||||
"total_tax_payable": "Total Tax Payable",
|
||||
"opening_balance": "Opening Balance",
|
||||
"mat_credit_created": "Add: MAT Credit Created",
|
||||
"mat_credit_utilized": "Less: MAT Credit Utilized",
|
||||
"closing_balance": "Closing Balance",
|
||||
"interest_234c": "Add: Interest u/s 234C",
|
||||
"total_tax": "Total Tax",
|
||||
"advance_tax": "Advance Tax",
|
||||
"tds": "TDS",
|
||||
"tcs": "TCS",
|
||||
"sat": "SAT",
|
||||
"tax_on_assessment": "Tax on Regular Assessment",
|
||||
"refund" : "Refund",
|
||||
"interest_244a_per143" : "Add : Interest u/s 244A as per 143",
|
||||
"refund_received" : "Less : Refund Received on",
|
||||
"balance_receivable" : "Balance Receivable",
|
||||
"Remarks" : "Remarks"
|
||||
}
|
||||
|
||||
# Vertical CIT structure (single record per year)
|
||||
data = []
|
||||
for key, label in field_mapping.items():
|
||||
value = rows[0].get(key, 0)
|
||||
data.append([label, value])
|
||||
|
||||
df = pd.DataFrame(data, columns=["Particulars", "CIT"])
|
||||
|
||||
# Excel output
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
|
||||
workbook = writer.book
|
||||
worksheet = workbook.add_worksheet("CIT Report")
|
||||
writer.sheets["CIT Report"] = worksheet
|
||||
|
||||
# Formats
|
||||
title_fmt = workbook.add_format({
|
||||
"bold": True,
|
||||
"align": "center",
|
||||
"font_size": 14
|
||||
})
|
||||
header_fmt = workbook.add_format({
|
||||
"bold": True,
|
||||
"border": 1,
|
||||
"align": "center"
|
||||
})
|
||||
text_fmt = workbook.add_format({"border": 1})
|
||||
num_fmt = workbook.add_format({
|
||||
"border": 1,
|
||||
"num_format": "#,##0.00"
|
||||
})
|
||||
|
||||
# Company Name
|
||||
worksheet.merge_range(
|
||||
"A1:B1",
|
||||
"Laxmi Civil Engineering Services Pvt Ltd",
|
||||
title_fmt
|
||||
)
|
||||
|
||||
# Assessment Year
|
||||
worksheet.merge_range(
|
||||
"A2:B2",
|
||||
f"Assessment Year : {assessment_year}",
|
||||
workbook.add_format({"bold": True, "align": "center"})
|
||||
)
|
||||
|
||||
# Header
|
||||
worksheet.write_row("A4", ["Particulars", "CIT"], header_fmt)
|
||||
|
||||
# Data rows
|
||||
row_no = 4
|
||||
for _, row in df.iterrows():
|
||||
worksheet.write(row_no, 0, row["Particulars"], text_fmt)
|
||||
worksheet.write(row_no, 1, row["CIT"], num_fmt)
|
||||
row_no += 1
|
||||
|
||||
# Column widths
|
||||
worksheet.set_column("A:A", 45)
|
||||
worksheet.set_column("B:B", 20)
|
||||
|
||||
output.seek(0)
|
||||
return output
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error →", e)
|
||||
return None
|
||||
|
||||
|
||||
# CLOSE CONNECTION
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
|
||||
|
||||
def cit_report_download(self, selected_year):
|
||||
try:
|
||||
# Call stored procedure
|
||||
self.cursor.callproc("GetCITByYear", [selected_year])
|
||||
|
||||
rows = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
|
||||
if not rows:
|
||||
return None
|
||||
|
||||
df = pd.DataFrame(rows)
|
||||
|
||||
# Excel output
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
|
||||
|
||||
for i, (_, row) in enumerate(df.iterrows(), start=1):
|
||||
# Convert row to vertical format
|
||||
vertical_df = pd.DataFrame(row).reset_index()
|
||||
vertical_df.columns = ['Field', 'Value']
|
||||
|
||||
start_row = (i - 1) * (len(vertical_df) + 3) # gap between blocks
|
||||
vertical_df.to_excel(
|
||||
writer,
|
||||
sheet_name='CIT_Report',
|
||||
index=False,
|
||||
startrow=start_row
|
||||
)
|
||||
|
||||
output.seek(0)
|
||||
return output
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error:", e)
|
||||
return None
|
||||
self.conn.close()
|
||||
@@ -1,21 +1,43 @@
|
||||
# import mysql.connector
|
||||
# import os
|
||||
|
||||
# # Database Config
|
||||
# class DBConfig:
|
||||
# MYSQL_HOST = os.getenv("DB_HOST")
|
||||
# MYSQL_USER = os.getenv("DB_USER")
|
||||
# MYSQL_PASSWORD = os.getenv("DB_PASSWORD")
|
||||
# MYSQL_DB = os.getenv("DB_NAME")
|
||||
|
||||
# @staticmethod
|
||||
# def get_db_connection():
|
||||
# """
|
||||
# Returns a MySQL connection object.
|
||||
# """
|
||||
# return mysql.connector.connect(
|
||||
# host=DBConfig.MYSQL_HOST,
|
||||
# user=DBConfig.MYSQL_USER,
|
||||
# password=DBConfig.MYSQL_PASSWORD,
|
||||
# database=DBConfig.MYSQL_DB
|
||||
# )
|
||||
|
||||
|
||||
import mysql.connector
|
||||
import os
|
||||
|
||||
# Database Config
|
||||
class DBConfig:
|
||||
MYSQL_HOST = os.getenv("MYSQL_HOST", "127.0.0.1")
|
||||
MYSQL_USER = os.getenv("MYSQL_USER", "root")
|
||||
MYSQL_PASSWORD = os.getenv("MYSQL_PASSWORD", "root")
|
||||
MYSQL_DB = os.getenv("MYSQL_DB", "test_income_taxdb")
|
||||
|
||||
class DBConfig:
|
||||
@staticmethod
|
||||
def get_db_connection():
|
||||
"""
|
||||
Returns a MySQL connection object.
|
||||
Create and return a MySQL database connection
|
||||
using environment variables.
|
||||
"""
|
||||
|
||||
return mysql.connector.connect(
|
||||
host=DBConfig.MYSQL_HOST,
|
||||
user=DBConfig.MYSQL_USER,
|
||||
password=DBConfig.MYSQL_PASSWORD,
|
||||
database=DBConfig.MYSQL_DB
|
||||
host=os.getenv("DB_HOST", "db"), # Docker service name
|
||||
port=int(os.getenv("DB_PORT", 3306)),
|
||||
user=os.getenv("DB_USER", "root"),
|
||||
password=os.getenv("DB_PASSWORD", "root"),
|
||||
database=os.getenv("DB_NAME", "test_income_taxdb"),
|
||||
autocommit=False
|
||||
)
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
from flask import (
|
||||
render_template, request, send_file, jsonify
|
||||
)
|
||||
from werkzeug.utils import secure_filename
|
||||
import pandas as pd
|
||||
import os
|
||||
import io
|
||||
|
||||
from AppCode.Config import DBConfig
|
||||
from AppCode.FileHandler import FileHandler
|
||||
from werkzeug.utils import secure_filename
|
||||
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort, flash,send_file
|
||||
import mysql.connector
|
||||
import pandas as pd
|
||||
import io
|
||||
from AppCode.YearGet import YearGet
|
||||
|
||||
|
||||
@@ -17,11 +19,33 @@ class DocumentHandler:
|
||||
self.isSuccess = False
|
||||
self.resultMessage = ""
|
||||
|
||||
# VIEW DOCUMENTS
|
||||
# =========================
|
||||
# Utility: Parse Year
|
||||
# =========================
|
||||
def parse_year(self, year_value):
|
||||
if not year_value:
|
||||
return None
|
||||
|
||||
year_value = year_value.strip()
|
||||
|
||||
if year_value.isdigit():
|
||||
return int(year_value)
|
||||
|
||||
try:
|
||||
# "AY 2026-2027" → 2026
|
||||
return int(year_value.split()[1].split('-')[0])
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
# =========================
|
||||
# View Documents
|
||||
# =========================
|
||||
def View(self, request):
|
||||
year = request.args.get('year', '')
|
||||
year_raw = request.args.get('year', '')
|
||||
stage = request.args.get('stage', '')
|
||||
|
||||
year = self.parse_year(year_raw)
|
||||
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
|
||||
@@ -30,15 +54,13 @@ class DocumentHandler:
|
||||
return
|
||||
|
||||
cursor = connection.cursor(dictionary=True)
|
||||
# --- FILTER QUERY ---
|
||||
|
||||
cursor.callproc("GetDocuments", [year, stage])
|
||||
|
||||
# fetch first result set
|
||||
for result in cursor.stored_results():
|
||||
self.documents = result.fetchall()
|
||||
break
|
||||
|
||||
# ---- GET YEARS FROM STORED PROCEDURE ----
|
||||
cursor.callproc("GetYear")
|
||||
|
||||
for result in cursor.stored_results():
|
||||
@@ -49,55 +71,72 @@ class DocumentHandler:
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
self.isSuccess = True
|
||||
|
||||
# =========================
|
||||
# Upload Documents
|
||||
# =========================
|
||||
def Upload(self, request):
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
|
||||
if connection:
|
||||
cursor = connection.cursor()
|
||||
files = request.files.getlist('documents')
|
||||
year = request.form['year']
|
||||
stage = request.form['stage']
|
||||
if not connection:
|
||||
return
|
||||
|
||||
for file in files:
|
||||
extension = file.filename.rsplit('.', 1)[1]
|
||||
if extension not in FileHandler.ALLOWED_EXTENSIONS:
|
||||
print("Skip invalid file type : ",extension)
|
||||
continue
|
||||
cursor = connection.cursor()
|
||||
|
||||
filename = secure_filename(file.filename)
|
||||
filepath = os.path.join(FileHandler.UPLOAD_FOLDER, filename)
|
||||
file.save(filepath)
|
||||
files = request.files.getlist('documents')
|
||||
year_raw = request.form.get('year')
|
||||
stage = request.form.get('stage')
|
||||
|
||||
cursor.callproc('InsertDocument', [ filename, filepath, extension, year, stage ])
|
||||
year = self.parse_year(year_raw)
|
||||
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
connection.close()
|
||||
# return redirect(url_for('view_documents'))
|
||||
if not year:
|
||||
self.resultMessage = "Invalid year selected."
|
||||
return
|
||||
|
||||
def Summary_report(self, request):
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
for file in files:
|
||||
if '.' not in file.filename:
|
||||
continue
|
||||
|
||||
year_str = request.args.get('year')
|
||||
extension = file.filename.rsplit('.', 1)[1].lower()
|
||||
|
||||
# If year not selected
|
||||
if not year_str or not year_str.isdigit():
|
||||
yearGetter = YearGet()
|
||||
allYears = yearGetter.get_year_by_model("AllYearsInAllModel")
|
||||
yearGetter.close()
|
||||
return render_template(
|
||||
'summary_reports.html',
|
||||
years=allYears,
|
||||
message="Please select a valid year to download."
|
||||
if extension not in FileHandler.ALLOWED_EXTENSIONS:
|
||||
print("Skipping invalid file:", extension)
|
||||
continue
|
||||
|
||||
filename = secure_filename(file.filename)
|
||||
filepath = os.path.join(FileHandler.UPLOAD_FOLDER, filename)
|
||||
|
||||
file.save(filepath)
|
||||
|
||||
cursor.callproc(
|
||||
'InsertDocument',
|
||||
[filename, filepath, extension, year, stage]
|
||||
)
|
||||
|
||||
# Convert year to int (IMPORTANT FIX)
|
||||
year = int(year_str)
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
# =========================
|
||||
# Summary Preview (JSON)
|
||||
# =========================
|
||||
def Summary_preview(self, request):
|
||||
"""
|
||||
Returns JSON preview of summary report for selected year.
|
||||
"""
|
||||
year_raw = request.args.get("year")
|
||||
year = self.parse_year(year_raw)
|
||||
|
||||
if not year:
|
||||
return jsonify([])
|
||||
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
if not connection:
|
||||
return jsonify([])
|
||||
|
||||
try:
|
||||
stages = {
|
||||
@@ -112,11 +151,151 @@ class DocumentHandler:
|
||||
for stage_name, table_name in stages.items():
|
||||
cursor = connection.cursor(dictionary=True)
|
||||
cursor.callproc("sp_get_stage_data", [table_name, year])
|
||||
|
||||
rows = []
|
||||
for result in cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
stage_data[stage_name] = pd.DataFrame(rows) if rows else pd.DataFrame()
|
||||
cursor.close()
|
||||
|
||||
columns = [
|
||||
'gross_total_income', 'disallowance_14a',
|
||||
'disallowance_37',
|
||||
'gross_total_income'+'disallowance_14a'+'disallowance_37',
|
||||
'deduction_80ia_business',
|
||||
'deduction_80ia_misc',
|
||||
'deduction_80ia_other',
|
||||
'deduction_sec37_disallowance',
|
||||
'deduction_80g', '-',
|
||||
'net_taxable_income',
|
||||
'-',
|
||||
'per_tax_a',
|
||||
'tax_a_cal',
|
||||
'per_surcharge_a',
|
||||
'surcharge_a_cal',
|
||||
'per_cess_a',
|
||||
'edu_cess_a_cal',
|
||||
'sum_of_a',
|
||||
'-',
|
||||
'per_tax_b',
|
||||
'tax_b_cal',
|
||||
'per_surcharge_b',
|
||||
'surcharge_b_cal',
|
||||
'per_cess_b',
|
||||
'edu_cess_b_cal',
|
||||
'sum_of_b',
|
||||
'-',
|
||||
'tax_payable',
|
||||
'total_tax_payable',
|
||||
'opening_balance',
|
||||
'mat_credit_created',
|
||||
'mat_credit_utilized',
|
||||
'closing_balance',
|
||||
'interest_234c', 'total_tax',
|
||||
'-', 'advance_tax', 'tds',
|
||||
'tcs', 'sat',
|
||||
'tax_on_assessment',
|
||||
'refund',
|
||||
'interest_244a_per143',
|
||||
'refund_received',
|
||||
'balance_receivable',
|
||||
'Remarks'
|
||||
]
|
||||
|
||||
particulars = [
|
||||
"Gross Total Income", "Add: Disallowance u/s 14A",
|
||||
"Add: Disallowance u/s 37", "GTI as per",
|
||||
"Less: Deduction u/s 80IA - On Business Income",
|
||||
"- On Misc Receipts", "- On Other",
|
||||
"- On Sec 37 Disallowance",
|
||||
"Less: Deduction u/s 80G", "-",
|
||||
"Net Taxable Income", "-",
|
||||
"Per% Tax @(A)",
|
||||
"Tax cal(A)",
|
||||
"Per% surcharge @(A)",
|
||||
"Surcharge cal (A)",
|
||||
"Per% cess(A)",
|
||||
"Edu cess cal(A)",
|
||||
"Sum of tax_cal(A)",
|
||||
"-",
|
||||
"Per% Tax @(B)",
|
||||
"Tax cal(B)",
|
||||
"Per% surcharge @(B)",
|
||||
"Surcharge cal (B)",
|
||||
"Per% cess(B)",
|
||||
"Edu cess cal(B)",
|
||||
"Sum of tax_cal(B)",
|
||||
"-",
|
||||
"Tax Payable",
|
||||
"Total Tax Payable",
|
||||
"Opening Balance:",
|
||||
"Add: MAT Credit Created",
|
||||
"Less: MAT Credit Utilized",
|
||||
"Closing Balance",
|
||||
"Add: Interest u/s 234C",
|
||||
"Total Tax", "-",
|
||||
"Advance Tax", "TDS", "TCS", "SAT",
|
||||
"Tax on Regular Assessment",
|
||||
"Refund", "Add : Interest u/s 244A as per 143",
|
||||
"Less : Refund Received on:","Balance Receivable","Remarks"
|
||||
]
|
||||
|
||||
def safe_get(df, col):
|
||||
return df[col].values[0] if col in df.columns and not df.empty else 0
|
||||
|
||||
preview = []
|
||||
for i, part in enumerate(particulars):
|
||||
preview.append({
|
||||
"Particular": part,
|
||||
"ITR": safe_get(stage_data['ITR'], columns[i]),
|
||||
"AO": safe_get(stage_data['AO'], columns[i]),
|
||||
"CIT": safe_get(stage_data['CIT'], columns[i]),
|
||||
"ITAT": safe_get(stage_data['ITAT'], columns[i]),
|
||||
})
|
||||
|
||||
return jsonify(preview)
|
||||
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
def Summary_report(self, request):
|
||||
dbconfig = DBConfig()
|
||||
connection = dbconfig.get_db_connection()
|
||||
|
||||
year_raw = request.args.get('year')
|
||||
|
||||
# Safely parse year to int
|
||||
try:
|
||||
year = int(year_raw)
|
||||
except (TypeError, ValueError):
|
||||
year = None
|
||||
|
||||
if not year:
|
||||
yearGetter = YearGet()
|
||||
allYears = yearGetter.get_year_by_model("AllYearsInAllModel")
|
||||
yearGetter.close()
|
||||
|
||||
return render_template(
|
||||
'summary_reports.html',
|
||||
years=allYears,
|
||||
message="Please select a valid year to download."
|
||||
)
|
||||
|
||||
try:
|
||||
stages = {
|
||||
"ITR": "itr",
|
||||
"AO": "ao",
|
||||
"CIT": "cit",
|
||||
"ITAT": "itat",
|
||||
}
|
||||
|
||||
stage_data = {}
|
||||
|
||||
for stage_name, table_name in stages.items():
|
||||
cursor = connection.cursor(dictionary=True)
|
||||
cursor.callproc("sp_get_stage_data", [table_name, year])
|
||||
rows = []
|
||||
for result in cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
stage_data[stage_name] = pd.DataFrame(rows) if rows else pd.DataFrame()
|
||||
cursor.close()
|
||||
|
||||
@@ -124,25 +303,85 @@ class DocumentHandler:
|
||||
return df[col].values[0] if col in df.columns and not df.empty else "-"
|
||||
|
||||
particulars = [
|
||||
"Gross Total Income", "Add: Disallowance u/s 14A", "Add: Disallowance u/s 37",
|
||||
"GTI as per", "Less: Deduction u/s 80IA - On Business Income", "- On Misc Receipts",
|
||||
"- On Other", "- On Sec 37 Disallowance", "Less: Deduction u/s 80G", " ",
|
||||
"Net Taxable Income", "Tax @ 30%", "Tax @ 18.5% on Book Profit",
|
||||
"Tax Payable", "Surcharge @ %", "Education Cess @ 3%", "Total Tax Payable",
|
||||
"Less: MAT Credit Utilized", "Add: Interest u/s 234C", "Total Tax", " ",
|
||||
"Gross Total Income", "Add: Disallowance u/s 14A",
|
||||
"Add: Disallowance u/s 37", "GTI as per",
|
||||
"Less: Deduction u/s 80IA - On Business Income",
|
||||
"- On Misc Receipts", "- On Other",
|
||||
"- On Sec 37 Disallowance",
|
||||
"Less: Deduction u/s 80G", "-",
|
||||
"Net Taxable Income", "-",
|
||||
"Per% Tax @(A)",
|
||||
"Tax cal(A)",
|
||||
"Per% surcharge @(A)",
|
||||
"Surcharge cal (A)",
|
||||
"Per% cess(A)",
|
||||
"Edu cess cal(A)",
|
||||
"Sum of tax_cal(A)",
|
||||
"-",
|
||||
"Per% Tax @(B)",
|
||||
"Tax cal(B)",
|
||||
"Per% surcharge @(B)",
|
||||
"Surcharge cal (B)",
|
||||
"Per% cess(B)",
|
||||
"Edu cess cal(B)",
|
||||
"Sum of tax_cal(B)",
|
||||
"-",
|
||||
"Tax Payable",
|
||||
"Total Tax Payable",
|
||||
"Opening Balance",
|
||||
"Add: MAT Credit Created",
|
||||
"Less: MAT Credit Utilized",
|
||||
"Closing Balance",
|
||||
"Add: Interest u/s 234C",
|
||||
"Total Tax", "-",
|
||||
"Advance Tax", "TDS", "TCS", "SAT",
|
||||
"Tax on Regular Assessment", "Refund" , "Remarks"
|
||||
"Tax on Regular Assessment",
|
||||
"Refund", "Add : Interest u/s 244A as per 143",
|
||||
"Less : Refund Received on","Balance Receivable","Remarks"
|
||||
]
|
||||
|
||||
columns = [
|
||||
'gross_total_income', 'disallowance_14a', 'disallowance_37',
|
||||
'-', 'deduction_80ia_business','deduction_80ia_misc',
|
||||
'deduction_80ia_other', 'deduction_sec37_disallowance','deduction_80g', '-',
|
||||
'net_taxable_income', 'tax_30_percent','tax_book_profit_18_5',
|
||||
'tax_payable','surcharge_12', 'edu_cess_3', 'total_tax_payable',
|
||||
'mat_credit' , 'interest_234c','total_tax', '-',
|
||||
'advance_tax', 'tds', 'tcs', 'sat',
|
||||
'tax_on_assessment', 'refund', 'Remarks'
|
||||
'gross_total_income', 'disallowance_14a',
|
||||
'disallowance_37',
|
||||
'gross_total_income'+'disallowance_14a'+'disallowance_37',
|
||||
'deduction_80ia_business',
|
||||
'deduction_80ia_misc',
|
||||
'deduction_80ia_other',
|
||||
'deduction_sec37_disallowance',
|
||||
'deduction_80g', '-',
|
||||
'net_taxable_income',
|
||||
'-',
|
||||
'per_tax_a',
|
||||
'tax_a_cal',
|
||||
'per_surcharge_a',
|
||||
'surcharge_a_cal',
|
||||
'per_cess_a',
|
||||
'edu_cess_a_cal',
|
||||
'sum_of_a',
|
||||
'-',
|
||||
'per_tax_b',
|
||||
'tax_b_cal',
|
||||
'per_surcharge_b',
|
||||
'surcharge_b_cal',
|
||||
'per_cess_b',
|
||||
'edu_cess_b_cal',
|
||||
'sum_of_b',
|
||||
'-',
|
||||
'tax_payable',
|
||||
'total_tax_payable',
|
||||
'opening_balance',
|
||||
'mat_credit_created',
|
||||
'mat_credit_utilized',
|
||||
'closing_balance',
|
||||
'interest_234c', 'total_tax',
|
||||
'-', 'advance_tax', 'tds',
|
||||
'tcs', 'sat',
|
||||
'tax_on_assessment',
|
||||
'refund',
|
||||
'interest_244a_per143',
|
||||
'refund_received',
|
||||
'balance_receivable',
|
||||
'Remarks'
|
||||
]
|
||||
|
||||
data = {
|
||||
@@ -155,56 +394,44 @@ class DocumentHandler:
|
||||
|
||||
df = pd.DataFrame(data)
|
||||
|
||||
# ===== Excel Export =====
|
||||
output = io.BytesIO()
|
||||
|
||||
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
|
||||
sheet_name = f"AY {year} - {year + 1}"
|
||||
sheet_name = f"AY {year}-{year + 1}"
|
||||
df.to_excel(writer, index=False, sheet_name=sheet_name, startrow=2)
|
||||
|
||||
workbook = writer.book
|
||||
worksheet = writer.sheets[sheet_name]
|
||||
|
||||
# ===== Company Heading =====
|
||||
company_heading = workbook.add_format({
|
||||
title = workbook.add_format({
|
||||
'bold': True,
|
||||
'font_size': 14,
|
||||
'font_color': 'black',
|
||||
'align': 'center',
|
||||
'valign': 'middle'
|
||||
'align': 'center'
|
||||
})
|
||||
|
||||
worksheet.merge_range(
|
||||
0, 0, 0, len(df.columns) - 1,
|
||||
"Laxmi Civil Engineering Services Pvt Ltd",
|
||||
company_heading
|
||||
title
|
||||
)
|
||||
|
||||
# ===== Header Format =====
|
||||
header = workbook.add_format({
|
||||
'bold': True,
|
||||
'align': 'center',
|
||||
'valign': 'middle',
|
||||
'bg_color': '#007bff',
|
||||
'font_color': 'white',
|
||||
'border': 1
|
||||
})
|
||||
|
||||
cell = workbook.add_format({
|
||||
'border': 1,
|
||||
'align': 'left',
|
||||
'valign': 'middle'
|
||||
})
|
||||
cell = workbook.add_format({'border': 1})
|
||||
|
||||
# Write headers
|
||||
for col_num, col_name in enumerate(df.columns):
|
||||
worksheet.write(2, col_num, col_name, header)
|
||||
max_len = max(df[col_name].astype(str).map(len).max(), len(col_name)) + 2
|
||||
worksheet.set_column(col_num, col_num, max_len)
|
||||
worksheet.set_column(col_num, col_num, 25)
|
||||
|
||||
# Write data rows
|
||||
for row in range(3, len(df) + 3):
|
||||
for row in range(len(df)):
|
||||
for col in range(len(df.columns)):
|
||||
worksheet.write(row, col, df.iloc[row - 3, col], cell)
|
||||
worksheet.write(row + 3, col, df.iloc[row, col], cell)
|
||||
|
||||
worksheet.freeze_panes(3, 1)
|
||||
|
||||
@@ -218,4 +445,4 @@ class DocumentHandler:
|
||||
)
|
||||
|
||||
finally:
|
||||
connection.close()
|
||||
connection.close()
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
from AppCode.Config import DBConfig
|
||||
import mysql.connector
|
||||
import pandas as pd
|
||||
@@ -32,14 +31,15 @@ class ITATHandler:
|
||||
|
||||
# INSERT ITAT (PROC)
|
||||
def add_itat(self, data):
|
||||
columns = [
|
||||
'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37',
|
||||
'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other',
|
||||
'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income',
|
||||
'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12',
|
||||
'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c',
|
||||
'total_tax', 'advance_tax', 'tds', 'tcs','sat', 'tax_on_assessment', 'refund', 'Remarks'
|
||||
]
|
||||
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', 'per_tax_a', 'tax_a_cal', 'per_surcharge_a', 'surcharge_a_cal', 'per_cess_a', 'edu_cess_a_cal', 'sum_of_a',
|
||||
'per_tax_b', 'tax_b_cal', 'per_surcharge_b', 'surcharge_b_cal', 'per_cess_b', 'edu_cess_b_cal', 'sum_of_b',
|
||||
'tax_payable','total_tax_payable', 'opening_balance', 'mat_credit_created', 'mat_credit_utilized', 'closing_balance',
|
||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'sat', 'tax_on_assessment', 'refund',
|
||||
'interest_244a_per143', 'refund_received', 'balance_receivable', 'remarks', 'created_at'
|
||||
]
|
||||
|
||||
values = [data.get(col, 0) for col in columns]
|
||||
|
||||
self.cursor.callproc("InsertITAT", values)
|
||||
@@ -47,14 +47,14 @@ class ITATHandler:
|
||||
|
||||
# UPDATE ITAT (PROC)
|
||||
def update_itat(self, id, data):
|
||||
columns = [
|
||||
'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37',
|
||||
'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other',
|
||||
'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income',
|
||||
'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12',
|
||||
'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c',
|
||||
'total_tax', 'advance_tax', 'tds', 'tcs', 'sat','tax_on_assessment', 'refund','Remarks'
|
||||
]
|
||||
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', 'per_tax_a', 'tax_a_cal', 'per_surcharge_a', 'surcharge_a_cal', 'per_cess_a', 'edu_cess_a_cal', 'sum_of_a',
|
||||
'per_tax_b', 'tax_b_cal', 'per_surcharge_b', 'surcharge_b_cal', 'per_cess_b', 'edu_cess_b_cal', 'sum_of_b',
|
||||
'tax_payable','total_tax_payable', 'opening_balance', 'mat_credit_created', 'mat_credit_utilized', 'closing_balance',
|
||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'sat', 'tax_on_assessment', 'refund',
|
||||
'interest_244a_per143', 'refund_received', 'balance_receivable', 'remarks', 'updated_at'
|
||||
]
|
||||
values = [id] + [data.get(col, 0) for col in columns]
|
||||
|
||||
self.cursor.callproc("UpdateITAT", values)
|
||||
@@ -66,32 +66,142 @@ class ITATHandler:
|
||||
self.conn.commit()
|
||||
|
||||
|
||||
|
||||
def itat_report_download(self, selected_year):
|
||||
try:
|
||||
# Call stored procedure
|
||||
self.cursor.callproc("GetITATByYear", [selected_year])
|
||||
rows = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
try:
|
||||
# AY calculation (2020 -> AY 2020-2021)
|
||||
ay_start = int(selected_year)
|
||||
ay_end = ay_start + 1
|
||||
assessment_year = f"AY {ay_start}-{ay_end}"
|
||||
|
||||
if not rows:
|
||||
return None
|
||||
# Fetch ITAT data
|
||||
self.cursor.callproc("GetITATByYear", [selected_year])
|
||||
rows = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
|
||||
df = pd.DataFrame(rows)
|
||||
|
||||
# Excel output
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
|
||||
df.T.to_excel(writer, header=False, sheet_name="ITAT_Report")
|
||||
|
||||
output.seek(0)
|
||||
return output
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error:", e)
|
||||
if not rows:
|
||||
return None
|
||||
|
||||
# Remove id column if exists
|
||||
for row in rows:
|
||||
row.pop("id", None)
|
||||
|
||||
# Mapping DB fields → readable Excel labels
|
||||
field_mapping = {
|
||||
"gross_total_income": "Gross Total Income",
|
||||
"disallowance_14a": "Add: Disallowance u/s 14A",
|
||||
"disallowance_37": "Add: Disallowance u/s 37",
|
||||
"-" : "-",
|
||||
"deduction_80ia_business": "Less: Deduction u/s 80IA - On Business Income",
|
||||
"deduction_80ia_misc": "On Misc Receipts",
|
||||
"deduction_80ia_other": "On Other",
|
||||
"deduction_sec37_disallowance": "On Sec 37 Disallowance",
|
||||
"deduction_80g": "Less: Deduction u/s 80G",
|
||||
"net_taxable_income": "Net Taxable Income",
|
||||
"-" : "-",
|
||||
"per_tax_a" : "Per% Tax @(A)",
|
||||
"tax_a_cal" : "Tax cal(A)",
|
||||
"per_surcharge_a" : "Per% surcharge @(A)",
|
||||
"surcharge_a_cal" : "Surcharge cal (A)",
|
||||
"per_cess_a" : "Per% cess(A)",
|
||||
"edu_cess_a_cal" : "Edu cess cal(A)",
|
||||
"sum_of_a" : "Sum of tax_cal(A)",
|
||||
"-" : "-",
|
||||
"per_tax_b" : "Per% Tax @(B)",
|
||||
"tax_b_cal" : "Tax cal(B)",
|
||||
"per_surcharge_b" : "Per% surcharge @(B)",
|
||||
"surcharge_b_cal" : "Surcharge cal (B)",
|
||||
"per_cess_b" : "Per% cess(B)",
|
||||
"edu_cess_b_cal" : "Edu cess cal(B)",
|
||||
"sum_of_b" : "Sum of tax_cal(B)",
|
||||
"tax_payable": "Tax Payable",
|
||||
"total_tax_payable": "Total Tax Payable",
|
||||
"opening_balance": "Opening Balance",
|
||||
"mat_credit_created": "Add: MAT Credit Created",
|
||||
"mat_credit_utilized": "Less: MAT Credit Utilized",
|
||||
"closing_balance": "Closing Balance",
|
||||
"interest_234c": "Add: Interest u/s 234C",
|
||||
"total_tax": "Total Tax",
|
||||
"advance_tax": "Advance Tax",
|
||||
"tds": "TDS",
|
||||
"tcs": "TCS",
|
||||
"sat": "SAT",
|
||||
"tax_on_assessment": "Tax on Regular Assessment",
|
||||
"refund" : "Refund",
|
||||
"interest_244a_per143" : "Add : Interest u/s 244A as per 143",
|
||||
"refund_received" : "Less : Refund Received on",
|
||||
"balance_receivable" : "Balance Receivable",
|
||||
"Remarks" : "Remarks"
|
||||
}
|
||||
|
||||
# Vertical ITAT structure
|
||||
data = []
|
||||
for key, label in field_mapping.items():
|
||||
value = rows[0].get(key, 0)
|
||||
data.append([label, value])
|
||||
|
||||
df = pd.DataFrame(data, columns=["Particulars", "ITAT"])
|
||||
|
||||
# Excel output
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
|
||||
workbook = writer.book
|
||||
worksheet = workbook.add_worksheet("ITAT Report")
|
||||
writer.sheets["ITAT Report"] = worksheet
|
||||
|
||||
# Formats
|
||||
title_fmt = workbook.add_format({
|
||||
"bold": True,
|
||||
"align": "center",
|
||||
"font_size": 14
|
||||
})
|
||||
header_fmt = workbook.add_format({
|
||||
"bold": True,
|
||||
"border": 1,
|
||||
"align": "center"
|
||||
})
|
||||
text_fmt = workbook.add_format({"border": 1})
|
||||
num_fmt = workbook.add_format({
|
||||
"border": 1,
|
||||
"num_format": "#,##0.00"
|
||||
})
|
||||
|
||||
# Company Name
|
||||
worksheet.merge_range(
|
||||
"A1:B1",
|
||||
"Laxmi Civil Engineering Services Pvt Ltd",
|
||||
title_fmt
|
||||
)
|
||||
|
||||
# Assessment Year
|
||||
worksheet.merge_range(
|
||||
"A2:B2",
|
||||
f"Assessment Year : {assessment_year}",
|
||||
workbook.add_format({"bold": True, "align": "center"})
|
||||
)
|
||||
|
||||
# Header
|
||||
worksheet.write_row("A4", ["Particulars", "ITAT"], header_fmt)
|
||||
|
||||
# Data rows
|
||||
row_no = 4
|
||||
for _, row in df.iterrows():
|
||||
worksheet.write(row_no, 0, row["Particulars"], text_fmt)
|
||||
worksheet.write(row_no, 1, row["ITAT"], num_fmt)
|
||||
row_no += 1
|
||||
|
||||
# Column widths
|
||||
worksheet.set_column("A:A", 45)
|
||||
worksheet.set_column("B:B", 20)
|
||||
|
||||
output.seek(0)
|
||||
return output
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error →", e)
|
||||
return None
|
||||
|
||||
|
||||
# CLOSE CONNECTION
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
from AppCode.Config import DBConfig
|
||||
import mysql.connector
|
||||
from AppCode.YearGet import YearGet
|
||||
|
||||
import pandas as pd
|
||||
import pymysql
|
||||
import io
|
||||
|
||||
# new
|
||||
from AppCode.Config import DBConfig
|
||||
import mysql.connector
|
||||
import pandas as pd
|
||||
import io
|
||||
from flask import send_file, render_template, request
|
||||
|
||||
from AppCode.Config import DBConfig
|
||||
|
||||
|
||||
class ITRHandler:
|
||||
@@ -21,11 +12,8 @@ class ITRHandler:
|
||||
self.conn = DBConfig.get_db_connection()
|
||||
self.cursor = self.conn.cursor(dictionary=True)
|
||||
|
||||
|
||||
# GET ALL ITR RECORDS using stored procedure "GetAllItr"
|
||||
def get_all_itr(self):
|
||||
# self.cursor = conn.cursor(dictionary=True)
|
||||
|
||||
self.cursor.callproc("GetAllItr")
|
||||
records = []
|
||||
for result in self.cursor.stored_results():
|
||||
@@ -52,95 +40,176 @@ class ITRHandler:
|
||||
|
||||
# INSERT ITR RECORD using procedure "add_itr"
|
||||
def add_itr(self, data):
|
||||
try:
|
||||
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', 'per_tax_a', 'tax_a_cal', 'per_surcharge_a', 'surcharge_a_cal', 'per_cess_a', 'edu_cess_a_cal', 'sum_of_a',
|
||||
'per_tax_b', 'tax_b_cal', 'per_surcharge_b', 'surcharge_b_cal', 'per_cess_b', 'edu_cess_b_cal', 'sum_of_b',
|
||||
'tax_payable','total_tax_payable', 'opening_balance', 'mat_credit_created', 'mat_credit_utilized', 'closing_balance',
|
||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'sat', 'tax_on_assessment', 'refund',
|
||||
'interest_244a_per143', 'refund_received', 'balance_receivable', 'remarks', 'created_at'
|
||||
]
|
||||
|
||||
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','sat', 'tax_on_assessment', 'refund', 'Remarks'
|
||||
]
|
||||
values = [data.get(col, 0) for col in columns]
|
||||
|
||||
values = [data.get(col, 0) for col in columns]
|
||||
# Call your stored procedure
|
||||
self.cursor.callproc("InsertITR", values)
|
||||
self.conn.commit()
|
||||
except Exception as e:
|
||||
self.conn.rollback()
|
||||
raise e
|
||||
finally:
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
|
||||
# Call your stored procedure
|
||||
self.cursor.callproc("InsertITR", values)
|
||||
self.conn.commit()
|
||||
|
||||
# update itr by id
|
||||
def update(self, id, data):
|
||||
columns = [
|
||||
'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37',
|
||||
'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other',
|
||||
'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income',
|
||||
'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12',
|
||||
'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c',
|
||||
'total_tax', 'advance_tax', 'tds', 'tcs', 'sat','tax_on_assessment', 'refund','Remarks'
|
||||
]
|
||||
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', 'per_tax_a', 'tax_a_cal', 'per_surcharge_a', 'surcharge_a_cal', 'per_cess_a', 'edu_cess_a_cal', 'sum_of_a',
|
||||
'per_tax_b', 'tax_b_cal', 'per_surcharge_b', 'surcharge_b_cal', 'per_cess_b', 'edu_cess_b_cal', 'sum_of_b',
|
||||
'tax_payable','total_tax_payable', 'opening_balance', 'mat_credit_created', 'mat_credit_utilized', 'closing_balance',
|
||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'sat', 'tax_on_assessment', 'refund',
|
||||
'interest_244a_per143', 'refund_received', 'balance_receivable', 'remarks', 'updated_at'
|
||||
]
|
||||
|
||||
values = [id] + [data.get(col, 0) for col in columns]
|
||||
|
||||
print("Final values:", values)
|
||||
|
||||
self.cursor.callproc("UpdateITR", values)
|
||||
self.conn.commit()
|
||||
|
||||
|
||||
# DELETE RECORD by ITR id
|
||||
# DELETE RECORD by ITR id
|
||||
def delete_itr_by_id(self, id):
|
||||
self.cursor.callproc('DeleteITRById', [id])
|
||||
self.conn.commit()
|
||||
|
||||
|
||||
# report download by year
|
||||
# # report download by year
|
||||
def itr_report_download(self, selected_year):
|
||||
try:
|
||||
# Call stored procedure
|
||||
self.cursor.callproc("GetITRByYear", [selected_year])
|
||||
|
||||
try:
|
||||
# Call stored procedure
|
||||
self.cursor.callproc("GetITRByYear", [selected_year])
|
||||
rows = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
|
||||
rows = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
|
||||
if not rows:
|
||||
return None
|
||||
|
||||
# Convert SQL rows to DataFrame
|
||||
df = pd.DataFrame(rows)
|
||||
|
||||
# Transpose
|
||||
df_transposed = df.transpose()
|
||||
df_transposed.insert(0, 'Field', df_transposed.index)
|
||||
|
||||
print("df-->",df_transposed)
|
||||
|
||||
|
||||
record_cols = {
|
||||
i: f"Record {i}"
|
||||
for i in df_transposed.columns if isinstance(i, int)
|
||||
}
|
||||
|
||||
df_transposed.rename(columns=record_cols, inplace=True)
|
||||
df_transposed.reset_index(drop=True, inplace=True)
|
||||
|
||||
# Save to Excel in memory
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
|
||||
df_transposed.to_excel(writer, index=False, sheet_name='ITR_Vertical')
|
||||
worksheet = writer.sheets['ITR_Vertical']
|
||||
worksheet.set_column(0, 0, 30)
|
||||
|
||||
output.seek(0)
|
||||
return output
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error →", e)
|
||||
if not rows:
|
||||
return None
|
||||
for row in rows:
|
||||
row.pop('id', None)
|
||||
|
||||
# Mapping DB fields → Excel labels (NO underscores)
|
||||
field_mapping = {
|
||||
"gross_total_income": "Gross Total Income",
|
||||
"disallowance_14a": "Add: Disallowance u/s 14A",
|
||||
"disallowance_37": "Add: Disallowance u/s 37",
|
||||
"-" : "-",
|
||||
"deduction_80ia_business": "Less: Deduction u/s 80IA - On Business Income",
|
||||
"deduction_80ia_misc": "On Misc Receipts",
|
||||
"deduction_80ia_other": "On Other",
|
||||
"deduction_sec37_disallowance": "On Sec 37 Disallowance",
|
||||
"deduction_80g": "Less: Deduction u/s 80G",
|
||||
"net_taxable_income": "Net Taxable Income",
|
||||
"-" : "-",
|
||||
"per_tax_a" : "Per% Tax @(A)",
|
||||
"tax_a_cal" : "Tax cal(A)",
|
||||
"per_surcharge_a" : "Per% surcharge @(A)",
|
||||
"surcharge_a_cal" : "Surcharge cal (A)",
|
||||
"per_cess_a" : "Per% cess(A)",
|
||||
"edu_cess_a_cal" : "Edu cess cal(A)",
|
||||
"sum_of_a" : "Sum of tax_cal(A)",
|
||||
"-" : "-",
|
||||
"per_tax_b" : "Per% Tax @(B)",
|
||||
"tax_b_cal" : "Tax cal(B)",
|
||||
"per_surcharge_b" : "Per% surcharge @(B)",
|
||||
"surcharge_b_cal" : "Surcharge cal (B)",
|
||||
"per_cess_b" : "Per% cess(B)",
|
||||
"edu_cess_b_cal" : "Edu cess cal(B)",
|
||||
"sum_of_b" : "Sum of tax_cal(B)",
|
||||
"tax_payable": "Tax Payable",
|
||||
"total_tax_payable": "Total Tax Payable",
|
||||
"opening_balance": "Opening Balance",
|
||||
"mat_credit_created": "Add: MAT Credit Created",
|
||||
"mat_credit_utilized": "Less: MAT Credit Utilized",
|
||||
"closing_balance": "Closing Balance",
|
||||
"interest_234c": "Add: Interest u/s 234C",
|
||||
"total_tax": "Total Tax",
|
||||
"advance_tax": "Advance Tax",
|
||||
"tds": "TDS",
|
||||
"tcs": "TCS",
|
||||
"sat": "SAT",
|
||||
"tax_on_assessment": "Tax on Regular Assessment",
|
||||
"refund" : "Refund",
|
||||
"interest_244a_per143" : "Add : Interest u/s 244A as per 143",
|
||||
"refund_received" : "Less : Refund Received on",
|
||||
"balance_receivable" : "Balance Receivable",
|
||||
"Remarks" : "Remarks"
|
||||
}
|
||||
|
||||
# Convert to vertical structures
|
||||
data = []
|
||||
for key, label in field_mapping.items():
|
||||
value = rows[0].get(key, 0)
|
||||
data.append([label, value])
|
||||
|
||||
df = pd.DataFrame(data, columns=["Particulars", "ITR"])
|
||||
|
||||
# Excel output
|
||||
output = io.BytesIO()
|
||||
with pd.ExcelWriter(output, engine="xlsxwriter") as writer:
|
||||
workbook = writer.book
|
||||
worksheet = workbook.add_worksheet("ITR Report")
|
||||
writer.sheets["ITR Report"] = worksheet
|
||||
|
||||
# Formats
|
||||
title_fmt = workbook.add_format({
|
||||
"bold": True, "align": "center", "valign": "vcenter",
|
||||
"font_size": 14
|
||||
})
|
||||
header_fmt = workbook.add_format({
|
||||
"bold": True, "border": 1, "align": "center"
|
||||
})
|
||||
cell_fmt = workbook.add_format({"border": 1})
|
||||
num_fmt = workbook.add_format({"border": 1, "num_format": "#,##0.00"})
|
||||
|
||||
# Company name
|
||||
worksheet.merge_range("A1:B1", "Laxmi Civil Engineering Services Pvt Ltd", title_fmt)
|
||||
|
||||
ay_start = int(selected_year)
|
||||
ay_end = ay_start + 1
|
||||
assessment_year = f"AY {ay_start}-{ay_end}"
|
||||
|
||||
# Assessment Year
|
||||
worksheet.merge_range(
|
||||
"A2:B2",
|
||||
f"Assessment Year : {assessment_year}",
|
||||
workbook.add_format({"align": "center", "bold": True})
|
||||
)
|
||||
|
||||
# Headers
|
||||
worksheet.write_row("A4", ["Particulars", "ITR"], header_fmt)
|
||||
|
||||
# Data rows
|
||||
row_no = 4
|
||||
for _, row in df.iterrows():
|
||||
worksheet.write(row_no, 0, row["Particulars"], cell_fmt)
|
||||
worksheet.write(row_no, 1, row["ITR"], num_fmt)
|
||||
row_no += 1
|
||||
|
||||
# Column widths
|
||||
worksheet.set_column("A:A", 45)
|
||||
worksheet.set_column("B:B", 20)
|
||||
|
||||
output.seek(0)
|
||||
return output
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error →", e)
|
||||
return None
|
||||
|
||||
# CLOSE CONNECTION
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
self.conn.close()
|
||||
@@ -1,10 +1,9 @@
|
||||
import os
|
||||
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, flash, jsonify, json
|
||||
from flask import current_app
|
||||
|
||||
from datetime import datetime
|
||||
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
|
||||
|
||||
import os
|
||||
|
||||
class LogHelper:
|
||||
@staticmethod
|
||||
@@ -14,9 +13,7 @@ class LogHelper:
|
||||
logData.WriteLog(action, details="")
|
||||
|
||||
|
||||
|
||||
class LogData:
|
||||
|
||||
filepath = ""
|
||||
timestamp = None
|
||||
|
||||
|
||||
@@ -1,40 +1,71 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash, session
|
||||
from flask import flash,redirect,url_for
|
||||
from functools import wraps
|
||||
from flask import session
|
||||
from ldap3 import Server, Connection, ALL
|
||||
from ldap3.core.exceptions import LDAPException
|
||||
|
||||
|
||||
class LoginAuth:
|
||||
def __init__(self):
|
||||
# Create Blueprint
|
||||
self.bp = Blueprint("auth", __name__)
|
||||
|
||||
# -------------------------------
|
||||
# LDAP CONFIGURATION
|
||||
# -------------------------------
|
||||
self.LDAP_SERVER = "ldap://localhost:389"
|
||||
|
||||
self.BASE_DN = "ou=users,dc=lcepl,dc=org" # LDAP Users DN
|
||||
|
||||
# -------------------------------
|
||||
# LOGIN ROUTE
|
||||
# -------------------------------
|
||||
@self.bp.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
if request.method == 'POST':
|
||||
username = request.form.get("username")
|
||||
password = request.form.get("password")
|
||||
|
||||
# Dummy validation — REPLACE with DB check later
|
||||
if username == "admin" and password == "admin123":
|
||||
session['user'] = username
|
||||
flash("Login successful!", "success")
|
||||
return redirect(url_for('welcome'))
|
||||
else:
|
||||
flash("Invalid username or password!", "danger")
|
||||
if not username or not password:
|
||||
flash("Username and password are required!", "danger")
|
||||
return render_template("login.html")
|
||||
|
||||
user_dn = f"uid={username},{self.BASE_DN}"
|
||||
server = Server(self.LDAP_SERVER, get_info=ALL)
|
||||
|
||||
try:
|
||||
# Attempt LDAP bind
|
||||
conn = Connection(server, user=user_dn, password=password, auto_bind=True)
|
||||
if conn.bound:
|
||||
session['user'] = username
|
||||
flash(f"Login successful! Welcome {username}", "success")
|
||||
return redirect(url_for('welcome'))
|
||||
else:
|
||||
flash("Invalid username or password!", "danger")
|
||||
except LDAPException as e:
|
||||
flash(f"LDAP login failed: {str(e)}", "danger")
|
||||
finally:
|
||||
if 'conn' in locals():
|
||||
conn.unbind()
|
||||
|
||||
# GET request: show login form
|
||||
return render_template("login.html")
|
||||
|
||||
# -------------------------------
|
||||
# LOGOUT ROUTE
|
||||
# -------------------------------
|
||||
@self.bp.route('/logout')
|
||||
def logout():
|
||||
session.clear()
|
||||
flash("Logged out successfully!", "success")
|
||||
return redirect(url_for('auth.login'))
|
||||
|
||||
# ===================================================
|
||||
# LOGIN REQUIRED DECORATOR INSIDE CLASS
|
||||
|
||||
# ===================================================
|
||||
# LOGIN REQUIRED DECORATOR INSIDE CLASS
|
||||
# ===================================================
|
||||
def login_required(self, f):
|
||||
"""
|
||||
Protect routes: redirect to login if user not authenticated.
|
||||
"""
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
if "user" not in session:
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
from AppCode.Config import DBConfig
|
||||
import mysql.connector
|
||||
|
||||
|
||||
|
||||
class MatCreditHandler:
|
||||
|
||||
def __init__(self):
|
||||
# db = DBConfig()
|
||||
self.conn = DBConfig.get_db_connection()
|
||||
self.cursor = self.conn.cursor(dictionary=True)
|
||||
|
||||
# get all Mat credit data
|
||||
# --------------------------------------------------
|
||||
# FETCH ALL MAT CREDIT + UTILIZATION (For UI Display)
|
||||
# --------------------------------------------------
|
||||
def fetch_all(self):
|
||||
try:
|
||||
|
||||
self.cursor.callproc("GetMatCedit")
|
||||
result_sets = self.cursor.stored_results()
|
||||
mat_rows = next(result_sets).fetchall()
|
||||
@@ -21,103 +21,108 @@ class MatCreditHandler:
|
||||
return mat_rows, utilization_rows
|
||||
finally:
|
||||
self.cursor.close()
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
|
||||
# Save Mat credit data single row
|
||||
# --------------------------------------------------
|
||||
# SAVE / UPDATE SINGLE MAT ROW (FROM MANUAL UI)
|
||||
# --------------------------------------------------
|
||||
@staticmethod
|
||||
def save_single(data):
|
||||
conn = DBConfig.get_db_connection()
|
||||
cur = conn.cursor()
|
||||
cur = conn.cursor(dictionary=True)
|
||||
|
||||
try:
|
||||
cur.execute(
|
||||
"SELECT id FROM mat_credit WHERE financial_year=%s",
|
||||
(data["financial_year"],)
|
||||
# Save / Update MAT Credit
|
||||
cur.callproc(
|
||||
"SaveOrUpdateMatCredit",
|
||||
(
|
||||
data["financial_year"],
|
||||
data["mat_credit"],
|
||||
data["balance"],
|
||||
data.get("remarks", "")
|
||||
)
|
||||
)
|
||||
row = cur.fetchone()
|
||||
|
||||
if row:
|
||||
mat_id = row[0]
|
||||
mat_id = None
|
||||
for result in cur.stored_results():
|
||||
mat_id = result.fetchone()["mat_id"]
|
||||
|
||||
cur.execute("""
|
||||
UPDATE mat_credit
|
||||
SET mat_credit=%s, balance=%s
|
||||
WHERE id=%s
|
||||
""", (data["mat_credit"], data["balance"], mat_id))
|
||||
|
||||
cur.execute(
|
||||
"DELETE FROM mat_utilization WHERE mat_credit_id=%s",
|
||||
(mat_id,)
|
||||
)
|
||||
else:
|
||||
cur.execute("""
|
||||
INSERT INTO mat_credit (financial_year, mat_credit, balance)
|
||||
VALUES (%s,%s,%s)
|
||||
""", (data["financial_year"], data["mat_credit"], data["balance"]))
|
||||
|
||||
mat_id = cur.lastrowid
|
||||
|
||||
for u in data["utilization"]:
|
||||
cur.execute("""
|
||||
INSERT INTO mat_utilization
|
||||
(mat_credit_id, utilized_year, utilized_amount)
|
||||
VALUES (%s,%s,%s)
|
||||
""", (mat_id, u["year"], u["amount"]))
|
||||
# Save utilization rows
|
||||
for u in data.get("utilization", []):
|
||||
if float(u["amount"]) > 0:
|
||||
cur.callproc(
|
||||
"InsertMatUtilization",
|
||||
(mat_id, u["year"], u["amount"])
|
||||
)
|
||||
|
||||
conn.commit()
|
||||
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
raise
|
||||
|
||||
raise e
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
|
||||
# save all Mat credit data
|
||||
# --------------------------------------------------
|
||||
# AUTO SAVE MAT FROM ITR (MAIN LOGIC)
|
||||
# --------------------------------------------------
|
||||
@staticmethod
|
||||
def save_bulk(rows):
|
||||
def save_from_itr(year, mat_created, mat_utilized, remarks="Auto from"):
|
||||
conn = DBConfig.get_db_connection()
|
||||
cur = conn.cursor()
|
||||
skipped = []
|
||||
cur = conn.cursor(dictionary=True)
|
||||
|
||||
try:
|
||||
for row in rows:
|
||||
cur.execute(
|
||||
"SELECT id FROM mat_credit WHERE financial_year=%s",
|
||||
(row["financial_year"],)
|
||||
mat_created = float(mat_created or 0)
|
||||
mat_utilized = float(mat_utilized or 0)
|
||||
|
||||
balance = mat_created - mat_utilized
|
||||
|
||||
# Save / Update MAT Credit
|
||||
cur.callproc(
|
||||
"SaveOrUpdateMatCredit",
|
||||
(year, mat_created, balance, remarks)
|
||||
)
|
||||
|
||||
mat_id = None
|
||||
for result in cur.stored_results():
|
||||
mat_id = result.fetchone()["mat_id"]
|
||||
|
||||
# Save utilization only if used
|
||||
if mat_utilized > 0:
|
||||
cur.callproc(
|
||||
"InsertMatUtilization",
|
||||
(mat_id, year, mat_utilized)
|
||||
)
|
||||
if cur.fetchone():
|
||||
skipped.append(row["financial_year"])
|
||||
continue
|
||||
|
||||
cur.execute("""
|
||||
INSERT INTO mat_credit (financial_year, mat_credit, balance)
|
||||
VALUES (%s,%s,%s)
|
||||
""", (row["financial_year"], row["mat_credit"], row["balance"]))
|
||||
|
||||
mat_id = cur.lastrowid
|
||||
|
||||
for u in row["utilization"]:
|
||||
cur.execute("""
|
||||
INSERT INTO mat_utilization
|
||||
(mat_credit_id, utilized_year, utilized_amount)
|
||||
VALUES (%s,%s,%s)
|
||||
""", (mat_id, u["year"], u["amount"]))
|
||||
|
||||
conn.commit()
|
||||
return skipped
|
||||
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
raise
|
||||
|
||||
raise e
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
# CLOSE CONNECTION
|
||||
# --------------------------------------------------
|
||||
# DELETE MAT CREDIT SAFELY (OPTIONAL)
|
||||
# --------------------------------------------------
|
||||
def delete_by_year(self, financial_year):
|
||||
try:
|
||||
self.cursor.execute(
|
||||
"DELETE FROM mat_credit WHERE financial_year=%s",
|
||||
(financial_year,)
|
||||
)
|
||||
self.conn.commit()
|
||||
finally:
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
|
||||
# --------------------------------------------------
|
||||
# CLOSE CONNECTION (MANUAL USE)
|
||||
# --------------------------------------------------
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
if self.cursor:
|
||||
self.cursor.close()
|
||||
if self.conn:
|
||||
self.conn.close()
|
||||
|
||||
@@ -11,28 +11,31 @@ class YearGet:
|
||||
def get_year_by_model(self, proc_name):
|
||||
try:
|
||||
self.cursor.callproc(proc_name)
|
||||
|
||||
years = []
|
||||
for result in self.cursor.stored_results():
|
||||
rows = result.fetchall()
|
||||
years = [row["year"] for row in rows]
|
||||
|
||||
print("-- years get --",years)
|
||||
return years
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error:", e)
|
||||
return []
|
||||
|
||||
# def get_all_year_in_all_model(self):
|
||||
# self.cursor.callproc("AllYearsInAllModel")
|
||||
# years = []
|
||||
# for result in self.cursor.stored_results():
|
||||
# rows = result.fetchall()
|
||||
# years = [row["year"] for row in rows]
|
||||
# return years
|
||||
|
||||
|
||||
def CheckYearExists(self, table_name, year):
|
||||
try:
|
||||
self.cursor.callproc('CheckYearExists', (table_name, year))
|
||||
|
||||
result = 0
|
||||
for result_set in self.cursor.stored_results():
|
||||
result = result_set.fetchone()[0]
|
||||
|
||||
return {"exists": result > 0}
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print("MySQL Error:", e)
|
||||
return {"exists": False, "error": str(e)}
|
||||
|
||||
def close(self):
|
||||
self.cursor.close()
|
||||
self.conn.close()
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
22
Dockerfile
Normal file
22
Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
||||
FROM python:3.11-slim
|
||||
|
||||
# Prevent Python buffering
|
||||
ENV PYTHONDONTWRITEBYTECODE=1
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system deps (if needed later)
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 5000
|
||||
|
||||
CMD ["python", "main.py"]
|
||||
|
||||
0
db/income_tax.sql
Normal file
0
db/income_tax.sql
Normal file
29
docker-compose.yml
Normal file
29
docker-compose.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mysql:8.0
|
||||
container_name: income_tax_db
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_DATABASE: test_income_taxdb
|
||||
ports:
|
||||
- "3307:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./db/income_tax.sql:/docker-entrypoint-initdb.d/income_tax.sql
|
||||
|
||||
web:
|
||||
build: .
|
||||
container_name: income_tax_web
|
||||
restart: always
|
||||
ports:
|
||||
- "5010:5010"
|
||||
env_file:
|
||||
- .env
|
||||
depends_on:
|
||||
- db
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
218
main.py
218
main.py
@@ -1,29 +1,28 @@
|
||||
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort, flash,send_file ,jsonify
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
import pandas as pd
|
||||
import pymysql
|
||||
import io
|
||||
import mysql.connector
|
||||
from werkzeug.utils import secure_filename
|
||||
from datetime import datetime
|
||||
|
||||
from datetime import date
|
||||
from AppCode.Config import DBConfig
|
||||
from AppCode.LoginAuth import LoginAuth
|
||||
from AppCode.FileHandler import FileHandler
|
||||
from AppCode.YearGet import YearGet
|
||||
from AppCode.DocumentHandler import DocumentHandler
|
||||
from AppCode.ITRHandler import ITRHandler
|
||||
from AppCode.AOHandler import AOHandler
|
||||
from AppCode.CITHandler import CITHandler
|
||||
from AppCode.ITATHandler import ITATHandler
|
||||
from AppCode.YearGet import YearGet
|
||||
from AppCode.LoginAuth import LoginAuth
|
||||
from AppCode.MatCreditHandler import MatCreditHandler
|
||||
import subprocess
|
||||
|
||||
|
||||
|
||||
# Server
|
||||
app = Flask(__name__)
|
||||
app.secret_key="secret1234"
|
||||
app.config['UPLOAD_FOLDER'] = FileHandler.UPLOAD_FOLDER
|
||||
app.secret_key=os.getenv("SECRET_KEY")
|
||||
|
||||
auth = LoginAuth()
|
||||
app.register_blueprint(auth.bp)
|
||||
|
||||
@@ -40,13 +39,10 @@ def welcome():
|
||||
def index():
|
||||
return render_template('index.html')
|
||||
|
||||
# Ensure folder exists
|
||||
def allowed_file(filename):
|
||||
return '.' in filename and filename.rsplit('.', 1)[1].lower() in FileHandler.ALLOWED_EXTENSIONS
|
||||
|
||||
|
||||
|
||||
# Upload File route
|
||||
@app.route('/upload', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def upload_file():
|
||||
if request.method == 'POST':
|
||||
FileHandler.CHeckExistingOrCreateNewUploadFolder()
|
||||
@@ -58,34 +54,40 @@ def upload_file():
|
||||
|
||||
# View all documents with filters
|
||||
@app.route('/documents')
|
||||
@auth.login_required
|
||||
def view_documents():
|
||||
docHandler = DocumentHandler()
|
||||
docHandler.View(request=request)
|
||||
return render_template('view_docs.html', documents=docHandler.documents, years=docHandler.years)
|
||||
|
||||
|
||||
# Upload file documents
|
||||
@app.route('/uploads/<filename>')
|
||||
@auth.login_required
|
||||
def uploaded_file(filename):
|
||||
mode = request.args.get('mode', 'view')
|
||||
filepath = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(filename))
|
||||
filepath = os.path.join(FileHandler.UPLOAD_FOLDER, secure_filename(filename))
|
||||
|
||||
if not os.path.exists(filepath):
|
||||
abort(404)
|
||||
flash("Unsupported file type for viewing", "warning")
|
||||
return redirect(url_for('view_documents'))
|
||||
|
||||
file_ext = filename.rsplit('.', 1)[-1].lower()
|
||||
|
||||
# --- View Mode ---
|
||||
if mode == 'view':
|
||||
# pdf
|
||||
if file_ext == 'pdf':
|
||||
return send_file(filepath, mimetype='application/pdf')
|
||||
# Word
|
||||
elif file_ext in ['doc', 'docx']:
|
||||
return send_file(filepath, as_attachment=True)
|
||||
# Excel
|
||||
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
|
||||
flash("Unsupported file type for viewing", "warning")
|
||||
return redirect(url_for('view_documents'))
|
||||
|
||||
return send_file(filepath, as_attachment=True)
|
||||
return send_file(filepath, as_attachment=True, download_name=filename)
|
||||
|
||||
|
||||
|
||||
@@ -95,6 +97,7 @@ def uploaded_file(filename):
|
||||
|
||||
## 1. READ/DISPLAY all ITR records
|
||||
@app.route('/itr_records')
|
||||
@auth.login_required
|
||||
def display_itr():
|
||||
itr = ITRHandler()
|
||||
records = itr.get_all_itr()
|
||||
@@ -104,18 +107,34 @@ def display_itr():
|
||||
|
||||
## 2. CREATE/ADD a new ITR record
|
||||
@app.route('/itr/add', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def add_itr():
|
||||
if request.method == 'POST':
|
||||
itr = ITRHandler()
|
||||
mat = MatCreditHandler()
|
||||
itr.add_itr(request.form)
|
||||
itr.close()
|
||||
flash("ITR record added successfully!", "success")
|
||||
if 'documents' in request.files:
|
||||
doc = DocumentHandler()
|
||||
doc.Upload(request)
|
||||
|
||||
# AUTO SAVE MAT FROM ITR
|
||||
mat.save_from_itr(
|
||||
year=request.form["year"],
|
||||
mat_created=float(request.form.get("mat_credit_created", 0)),
|
||||
mat_utilized=float(request.form.get("mat_credit_utilized", 0)),
|
||||
remarks="Created via ITR"
|
||||
)
|
||||
|
||||
# flash("ITR record added successfully!", "success")
|
||||
flash("ITR record and documents uploaded successfully!", "success")
|
||||
return redirect(url_for('display_itr'))
|
||||
|
||||
return render_template('add_itr.html')
|
||||
return render_template('add_itr.html',current_date=date.today().isoformat())
|
||||
|
||||
## 4. DELETE an ITR record
|
||||
## 4. DELETE an ITR records
|
||||
@app.route('/itr/delete/<int:id>', methods=['POST'])
|
||||
@auth.login_required
|
||||
def delete_itr(id):
|
||||
itr = ITRHandler()
|
||||
itr.delete_itr_by_id(id=id)
|
||||
@@ -124,18 +143,19 @@ def delete_itr(id):
|
||||
|
||||
## 3. UPDATE an existing ITR record
|
||||
@app.route('/itr/update/<int:id>', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def update_itr(id):
|
||||
itr = ITRHandler()
|
||||
|
||||
if request.method == 'POST':
|
||||
data = {k: request.form.get(k, 0) for k in request.form}
|
||||
itr.update(id, data=data)
|
||||
itr.update(id, data)
|
||||
itr.close()
|
||||
return redirect(url_for('display_itr'))
|
||||
|
||||
record = itr.get_itr_by_id(id)
|
||||
itr.close()
|
||||
return render_template('update_itr.html', record=record)
|
||||
return render_template('update_itr.html', record=record, current_date=date.today().isoformat())
|
||||
|
||||
|
||||
|
||||
@@ -146,6 +166,7 @@ def update_itr(id):
|
||||
|
||||
# 1. DISPLAY all AO records
|
||||
@app.route('/ao_records')
|
||||
@auth.login_required
|
||||
def display_ao():
|
||||
ao = AOHandler()
|
||||
ao_records = ao.get_all_ao()
|
||||
@@ -155,17 +176,33 @@ def display_ao():
|
||||
|
||||
# 2. ADD a new AO record
|
||||
@app.route('/ao/add', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def add_ao():
|
||||
if request.method == 'POST':
|
||||
ao = AOHandler()
|
||||
mat = MatCreditHandler()
|
||||
ao.add_ao(request.form)
|
||||
ao.close()
|
||||
|
||||
if 'documents' in request.files:
|
||||
doc = DocumentHandler()
|
||||
doc.Upload(request)
|
||||
|
||||
# AUTO SAVE MAT FROM ITR
|
||||
mat.save_from_itr(
|
||||
year=request.form["year"],
|
||||
mat_created=float(request.form.get("mat_credit_created", 0)),
|
||||
mat_utilized=float(request.form.get("mat_credit_utilized", 0)),
|
||||
remarks="Created via ao"
|
||||
)
|
||||
|
||||
flash("AO record added successfully!", "success")
|
||||
return redirect(url_for('display_ao'))
|
||||
return render_template('add_ao.html')
|
||||
return render_template('add_ao.html',current_date=date.today().isoformat())
|
||||
|
||||
# 3. UPDATE AO record
|
||||
@app.route('/ao/update/<int:id>', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def update_ao(id):
|
||||
ao = AOHandler()
|
||||
record = ao.get_ao_by_id(id)
|
||||
@@ -186,6 +223,7 @@ def update_ao(id):
|
||||
|
||||
# 4. DELETE AO record safely
|
||||
@app.route('/ao/delete/<int:id>', methods=['POST'])
|
||||
@auth.login_required
|
||||
def delete_ao(id):
|
||||
ao = AOHandler()
|
||||
ao.delete_ao_by_id(id=id)
|
||||
@@ -201,6 +239,7 @@ def delete_ao(id):
|
||||
|
||||
# 1 DISPLAY all CIT records
|
||||
@app.route('/cit_records')
|
||||
@auth.login_required
|
||||
def display_cit():
|
||||
cit = CITHandler()
|
||||
cit_records = cit.get_all_cit()
|
||||
@@ -209,18 +248,33 @@ def display_cit():
|
||||
|
||||
# 2 new CIT records add
|
||||
@app.route('/cit/add', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def add_cit():
|
||||
if request.method == 'POST':
|
||||
cit = CITHandler()
|
||||
mat = MatCreditHandler()
|
||||
cit.add_cit(request.form)
|
||||
cit.close()
|
||||
|
||||
if 'documents' in request.files:
|
||||
doc = DocumentHandler()
|
||||
doc.Upload(request)
|
||||
|
||||
# AUTO SAVE MAT FROM ITR
|
||||
mat.save_from_itr(
|
||||
year=request.form["year"],
|
||||
mat_created=float(request.form.get("mat_credit_created", 0)),
|
||||
mat_utilized=float(request.form.get("mat_credit_utilized", 0)),
|
||||
remarks="Created via cit"
|
||||
)
|
||||
flash("CIT record added successfully!", "success")
|
||||
return redirect(url_for('display_cit'))
|
||||
|
||||
return render_template('add_cit.html')
|
||||
return render_template('add_cit.html', current_date=date.today().isoformat())
|
||||
|
||||
# 3 delete CIT records by id
|
||||
@app.route('/cit/delete/<int:id>', methods=['POST'])
|
||||
@auth.login_required
|
||||
def delete_cit(id):
|
||||
cit = CITHandler()
|
||||
cit.delete_cit(id)
|
||||
@@ -230,6 +284,7 @@ def delete_cit(id):
|
||||
|
||||
# 4 update CIT records by id
|
||||
@app.route('/cit/update/<int:id>', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def update_cit(id):
|
||||
cit = CITHandler()
|
||||
record = cit.get_cit_by_id(id)
|
||||
@@ -254,6 +309,7 @@ def update_cit(id):
|
||||
|
||||
# 1.DISPLAY all ITAT records
|
||||
@app.route('/itat_records')
|
||||
@auth.login_required
|
||||
def display_itat():
|
||||
itat = ITATHandler()
|
||||
records = itat.get_all_itat()
|
||||
@@ -262,19 +318,35 @@ def display_itat():
|
||||
|
||||
# 2.Add new ITAT records
|
||||
@app.route('/itat/add', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def add_itat():
|
||||
if request.method == 'POST':
|
||||
itat = ITATHandler()
|
||||
# data = {k: request.form.get(k, 0) for k in request.form}
|
||||
itat.add_itat(request.form)
|
||||
mat = MatCreditHandler()
|
||||
data = {k: request.form.get(k, 0) for k in request.form}
|
||||
itat.add_itat(data)
|
||||
itat.close()
|
||||
|
||||
if 'documents' in request.files:
|
||||
doc = DocumentHandler()
|
||||
doc.Upload(request)
|
||||
|
||||
# AUTO SAVE MAT FROM ITR
|
||||
mat.save_from_itr(
|
||||
year=request.form["year"],
|
||||
mat_created=float(request.form.get("mat_credit_created", 0)),
|
||||
mat_utilized=float(request.form.get("mat_credit_utilized", 0)),
|
||||
remarks="Created via ITR"
|
||||
)
|
||||
|
||||
flash("ITAT record added successfully!", "success")
|
||||
return redirect(url_for('display_itat'))
|
||||
|
||||
return render_template('add_itat.html')
|
||||
return render_template('add_itat.html',current_date=date.today().isoformat())
|
||||
|
||||
# 3.Update ITAT records by id
|
||||
@app.route('/itat/update/<int:id>', methods=['GET', 'POST'])
|
||||
@auth.login_required
|
||||
def update_itat(id):
|
||||
itat = ITATHandler()
|
||||
record = itat.get_itat_by_id(id)
|
||||
@@ -294,6 +366,7 @@ def update_itat(id):
|
||||
|
||||
# 3.delete ITAT records by id
|
||||
@app.route('/itat/delete/<int:id>', methods=['POST'])
|
||||
@auth.login_required
|
||||
def delete_itat(id):
|
||||
itat = ITATHandler()
|
||||
itat.delete_itat_by_id(id)
|
||||
@@ -307,11 +380,13 @@ def delete_itat(id):
|
||||
## =======================================================
|
||||
# report page
|
||||
@app.route('/reports')
|
||||
@auth.login_required
|
||||
def reports():
|
||||
return render_template("reports.html")
|
||||
|
||||
# Itr report download by year
|
||||
@app.route('/itr_report', methods=['GET'])
|
||||
@auth.login_required
|
||||
def itr_report():
|
||||
yearGetter = YearGet()
|
||||
selected_year = request.args.get('year')
|
||||
@@ -338,6 +413,7 @@ def itr_report():
|
||||
|
||||
# Ao report download by year
|
||||
@app.route('/ao_report', methods=['GET'])
|
||||
@auth.login_required
|
||||
def ao_report():
|
||||
yearGetter = YearGet()
|
||||
selected_year = request.args.get('year')
|
||||
@@ -365,6 +441,7 @@ def ao_report():
|
||||
|
||||
# Cit report download by year
|
||||
@app.route('/cit_report', methods=['GET'])
|
||||
@auth.login_required
|
||||
def cit_report():
|
||||
selected_year = request.args.get('year')
|
||||
yearGetter = YearGet()
|
||||
@@ -393,6 +470,7 @@ def cit_report():
|
||||
|
||||
# Itat report download by year
|
||||
@app.route('/itat_report', methods=['GET'])
|
||||
@auth.login_required
|
||||
def itat_report():
|
||||
selected_year = request.args.get('year')
|
||||
yearGetter = YearGet()
|
||||
@@ -421,12 +499,36 @@ def itat_report():
|
||||
|
||||
# summary report
|
||||
@app.route('/summary_report', methods=['GET'])
|
||||
@auth.login_required
|
||||
def summary_report():
|
||||
docHandler = DocumentHandler()
|
||||
return docHandler.Summary_report(request=request)
|
||||
|
||||
@app.route('/summary/download', methods=['GET'])
|
||||
@auth.login_required
|
||||
def download_summary():
|
||||
year_raw = request.args.get('year')
|
||||
if not year_raw:
|
||||
return "Year parameter is required", 400
|
||||
|
||||
docHandler = DocumentHandler()
|
||||
# reuse your existing Summary_report method
|
||||
return docHandler.Summary_report(request=request)
|
||||
|
||||
|
||||
# check year in table existe or not by using ajax calling.
|
||||
# @app.route('/check_year', methods=['POST'])
|
||||
# @auth.login_required
|
||||
# def check_year():
|
||||
# data = request.get_json()
|
||||
# table_name = data.get("table")
|
||||
# year = data.get("year")
|
||||
|
||||
# check_year_obj = YearGet()
|
||||
# result = check_year_obj.CheckYearExists(table_name, year)
|
||||
# check_year_obj.close()
|
||||
# return result
|
||||
|
||||
# new new -- check year in table existe or not by using ajax calling.
|
||||
@app.route('/check_year', methods=['POST'])
|
||||
def check_year():
|
||||
table_name = request.json.get("table")
|
||||
@@ -444,16 +546,15 @@ def check_year():
|
||||
|
||||
return {"exists": result > 0}
|
||||
|
||||
# new new
|
||||
|
||||
|
||||
# Mat credit from
|
||||
@app.route("/mat_credit", methods=["GET"])
|
||||
@auth.login_required
|
||||
def mat_credit():
|
||||
|
||||
mat= MatCreditHandler()
|
||||
mat_rows, utilization_rows = mat.fetch_all()
|
||||
mat.close()
|
||||
mat = MatCreditHandler()
|
||||
try:
|
||||
mat_rows, utilization_rows = mat.fetch_all()
|
||||
finally:
|
||||
mat.close()
|
||||
|
||||
utilization_map = {}
|
||||
all_years = set()
|
||||
@@ -471,27 +572,40 @@ def mat_credit():
|
||||
added_years=sorted(all_years)
|
||||
)
|
||||
|
||||
# save mat credit row data
|
||||
# save mat credit row data
|
||||
@app.route("/save_mat_row", methods=["POST"])
|
||||
@auth.login_required
|
||||
def save_mat_row():
|
||||
mat= MatCreditHandler()
|
||||
mat = MatCreditHandler()
|
||||
try:
|
||||
mat.save_single(request.json)
|
||||
return jsonify({"message": "Row saved successfully"})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
finally:
|
||||
mat.close()
|
||||
|
||||
@app.route("/summary/preview")
|
||||
def summary_preview_route():
|
||||
handler = DocumentHandler()
|
||||
return handler.Summary_preview(request)
|
||||
|
||||
|
||||
# save mat credit bulk data
|
||||
@app.route("/save_mat_all", methods=["POST"])
|
||||
def save_mat_all():
|
||||
mat= MatCreditHandler()
|
||||
try:
|
||||
skipped = mat.save_bulk(request.json)
|
||||
return jsonify({"message": "Saved successfully", "skipped": skipped})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 500
|
||||
# @app.route("/save_mat_all", methods=["POST"])
|
||||
# @auth.login_required
|
||||
# def save_mat_all():
|
||||
# mat= MatCreditHandler()
|
||||
# try:
|
||||
# skipped = mat.save_bulk(request.json)
|
||||
# return jsonify({"message": "Saved successfully", "skipped": skipped})
|
||||
# except Exception as e:
|
||||
# return jsonify({"error": str(e)}), 500
|
||||
|
||||
|
||||
# run
|
||||
# run server
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5003, debug=True)
|
||||
app.run(
|
||||
host=os.getenv("FLASK_HOST"),
|
||||
port=int(os.getenv("FLASK_PORT")),
|
||||
debug=os.getenv("FLASK_DEBUG") == "true"
|
||||
)
|
||||
13
requirements.txt
Normal file
13
requirements.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Flask==3.0.1
|
||||
python-dotenv==1.0.1
|
||||
pandas==2.2.0
|
||||
Werkzeug==3.0.1
|
||||
|
||||
mysql-connector-python==8.3.0
|
||||
|
||||
Flask-HTTPAuth==4.8.0
|
||||
|
||||
openpyxl==3.1.2
|
||||
xlrd==2.0.1
|
||||
|
||||
gunicorn==21.2.0
|
||||
@@ -1,297 +0,0 @@
|
||||
/* ================= GLOBAL ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f0f4ff;
|
||||
/* very light blue background */
|
||||
display: flex;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff;
|
||||
/* primary blue */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: #ffffff;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
color: #007bff;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #cce5ff;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f0f8ff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #007bff;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #cce5ff;
|
||||
color: #004085;
|
||||
}
|
||||
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #a2cdfa;
|
||||
}
|
||||
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
width: calc(100% - 260px);
|
||||
padding: 30px;
|
||||
margin-top: 80px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* ================= BACK BUTTON ================= */
|
||||
.back-btn {
|
||||
background: #007bff;
|
||||
padding: 10px 16px;
|
||||
color: white;
|
||||
display: inline-block;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 20px;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
|
||||
/* ================= FORM ================= */
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
form input,
|
||||
form select {
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
margin-top: 5px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
background-color: #f8f9ff;
|
||||
/* subtle input background */
|
||||
outline: none;
|
||||
|
||||
}
|
||||
|
||||
|
||||
input:focus,
|
||||
select:focus {
|
||||
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
|
||||
/* blue glow on focus */
|
||||
}
|
||||
|
||||
.auto {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #ccd1d9;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
background-color: #d5edd7;
|
||||
transition: all 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
|
||||
/* ================= SUBMIT BUTTON (GREEN) ================= */
|
||||
button {
|
||||
width: 60%;
|
||||
margin-top: 20px;
|
||||
margin-left: 20%;
|
||||
padding: 12px 20px;
|
||||
background-color: #28a745;
|
||||
/* Bootstrap green */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #218838;
|
||||
/* Darker green on hover */
|
||||
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #1e7e34;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
|
||||
/* ================= TABLE ================= */
|
||||
.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: #007bff;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.action-cell form {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* Full width rows (span 2 columns) */
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group.full-width {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
/* Special case: two inputs inside one form-group */
|
||||
.form-group.inline-2 {
|
||||
flex-direction: row;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.form-group.inline-2>div {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f0f4ff;
|
||||
/* very light blue background */
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 90%;
|
||||
margin: 20px 20px 20px 20px;
|
||||
/* top margin to clear navbar */
|
||||
background: white;
|
||||
padding: 10%;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.no-record {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin-top: 20px;
|
||||
color: #555;
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
|
||||
/* ================= FORM ================= */
|
||||
form label {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
/* dark blue text */
|
||||
}
|
||||
|
||||
form input,
|
||||
form select {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-top: 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
form input:focus,
|
||||
form select:focus {
|
||||
border-color: #0056b3;
|
||||
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
|
||||
}
|
||||
|
||||
.auto {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #ccd1d9;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
background-color: #d5edd7;
|
||||
transition: all 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
/* ================= SUBMIT BUTTON (GREEN) ================= */
|
||||
button {
|
||||
width: 60%;
|
||||
margin-top: 20px;
|
||||
margin-left: 20%;
|
||||
padding: 12px 20px;
|
||||
background-color: #28a745;
|
||||
/* Bootstrap green */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #218838;
|
||||
/* Darker green on hover */
|
||||
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #1e7e34;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
/* ================= TABLE (if used in this page) ================= */
|
||||
.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: #007bff;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Full width rows (span 2 columns) */
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group.full-width {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
/* Special case: two inputs inside one form-group */
|
||||
.form-group.inline-2 {
|
||||
flex-direction: row;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.form-group.inline-2>div {
|
||||
flex: 1;
|
||||
}
|
||||
@@ -1,214 +0,0 @@
|
||||
/* ================= GLOBAL ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f0f4ff;
|
||||
/* very light blue background */
|
||||
display: flex;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: #ffffff;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
color: #007bff;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #cce5ff;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f0f8ff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #007bff;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #cce5ff;
|
||||
color: #004085;
|
||||
}
|
||||
|
||||
/* ================= LOGOUT ================= */
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #a2cdfa;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
width: calc(100% - 260px);
|
||||
padding: 30px;
|
||||
margin-top: 80px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
width: 95%;
|
||||
max-width: 700px;
|
||||
margin: auto;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
|
||||
/* ================= FORM ================= */
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
form label {
|
||||
display: block;
|
||||
margin-bottom: 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
form input,
|
||||
form select {
|
||||
padding: 10px;
|
||||
width: 100%;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
background-color: #f8f9ff;
|
||||
outline: none;
|
||||
transition: border-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
input:focus,
|
||||
select:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
|
||||
}
|
||||
|
||||
/* ================= SUBMIT BUTTON (GREEN) ================= */
|
||||
button {
|
||||
width: 60%;
|
||||
margin-top: 20px;
|
||||
margin-left: 20%;
|
||||
padding: 12px 20px;
|
||||
background-color: #28a745;
|
||||
/* Bootstrap green */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #218838;
|
||||
/* Darker green on hover */
|
||||
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #1e7e34;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f0f4ff;
|
||||
/* very light blue background */
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 90%;
|
||||
margin: 20px 20px 20px 20px;
|
||||
/* top margin to clear navbar */
|
||||
background: white;
|
||||
padding: 10%;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.no-record {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin-top: 20px;
|
||||
color: #555;
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
|
||||
/* ================= FORM ================= */
|
||||
form label {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
color: #000000;
|
||||
/* dark blue text */
|
||||
}
|
||||
|
||||
form input,
|
||||
form select {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-top: 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
form input:focus,
|
||||
form select:focus {
|
||||
border-color: #0056b3;
|
||||
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
|
||||
}
|
||||
|
||||
.auto {
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #ccd1d9;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
background-color: #d5edd7;
|
||||
transition: all 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
/* ================= SUBMIT BUTTON (GREEN) ================= */
|
||||
button {
|
||||
width: 60%;
|
||||
margin-top: 20px;
|
||||
margin-left: 20%;
|
||||
padding: 12px 20px;
|
||||
background-color: #28a745;
|
||||
/* Bootstrap green */
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #218838;
|
||||
/* Darker green on hover */
|
||||
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
button:active {
|
||||
background-color: #1e7e34;
|
||||
}
|
||||
|
||||
button:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
/* ================= TABLE (if used in this page) ================= */
|
||||
.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: #007bff;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Full width rows (span 2 columns) */
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.form-group.full-width {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
/* Special case: two inputs inside one form-group */
|
||||
.form-group.inline-2 {
|
||||
flex-direction: row;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.form-group.inline-2>div {
|
||||
flex: 1;
|
||||
}
|
||||
151
static/css/add_model.css
Normal file
151
static/css/add_model.css
Normal file
@@ -0,0 +1,151 @@
|
||||
/* ================= PAGE WRAPPER ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
width: calc(100% - 260px);
|
||||
margin-top: 80px;
|
||||
padding: 20px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
background: #ffffff;
|
||||
padding: 25px;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: auto;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
/* ================= PAGE TITLE ================= */
|
||||
.container h2 {
|
||||
color: #007bff;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
/* ================= FORM ================= */
|
||||
form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* ================= FORM GROUP ================= */
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* ================= INPUTS ================= */
|
||||
form input,
|
||||
form select {
|
||||
padding: 10px 12px;
|
||||
width: 100%;
|
||||
margin-top: 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
background-color: #f8f9ff;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
form input:focus,
|
||||
form select:focus {
|
||||
outline: none;
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 6px rgba(0, 123, 255, 0.35);
|
||||
}
|
||||
|
||||
/* ================= AUTO FIELDS ================= */
|
||||
.auto {
|
||||
background-color: #d5edd7;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ================= INLINE 2 COLUMNS ================= */
|
||||
.form-group.inline-2 {
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.form-group.inline-2>div {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* ================= SUBMIT BUTTON ================= */
|
||||
button {
|
||||
width: 60%;
|
||||
margin: 25px auto 0;
|
||||
padding: 12px 20px;
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #218838;
|
||||
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
/* ================= MOBILE ================= */
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin-top: 70px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* STACK INPUTS */
|
||||
.form-group.inline-2 {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= SMALL MOBILE ================= */
|
||||
@media (max-width: 420px) {
|
||||
|
||||
form input,
|
||||
form select {
|
||||
font-size: 13px;
|
||||
padding: 9px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= LARGE SCREEN ================= */
|
||||
@media (min-width: 1200px) {
|
||||
|
||||
.container {
|
||||
max-width: 1300px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
/* ================= GLOBAL ================= */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background-color: #f4f7f9;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: white;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #d6d6d6;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.menu-items {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
transition: 0.2s;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #e9f3ff;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f4faff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #0056b3;
|
||||
border-bottom: 1px solid #e2eaff;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #e9f3ff;
|
||||
}
|
||||
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #006ae6;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
margin-top: 80px;
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
background: #fff;
|
||||
padding: 35px 40px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #2c3e50;
|
||||
margin-bottom: 25px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ================= FORM ELEMENTS ================= */
|
||||
label {
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
margin-top: 8px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.2);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
button {
|
||||
margin-top: 25px;
|
||||
padding: 12px 25px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0069d9;
|
||||
}
|
||||
|
||||
/* Optional: responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
select {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
/* ================= GLOBAL ================= */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background-color: #f4f7f9;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: white;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #d6d6d6;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.menu-items {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
transition: 0.2s;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #e9f3ff;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f4faff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #0056b3;
|
||||
border-bottom: 1px solid #e2eaff;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #e9f3ff;
|
||||
}
|
||||
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #006ae6;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
margin-top: 80px;
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
background: #fff;
|
||||
padding: 35px 40px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #2c3e50;
|
||||
margin-bottom: 25px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ================= FORM ELEMENTS ================= */
|
||||
label {
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
margin-top: 8px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.2);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
button {
|
||||
margin-top: 25px;
|
||||
padding: 12px 25px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0069d9;
|
||||
}
|
||||
|
||||
/* Optional: responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
select {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f4f7f6;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff; /* primary blue */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
width: auto;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: #ffffff;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
color: #007bff;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
/* ================= MENU BUTTONS ================= */
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #cce5ff;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f0f8ff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #cce5ff;
|
||||
color: #004085;
|
||||
}
|
||||
.no-record {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin-top: 20px;
|
||||
color: #555;
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
|
||||
/* ================= LOGOUT ================= */
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #a2cdfa;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
margin-top: 80px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 95%;
|
||||
margin: auto;
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
.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;
|
||||
position: absolute; /* Pins button to the right side */
|
||||
right: 0;
|
||||
|
||||
}
|
||||
|
||||
.btn-update {
|
||||
background-color: #007bff;
|
||||
}
|
||||
|
||||
.btn-delete {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
|
||||
/* ================= TABLE ================= */
|
||||
.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: #007bff;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.action-cell form {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* ================= BACK BUTTON ================= */
|
||||
.back-btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 18px;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
@@ -1,251 +0,0 @@
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f4f7f6;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff; /* primary blue */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
width: auto;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: #ffffff;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
color: #007bff;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
/* ================= MENU BUTTONS ================= */
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #cce5ff;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f0f8ff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #cce5ff;
|
||||
color: #004085;
|
||||
}
|
||||
.no-record {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin-top: 20px;
|
||||
color: #555;
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
|
||||
/* ================= LOGOUT ================= */
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #a2cdfa;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
.main {
|
||||
margin-left: 20px;
|
||||
padding: 8px;
|
||||
width: calc(100% - 50px);
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 95%;
|
||||
margin: auto;
|
||||
background: white;
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
.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;
|
||||
}
|
||||
|
||||
/* ================= TABLE ================= */
|
||||
.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: #007bff;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.action-cell form {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* ================= BACK BUTTON ================= */
|
||||
.back-btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 18px;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
@@ -1,254 +0,0 @@
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f4f7f6;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff; /* primary blue */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
width: auto;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: #ffffff;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
color: #007bff;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
/* ================= MENU BUTTONS ================= */
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #cce5ff;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f0f8ff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #cce5ff;
|
||||
color: #004085;
|
||||
}
|
||||
.no-record {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin-top: 20px;
|
||||
color: #555;
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
|
||||
/* ================= LOGOUT ================= */
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #a2cdfa;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
.main {
|
||||
margin-left: 20px;
|
||||
padding: 8px;
|
||||
width: calc(100% - 50px);
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 95%;
|
||||
margin: auto;
|
||||
background: white ;
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
.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;
|
||||
}
|
||||
|
||||
/* ================= TABLE ================= */
|
||||
.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: #007bff;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.action-cell form {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* ================= BACK BUTTON ================= */
|
||||
.back-btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 18px;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
@@ -1,251 +0,0 @@
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #f4f7f6;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff; /* primary blue */
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
width: auto;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: #ffffff;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e0e0e0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 0;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
color: #007bff;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
/* ================= MENU BUTTONS ================= */
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #cce5ff;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f0f8ff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #007bff;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #cce5ff;
|
||||
color: #004085;
|
||||
}
|
||||
.no-record {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin-top: 20px;
|
||||
color: #555;
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
|
||||
/* ================= LOGOUT ================= */
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #a2cdfa;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
margin-top: 80px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 95%;
|
||||
margin: auto;
|
||||
background: white;
|
||||
padding: 30px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
.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;
|
||||
}
|
||||
|
||||
/* ================= TABLE ================= */
|
||||
.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: #007bff;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.action-cell form {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
/* ================= BACK BUTTON ================= */
|
||||
.back-btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 18px;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
189
static/css/display_model.css
Normal file
189
static/css/display_model.css
Normal file
@@ -0,0 +1,189 @@
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
/* ================= BODY ================= */
|
||||
body {
|
||||
background-color: #f4f7f6;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
margin-top: 80px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
background: #ffffff;
|
||||
padding: 25px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* ================= HEADING ================= */
|
||||
.container h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
color: #003366;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
.btn {
|
||||
padding: 8px 14px;
|
||||
border-radius: 6px;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn-add {
|
||||
background-color: #28a745;
|
||||
}
|
||||
|
||||
.btn-update {
|
||||
background-color: #007bff;
|
||||
}
|
||||
|
||||
.btn-delete {
|
||||
background-color: #dc3545;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
/* ================= NO RECORD ================= */
|
||||
.no-record {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
color: #555;
|
||||
padding: 15px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
/* ================= TABLE ================= */
|
||||
.table-wrapper {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
min-width: 900px;
|
||||
/* allows horizontal scroll on mobile */
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 12px;
|
||||
border: 1px solid #dee2e6;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td:first-child,
|
||||
th:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #f0f8ff;
|
||||
}
|
||||
|
||||
/* ================= ACTION COLUMN ================= */
|
||||
.action-cell {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.action-cell form {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ================= TABLET ================= */
|
||||
@media (max-width: 992px) {
|
||||
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
table {
|
||||
min-width: 800px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= MOBILE ================= */
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.container {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: 13px;
|
||||
padding: 7px 12px;
|
||||
}
|
||||
|
||||
table {
|
||||
min-width: 700px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= SMALL MOBILE ================= */
|
||||
@media (max-width: 480px) {
|
||||
|
||||
.container h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.btn-add {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
margin-bottom: 15px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
table {
|
||||
min-width: 650px;
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,24 @@
|
||||
body {
|
||||
background-color: #f4f6f9;
|
||||
font-family: "Segoe UI", Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
/* prevent horizontal scroll for page */
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT FIX ================= */
|
||||
/* base.html usually gives sidebar width ~250px */
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
padding: 40px 30px;
|
||||
/* sidebar width */
|
||||
padding: 70px 30px 40px 30px;
|
||||
/* top padding for navbar */
|
||||
overflow-x: hidden;
|
||||
/* prevent horizontal scroll */
|
||||
transition: margin-left 0.3s ease;
|
||||
}
|
||||
|
||||
/* ================= CARD / CONTAINER ================= */
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 1100px;
|
||||
margin: 0 auto;
|
||||
@@ -19,6 +27,8 @@ body {
|
||||
padding: 35px 40px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.08);
|
||||
overflow-x: hidden;
|
||||
/* prevent horizontal scroll */
|
||||
}
|
||||
|
||||
/* ================= HEADING ================= */
|
||||
@@ -52,7 +62,6 @@ form select {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* APPLY BUTTON (GREEN) */
|
||||
form button {
|
||||
background-color: #28a745;
|
||||
color: #ffffff;
|
||||
@@ -62,19 +71,32 @@ form button {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
form button:hover {
|
||||
background-color: #218838;
|
||||
}
|
||||
|
||||
/* ================= TABLE RESPONSIVE ================= */
|
||||
.table-responsive {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
/* only table scrolls */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
/* smooth scroll on mobile */
|
||||
}
|
||||
|
||||
/* ================= TABLE ================= */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 14px;
|
||||
min-width: 700px;
|
||||
/* ensures horizontal scroll on small screens */
|
||||
}
|
||||
|
||||
/* Table Head */
|
||||
thead {
|
||||
background-color: #0d6efd;
|
||||
color: #ffffff;
|
||||
@@ -86,6 +108,7 @@ thead th {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Table Body */
|
||||
tbody td {
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
@@ -100,7 +123,7 @@ tbody tr:hover {
|
||||
background-color: #eef4ff;
|
||||
}
|
||||
|
||||
/* ================= ACTION LINKS ================= */
|
||||
/* Table action buttons */
|
||||
table a {
|
||||
text-decoration: none;
|
||||
color: #ffffff;
|
||||
@@ -108,9 +131,9 @@ table a {
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
display: inline-block;
|
||||
transition: background 0.3s ease;
|
||||
}
|
||||
|
||||
/* Download button */
|
||||
table a[href*="download"] {
|
||||
background-color: #17a2b8;
|
||||
}
|
||||
@@ -119,7 +142,6 @@ table a[href*="download"]:hover {
|
||||
background-color: #138496;
|
||||
}
|
||||
|
||||
/* View button */
|
||||
table a[href*="view"] {
|
||||
background-color: #20c997;
|
||||
}
|
||||
@@ -129,10 +151,12 @@ table a[href*="view"]:hover {
|
||||
}
|
||||
|
||||
/* ================= RESPONSIVE ================= */
|
||||
|
||||
/* Medium screens: tablets */
|
||||
@media (max-width: 992px) {
|
||||
.main {
|
||||
margin-left: 0;
|
||||
padding: 20px;
|
||||
padding: 50px 20px 20px 20px;
|
||||
}
|
||||
|
||||
form {
|
||||
@@ -144,4 +168,40 @@ table a[href*="view"]:hover {
|
||||
form button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* Small screens: mobile */
|
||||
@media (max-width: 576px) {
|
||||
.main {
|
||||
padding: 40px 15px 15px 15px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
table {
|
||||
font-size: 12px;
|
||||
min-width: 100%;
|
||||
/* table scrolls only */
|
||||
}
|
||||
|
||||
table a {
|
||||
padding: 5px 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
form label {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
form select,
|
||||
form button {
|
||||
font-size: 13px;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
/* RESET */
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@@ -11,13 +11,12 @@ body {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
/* NAVBAR */
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
@@ -26,18 +25,6 @@ body {
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
width: auto;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
@@ -46,7 +33,19 @@ body {
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
/* SIDEBAR */
|
||||
.nav-logo {
|
||||
height: 46px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
/* hidden on desktop */
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: #ffffff;
|
||||
@@ -58,15 +57,10 @@ body {
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #e5d1be;
|
||||
transition: 0.3s;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
color: #007bff;
|
||||
text-align: center;
|
||||
@@ -88,6 +82,7 @@ body {
|
||||
background: #88ccfa;
|
||||
}
|
||||
|
||||
/* Submenu */
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #ffffff;
|
||||
@@ -104,19 +99,16 @@ body {
|
||||
|
||||
.submenu a:hover {
|
||||
background: #b3dbf7;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
/* Logout */
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
padding: 12px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
@@ -128,18 +120,12 @@ body {
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* MAIN CONTENT */
|
||||
/* ================= MAIN ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
margin-left: 250px;
|
||||
margin-top: 60px;
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
margin-top: 80px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.main.collapsed {
|
||||
margin-left: 20px;
|
||||
width: calc(100% - 40px);
|
||||
width: calc(100% - 250px);
|
||||
}
|
||||
|
||||
/* Container */
|
||||
@@ -147,19 +133,87 @@ body {
|
||||
background: white;
|
||||
padding: 40px;
|
||||
border-radius: 12px;
|
||||
max-width: 800px;
|
||||
max-width: 900px;
|
||||
margin: auto;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.07);
|
||||
}
|
||||
|
||||
.header {
|
||||
font-size: 32px;
|
||||
color: #2c3e50;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
font-weight: 600;
|
||||
/* ================= TABLET ================= */
|
||||
@media (max-width: 992px) {
|
||||
.nav-left h3 {
|
||||
font-size: 16px;
|
||||
max-width: 200px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
/* sidebar still visible */
|
||||
.sidebar {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-left: 220px;
|
||||
width: calc(100% - 220px);
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
/* ================= MOBILE ================= */
|
||||
@media (max-width: 768px) {
|
||||
|
||||
body {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Show toggle only on mobile */
|
||||
.toggle-btn {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-left h3 {
|
||||
font-size: 14px;
|
||||
max-width: 160px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
/* Sidebar as drawer */
|
||||
.sidebar {
|
||||
left: -100%;
|
||||
width: 85%;
|
||||
max-width: 280px;
|
||||
z-index: 2000;
|
||||
box-shadow: 4px 0 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.sidebar.show {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
/* Main content full width */
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
margin-top: 70px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= VERY SMALL PHONES ================= */
|
||||
@media (max-width: 480px) {
|
||||
.nav-left h3 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
/* ================= GLOBAL ================= */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background-color: #f4f7f9;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: white;
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #d6d6d6;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.menu-items {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
transition: 0.2s;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #e9f3ff;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f4faff;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #0056b3;
|
||||
border-bottom: 1px solid #e2eaff;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #e9f3ff;
|
||||
}
|
||||
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #006ae6;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
margin-top: 80px;
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
background: #fff;
|
||||
padding: 35px 40px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #2c3e50;
|
||||
margin-bottom: 25px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ================= FORM ELEMENTS ================= */
|
||||
label {
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
margin-top: 8px;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.2);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
button {
|
||||
margin-top: 25px;
|
||||
padding: 12px 25px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0069d9;
|
||||
}
|
||||
|
||||
/* Optional: responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
select {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
169
static/css/login.css
Normal file
169
static/css/login.css
Normal file
@@ -0,0 +1,169 @@
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ================= BODY ================= */
|
||||
body {
|
||||
font-family: "Segoe UI", Arial, sans-serif;
|
||||
background: #eef2f6;
|
||||
min-height: 100vh;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
/* ================= LOGIN CARD ================= */
|
||||
.login-container {
|
||||
background: #ffffff;
|
||||
width: 100%;
|
||||
max-width: 420px;
|
||||
padding: 28px;
|
||||
|
||||
border-radius: 14px;
|
||||
text-align: center;
|
||||
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* ================= MAIN HEADING ================= */
|
||||
.title {
|
||||
color: #007bff;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
|
||||
white-space: nowrap;
|
||||
/* keep single line */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
/* ================= SUB HEADING ================= */
|
||||
.sub-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #444;
|
||||
|
||||
white-space: nowrap;
|
||||
/* keep single line */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
/* ================= LOGIN TEXT ================= */
|
||||
.subtitle {
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
margin-bottom: 22px;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/* ================= FLASH MESSAGE ================= */
|
||||
.flash {
|
||||
color: #d9534f;
|
||||
font-size: 14px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/* ================= INPUTS ================= */
|
||||
input[type="text"],
|
||||
input[type="password"] {
|
||||
width: 100%;
|
||||
padding: 12px 14px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
font-size: 15px;
|
||||
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input:focus {
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
/* ================= BUTTON ================= */
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
|
||||
background: #007bff;
|
||||
color: #ffffff;
|
||||
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background: #0056b3;
|
||||
}
|
||||
|
||||
/* ================= MOBILE DEVICES ================= */
|
||||
@media (max-width: 480px) {
|
||||
|
||||
.login-container {
|
||||
padding: 22px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
input {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= TABLETS ================= */
|
||||
@media (min-width: 481px) and (max-width: 768px) {
|
||||
|
||||
.title {
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= LARGE SCREENS ================= */
|
||||
@media (min-width: 1200px) {
|
||||
|
||||
.login-container {
|
||||
max-width: 460px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
/* ===== CONTAINER ===== */
|
||||
.container {
|
||||
/* =========================
|
||||
CONTAINER
|
||||
========================= */
|
||||
.mat-container {
|
||||
max-width: 1200px;
|
||||
margin: 30px auto;
|
||||
padding: 25px;
|
||||
@@ -8,41 +10,94 @@
|
||||
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* ===== TABLE ===== */
|
||||
.page-title {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
YEAR CONTROLS
|
||||
========================= */
|
||||
.year-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.year-controls select {
|
||||
padding: 8px 10px;
|
||||
font-size: 14px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #ced4da;
|
||||
}
|
||||
|
||||
.year-controls button {
|
||||
padding: 8px 14px;
|
||||
font-size: 14px;
|
||||
border-radius: 6px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background-color: #0d6efd;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.year-controls button:hover {
|
||||
background-color: #0b5ed7;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
TABLE WRAPPER
|
||||
========================= */
|
||||
.table-wrapper {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
TABLE
|
||||
========================= */
|
||||
#matTable {
|
||||
width: 100%;
|
||||
min-width: 900px;
|
||||
border-collapse: collapse;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ===== HEADER ===== */
|
||||
/* =========================
|
||||
HEADER
|
||||
========================= */
|
||||
#matTable thead th {
|
||||
background: linear-gradient(135deg, #0d6efd, #0a58ca);
|
||||
color: #ffffff;
|
||||
padding: 12px 8px;
|
||||
border: 1px solid #0a58ca;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ===== BODY CELLS ===== */
|
||||
/* =========================
|
||||
BODY CELLS
|
||||
========================= */
|
||||
#matTable tbody td {
|
||||
padding: 8px;
|
||||
border: 1px solid #dcdcdc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
/* ===== FY COLUMN ===== */
|
||||
#matTable tbody td:first-child {
|
||||
font-weight: 600;
|
||||
background-color: #f5f8ff;
|
||||
}
|
||||
|
||||
/* ===== INPUT FIELDS ===== */
|
||||
/* =========================
|
||||
INPUTS
|
||||
========================= */
|
||||
#matTable input {
|
||||
width: 100%;
|
||||
padding: 6px 6px;
|
||||
padding: 6px;
|
||||
border: 1px solid #cfd8dc;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
@@ -50,19 +105,15 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* TEXT INPUT (Unutilized) */
|
||||
#matTable input[type="text"] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* INPUT FOCUS */
|
||||
#matTable input:focus {
|
||||
border-color: #0d6efd;
|
||||
box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.15);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* ===== ACTION BUTTON ===== */
|
||||
/* =========================
|
||||
BUTTONS
|
||||
========================= */
|
||||
#matTable button {
|
||||
background-color: #198754;
|
||||
border: none;
|
||||
@@ -71,76 +122,88 @@
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
#matTable button:hover {
|
||||
background-color: #157347;
|
||||
}
|
||||
|
||||
/* ===== SAVE ALL BUTTON ===== */
|
||||
button[onclick="saveAll()"] {
|
||||
display: block;
|
||||
width: 300px;
|
||||
margin: 25px auto 0;
|
||||
background-color: #28a745;
|
||||
.add-row-btn {
|
||||
background-color: #0d6efd;
|
||||
color: #fff;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
border: none;
|
||||
padding: 8px 18px;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button[onclick="saveAll()"]:hover {
|
||||
background-color: #218838;
|
||||
.add-row-btn:hover {
|
||||
background-color: #0b5ed7;
|
||||
}
|
||||
|
||||
/* ===== ROW HOVER ===== */
|
||||
/* =========================
|
||||
ROW STATES
|
||||
========================= */
|
||||
#matTable tbody tr:hover {
|
||||
background-color: #f1f6ff;
|
||||
}
|
||||
|
||||
/* ===== ERROR HIGHLIGHT ===== */
|
||||
.input-error {
|
||||
border-color: #dc3545 !important;
|
||||
background-color: #fff5f5;
|
||||
}
|
||||
|
||||
/* ===== SUCCESS HIGHLIGHT ===== */
|
||||
.row-saved {
|
||||
background-color: #e9f7ef !important;
|
||||
}
|
||||
|
||||
/* ===== RESPONSIVE ===== */
|
||||
/* =========================
|
||||
ACTION FOOTER
|
||||
========================= */
|
||||
.action-footer {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
/* =========================
|
||||
MOBILE ONLY FIXES
|
||||
(DOES NOT AFFECT DESKTOP)
|
||||
========================= */
|
||||
@media (max-width: 768px) {
|
||||
|
||||
.mat-container {
|
||||
margin: 10px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
/* YEAR CONTROLS STACKED */
|
||||
.year-controls {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.year-controls select,
|
||||
.year-controls button {
|
||||
width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* TABLE */
|
||||
#matTable {
|
||||
font-size: 12px;
|
||||
min-width: 800px;
|
||||
}
|
||||
|
||||
#matTable input {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#matTable thead {
|
||||
display: none;
|
||||
#matTable button {
|
||||
font-size: 12px;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
#matTable tbody tr {
|
||||
display: block;
|
||||
margin-bottom: 15px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#matTable tbody td {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 8px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#matTable tbody td::before {
|
||||
content: attr(data-label);
|
||||
font-weight: 600;
|
||||
color: #0d6efd;
|
||||
/* ADD ROW BUTTON FULL WIDTH */
|
||||
.add-row-btn {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
@@ -1,76 +1,162 @@
|
||||
/* ================= GLOBAL ================= */
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
}
|
||||
|
||||
/* ================= BODY ================= */
|
||||
body {
|
||||
background: #f4f7f6;
|
||||
display: flex;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background-color: #f4f7f9;
|
||||
overflow: hidden;
|
||||
/* ❌ no scroll desktop/laptop */
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
/* ================= MAIN WRAPPER ================= */
|
||||
.main {
|
||||
margin-left: 20px;
|
||||
padding: 8px;
|
||||
width: calc(100% - 50px);
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
transition: 0.3s;
|
||||
margin-left: 260px;
|
||||
margin-top: 80px;
|
||||
width: calc(100% - 260px);
|
||||
height: calc(100vh - 80px);
|
||||
padding: 0 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
max-width: 900px;
|
||||
width: 100%;
|
||||
background: #ffffff;
|
||||
padding: 45px 55px;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.12);
|
||||
|
||||
/* ⬇️ MOVE UP & LEFT */
|
||||
transform: translate(-40px, -30px);
|
||||
}
|
||||
|
||||
h2 {
|
||||
/* ================= HEADING ================= */
|
||||
.container h2 {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #1f2d3d;
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
/* ================= REPORT LIST ================= */
|
||||
ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
ul li {
|
||||
margin: 14px 0;
|
||||
list-style: none;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: 18px;
|
||||
}
|
||||
|
||||
/* ================= REPORT BUTTONS ================= */
|
||||
ul li a {
|
||||
color: #007bff;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
transition: 0.2s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #f1f7ff, #e9f2ff);
|
||||
border-radius: 12px;
|
||||
color: #0056ff;
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid #e1ecff;
|
||||
}
|
||||
|
||||
ul li a:hover {
|
||||
color: #0056b3;
|
||||
text-decoration: underline;
|
||||
background: linear-gradient(135deg, #e3efff, #dbe9ff);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 8px 18px rgba(0, 86, 255, 0.15);
|
||||
}
|
||||
|
||||
/* ================= LAPTOP VIEW ================= */
|
||||
@media (max-width: 1400px) and (min-width: 992px) {
|
||||
|
||||
.container {
|
||||
max-width: 820px;
|
||||
padding: 40px 45px;
|
||||
transform: translate(-30px, -20px);
|
||||
/* ⬅️ softer move */
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
ul li a {
|
||||
font-size: 16px;
|
||||
padding: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= TABLET ================= */
|
||||
@media (max-width: 992px) {
|
||||
|
||||
body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* ================= RESPONSIVE ================= */
|
||||
@media (max-width: 768px) {
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
height: auto;
|
||||
padding: 40px 25px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.container {
|
||||
transform: none;
|
||||
/* ❌ reset move */
|
||||
padding: 40px 32px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= MOBILE ================= */
|
||||
@media (max-width: 768px) {
|
||||
|
||||
body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-top: 70px;
|
||||
height: auto;
|
||||
padding: 25px 15px;
|
||||
}
|
||||
|
||||
.container {
|
||||
transform: none;
|
||||
/* ❌ reset move */
|
||||
padding: 28px 22px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
ul li a {
|
||||
font-size: 15px;
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= SMALL MOBILE ================= */
|
||||
@media (max-width: 480px) {
|
||||
|
||||
.container {
|
||||
padding: 22px 18px;
|
||||
}
|
||||
|
||||
ul li a {
|
||||
font-size: 14px;
|
||||
padding: 14px;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,20 @@
|
||||
/* ================= GLOBAL ================= */
|
||||
/* ================= RESET ================= */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* ================= BODY ================= */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background-color: #f4f7f9;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
/* no scroll desktop */
|
||||
}
|
||||
|
||||
/* ================= LINKS ================= */
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
color: #007bff;
|
||||
@@ -36,7 +44,7 @@ a {
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
height: 70px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
@@ -54,7 +62,6 @@ a {
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #d6d6d6;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -68,17 +75,15 @@ a {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
font-size: 16px;
|
||||
color: #007bff;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
transition: 0.2s;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
@@ -91,117 +96,142 @@ a {
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
display: block;
|
||||
color: #0056b3;
|
||||
border-bottom: 1px solid #e2eaff;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #e9f3ff;
|
||||
}
|
||||
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #006ae6;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
margin-top: 80px;
|
||||
margin-left: 250px;
|
||||
margin-top: 60px;
|
||||
width: calc(100% - 250px);
|
||||
height: calc(100vh - 60px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* ✅ vertical center */
|
||||
justify-content: center;
|
||||
/* ✅ horizontal center */
|
||||
padding: 30px;
|
||||
width: calc(100% - 260px);
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
max-width: 600px;
|
||||
margin: auto;
|
||||
background: #fff;
|
||||
padding: 35px 40px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
width: 100%;
|
||||
max-width: 680px;
|
||||
/* 🔥 laptop & desktop size */
|
||||
background: #ffffff;
|
||||
padding: 45px 55px;
|
||||
border-radius: 14px;
|
||||
box-shadow: 0 14px 40px rgba(0, 0, 0, 0.12);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #2c3e50;
|
||||
/* ================= HEADING ================= */
|
||||
.container h2 {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #1f2d3d;
|
||||
margin-bottom: 25px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ================= FORM ================= */
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* ================= FORM ELEMENTS ================= */
|
||||
label {
|
||||
font-weight: 600;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 6px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: 10px 14px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
width: 100%;
|
||||
max-width: 250px;
|
||||
margin-top: 8px;
|
||||
max-width: 320px;
|
||||
padding: 12px 14px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #ccc;
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.2);
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.18);
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
/* ================= BUTTON ================= */
|
||||
button {
|
||||
margin-top: 25px;
|
||||
padding: 12px 25px;
|
||||
margin-top: 22px;
|
||||
width: 100%;
|
||||
max-width: 320px;
|
||||
padding: 13px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0069d9;
|
||||
}
|
||||
|
||||
/* Optional: responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
/* ================= LAPTOP ================= */
|
||||
@media (max-width: 1400px) {
|
||||
.container {
|
||||
max-width: 620px;
|
||||
padding: 40px 48px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= TABLET ================= */
|
||||
@media (max-width: 992px) {
|
||||
body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
height: auto;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
|
||||
select {
|
||||
max-width: 100%;
|
||||
.container {
|
||||
max-width: 560px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================= MOBILE ================= */
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-top: 70px;
|
||||
height: auto;
|
||||
padding: 20px 15px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 100%;
|
||||
padding: 28px 22px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
select,
|
||||
button {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -1,72 +1,278 @@
|
||||
/* ================= FORM ELEMENTS ================= */
|
||||
/* ================= PAGE WRAPPER ================= */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
width: calc(100% - 260px);
|
||||
margin-top: 80px;
|
||||
padding: 20px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* ================= CONTAINER ================= */
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
margin: 0;
|
||||
padding: 25px 30px;
|
||||
background: #ffffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 8px 22px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* ================= PAGE TITLE ================= */
|
||||
.container h2 {
|
||||
text-align: center;
|
||||
color: #007bff;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* ================= FORM ================= */
|
||||
form {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
form label {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
margin-top: 6px;
|
||||
font-size: 15px;
|
||||
background-color: white;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
/* ================= INPUTS ================= */
|
||||
form input,
|
||||
form select {
|
||||
width: 100%;
|
||||
padding: 10px 12px;
|
||||
margin-top: 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
background-color: #f8f9ff;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
|
||||
outline: none;
|
||||
form input:focus,
|
||||
form select:focus {
|
||||
outline: none;
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 6px rgba(0, 123, 255, 0.35);
|
||||
}
|
||||
|
||||
/* ================= AUTO FIELDS ================= */
|
||||
.auto {
|
||||
background-color: #d5edd7;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ================= FORM GROUP ================= */
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Inline two columns */
|
||||
.form-group.inline-2 {
|
||||
flex-direction: row;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.form-group.inline-2 > div {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
button {
|
||||
margin-top: 20px;
|
||||
padding: 10px 18px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
transition: 0.3s;
|
||||
display: block;
|
||||
width: 60%;
|
||||
margin: 25px auto 0;
|
||||
padding: 12px 20px;
|
||||
background-color: #28a745;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0069d9;
|
||||
}
|
||||
|
||||
|
||||
.main {
|
||||
margin-left: 20px;
|
||||
padding: 8px;
|
||||
width: calc(100% - 50px);
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
transition: 0.3s;
|
||||
background-color: #218838;
|
||||
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.35);
|
||||
}
|
||||
|
||||
/* ================= BACK BUTTON ================= */
|
||||
.back-btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 18px;
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
transition: 0.3s;
|
||||
display: inline-block;
|
||||
margin-top: 20px;
|
||||
padding: 10px 18px;
|
||||
background-color: #007bff;
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background-color: #006ae6;
|
||||
background-color: #006ae6;
|
||||
}
|
||||
|
||||
/* ================= STICKY FILTER BAR ================= */
|
||||
.head {
|
||||
position: sticky;
|
||||
top: 60px;
|
||||
background: #fff;
|
||||
z-index: 1000;
|
||||
padding: 15px 0;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
/* ================= SELECT + DOWNLOAD ================= */
|
||||
.select-download-wrapper {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.select-download-wrapper select {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
margin-top: 6px;
|
||||
font-size: 15px;
|
||||
background-color: white;
|
||||
cursor: pointer;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
select:focus {
|
||||
border-color: #007bff;
|
||||
box-shadow: 0 0 5px rgba(0,123,255,0.5);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* ================= DOWNLOAD BUTTON ================= */
|
||||
#downloadBtn {
|
||||
display: none;
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
background-color: #28a745;
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
white-space: nowrap;
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
#downloadBtn:hover {
|
||||
background-color: #218838;
|
||||
}
|
||||
|
||||
/* ================= TABLE PREVIEW ================= */
|
||||
#previewContent {
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#previewContent table {
|
||||
width: 100%;
|
||||
min-width: 600px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
#previewContent th,
|
||||
#previewContent td {
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Sticky table header */
|
||||
#previewContent th {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
background-color: #007bff;
|
||||
color: #fff;
|
||||
z-index: 10;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
/* ================= MESSAGE ================= */
|
||||
.message {
|
||||
margin-top: 15px;
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* ================= RESPONSIVE ================= */
|
||||
@media (max-width: 992px) {
|
||||
.main {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.form-group.inline-2 {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.main {
|
||||
padding: 15px;
|
||||
margin-top: 70px;
|
||||
}
|
||||
|
||||
#previewContent table {
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
#previewContent th,
|
||||
#previewContent td {
|
||||
font-size: 13px;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
form input,
|
||||
form select {
|
||||
font-size: 13px;
|
||||
padding: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,202 +1,101 @@
|
||||
/* ================= GLOBAL ================= */
|
||||
/* ===== RESET ===== */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Segoe UI", sans-serif;
|
||||
font-family: "Segoe UI", Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* ===== BODY ===== */
|
||||
body {
|
||||
background: #f4f7f6;
|
||||
display: flex;
|
||||
background-color: #f4f7f6;
|
||||
overflow: hidden;
|
||||
/* NO SCROLL */
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
/* ================= NAVBAR ================= */
|
||||
.navbar {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
background-color: #007bff;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
z-index: 1000;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.nav-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
height: 80px;
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
font-size: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* ================= SIDEBAR ================= */
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
background: white; /* ← clean white sidebar */
|
||||
height: calc(100vh - 60px);
|
||||
position: fixed;
|
||||
top: 60px;
|
||||
left: 0;
|
||||
padding-top: 20px;
|
||||
overflow-y: auto;
|
||||
border-right: 1px solid #d6d6d6;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.sidebar.hide {
|
||||
left: -250px;
|
||||
}
|
||||
|
||||
.menu-items {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.menu-btn {
|
||||
padding: 14px 20px;
|
||||
font-size: 17px;
|
||||
color: #007bff; /* blue text */
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
transition: 0.2s;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.menu-btn:hover {
|
||||
background: #e9f3ff; /* light blue hover */
|
||||
}
|
||||
|
||||
.submenu {
|
||||
display: none;
|
||||
background: #f4faff; /* very light blue */
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
display: block;
|
||||
padding: 12px 35px;
|
||||
color: #0056b3;
|
||||
border-bottom: 1px solid #e2eaff;
|
||||
transition: 0.2s;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background: #e9f3ff;
|
||||
}
|
||||
|
||||
.sidebar-logout {
|
||||
margin-top: auto;
|
||||
padding: 10px 16px;
|
||||
background: #007bff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 6px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.sidebar-logout:hover {
|
||||
background: #006ae6;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
|
||||
/* ================= MAIN CONTENT ================= */
|
||||
/* ===== MAIN AREA (NAVBAR ALREADY EXISTS) ===== */
|
||||
.main {
|
||||
margin-left: 20px;
|
||||
padding: 8px;
|
||||
width: calc(100% - 50px);
|
||||
margin-top: 50px;
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
transition: 0.3s;
|
||||
margin-top: 70px;
|
||||
/* height of navbar */
|
||||
height: calc(100vh - 70px);
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
/* LEFT */
|
||||
align-items: flex-start;
|
||||
/* TOP */
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* ================= FORM CONTAINER ================= */
|
||||
/* ===== FORM CONTAINER ===== */
|
||||
.container {
|
||||
background: white;
|
||||
padding: 30px;
|
||||
width: 95%;
|
||||
margin: auto;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
width: 100%;
|
||||
max-width: 520px;
|
||||
background: #ffffff;
|
||||
padding: 28px 30px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
h2 {
|
||||
/* ===== HEADING ===== */
|
||||
.container h2 {
|
||||
text-align: center;
|
||||
color: #0d6efd;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
color: #007bff; /* blue heading */
|
||||
}
|
||||
|
||||
/* ===== FORM ELEMENTS ===== */
|
||||
form label {
|
||||
display: block;
|
||||
margin-top: 10px;
|
||||
font-weight: bold;
|
||||
margin-top: 14px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
form input,
|
||||
select {
|
||||
form select,
|
||||
form input[type="file"] {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
margin-top: 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #ccc;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* ================= BUTTONS ================= */
|
||||
/* ===== BUTTON ===== */
|
||||
button {
|
||||
margin-top: 20px;
|
||||
padding: 10px 18px;
|
||||
background-color: #007bff;
|
||||
width: 100%;
|
||||
margin-top: 22px;
|
||||
padding: 12px;
|
||||
background-color: #0d6efd;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
button:hover {
|
||||
background-color: #0069d9;
|
||||
background-color: #0b5ed7;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 18px;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
transition: 0.3s;
|
||||
}
|
||||
/* ===== MOBILE VIEW ===== */
|
||||
@media (max-width: 768px) {
|
||||
.main {
|
||||
margin-top: 60px;
|
||||
height: calc(100vh - 60px);
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.back-btn:hover {
|
||||
background: #006ae6;
|
||||
}
|
||||
.container {
|
||||
max-width: 100%;
|
||||
padding: 22px;
|
||||
}
|
||||
|
||||
.container h2 {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
function getValue(id) {
|
||||
var el = document.getElementsByName(id)[0];
|
||||
return el ? parseFloat(el.value) || 0 : 0;
|
||||
@@ -11,57 +10,129 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
}
|
||||
|
||||
window.calculate = function () {
|
||||
|
||||
// --- BASIC INPUTS ---
|
||||
var gross_total_income = getValue("gross_total_income");
|
||||
var disallowance_14a = getValue("disallowance_14a");
|
||||
var disallowance_37 = getValue("disallowance_37");
|
||||
|
||||
// -- total gross income ---
|
||||
var gross_total = gross_total_income + disallowance_37 + disallowance_14a
|
||||
console.log("gross_total income:: " + gross_total)
|
||||
// -- total gross income --
|
||||
var gross_total = gross_total_income + disallowance_37 + disallowance_14a;
|
||||
setValue("gti_as_per_ao", gross_total);
|
||||
|
||||
// --- DEDUCTIONS ---
|
||||
var d80_business = getValue("deduction_80ia_business");
|
||||
var d80_misc = getValue("deduction_80ia_misc");
|
||||
var d80_other = getValue("deduction_80ia_other");
|
||||
var d80_sec37 = getValue("deduction_sec37_disallowance");
|
||||
|
||||
var deduction_sec37 = d80_business + d80_misc + d80_other;
|
||||
setValue("deduction_sec37_disallowance", deduction_sec37);
|
||||
// -- TAX A CALCULATIONS --
|
||||
var per_a = getValue("per_a");
|
||||
var tax_a = getValue("tax_a");
|
||||
var per_surcharge_a = getValue("per_surcharge_a");
|
||||
var surcharge_a = getValue("surcharge_a");
|
||||
var per_cess_a = getValue("per_cess_a");
|
||||
var edu_cess_a = getValue("edu_cess_a");
|
||||
|
||||
// -- TAX b CALCULATIONS --
|
||||
|
||||
var tax_book_profit = getValue("tax_book_profit");
|
||||
console.log(tax_book_profit);
|
||||
|
||||
var per_surcharge_b = getValue("per_surcharge_b");
|
||||
var surcharge_b = getValue("surcharge_b");
|
||||
var per_cess_b = getValue("per_cess_b");
|
||||
var edu_cess_b = getValue("edu_cess_b");
|
||||
|
||||
var deduction = d80_business + d80_misc + d80_other + d80_sec37 - 1.35;
|
||||
|
||||
var deduction_80g = getValue("deduction_80g");
|
||||
|
||||
// --- NET TAXABLE INCOME ---
|
||||
var net_taxable_income = gross_total - deduction_sec37 - deduction_80g;
|
||||
var net_taxable_income = gross_total - deduction - deduction_80g;
|
||||
setValue("net_taxable_income", net_taxable_income);
|
||||
|
||||
// --- TAX 30% ---
|
||||
var tax30 = net_taxable_income * 0.30;
|
||||
setValue("tax_30_percent", tax30);
|
||||
// --- TAX (A)% AMOUNT ---
|
||||
var tax_a = net_taxable_income * (per_a / 100);
|
||||
setValue("tax_a", tax_a);
|
||||
|
||||
// --- SURCHARGE (A)% AMOUNT ---
|
||||
var surcharge_a = tax_a * (per_surcharge_a / 100);
|
||||
setValue("surcharge_a", surcharge_a);
|
||||
|
||||
// --- CESS (A)% AMOUNT ---
|
||||
var edu_cess_a = (surcharge_a + tax_a) * (per_cess_a / 100);
|
||||
setValue("edu_cess_a", edu_cess_a);
|
||||
|
||||
//SUM OF (A)%
|
||||
var sum_of_a = tax_a + surcharge_a + edu_cess_a;
|
||||
|
||||
setValue("sum_of_a", sum_of_a);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// --- SURCHARGE (B)% AMOUNT ---
|
||||
var surcharge_b = tax_book_profit * (per_surcharge_b / 100);
|
||||
setValue("surcharge_b", surcharge_b);
|
||||
|
||||
// --- CESS (B)% AMOUNT ---
|
||||
var edu_cess_b = (surcharge_b + tax_book_profit) * (per_cess_b / 100);
|
||||
setValue("edu_cess_b", edu_cess_b);
|
||||
|
||||
//SUM OF (B)%
|
||||
var sum_of_b = tax_book_profit + surcharge_b + edu_cess_b;
|
||||
|
||||
setValue("sum_of_b", sum_of_b);
|
||||
|
||||
// --- TAX PAYABLE (18.5%) ---
|
||||
var tax185 = getValue("tax_book_profit_18_5");
|
||||
|
||||
var tax_payable = (tax30 > tax185) ? tax30 : tax185;
|
||||
// --- Education Cess 3% ---
|
||||
var tax_payable = tax_a > tax_book_profit ? tax_a : tax_book_profit;
|
||||
setValue("tax_payable", tax_payable);
|
||||
|
||||
// --- SURCHARGE ---
|
||||
var percent = getValue("persentage");
|
||||
var surcharge = tax_payable * (percent / 100);
|
||||
setValue("surcharge_12", surcharge);
|
||||
setValue("surcharge", surcharge);
|
||||
|
||||
var edu_cess = (tax_payable + surcharge) * 0.03;
|
||||
setValue("edu_cess_3", edu_cess);
|
||||
// --- EDUCATION CESS ---
|
||||
var per_cess = getValue("persentage_cess");
|
||||
var edu_cess = (tax_payable + surcharge) * (per_cess / 100);
|
||||
setValue("edu_cess", edu_cess);
|
||||
|
||||
// --- total tax payable ---
|
||||
var total_tax_payable = tax_payable + surcharge + edu_cess;
|
||||
var total_tax_payable = sum_of_a > sum_of_b ? sum_of_a : sum_of_b;
|
||||
setValue("total_tax_payable", total_tax_payable);
|
||||
|
||||
// // --- mat_credit_created --- new
|
||||
// setValue("mat_credit_created", Math.max(tax185 - total_tax_payable, 0));
|
||||
// // --- mat credit_utilized --- new
|
||||
// setValue("mat_credit_utilized", Math.max(total_tax_payable - tax185, 0));
|
||||
|
||||
// --- MAT credit and utilized ---
|
||||
var a = sum_of_a;
|
||||
var b = sum_of_b;
|
||||
var result = 0;
|
||||
var zero = 0;
|
||||
if (b > a) {
|
||||
result = b - a;
|
||||
setValue("mat_credit_created", result);
|
||||
setValue("mat_credit_utilized", zero);
|
||||
}
|
||||
|
||||
if (a > b) {
|
||||
result = a - b;
|
||||
setValue("mat_credit_utilized", result);
|
||||
setValue("mat_credit_created", zero);
|
||||
}
|
||||
|
||||
// --- FINAL TAX ---
|
||||
var mat_credit = getValue("mat_credit");
|
||||
var mat_credit_uti = getValue("mat_credit_utilized");
|
||||
var interest_234c = getValue("interest_234c");
|
||||
|
||||
var total_tax = total_tax_payable + mat_credit + interest_234c;
|
||||
// var total_tax = total_tax_payable + mat_credit + interest_234c;
|
||||
var total_tax = total_tax_payable + interest_234c - mat_credit_uti;
|
||||
setValue("total_tax", total_tax);
|
||||
|
||||
// --- ASSESSMENT ---
|
||||
@@ -75,4 +146,4 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
var refund = total_tax - all_tax;
|
||||
setValue("refund", refund);
|
||||
};
|
||||
});
|
||||
});
|
||||
@@ -45,20 +45,53 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
var tax_payable = (tax30 > tax185) ? tax30 : tax185;
|
||||
setValue("tax_payable", tax_payable);
|
||||
|
||||
// // --- SURCHARGE ---
|
||||
// var percent = getValue("persentage");
|
||||
// var surcharge = tax_payable * (percent / 100);
|
||||
// setValue("surcharge_12", surcharge);
|
||||
|
||||
// // --- Education Cess 3% ---
|
||||
// var edu_cess = (tax_payable + surcharge) * 0.03;
|
||||
// setValue("edu_cess_3", edu_cess);
|
||||
|
||||
// --- SURCHARGE ---
|
||||
var percent = getValue("persentage");
|
||||
var surcharge = tax_payable * (percent / 100);
|
||||
setValue("surcharge_12", surcharge);
|
||||
setValue("surcharge", surcharge);
|
||||
|
||||
var edu_cess = (tax_payable + surcharge) * 0.03;
|
||||
setValue("edu_cess_3", edu_cess);
|
||||
// --- EDUCATION CESS ---
|
||||
var per_cess = getValue("persentage_cess");
|
||||
var edu_cess = (tax_payable + surcharge) * (per_cess / 100);
|
||||
setValue("edu_cess", edu_cess);
|
||||
|
||||
// --- total tax payable ---
|
||||
var total_tax_payable = tax_payable + surcharge + edu_cess;
|
||||
setValue("total_tax_payable", total_tax_payable);
|
||||
|
||||
|
||||
// --- mat credit_utilized ---
|
||||
var a = tax185
|
||||
var b = total_tax_payable
|
||||
var result = 0
|
||||
if (a > b) {
|
||||
result = a - b
|
||||
setValue("mat_credit_created", result);
|
||||
}
|
||||
else {
|
||||
setValue("mat_credit_created", result);
|
||||
}
|
||||
|
||||
if (b > a) {
|
||||
result = b - a
|
||||
setValue("mat_credit_utilized", result);
|
||||
}
|
||||
else {
|
||||
setValue("mat_credit_utilized", result);
|
||||
}
|
||||
|
||||
|
||||
// --- FINAL TAX ---
|
||||
var mat_credit = getValue("mat_credit");
|
||||
var mat_credit = getValue("mat_credit_utilized");
|
||||
var interest_234c = getValue("interest_234c");
|
||||
|
||||
var total_tax = total_tax_payable + mat_credit + interest_234c;
|
||||
|
||||
@@ -1,78 +1,134 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
|
||||
function getValue(id) {
|
||||
var el = document.getElementsByName(id)[0];
|
||||
function getValue(name) {
|
||||
var el = document.getElementsByName(name)[0];
|
||||
return el ? parseFloat(el.value) || 0 : 0;
|
||||
}
|
||||
|
||||
function setValue(id, val) {
|
||||
var el = document.getElementsByName(id)[0];
|
||||
function setValue(name, val) {
|
||||
var el = document.getElementsByName(name)[0];
|
||||
if (el) el.value = Number(val).toFixed(2);
|
||||
}
|
||||
|
||||
// ---- Track last edited field for Tax(A) ----
|
||||
let lastEditedTaxA = null;
|
||||
|
||||
document.getElementsByName("per_tax_a")[0].addEventListener("input", () => {
|
||||
lastEditedTaxA = "percentage";
|
||||
});
|
||||
|
||||
document.getElementsByName("tax_a_cal")[0].addEventListener("input", () => {
|
||||
lastEditedTaxA = "amount";
|
||||
});
|
||||
|
||||
window.calculate = function () {
|
||||
|
||||
// --- BASIC INPUTS ---
|
||||
// ---------------- BASIC INPUTS ----------------
|
||||
var gross_total_income = getValue("gross_total_income");
|
||||
var disallowance_14a = getValue("disallowance_14a");
|
||||
var disallowance_37 = getValue("disallowance_37");
|
||||
|
||||
// -- total gross income --
|
||||
var gross_total = gross_total_income + disallowance_37 + disallowance_14a
|
||||
console.log("gross_total income:: " + gross_total)
|
||||
var gross_total = gross_total_income + disallowance_14a + disallowance_37;
|
||||
setValue("gti_as_per_ao", gross_total);
|
||||
|
||||
// --- DEDUCTIONS ---
|
||||
// ---------------- DEDUCTIONS ----------------
|
||||
var d80_business = getValue("deduction_80ia_business");
|
||||
var d80_misc = getValue("deduction_80ia_misc");
|
||||
var d80_other = getValue("deduction_80ia_other");
|
||||
var d80_sec37 = getValue("deduction_sec37_disallowance");
|
||||
var deduction_80g = getValue("deduction_80g");
|
||||
|
||||
var deduction = d80_business + d80_misc + d80_other + d80_sec37 - 1.35;
|
||||
|
||||
var deduction_80g = getValue("deduction_80g");
|
||||
|
||||
// --- NET TAXABLE INCOME ---
|
||||
var net_taxable_income = gross_total - deduction - deduction_80g;
|
||||
setValue("net_taxable_income", net_taxable_income);
|
||||
|
||||
// --- TAX 30% ---
|
||||
var tax30 = net_taxable_income * 0.30;
|
||||
setValue("tax_30_percent", tax30);
|
||||
// ================= TAX (A) – TWO WAY =================
|
||||
var per_tax_a = getValue("per_tax_a");
|
||||
var tax_a_cal = getValue("tax_a_cal");
|
||||
|
||||
// --- TAX PAYABLE (18.5%) ---
|
||||
var tax185 = getValue("tax_book_profit_18_5");
|
||||
if (net_taxable_income > 0) {
|
||||
if (lastEditedTaxA === "percentage") {
|
||||
tax_a_cal = net_taxable_income * (per_tax_a / 100);
|
||||
setValue("tax_a_cal", tax_a_cal);
|
||||
}
|
||||
else if (lastEditedTaxA === "amount") {
|
||||
per_tax_a = (tax_a_cal / net_taxable_income) * 100;
|
||||
setValue("per_tax_a", per_tax_a);
|
||||
}
|
||||
}
|
||||
|
||||
var tax_payable = (tax30 > tax185) ? tax30 : tax185;
|
||||
var per_surcharge_a = getValue("per_surcharge_a");
|
||||
var surcharge_a_cal = tax_a_cal * (per_surcharge_a / 100);
|
||||
setValue("surcharge_a_cal", surcharge_a_cal);
|
||||
|
||||
var per_cess_a = getValue("per_cess_a");
|
||||
var edu_cess_a_cal = (tax_a_cal + surcharge_a_cal) * (per_cess_a / 100);
|
||||
setValue("edu_cess_a_cal", edu_cess_a_cal);
|
||||
|
||||
var sum_of_a = tax_a_cal + surcharge_a_cal + edu_cess_a_cal;
|
||||
setValue("sum_of_a", sum_of_a);
|
||||
|
||||
// ================= TAX (B) =================
|
||||
var tax_b_cal = getValue("tax_b_cal");
|
||||
|
||||
var per_surcharge_b = getValue("per_surcharge_b");
|
||||
var surcharge_b_cal = tax_b_cal * (per_surcharge_b / 100);
|
||||
setValue("surcharge_b_cal", surcharge_b_cal);
|
||||
|
||||
var per_cess_b = getValue("per_cess_b");
|
||||
var edu_cess_b_cal = (tax_b_cal + surcharge_b_cal) * (per_cess_b / 100);
|
||||
setValue("edu_cess_b_cal", edu_cess_b_cal);
|
||||
|
||||
var sum_of_b = tax_b_cal + surcharge_b_cal + edu_cess_b_cal;
|
||||
setValue("sum_of_b", sum_of_b);
|
||||
|
||||
// ================= TAX PAYABLE =================
|
||||
var tax_payable = (sum_of_a > sum_of_b) ? tax_a_cal : tax_b_cal;
|
||||
setValue("tax_payable", tax_payable);
|
||||
|
||||
// --- SURCHARGE ---
|
||||
var percent = getValue("persentage");
|
||||
var surcharge = tax_payable * (percent / 100);
|
||||
setValue("surcharge_12", surcharge);
|
||||
|
||||
var edu_cess = (tax_payable + surcharge) * 0.03;
|
||||
setValue("edu_cess_3", edu_cess);
|
||||
|
||||
// --- total tax payable ---
|
||||
var total_tax_payable = tax_payable + surcharge + edu_cess;
|
||||
var total_tax_payable = (sum_of_a > sum_of_b) ? sum_of_a : sum_of_b;
|
||||
setValue("total_tax_payable", total_tax_payable);
|
||||
|
||||
// --- FINAL TAX ---
|
||||
var mat_credit = getValue("mat_credit");
|
||||
// ================= MAT CREDIT =================
|
||||
var mat_created = 0;
|
||||
var mat_utilized = 0;
|
||||
|
||||
if (sum_of_a < sum_of_b) {
|
||||
mat_created = sum_of_b - sum_of_a;
|
||||
} else {
|
||||
mat_utilized = sum_of_a - sum_of_b;
|
||||
}
|
||||
|
||||
setValue("mat_credit_created", mat_created);
|
||||
setValue("mat_credit_utilized", mat_utilized);
|
||||
|
||||
// ================= Opening Balance and closing =================
|
||||
var opening_balance = getValue("opening_balance");
|
||||
var closing_balance = (opening_balance + mat_created) - mat_utilized
|
||||
setValue("closing_balance", closing_balance);
|
||||
|
||||
// ================= FINAL TAX =================
|
||||
var interest_234c = getValue("interest_234c");
|
||||
|
||||
var total_tax = total_tax_payable + mat_credit + interest_234c;
|
||||
var total_tax = total_tax_payable + interest_234c - mat_utilized;
|
||||
setValue("total_tax", total_tax);
|
||||
|
||||
// --- ASSESSMENT ---
|
||||
// ================= ADJUSTMENTS =================
|
||||
var adv_tax = getValue("advance_tax");
|
||||
var tds = getValue("tds");
|
||||
var tcs = getValue("tcs");
|
||||
var tax_on_regular_assessment = getValue("tax_on_assessment");
|
||||
var tax_on_assessment = getValue("tax_on_assessment");
|
||||
var interest_244a_per143 = getValue("interest_244a_per143");
|
||||
var refund_received = getValue("refund_received");
|
||||
|
||||
var all_tax = adv_tax + tds + tcs + tax_on_regular_assessment;
|
||||
var paid_tax = adv_tax + tds + tcs + tax_on_assessment;
|
||||
|
||||
var refund = total_tax - all_tax;
|
||||
var refund = total_tax - paid_tax;
|
||||
setValue("refund", refund);
|
||||
|
||||
var balance_receivable = (refund + interest_244a_per143) - refund_received
|
||||
setValue("balance_receivable", balance_receivable);
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
/* =====================================================
|
||||
GLOBAL STATE
|
||||
===================================================== */
|
||||
let addedYears = [];
|
||||
|
||||
/* =====================================================
|
||||
INITIALIZE YEARS FROM DATABASE HEADERS
|
||||
===================================================== */
|
||||
// INITIALIZE YEARS FROM DATABASE HEADERS
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const headers = document.querySelectorAll("#tableHeader th");
|
||||
|
||||
@@ -19,9 +14,8 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
});
|
||||
});
|
||||
|
||||
/* =====================================================
|
||||
ADD YEAR COLUMN (DYNAMIC)
|
||||
===================================================== */
|
||||
|
||||
// ADD YEAR COLUMN (DYNAMIC)
|
||||
function addYearColumn() {
|
||||
const yearSelect = document.getElementById("yearSelect");
|
||||
const year = yearSelect.value;
|
||||
@@ -54,9 +48,8 @@ function addYearColumn() {
|
||||
});
|
||||
}
|
||||
|
||||
/* =====================================================
|
||||
ADD NEW ROW
|
||||
===================================================== */
|
||||
|
||||
// ADD NEW ROW
|
||||
function addRow() {
|
||||
const tbody = document.querySelector("#matTable tbody");
|
||||
const tr = document.createElement("tr");
|
||||
@@ -79,9 +72,8 @@ function addRow() {
|
||||
tbody.appendChild(tr);
|
||||
}
|
||||
|
||||
/* =====================================================
|
||||
SAVE SINGLE ROW
|
||||
===================================================== */
|
||||
|
||||
// SAVE SINGLE ROW
|
||||
function saveRow(btn) {
|
||||
const tr = btn.closest("tr");
|
||||
const inputs = tr.querySelectorAll("input");
|
||||
@@ -128,9 +120,8 @@ function saveRow(btn) {
|
||||
});
|
||||
}
|
||||
|
||||
/* =====================================================
|
||||
SAVE ALL ROWS
|
||||
===================================================== */
|
||||
|
||||
// SAVE ALL ROWS
|
||||
function saveAll() {
|
||||
let rows = [];
|
||||
|
||||
|
||||
50
static/js/summary_preview.js
Normal file
50
static/js/summary_preview.js
Normal file
@@ -0,0 +1,50 @@
|
||||
document.getElementById("year").addEventListener("change", function () {
|
||||
const year = this.value;
|
||||
|
||||
const downloadBtn = document.getElementById("downloadBtn");
|
||||
const previewDiv = document.getElementById("preview");
|
||||
const contentDiv = document.getElementById("previewContent");
|
||||
|
||||
if (!year) {
|
||||
downloadBtn.style.display = "none";
|
||||
previewDiv.style.display = "none";
|
||||
contentDiv.innerHTML = "";
|
||||
return;
|
||||
}
|
||||
|
||||
downloadBtn.href = `/summary/download?year=${year}`;
|
||||
downloadBtn.style.display = "inline-block";
|
||||
|
||||
fetch(`/summary/preview?year=${year}`)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
let html = `<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Particular</th>
|
||||
<th>ITR</th>
|
||||
<th>AO</th>
|
||||
<th>CIT</th>
|
||||
<th>ITAT</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>`;
|
||||
|
||||
data.forEach(row => {
|
||||
html += `<tr>
|
||||
<td>${row.Particular}</td>
|
||||
<td>${row.ITR}</td>
|
||||
<td>${row.AO}</td>
|
||||
<td>${row.CIT}</td>
|
||||
<td>${row.ITAT}</td>
|
||||
</tr>`;
|
||||
});
|
||||
|
||||
html += `</tbody></table>`;
|
||||
contentDiv.innerHTML = html;
|
||||
|
||||
// Show preview
|
||||
previewDiv.style.display = "block";
|
||||
})
|
||||
.catch(err => console.error("Preview load error:", err));
|
||||
});
|
||||
@@ -1,61 +1,14 @@
|
||||
const sidebar = document.getElementById("sidebar");
|
||||
const main = document.getElementById("main");
|
||||
|
||||
// Track toggle manually
|
||||
let isSidebarOpen = true;
|
||||
|
||||
// Toggle sidebar normally
|
||||
function toggleSidebar() {
|
||||
isSidebarOpen = !isSidebarOpen;
|
||||
|
||||
sidebar.classList.toggle("hide", !isSidebarOpen);
|
||||
|
||||
// Add temporary transition only during toggle
|
||||
main.style.transition = "margin-left 0.3s ease";
|
||||
sidebar.style.transition = "left 0.3s ease";
|
||||
|
||||
// Adjust main margin
|
||||
main.style.marginLeft = isSidebarOpen ? "260px" : "20px";
|
||||
|
||||
// Remove transitions after animation to avoid disturbance
|
||||
setTimeout(() => {
|
||||
main.style.transition = "none";
|
||||
sidebar.style.transition = "none";
|
||||
}, 300);
|
||||
// Toggle ONLY on mobile
|
||||
if (window.innerWidth <= 768) {
|
||||
document.getElementById("sidebar").classList.toggle("show");
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle submenu — also force sidebar to open if it is hidden
|
||||
function toggleMenu(id) {
|
||||
const menu = document.getElementById(id);
|
||||
if (!menu) return;
|
||||
|
||||
// 👉 If sidebar is collapsed, open it automatically
|
||||
if (!isSidebarOpen) {
|
||||
isSidebarOpen = true;
|
||||
sidebar.classList.remove("hide");
|
||||
main.style.marginLeft = "260px";
|
||||
}
|
||||
|
||||
// Close all other submenus
|
||||
document.querySelectorAll(".submenu").forEach(sm => {
|
||||
if (sm !== menu) sm.style.display = "none";
|
||||
});
|
||||
|
||||
// Toggle the clicked submenu instantly
|
||||
menu.style.display = menu.style.display === "block" ? "none" : "block";
|
||||
menu.style.display = (menu.style.display === "block") ? "none" : "block";
|
||||
}
|
||||
|
||||
// Remove transition when clicking submenu links
|
||||
document.querySelectorAll(".submenu a").forEach(link => {
|
||||
link.addEventListener("click", () => {
|
||||
main.style.transition = "none";
|
||||
sidebar.style.transition = "none";
|
||||
});
|
||||
});
|
||||
|
||||
// Initialize sidebar as open when page loads
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
sidebar.classList.remove("hide");
|
||||
main.style.marginLeft = "260px";
|
||||
isSidebarOpen = true;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,36 +1,41 @@
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const yearDropdown = document.getElementById("year");
|
||||
const errorDiv = document.getElementById("yearError");
|
||||
const form = document.querySelector("form");
|
||||
|
||||
// Get the form dynamically
|
||||
const form = document.querySelector("form"); // get from id as table name
|
||||
|
||||
// Dynamic table name = form id
|
||||
const tableName = form.id.toLowerCase();
|
||||
const tableName = form.id.toLowerCase(); // ao, cit, etc.
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
const startYear = 1990;
|
||||
|
||||
// Fill Year dropdown
|
||||
/* ---------- Fill Year Dropdown ---------- */
|
||||
for (let y = currentYear; y >= startYear; y--) {
|
||||
let nextYear = y + 1;
|
||||
|
||||
let option = document.createElement("option");
|
||||
option.value = y;
|
||||
option.value = y; // IMPORTANT
|
||||
option.textContent = `AY ${y}-${nextYear}`;
|
||||
|
||||
yearDropdown.appendChild(option);
|
||||
}
|
||||
|
||||
// Validate selected year
|
||||
/* ---------- Validate on Change ---------- */
|
||||
yearDropdown.addEventListener("change", function () {
|
||||
let selectedYear = parseInt(this.value);
|
||||
const selectedYear = this.value;
|
||||
|
||||
// If empty → block submit
|
||||
if (!selectedYear) {
|
||||
errorDiv.style.display = "block";
|
||||
errorDiv.innerText = "Please select an Assessment Year.";
|
||||
form.onsubmit = () => false;
|
||||
return;
|
||||
}
|
||||
|
||||
fetch("/check_year", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
table: tableName, // dynamic table name
|
||||
table: tableName,
|
||||
year: selectedYear
|
||||
})
|
||||
})
|
||||
@@ -38,15 +43,27 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
.then(data => {
|
||||
if (data.exists) {
|
||||
errorDiv.style.display = "block";
|
||||
errorDiv.innerText = `Year ${selectedYear}-${selectedYear + 1} already exists!`;
|
||||
|
||||
// Block submission
|
||||
form.onsubmit = function () { return false; };
|
||||
errorDiv.innerText = `AY ${selectedYear}-${parseInt(selectedYear) + 1} already exists!`;
|
||||
form.onsubmit = () => false;
|
||||
} else {
|
||||
errorDiv.style.display = "none";
|
||||
form.onsubmit = null; // Allow submit
|
||||
errorDiv.innerText = "";
|
||||
form.onsubmit = null; // allow submit
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
errorDiv.style.display = "block";
|
||||
errorDiv.innerText = "Error validating year. Please try again.";
|
||||
form.onsubmit = () => false;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/* ---------- Final Safety Check on Submit ---------- */
|
||||
form.addEventListener("submit", function (e) {
|
||||
if (!yearDropdown.value) {
|
||||
e.preventDefault();
|
||||
errorDiv.style.display = "block";
|
||||
errorDiv.innerText = "Assessment Year is required.";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,29 +1,37 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Add New AO Record{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<!-- Child page CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_ao.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
<h2 style="text-align:center;">New Assessing Officer Form</h2>
|
||||
<form id="ao" method="POST">
|
||||
<h2 style="text-align:center;">New AO Form</h2>
|
||||
<form id="ao" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="stage" value="ao">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Year:</label>
|
||||
<select id="year" name="year" required></select>
|
||||
<label>Assessment Year:</label>
|
||||
<select id="year" name="year" required>
|
||||
<option value="" disabled selected>
|
||||
-- Please select Assessment Year --
|
||||
</option>
|
||||
</select>
|
||||
<div id="yearError" style="color:red; display:none; margin-bottom:10px;"></div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Record Created Date:</label>
|
||||
<input type="date" name="created_at" value="{{ current_date }}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 14A:</label>
|
||||
<input type="number" name="disallowance_14a" step="any" value="0.00" oninput="calculate()" required>
|
||||
@@ -33,36 +41,42 @@
|
||||
<input type="number" name="disallowance_37" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>GTI as per AO</label>
|
||||
<input type="number" name="gti_as_per_ao" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction 80IA Business Income:</label>
|
||||
<label>Less :Deduction 80IA Business Income:</label>
|
||||
<input type="number" name="deduction_80ia_business" step="any" value="0.00" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Deduction 80IA Misc:</label>
|
||||
<label>Less :Deduction 80IA Misc:</label>
|
||||
<input type="number" name="deduction_80ia_misc" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less : Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Deduction Sec 37 Disallowance:</label>
|
||||
<label>Less :Deduction Sec 37 Disallowance:</label>
|
||||
<input type="number" name="deduction_sec37_disallowance" step="any" value="0.00" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less: Deduction 80G: </label>
|
||||
<input type="number" name="deduction_80g" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Net Taxable Income:</label>
|
||||
<input type="number" name="net_taxable_income" class="auto" step="any" value="0.00" readonly>
|
||||
@@ -71,35 +85,76 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax @ 30% (A):</label>
|
||||
<input type="number" name="tax_30_percent" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Enter Percentage(%) calculate: Tax(A):</label>
|
||||
<input type="number" name="per_tax_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @(A):</label>
|
||||
<input type="number" name="tax_a_cal" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(B):</label>
|
||||
<input type="number" name="per_tax_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @ 18.5% on Book Profit (B):</label>
|
||||
<input type="number" name="tax_book_profit_18_5" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage (%) Surcharge:</label>
|
||||
<input type="number" name="persentage" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge:</label>
|
||||
<input type="number" name="surcharge_12" class="auto" value="0.00" readonly>
|
||||
<input type="number" name="tax_b_cal" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Education Cess @ 3%:</label>
|
||||
<input type="number" name="edu_cess_3" class="auto" step="any" value="0.00" readonly>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(A):</label>
|
||||
<input type="number" name="per_surcharge_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(A):</label>
|
||||
<input type="number" name="surcharge_a_cal" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(B)</label>
|
||||
<input type="number" name="per_surcharge_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(B):</label>
|
||||
<input type="number" name="surcharge_b_cal" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(A):</label>
|
||||
<input type="number" name="per_cess_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(A): </label>
|
||||
<input type="number" name="edu_cess_a_cal" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(B):</label>
|
||||
<input type="number" name="per_cess_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(B): </label>
|
||||
<input type="number" name="edu_cess_b_cal" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total cal Tax(A): </label>
|
||||
<input type="number" name="sum_of_a" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cal Tax(B): </label>
|
||||
<input type="number" name="sum_of_b" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total tax Payable:</label>
|
||||
@@ -109,8 +164,26 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Opening Balance:</label>
|
||||
<input type="number" name="opening_balance" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Mat Credit Created:</label>
|
||||
<input type="number" name="mat_credit_created" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit_utilized" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Closing Balance:</label>
|
||||
<input type="number" name="closing_balance" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Interest 234c:</label>
|
||||
@@ -123,13 +196,13 @@
|
||||
<label>Total Tax:</label>
|
||||
<input type="number" name="total_tax" step="any" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Advance Tax:</label>
|
||||
<input type="number" name="advance_tax" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>TDS :</label>
|
||||
<input type="number" name="tds" step="any" value="0.00" oninput="calculate()" required>
|
||||
@@ -148,36 +221,48 @@
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax on Regular Assessment:</label>
|
||||
<input type="number" name="tax_on_assessment" step="any" value="0.00" oninput="calculate()" required>
|
||||
<input type="number" name="tax_on_assessment" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Refund:</label>
|
||||
<input type="number" name="refund" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Add : Interest u/s 244A as per 143:</label>
|
||||
<input type="number" name="interest_244a_per143" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Less : Refund Received on:</label>
|
||||
<input type="number" name="refund_received" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Balance Receivable:</label>
|
||||
<input type="number" name="balance_receivable" class="auto" step="any" value="0.00"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Select Documents:</label>
|
||||
<input type="file" name="documents" multiple>
|
||||
</div>
|
||||
<div>
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/ao_calc.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/year_dropdown.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
<script>
|
||||
function showSuccessMessage() {
|
||||
alert("Form submitted successfully!");
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/itr_calc.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/year_dropdown.js') }}"></script>
|
||||
{% endblock %}
|
||||
@@ -4,26 +4,34 @@
|
||||
|
||||
{% block extra_css %}
|
||||
<!-- Child page CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_cit.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_model.css') }}">
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
<h2 style="text-align:center;">New CIT Form </h2>
|
||||
<form id="cit" method="POST">
|
||||
<form id="cit" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="stage" value="itr">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Year:</label>
|
||||
<select id="year" name="year" required></select>
|
||||
<label>Assessment Year:</label>
|
||||
<select id="year" name="year" required>
|
||||
<option value="" disabled selected>
|
||||
-- Please select Assessment Year --
|
||||
</option>
|
||||
</select>
|
||||
<div id="yearError" style="color:red; display:none; margin-bottom:10px;"></div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Record Created Date:</label>
|
||||
<input type="date" name="created_at" value="{{ current_date }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 14A:</label>
|
||||
<input type="number" name="disallowance_14a" step="any" value="0.00" oninput="calculate()" required>
|
||||
@@ -34,6 +42,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>GTI as per CIT</label>
|
||||
<input type="number" name="gti_as_per_ao" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction 80IA Business Income:</label>
|
||||
@@ -44,25 +59,25 @@
|
||||
<label>Deduction 80IA Misc:</label>
|
||||
<input type="number" name="deduction_80ia_misc" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction Sec 37 Disallowance:</label>
|
||||
<input type="number" name="deduction_sec37_disallowance" step="any" value="0.00" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less: Deduction 80G: </label>
|
||||
<input type="number" name="deduction_80g" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Net Taxable Income:</label>
|
||||
<input type="number" name="net_taxable_income" class="auto" step="any" value="0.00" readonly>
|
||||
@@ -71,35 +86,77 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax @ 30% (A):</label>
|
||||
<input type="number" name="tax_30_percent" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Enter Percentage(%) calculate: Tax(A):</label>
|
||||
<input type="number" name="per_tax_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @(A):</label>
|
||||
<input type="number" name="tax_a_cal" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(B):</label>
|
||||
<input type="number" name="per_tax_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @ 18.5% on Book Profit (B):</label>
|
||||
<input type="number" name="tax_book_profit_18_5" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage (%) Surcharge:</label>
|
||||
<input type="number" name="persentage" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge:</label>
|
||||
<input type="number" name="surcharge_12" class="auto" value="0.00" readonly>
|
||||
<input type="number" name="tax_b_cal" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Education Cess @ 3%:</label>
|
||||
<input type="number" name="edu_cess_3" class="auto" step="any" value="0.00" readonly>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(A):</label>
|
||||
<input type="number" name="per_surcharge_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(A):</label>
|
||||
<input type="number" name="surcharge_a_cal" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(B)</label>
|
||||
<input type="number" name="per_surcharge_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(B):</label>
|
||||
<input type="number" name="surcharge_b_cal" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(A):</label>
|
||||
<input type="number" name="per_cess_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(A): </label>
|
||||
<input type="number" name="edu_cess_a_cal" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(B):</label>
|
||||
<input type="number" name="per_cess_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(B): </label>
|
||||
<input type="number" name="edu_cess_b_cal" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total cal Tax(A): </label>
|
||||
<input type="number" name="sum_of_a" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cal Tax(B): </label>
|
||||
<input type="number" name="sum_of_b" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total tax Payable:</label>
|
||||
@@ -109,8 +166,25 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Opening Balance:</label>
|
||||
<input type="number" name="opening_balance" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Mat Credit Created:</label>
|
||||
<input type="number" name="mat_credit_created" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit_utilized" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Closing Balance:</label>
|
||||
<input type="number" name="closing_balance" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Interest 234c:</label>
|
||||
@@ -123,13 +197,13 @@
|
||||
<label>Total Tax:</label>
|
||||
<input type="number" name="total_tax" step="any" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Advance Tax:</label>
|
||||
<input type="number" name="advance_tax" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>TDS :</label>
|
||||
<input type="number" name="tds" step="any" value="0.00" oninput="calculate()" required>
|
||||
@@ -138,7 +212,6 @@
|
||||
<label>TCS :</label>
|
||||
<input type="number" name="tcs" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
@@ -150,16 +223,37 @@
|
||||
<label>Tax on Regular Assessment:</label>
|
||||
<input type="number" name="tax_on_assessment" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Refund:</label>
|
||||
<input type="number" name="refund" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Add : Interest u/s 244A as per 143:</label>
|
||||
<input type="number" name="interest_244a_per143" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Less : Refund Received on:</label>
|
||||
<input type="number" name="refund_received" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Balance Receivable:</label>
|
||||
<input type="number" name="balance_receivable" class="auto" step="any" value="0.00"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Select Documents:</label>
|
||||
<input type="file" name="documents" multiple>
|
||||
</div>
|
||||
<div>
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
@@ -168,6 +262,6 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/cit_calc.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/itr_calc.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/year_dropdown.js') }}"></script>
|
||||
{% endblock %}
|
||||
@@ -4,29 +4,35 @@
|
||||
|
||||
{% block extra_css %}
|
||||
<!-- Child page CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_itr.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
|
||||
<h2 style="text-align:center;">New Income Tax Appellate Tribunal Form</h2>
|
||||
|
||||
<form id="itat" method="POST" onsubmit="return showSuccessMessage()">
|
||||
|
||||
<form id="itat" method="POST" enctype="multipart/form-data" onsubmit="return showSuccessMessage()">
|
||||
<input type="hidden" name="stage" value="itr">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Year:</label>
|
||||
<select id="year" name="year" required></select>
|
||||
<label>Assessment Year:</label>
|
||||
<select id="year" name="year" required>
|
||||
<option value="" disabled selected>
|
||||
-- Please select Assessment Year --
|
||||
</option>
|
||||
</select>
|
||||
<div id="yearError" style="color:red; display:none; margin-bottom:10px;"></div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Record Created Date:</label>
|
||||
<input type="date" name="created_at" value="{{ current_date }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 14A:</label>
|
||||
<input type="number" name="disallowance_14a" step="any" value="0.00" oninput="calculate()" required>
|
||||
@@ -39,33 +45,40 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction 80IA Business Income:</label>
|
||||
<label>GTI as per AO</label>
|
||||
<input type="number" name="gti_as_per_ao" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Business Income:</label>
|
||||
<input type="number" name="deduction_80ia_business" step="any" value="0.00" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Deduction 80IA Misc:</label>
|
||||
<label>Less :Deduction 80IA Misc:</label>
|
||||
<input type="number" name="deduction_80ia_misc" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Deduction Sec 37 Disallowance:</label>
|
||||
<label>Less :Deduction Sec 37 Disallowance:</label>
|
||||
<input type="number" name="deduction_sec37_disallowance" step="any" value="0.00" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less: Deduction 80G: </label>
|
||||
<input type="number" name="deduction_80g" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Net Taxable Income:</label>
|
||||
<input type="number" name="net_taxable_income" class="auto" step="any" value="0.00" readonly>
|
||||
@@ -74,35 +87,77 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax @ 30% (A):</label>
|
||||
<input type="number" name="tax_30_percent" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Enter Percentage(%) calculate: Tax(A):</label>
|
||||
<input type="number" name="per_tax_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @(A):</label>
|
||||
<input type="number" name="tax_a_cal" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(B):</label>
|
||||
<input type="number" name="per_tax_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @ 18.5% on Book Profit (B):</label>
|
||||
<input type="number" name="tax_book_profit_18_5" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage (%) Surcharge:</label>
|
||||
<input type="number" name="persentage" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge:</label>
|
||||
<input type="number" name="surcharge_12" class="auto" value="0.00" readonly>
|
||||
<input type="number" name="tax_b_cal" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Education Cess @ 3%:</label>
|
||||
<input type="number" name="edu_cess_3" class="auto" step="any" value="0.00" readonly>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(A):</label>
|
||||
<input type="number" name="per_surcharge_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(A):</label>
|
||||
<input type="number" name="surcharge_a_cal" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(B)</label>
|
||||
<input type="number" name="per_surcharge_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(B):</label>
|
||||
<input type="number" name="surcharge_b_cal" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(A):</label>
|
||||
<input type="number" name="per_cess_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(A): </label>
|
||||
<input type="number" name="edu_cess_a_cal" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(B):</label>
|
||||
<input type="number" name="per_cess_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(B): </label>
|
||||
<input type="number" name="edu_cess_b_cal" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total cal Tax(A): </label>
|
||||
<input type="number" name="sum_of_a" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cal Tax(B): </label>
|
||||
<input type="number" name="sum_of_b" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total tax Payable:</label>
|
||||
@@ -112,8 +167,26 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Opening Balance:</label>
|
||||
<input type="number" name="opening_balance" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Mat Credit Created:</label>
|
||||
<input type="number" name="mat_credit_created" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit_utilized" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Closing Balance:</label>
|
||||
<input type="number" name="closing_balance" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Interest 234c:</label>
|
||||
@@ -126,13 +199,13 @@
|
||||
<label>Total Tax:</label>
|
||||
<input type="number" name="total_tax" step="any" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Advance Tax:</label>
|
||||
<input type="number" name="advance_tax" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>TDS :</label>
|
||||
<input type="number" name="tds" step="any" value="0.00" oninput="calculate()" required>
|
||||
@@ -160,9 +233,31 @@
|
||||
<input type="number" name="refund" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Add : Interest u/s 244A as per 143:</label>
|
||||
<input type="number" name="interest_244a_per143" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Less : Refund Received on:</label>
|
||||
<input type="number" name="refund_received" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Balance Receivable:</label>
|
||||
<input type="number" name="balance_receivable" class="auto" step="any" value="0.00"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Select Documents:</label>
|
||||
<input type="file" name="documents" multiple>
|
||||
</div>
|
||||
<div>
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
@@ -173,11 +268,4 @@
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/itr_calc.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='js/year_dropdown.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
<script>
|
||||
function showSuccessMessage() {
|
||||
alert("Form submitted successfully!");
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -4,27 +4,34 @@
|
||||
|
||||
{% block extra_css %}
|
||||
<!-- Child page CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_itr.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<h2 style="text-align:center;">New Income Tax Return Form</h2>
|
||||
|
||||
<form id="itr" method="POST">
|
||||
<form id="itr" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="stage" value="itr">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Year:</label>
|
||||
<select id="year" name="year" required></select>
|
||||
<label>Assessment Year:</label>
|
||||
<select id="year" name="year" required>
|
||||
<option value="" disabled selected>
|
||||
-- Please select Assessment Year --
|
||||
</option>
|
||||
</select>
|
||||
<div id="yearError" style="color:red; display:none; margin-bottom:10px;"></div>
|
||||
</div>
|
||||
<div>
|
||||
<label>Record Created Date:</label>
|
||||
<input type="date" name="created_at" value="{{ current_date }}" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 14A:</label>
|
||||
<input type="number" name="disallowance_14a" step="any" value="0.00" oninput="calculate()" required>
|
||||
@@ -34,36 +41,42 @@
|
||||
<input type="number" name="disallowance_37" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>GTI as per AO</label>
|
||||
<input type="number" name="gti_as_per_ao" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction 80IA Business Income:</label>
|
||||
<label>Less :Deduction 80IA Business Income:</label>
|
||||
<input type="number" name="deduction_80ia_business" step="any" value="0.00" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Deduction 80IA Misc:</label>
|
||||
<label>Less :Deduction 80IA Misc:</label>
|
||||
<input type="number" name="deduction_80ia_misc" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less : Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Deduction Sec 37 Disallowance:</label>
|
||||
<label>Less :Deduction Sec 37 Disallowance:</label>
|
||||
<input type="number" name="deduction_sec37_disallowance" step="any" value="0.00" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less: Deduction 80G: </label>
|
||||
<input type="number" name="deduction_80g" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Net Taxable Income:</label>
|
||||
<input type="number" name="net_taxable_income" class="auto" step="any" value="0.00" readonly>
|
||||
@@ -72,35 +85,77 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax @ 30% (A):</label>
|
||||
<input type="number" name="tax_30_percent" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Enter Percentage(%) calculate: Tax(A):</label>
|
||||
<input type="number" name="per_tax_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @(A):</label>
|
||||
<input type="number" name="tax_a_cal" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(B):</label>
|
||||
<input type="number" name="per_tax_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @ 18.5% on Book Profit (B):</label>
|
||||
<input type="number" name="tax_book_profit_18_5" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage (%) Surcharge:</label>
|
||||
<input type="number" name="persentage" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge:</label>
|
||||
<input type="number" name="surcharge_12" class="auto" value="0.00" readonly>
|
||||
<input type="number" name="tax_b_cal" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Education Cess @ 3%:</label>
|
||||
<input type="number" name="edu_cess_3" class="auto" step="any" value="0.00" readonly>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(A):</label>
|
||||
<input type="number" name="per_surcharge_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(A):</label>
|
||||
<input type="number" name="surcharge_a_cal" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(B)</label>
|
||||
<input type="number" name="per_surcharge_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(B):</label>
|
||||
<input type="number" name="surcharge_b_cal" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(A):</label>
|
||||
<input type="number" name="per_cess_a" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(A): </label>
|
||||
<input type="number" name="edu_cess_a_cal" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(B):</label>
|
||||
<input type="number" name="per_cess_b" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(B): </label>
|
||||
<input type="number" name="edu_cess_b_cal" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total cal Tax(A): </label>
|
||||
<input type="number" name="sum_of_a" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cal Tax(B): </label>
|
||||
<input type="number" name="sum_of_b" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="0.00" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total tax Payable:</label>
|
||||
@@ -110,8 +165,26 @@
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit" step="any" value="0.00" oninput="calculate()" required>
|
||||
<label>Opening Balance:</label>
|
||||
<input type="number" name="opening_balance" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Mat Credit Created:</label>
|
||||
<input type="number" name="mat_credit_created" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit_utilized" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Closing Balance:</label>
|
||||
<input type="number" name="closing_balance" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Interest 234c:</label>
|
||||
@@ -124,13 +197,13 @@
|
||||
<label>Total Tax:</label>
|
||||
<input type="number" name="total_tax" step="any" class="auto" value="0.00" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Advance Tax:</label>
|
||||
<input type="number" name="advance_tax" step="any" value="0.00" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>TDS :</label>
|
||||
<input type="number" name="tds" step="any" value="0.00" oninput="calculate()" required>
|
||||
@@ -153,14 +226,39 @@
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Refund:</label>
|
||||
<input type="number" name="refund" class="auto" step="any" value="0.00" readonly>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Refund:</label>
|
||||
<input type="number" name="refund" class="auto" step="any" value="0.00">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Add : Interest u/s 244A as per 143:</label>
|
||||
<input type="number" name="interest_244a_per143" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Less : Refund Received on:</label>
|
||||
<input type="number" name="refund_received" step="any" value="0.00" oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Balance Receivable:</label>
|
||||
<input type="number" name="balance_receivable" class="auto" step="any" value="0.00"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Select Documents:</label>
|
||||
<input type="file" name="documents" multiple>
|
||||
</div>
|
||||
<div>
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Submit</button>
|
||||
|
||||
@@ -3,33 +3,22 @@
|
||||
{% block title %}Download AO Report{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/ao_report.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/report_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<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 }}">AY {{ y }} - {{ y + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<br>
|
||||
|
||||
<button type="submit">Download Excel</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<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 }}">AY {{ y }} - {{ y + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<br>
|
||||
<button type="submit">Download Excel</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -4,60 +4,70 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>{% block title %}Income Tax Utilities{% endblock %}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<!-- Shared CSS -->
|
||||
<!-- Main CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/index.css') }}">
|
||||
|
||||
<!-- Extra CSS for child pages -->
|
||||
{% block extra_css %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- NAVBAR -->
|
||||
|
||||
<!-- ================= NAVBAR ================= -->
|
||||
<div class="navbar">
|
||||
<div class="nav-left">
|
||||
<!-- ☰ visible ONLY on mobile via CSS -->
|
||||
<span class="toggle-btn" onclick="toggleSidebar()">☰</span>
|
||||
<img src="{{ url_for('static', filename='images/lcepllogo.png') }}" class="nav-logo" alt="Logo" />
|
||||
|
||||
<img src="{{ url_for('static', filename='images/lcepllogo.png') }}" class="nav-logo" alt="LCEPL Logo">
|
||||
|
||||
<h3>LAXMI CIVIL ENGINEERING SERVICES PVT. LTD.</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SIDEBAR -->
|
||||
<div class="sidebar hide" id="sidebar">
|
||||
<!-- ================= SIDEBAR ================= -->
|
||||
<div class="sidebar" id="sidebar">
|
||||
|
||||
<a href="{{ url_for('index') }}">
|
||||
<h2>Dashboard</h2>
|
||||
</a>
|
||||
<!-- ITR model -->
|
||||
|
||||
<!-- ITR -->
|
||||
<div class="menu-btn" onclick="toggleMenu('itrMenu')">ITR ▼</div>
|
||||
<div class="submenu" id="itrMenu">
|
||||
<a href="{{ url_for('add_itr') }}">➕ Add ITR</a>
|
||||
<a href="{{ url_for('display_itr') }}">🧾 ITR Records</a>
|
||||
</div>
|
||||
<!-- AO model -->
|
||||
|
||||
<!-- AO -->
|
||||
<div class="menu-btn" onclick="toggleMenu('aoMenu')">AO ▼</div>
|
||||
<div class="submenu" id="aoMenu">
|
||||
<a href="{{ url_for('add_ao') }}">➕ Add AO</a>
|
||||
<a href="{{ url_for('display_ao') }}">🧾 AO Records</a>
|
||||
</div>
|
||||
<!-- CIT model -->
|
||||
|
||||
<!-- CIT -->
|
||||
<div class="menu-btn" onclick="toggleMenu('citMenu')">CIT ▼</div>
|
||||
<div class="submenu" id="citMenu">
|
||||
<a href="{{ url_for('add_cit') }}">➕ Add CIT</a>
|
||||
<a href="{{ url_for('display_cit') }}">🧾 CIT Records</a>
|
||||
</div>
|
||||
<!-- ITAT model -->
|
||||
|
||||
<!-- ITAT -->
|
||||
<div class="menu-btn" onclick="toggleMenu('itatMenu')">ITAT ▼</div>
|
||||
<div class="submenu" id="itatMenu">
|
||||
<a href="{{ url_for('add_itat') }}">➕ Add ITAT</a>
|
||||
<a href="{{ url_for('display_itat') }}">🧾 ITAT Records</a>
|
||||
</div>
|
||||
<!-- MAT credit model -->
|
||||
<div class="menu-btn" onclick="toggleMenu('matCredit')">Mat Credit ▼</div>
|
||||
<div class="submenu" id="matCredit">
|
||||
<a href="{{ url_for('mat_credit') }}">📄 Mat Credit from</a>
|
||||
|
||||
<!-- MAT CREDIT -->
|
||||
<div class="menu-btn" onclick="toggleMenu('matMenu')">MAT Credit ▼</div>
|
||||
<div class="submenu" id="matMenu">
|
||||
<a href="{{ url_for('mat_credit') }}">📄 MAT Credit Form</a>
|
||||
</div>
|
||||
|
||||
<!-- Documents & Reports -->
|
||||
<!-- DOCUMENTS -->
|
||||
<div class="menu-btn" onclick="toggleMenu('docMenu')">Documents & Reports ▼</div>
|
||||
<div class="submenu" id="docMenu">
|
||||
<a href="{{ url_for('upload_file') }}">📂 Upload</a>
|
||||
@@ -66,21 +76,21 @@
|
||||
<a href="{{ url_for('summary_report') }}">📝 Summary Report</a>
|
||||
</div>
|
||||
|
||||
<!-- Logout at bottom -->
|
||||
<!-- LOGOUT -->
|
||||
<a href="{{ url_for('auth.logout') }}" class="sidebar-logout">
|
||||
<img src="{{ url_for('static', filename='images/logout_icon.png') }}" class="logout-icon" alt="Logout" />
|
||||
<img src="{{ url_for('static', filename='images/logout_icon.png') }}" class="logout-icon" alt="Logout">
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- MAIN CONTENT -->
|
||||
<!-- ================= MAIN CONTENT ================= -->
|
||||
<div class="main" id="main">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<!-- Shared JS -->
|
||||
<!-- JS -->
|
||||
<script src="{{ url_for('static', filename='js/toggle.js') }}"></script>
|
||||
|
||||
<!-- Extra JS for child pages -->
|
||||
{% block extra_js %}{% endblock %}
|
||||
</body>
|
||||
|
||||
|
||||
@@ -3,32 +3,22 @@
|
||||
{% block title %}Download CIT Report{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/cit_report.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/report_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<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 }}">AY {{ y }} - {{ y + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<br>
|
||||
<button type="submit">Download Excel</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<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 }}">AY {{ y }} - {{ y + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<br>
|
||||
<button type="submit">Download Excel</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,15 +1,13 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}AO Records{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/display_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<!-- Load only display_itr CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/display_itr.css') }}">
|
||||
<div class="container">
|
||||
|
||||
<h2 style="text-align: center;">Assessing Officer Records 👨💼</h2>
|
||||
|
||||
<!-- Add AO Record Button -->
|
||||
<div style="text-align: right; margin-bottom: 10px;">
|
||||
<a href="{{ url_for('add_ao') }}" class="btn btn-add">➕ Add AO Record</a>
|
||||
@@ -24,6 +22,8 @@
|
||||
<th>Gross Total Income</th>
|
||||
<th>Net Taxable Income</th>
|
||||
<th>Total Tax</th>
|
||||
<th>Refund</th>
|
||||
<th>Created Record Date</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -33,7 +33,9 @@
|
||||
<td>AY {{ ao.year }}-{{ ao.year+1 }}</td>
|
||||
<td>{{ ao.gross_total_income }}</td>
|
||||
<td>{{ ao.net_taxable_income }}</td>
|
||||
<td>{{ ao.total_tax }}</td>
|
||||
<td>{{ ao.total_tax_payable }}</td>
|
||||
<td>{{ "{:,.2f}".format(ao.refund) }}</td>
|
||||
<td>{{ ao.created_at.strftime('%Y-%m-%d') }}</td>
|
||||
<td>
|
||||
<a href="{{ url_for('update_ao', id=ao.id) }}" class="btn btn-update">Edit</a>
|
||||
|
||||
@@ -47,7 +49,9 @@
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<p style="text-align: center; margin-top: 20px;" class="no-record">No AO records found.</p>
|
||||
<p style="text-align: center; margin-top: 20px" class="no-record">
|
||||
No records found. Click the button above to add one!
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,57 +1,58 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}CIT Records{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/display_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Load only display_itr CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/display_cit.css') }}">
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
|
||||
<h2 style="text-align: center;">CIT Records🧾</h2>
|
||||
<div style="text-align: right; margin-bottom: 10px;">
|
||||
<a href="{{ url_for('add_cit') }}" class="btn btn-add">➕ Add New Record</a>
|
||||
</div>
|
||||
{% if cit_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 cit_records %}
|
||||
<tr>
|
||||
<td>AY {{ record.year }}-{{ record.year+1 }}</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_cit', id=record.id) }}" class="btn btn-update">Edit</a>
|
||||
<form action="{{ url_for('delete_cit', 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;" class="no-record">
|
||||
No records found. Click the button above to add one!
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="container">
|
||||
<h2 style="text-align: center;">CIT Records🧾</h2>
|
||||
<div style="text-align: right; margin-bottom: 10px;">
|
||||
<a href="{{ url_for('add_cit') }}" class="btn btn-add">➕ Add New Record</a>
|
||||
</div>
|
||||
{% if cit_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>Created Record Date</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for record in cit_records %}
|
||||
<tr>
|
||||
<td>AY {{ record.year }}-{{ record.year+1 }}</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>{{ record.created_at.strftime('%Y-%m-%d') }}</td>
|
||||
<td class="action-cell">
|
||||
<a href="{{ url_for('update_cit', id=record.id) }}" class="btn btn-update">Edit</a>
|
||||
<form action="{{ url_for('delete_cit', 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;" class="no-record">
|
||||
No records found. Click the button above to add one!
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -2,71 +2,59 @@
|
||||
|
||||
{% block title %}ITAT Records{% endblock %}
|
||||
|
||||
<!-- Load page-specific CSS -->
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/display_itat.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/display_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="container">
|
||||
<h2 style="text-align: center;">Income Tax Appellate Tribunal Records 📄</h2>
|
||||
<div style="text-align: right; margin-bottom: 10px;">
|
||||
|
||||
<h2 style="text-align: center;">Income Tax Appellate Tribunal Records 📄</h2>
|
||||
<div style="text-align: right; margin-bottom: 10px;">
|
||||
<a href="{{ url_for('add_itat') }}" class="btn btn-add">➕ Add New Record</a>
|
||||
|
||||
<a href="{{ url_for('add_itat') }}" class="btn btn-add">➕ Add New Record</a>
|
||||
|
||||
<!-- FLASH MESSAGES -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ category }}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<!-- TABLE -->
|
||||
{% if records %}
|
||||
<div class="table-wrapper">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Year</th>
|
||||
<th>MAT Tax Credit</th>
|
||||
<th>Surcharge</th>
|
||||
<th>Cess</th>
|
||||
<th>Total Credit</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for record in records %}
|
||||
<tr>
|
||||
<td>AY {{ record.year }}-{{ record.year+1 }}</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_itat', id=record.id) }}" class="btn btn-update">Edit</a>
|
||||
|
||||
<form action="{{ url_for('delete_itat', 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 class="no-record">No ITAT records found. Click the button above to add one!</p>
|
||||
{% endif %}
|
||||
<!-- TABLE -->
|
||||
{% 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>Created Record Date</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for record in records %}
|
||||
<tr>
|
||||
<td>AY {{ record.year }}-{{ record.year+1 }}</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>{{ record.created_at.strftime('%Y-%m-%d') }}</td>
|
||||
<td class="action-cell">
|
||||
<a href="{{ url_for('update_itat', id=record.id) }}" class="btn btn-update">Edit</a>
|
||||
|
||||
<form action="{{ url_for('delete_itat', 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 class="no-record">No records found. Click the button above to add one!</p>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,14 +1,12 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}ITR Records{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/display_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<!-- Load only display_itr CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/display_itr.css') }}">
|
||||
|
||||
|
||||
<div class="container">
|
||||
|
||||
<h2>Income Tax Return Records 🧾</h2>
|
||||
<div style="text-align: right; margin-bottom: 10px;">
|
||||
<a href="{{ url_for('add_itr') }}" class="btn btn-add">➕ Add New Record</a>
|
||||
@@ -24,6 +22,7 @@
|
||||
<th>Net Taxable Income</th>
|
||||
<th>Total Tax Payable</th>
|
||||
<th>Refund</th>
|
||||
<th>Created Record Date</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -35,6 +34,7 @@
|
||||
<td>{{ "{:,.2f}".format(record.net_taxable_income) }}</td>
|
||||
<td>{{ "{:,.2f}".format(record.total_tax_payable) }}</td>
|
||||
<td>{{ "{:,.2f}".format(record.refund) }}</td>
|
||||
<td>{{ record.created_at.strftime('%Y-%m-%d') }}</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"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<h2 class="header">Dashboard 🏛️</h2>
|
||||
<p style="text-align: center; font-size: 20px;">
|
||||
<p>
|
||||
Welcome to Income Tax Utilities Dashboard
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -3,29 +3,22 @@
|
||||
{% block title %}Download ITAT Report{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/itat_report.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/report_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<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 }}">AY {{ y }} - {{ y + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<br>
|
||||
<button type="submit">Download Excel</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<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 }}">AY {{ y }} - {{ y + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<br>
|
||||
<button type="submit">Download Excel</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -3,31 +3,22 @@
|
||||
{% block title %}Download ITR Report{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/itr_report.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/report_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<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 }}">AY {{ y }} - {{ y + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<br>
|
||||
<button type="submit">
|
||||
Download Excel
|
||||
</button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<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 }}">AY {{ y }} - {{ y + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<br>
|
||||
<button type="submit">Download Excel</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -4,68 +4,14 @@
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>LCEPL Income Tax</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
background: #f3f3f3;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
background: white;
|
||||
padding: 2rem;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="password"] {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
padding: 0.5rem;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.flash {
|
||||
color: red;
|
||||
text-align: center;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/login.css') }}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="login-container">
|
||||
<h1 class="title">Laxmi Civil Engineering Services</h1>
|
||||
<h2 class="sub-title">Income Tax Software</h2>
|
||||
<h4 class="subtitle">LOGIN</h4>
|
||||
|
||||
{% with messages = get_flashed_messages(with_categories=true) %} {% if
|
||||
|
||||
@@ -7,68 +7,65 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
<div class="container">
|
||||
<div class="container mat-container">
|
||||
|
||||
<!-- YEAR ADD CONTROLS -->
|
||||
<div class="year-controls">
|
||||
<select id="yearSelect">
|
||||
<option value="">-- Select AY --</option>
|
||||
{% for y in range(2001, 2026) %}
|
||||
<option value="{{ y }}-{{ y+1 }}">{{ y }}-{{ y+1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button onclick="addYearColumn()">➕ Add Year</button>
|
||||
</div>
|
||||
|
||||
<!-- SCROLL WRAPPER -->
|
||||
<div class="table-wrapper">
|
||||
<table id="matTable">
|
||||
<thead>
|
||||
<tr id="tableHeader">
|
||||
<th>AY</th>
|
||||
<th>MAT Credit</th>
|
||||
|
||||
{% for y in added_years %}
|
||||
<th>Utilized {{ y }}</th>
|
||||
{% endfor %}
|
||||
|
||||
<th>Balance</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for row in mat_rows %}
|
||||
<tr>
|
||||
<td contenteditable="true">{{ row.financial_year }}</td>
|
||||
<td><input value="{{ row.mat_credit }}"></td>
|
||||
|
||||
{% for y in added_years %}
|
||||
<td>
|
||||
<input value="{{ utilization_map.get(row.id, {}).get(y, '') }}">
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
<td><input value="{{ row.balance }}"></td>
|
||||
<td><button onclick="saveRow(this)">Save</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<button onclick="addRow()">➕ Add Row</button>
|
||||
<button onclick="saveAll()">💾 Save All</button>
|
||||
<h2 class="page-title">MAT Credit and Utilization Records</h2>
|
||||
|
||||
<!-- YEAR ADD CONTROLS -->
|
||||
<div class="year-controls">
|
||||
<select id="yearSelect">
|
||||
<option value="">-- Select AY --</option>
|
||||
{% for y in range(2001, 2026) %}
|
||||
<option value="{{ y }}-{{ y+1 }}">{{ y }}-{{ y+1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button onclick="addYearColumn()">➕ Add Utilized Year</button>
|
||||
</div>
|
||||
|
||||
<!-- TABLE WRAPPER -->
|
||||
<div class="table-wrapper">
|
||||
<table id="matTable">
|
||||
<thead>
|
||||
<tr id="tableHeader">
|
||||
<th>AY</th>
|
||||
<th>MAT Credit</th>
|
||||
|
||||
{% for y in added_years %}
|
||||
<th>Utilized {{ y }}</th>
|
||||
{% endfor %}
|
||||
|
||||
<th>Balance</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for row in mat_rows %}
|
||||
<tr>
|
||||
<td contenteditable="false">{{ row.financial_year }}-{{ row.financial_year | int + 1 }}</td>
|
||||
<td><input value="{{ row.mat_credit }}"></td>
|
||||
|
||||
{% for y in added_years %}
|
||||
<td>
|
||||
<input value="{{ utilization_map.get(row.id, {}).get(y, '') }}">
|
||||
</td>
|
||||
{% endfor %}
|
||||
|
||||
<td><input value="{{ row.balance }}"></td>
|
||||
<td><button onclick="saveRow(this)">Save</button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="action-footer">
|
||||
<button class="add-row-btn" onclick="addRow()">➕ Add New Row</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/mat_credit.js') }}"></script>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -5,15 +5,13 @@
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/report.css') }}">
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<h2>Reports</h2>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('itr_report') }}">→ View ITR Reports</a></li>
|
||||
<li><a href="{{ url_for('ao_report') }}">→ View AO Reports</a></li>
|
||||
<li><a href="{{ url_for('cit_report') }}">→ View CIT Reports</a></li>
|
||||
<li><a href="{{ url_for('itat_report') }}">→ View ITAT Reports</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="container">
|
||||
<h2>Reports</h2>
|
||||
<ul>
|
||||
<li><a href="{{ url_for('itr_report') }}">→ View ITR Reports</a></li>
|
||||
<li><a href="{{ url_for('ao_report') }}">→ View AO Reports</a></li>
|
||||
<li><a href="{{ url_for('cit_report') }}">→ View CIT Reports</a></li>
|
||||
<li><a href="{{ url_for('itat_report') }}">→ View ITAT Reports</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
@@ -1,35 +1,35 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Download Summary Report{% endblock %}
|
||||
|
||||
{% extends "base.html" %} {% block title %}Download Summary Report{% endblock %}
|
||||
{% block extra_css %}
|
||||
<!-- Optional: Add page-specific CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/summary.css') }}">
|
||||
{% endblock %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/summary.css') }}" />
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<h2>Download Year-wise Summary Report</h2>
|
||||
{% endblock %} {% block content %}
|
||||
<div class="container">
|
||||
<div class="head">
|
||||
<h2>Download Year-wise Summary Report</h2>
|
||||
|
||||
{% if message %}
|
||||
<p class="message">{{ message }}</p>
|
||||
{% endif %}
|
||||
{% if message %}
|
||||
<p class="message">{{ message }}</p>
|
||||
{% endif %}
|
||||
|
||||
<form method="GET" action="{{ url_for('summary_report') }}">
|
||||
<label>Select Year:</label>
|
||||
<select name="year" id="year" required>
|
||||
<option value="">-- Select Year --</option>
|
||||
{% for year in years %}
|
||||
<option value="{{ year }}">AY {{ year }}-{{ year + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<button type="submit">Download Summary Report</button>
|
||||
</form>
|
||||
<div class="select-download-wrapper">
|
||||
<select name="year" id="year" required>
|
||||
<option value="">-- Select Year --</option>
|
||||
{% for year in years %}
|
||||
<option value="{{ year }}">AY {{ year }}-{{ year + 1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<a id="downloadBtn" href="#">Download Summary Report</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Preview Section -->
|
||||
<div id="preview" style="display: none">
|
||||
<h3>Summary Preview</h3>
|
||||
|
||||
<div id="previewContent"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %} {% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/summary_preview.js') }}"></script>
|
||||
{% endblock %}
|
||||
@@ -3,32 +3,283 @@
|
||||
{% block title %}Update AO Record{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_ao.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="container">
|
||||
<h2>Update AO Record for Year {{ record.year }} - {{ record.year + 1 }}</h2>
|
||||
<form method="POST" action="{{ url_for('update_ao', id=record.id) }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Year:</label>
|
||||
<input type="tex" name="year" value="{{record.year}}" class="auto" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Created Date:</label>
|
||||
<input type="date" name="created_at"
|
||||
value="{{ record.created_at.strftime('%Y-%m-%d') if record.created_at else current_date }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Last Updated:</label>
|
||||
<input type="date" name="updated_at"
|
||||
value="{{ record.updated_at.strftime('%Y-%m-%d') if record.updated_at else current_date }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Update AO Record for Year {{ record.year }}</h2>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="{{ record.gross_total_income }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 14A:</label>
|
||||
<input type="number" name="disallowance_14a" step="any" value="{{ record.disallowance_14a }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 37:</label>
|
||||
<input type="number" name="disallowance_37" step="any" value="{{ record.disallowance_37 }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ url_for('update_ao', id=record.id) }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>GTI as per AO</label>
|
||||
<input type="number" name="gti_as_per_ao" class="auto" step="any"
|
||||
value="{{ record.gross_total_income + record.disallowance_37 + record.disallowance_14a }}"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="year">Year:</label>
|
||||
<input type="text" id="year" name="year" value="{{ record.year }}" readonly class="readonly-field">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Business Income:</label>
|
||||
<input type="number" name="deduction_80ia_business" step="any"
|
||||
value="{{ record.deduction_80ia_business }}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Misc:</label>
|
||||
<input type="number" name="deduction_80ia_misc" step="any" value="{{ record.deduction_80ia_misc }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="{{ record.deduction_80ia_other }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% for field in record.keys() if field not in ['id', 'year', 'remarks'] %}
|
||||
<label for="{{ field }}">{{ field.replace("_", " ").title() }}:</label>
|
||||
<input type="number" id="{{ field }}" name="{{ field }}" step="any" value="{{ record[field] }}" required>
|
||||
{% endfor %}
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction Sec 37 Disallowance:</label>
|
||||
<input type="number" name="deduction_sec37_disallowance" step="any"
|
||||
value="{{ record.deduction_sec37_disallowance }}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less: Deduction 80G: </label>
|
||||
<input type="number" name="deduction_80g" step="any" value="{{ record.deduction_80g }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="Remarks">Remarks:</label>
|
||||
<input type="text" id="Remarks" name="Remarks" value="{{ record.remarks}}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Net Taxable Income:</label>
|
||||
<input type="number" name="net_taxable_income" class="auto" step="any"
|
||||
value="{{ record.net_taxable_income }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Update Record</button>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(A):</label>
|
||||
<input type="number" name="per_tax_a" step="any" value="{{ record.per_tax_a }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @(A):</label>
|
||||
<input type="number" name="tax_a_cal" step="any" value="{{ record.tax_a_cal }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(B):</label>
|
||||
<input type="number" name="per_tax_b" step="any" value="{{ record.per_tax_b }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @ 18.5% on Book Profit (B):</label>
|
||||
<input type="number" name="tax_b_cal" step="any" value="{{ record.tax_b_cal }}" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(A):</label>
|
||||
<input type="number" name="per_surcharge_a" step="any" value="{{ record.per_surcharge_a }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(A):</label>
|
||||
<input type="number" name="surcharge_a_cal" class="auto" value="{{ record.surcharge_a_cal }}" readonly>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(B)</label>
|
||||
<input type="number" name="per_surcharge_b" step="any" value="{{ record.per_surcharge_b}}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(B):</label>
|
||||
<input type="number" name="surcharge_b_cal" class="auto" value="{{ record.surcharge_b_cal }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(A):</label>
|
||||
<input type="number" name="per_cess_a" step="any" value="{{ record.per_cess_a }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(A): </label>
|
||||
<input type="number" name="edu_cess_a_cal" class="auto" step="any" value="{{ record.edu_cess_a_cal }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(B):</label>
|
||||
<input type="number" name="per_cess_b" step="any" value="{{ record.per_cess_b }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(B): </label>
|
||||
<input type="number" name="edu_cess_b_cal" class="auto" step="any" value="{{ record.edu_cess_b_cal }}"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total cal Tax(A): </label>
|
||||
<input type="number" name="sum_of_a" class="auto" step="any" value="{{ record.sum_of_a }}" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cal Tax(B): </label>
|
||||
<input type="number" name="sum_of_b" class="auto" step="any" value="{{ record.sum_of_b }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="{{ record.tax_payable }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total tax Payable:</label>
|
||||
<input type="number" name="total_tax_payable" class="auto" step="any"
|
||||
value="{{ record.total_tax_payable }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Opening Balance:</label>
|
||||
<input type="number" name="opening_balance" step="any" value="{{ record.opening_balance }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
|
||||
<div>
|
||||
<label>Less :Mat Credit Created:</label>
|
||||
<input type="number" name="mat_credit_created" step="any" value="{{ record.mat_credit_created }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit_utilized" step="any" value="{{ record.mat_credit_utilized }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Closing Balance:</label>
|
||||
<input type="number" name="closing_balance" step="any" value="{{ record.closing_balance }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Interest 234c:</label>
|
||||
<input type="number" name="interest_234c" step="any" value="{{ record.interest_234c }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total Tax:</label>
|
||||
<input type="number" name="total_tax" step="any" class="auto" value="{{ record.total_tax }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Advance Tax:</label>
|
||||
<input type="number" name="advance_tax" step="any" value="{{ record.advance_tax }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>TDS :</label>
|
||||
<input type="number" name="tds" step="any" value="{{ record.tds }}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>TCS :</label>
|
||||
<input type="number" name="tcs" step="any" value="{{ record.tcs }}" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>SAT :</label>
|
||||
<input type="number" name="sat" step="any" value="{{ record.sat }}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax on Regular Assessment:</label>
|
||||
<input type="number" name="tax_on_assessment" step="any" value="{{ record.tax_on_assessment }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Refund:</label>
|
||||
<input type="number" name="refund" class="auto" step="any" value="{{ record.refund }}" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Add : Interest u/s 244A as per 143:</label>
|
||||
<input type="number" name="interest_244a_per143" step="any" value="{{ record.interest_244a_per143 }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Less : Refund Received on:</label>
|
||||
<input type="number" name="refund_received" step="any" value="{{ record.refund_received }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Balance Receivable:</label>
|
||||
<input type="number" name="balance_receivable" class="auto" step="any"
|
||||
value="{{ record.balance_receivable }}" oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks" value="{{ record.Remarks }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Update Record</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -3,31 +3,278 @@
|
||||
{% block title %}Update CIT Record{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_cit.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="container">
|
||||
|
||||
<h2>Update CIT Record for AY {{ record.year }}</h2>
|
||||
|
||||
<form method="POST" action="{{ url_for('update_cit', id=record.id) }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Year:</label>
|
||||
<input type="tex" name="year" value="{{record.year}}" class="auto" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Created Date:</label>
|
||||
<input type="date" name="created_at"
|
||||
value="{{ record.created_at.strftime('%Y-%m-%d') if record.created_at else current_date }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Last Updated:</label>
|
||||
<input type="date" name="updated_at"
|
||||
value="{{ record.updated_at.strftime('%Y-%m-%d') if record.updated_at else current_date }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="year">Year:</label>
|
||||
<input type="text" id="year" name="year" value="{{ record.year }}" readonly class="readonly-field">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="{{ record.gross_total_income}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 14A:</label>
|
||||
<input type="number" name="disallowance_14a" step="any" value="{{ record.disallowance_14a}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 37:</label>
|
||||
<input type="number" name="disallowance_37" step="any" value="{{ record.disallowance_37}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>GTI as per AO</label>
|
||||
<input type="number" name="gti_as_per_ao" class="auto" step="any"
|
||||
value="{{ record.gross_total_income + record.disallowance_37 + record.disallowance_14a }}"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% for field in record.keys() if field not in ['id', 'year','Remarks'] %}
|
||||
<label for="{{ field }}">{{ field.replace("_", " ").title() }}:</label>
|
||||
<input type="number" id="{{ field }}" name="{{ field }}" step="any" value="{{ record[field] }}" required>
|
||||
{% endfor %}
|
||||
<label for="Remarks">Remarks:</label>
|
||||
<input type="text" id="Remarks" name="Remarks" value="{{ record.Remarks }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Business Income:</label>
|
||||
<input type="number" name="deduction_80ia_business" step="any"
|
||||
value="{{ record.deduction_80ia_business}}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Misc:</label>
|
||||
<input type="number" name="deduction_80ia_misc" step="any" value="{{ record.deduction_80ia_misc}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="{{ record.deduction_80ia_other}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction Sec 37 Disallowance:</label>
|
||||
<input type="number" name="deduction_sec37_disallowance" step="any"
|
||||
value="{{ record.deduction_sec37_disallowance}}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less: Deduction 80G: </label>
|
||||
<input type="number" name="deduction_80g" step="any" value="{{ record.deduction_80g}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" form-group">
|
||||
<label>Net Taxable Income:</label>
|
||||
<input type="number" name="net_taxable_income" class="auto" step="any"
|
||||
value="{{ record.net_taxable_income}}" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(A):</label>
|
||||
<input type="number" name="per_tax_a" step="any" value="{{ record.per_tax_a }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @(A):</label>
|
||||
<input type="number" name="tax_a_cal" step="any" value="{{ record.tax_a_cal }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(B):</label>
|
||||
<input type="number" name="per_tax_b" step="any" value="{{ record.per_tax_b }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @ 18.5% on Book Profit (B):</label>
|
||||
<input type="number" name="tax_b_cal" step="any" value="{{ record.tax_b_cal }}" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(A):</label>
|
||||
<input type="number" name="per_surcharge_a" step="any" value="{{ record.per_surcharge_a }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(A):</label>
|
||||
<input type="number" name="surcharge_a_cal" class="auto" value="{{ record.surcharge_a_cal }}" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(B)</label>
|
||||
<input type="number" name="per_surcharge_b" step="any" value="{{ record.per_surcharge_b}}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(B):</label>
|
||||
<input type="number" name="surcharge_b_cal" class="auto" value="{{ record.surcharge_b_cal }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(A):</label>
|
||||
<input type="number" name="per_cess_a" step="any" value="{{ record.per_cess_a }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(A): </label>
|
||||
<input type="number" name="edu_cess_a_cal" class="auto" step="any" value="{{ record.edu_cess_a_cal }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(B):</label>
|
||||
<input type="number" name="per_cess_b" step="any" value="{{ record.per_cess_b }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(B): </label>
|
||||
<input type="number" name="edu_cess_b_cal" class="auto" step="any" value="{{ record.edu_cess_b_cal }}"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total cal Tax(A): </label>
|
||||
<input type="number" name="sum_of_a" class="auto" step="any" value="{{ record.sum_of_a }}" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cal Tax(B): </label>
|
||||
<input type="number" name="sum_of_b" class="auto" step="any" value="{{ record.sum_of_b }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="{{ record.tax_payable}}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total tax Payable:</label>
|
||||
<input type="number" name="total_tax_payable" class="auto" step="any"
|
||||
value="{{ record.total_tax_payable}}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Opening Balance:</label>
|
||||
<input type="number" name="opening_balance" step="any" value="{{ record.opening_balance }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Mat Credit Created:</label>
|
||||
<input type="number" name="mat_credit_created" step="any" value="{{ record.mat_credit_created }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit_utilized" step="any" value="{{ record.mat_credit_utilized }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Closing Balance:</label>
|
||||
<input type="number" name="closing_balance" step="any" value="{{ record.closing_balance }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Interest 234c:</label>
|
||||
<input type="number" name="interest_234c" step="any" value="{{ record.interest_234c}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total Tax:</label>
|
||||
<input type="number" name="total_tax" step="any" class="auto" value="{{ record.total_tax}}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Advance Tax:</label>
|
||||
<input type="number" name="advance_tax" step="any" value="{{ record.advance_tax}}" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
<div>
|
||||
<label>TDS :</label>
|
||||
<input type="number" name="tds" step="any" value="{{ record.tds}}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>TCS :</label>
|
||||
<input type="number" name="tcs" step="any" value="{{ record.tcs}}" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>SAT :</label>
|
||||
<input type="number" name="sat" step="any" value="{{ record.sat}}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax on Regular Assessment:</label>
|
||||
<input type="number" name="tax_on_assessment" step="any" value="{{ record.tax_on_assessment}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Refund:</label>
|
||||
<input type="number" name="refund" class="auto" step="any" value="{{ record.refund}}" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Add : Interest u/s 244A as per 143:</label>
|
||||
<input type="number" name="interest_244a_per143" step="any" value="{{ record.interest_244a_per143 }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Less : Refund Received on:</label>
|
||||
<input type="number" name="refund_received" step="any" value="{{ record.refund_received }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Balance Receivable:</label>
|
||||
<input type="number" name="balance_receivable" class="auto" step="any"
|
||||
value="{{ record.balance_receivable }}" oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks" value="{{ record.Remarks}}">
|
||||
</div>
|
||||
|
||||
<button type="submit">Update Record</button>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -2,30 +2,283 @@
|
||||
{% block title %}Update ITAT Record{% endblock %}
|
||||
{% block extra_css %}
|
||||
<!-- Child page CSS -->
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_itat.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_model.css') }}">
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<div class="container">
|
||||
|
||||
<h2>Update ITAT Record for Year {{ record.year }}</h2>
|
||||
|
||||
<form method="POST" action="{{ url_for('update_itat', id=record.id) }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Year:</label>
|
||||
<input type="tex" name="year" value="{{record.year}}" class="auto" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Created Date:</label>
|
||||
<input type="date" name="created_at"
|
||||
value="{{ record.created_at.strftime('%Y-%m-%d') if record.created_at else current_date }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Last Updated:</label>
|
||||
<input type="date" name="updated_at"
|
||||
value="{{ record.updated_at.strftime('%Y-%m-%d') if record.updated_at else current_date }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="year">Year:</label>
|
||||
<input type="text" id="year" name="year" value="{{ record.year }}" readonly class="readonly-field">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="{{ record.gross_total_income}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 14A:</label>
|
||||
<input type="number" name="disallowance_14a" step="any" value="{{ record.disallowance_14a}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 37:</label>
|
||||
<input type="number" name="disallowance_37" step="any" value="{{ record.disallowance_37}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% for field in record.keys() if field not in ['id', 'year', 'Remarks'] %}
|
||||
<label for="{{ field }}">{{ field.replace("_", " ").title() }}:</label>
|
||||
<input type="number" id="{{ field }}" name="{{ field }}" step="any" value="{{ record[field] }}" required>
|
||||
{% endfor %}
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>GTI as per AO</label>
|
||||
<input type="number" name="gti_as_per_ao" class="auto" step="any"
|
||||
value="{{ record.gross_total_income + record.disallowance_37 + record.disallowance_14a }}"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="Remarks">Remarks:</label>
|
||||
<input type="text" id="Remarks" name="Remarks" value="{{ record.Remarks }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Business Income:</label>
|
||||
<input type="number" name="deduction_80ia_business" step="any"
|
||||
value="{{ record.deduction_80ia_business}}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Misc:</label>
|
||||
<input type="number" name="deduction_80ia_misc" step="any" value="{{ record.deduction_80ia_misc}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="{{ record.deduction_80ia_other}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction Sec 37 Disallowance:</label>
|
||||
<input type="number" name="deduction_sec37_disallowance" step="any"
|
||||
value="{{ record.deduction_sec37_disallowance}}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less: Deduction 80G: </label>
|
||||
<input type="number" name="deduction_80g" step="any" value="{{ record.deduction_80g}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" form-group">
|
||||
<label>Net Taxable Income:</label>
|
||||
<input type="number" name="net_taxable_income" class="auto" step="any"
|
||||
value="{{ record.net_taxable_income}}" readonly>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(A):</label>
|
||||
<input type="number" name="per_tax_a" step="any" value="{{ record.per_tax_a }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @(A):</label>
|
||||
<input type="number" name="tax_a_cal" step="any" value="{{ record.tax_a_cal }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(B):</label>
|
||||
<input type="number" name="per_tax_b" step="any" value="{{ record.per_tax_b }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @ 18.5% on Book Profit (B):</label>
|
||||
<input type="number" name="tax_b_cal" step="any" value="{{ record.tax_b_cal }}" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(A):</label>
|
||||
<input type="number" name="per_surcharge_a" step="any" value="{{ record.per_surcharge_a }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(A):</label>
|
||||
<input type="number" name="surcharge_a_cal" class="auto" value="{{ record.surcharge_a_cal }}" readonly>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(B)</label>
|
||||
<input type="number" name="per_surcharge_b" step="any" value="{{ record.per_surcharge_b}}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(B):</label>
|
||||
<input type="number" name="surcharge_b_cal" class="auto" value="{{ record.surcharge_b_cal }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(A):</label>
|
||||
<input type="number" name="per_cess_a" step="any" value="{{ record.per_cess_a }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(A): </label>
|
||||
<input type="number" name="edu_cess_a_cal" class="auto" step="any" value="{{ record.edu_cess_a_cal }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(B):</label>
|
||||
<input type="number" name="per_cess_b" step="any" value="{{ record.per_cess_b }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(B): </label>
|
||||
<input type="number" name="edu_cess_b_cal" class="auto" step="any" value="{{ record.edu_cess_b_cal }}"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total cal Tax(A): </label>
|
||||
<input type="number" name="sum_of_a" class="auto" step="any" value="{{ record.sum_of_a }}" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cal Tax(B): </label>
|
||||
<input type="number" name="sum_of_b" class="auto" step="any" value="{{ record.sum_of_b }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="{{ record.tax_payable }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total tax Payable:</label>
|
||||
<input type="number" name="total_tax_payable" class="auto" step="any"
|
||||
value="{{ record.total_tax_payable }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Opening Balance:</label>
|
||||
<input type="number" name="opening_balance" step="any" value="{{ record.opening_balance }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Mat Credit Created:</label>
|
||||
<input type="number" name="mat_credit_created" step="any" value="{{ record.mat_credit_created }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit_utilized" step="any" value="{{ record.mat_credit_utilized }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Closing Balance:</label>
|
||||
<input type="number" name="closing_balance" step="any" value="{{ record.closing_balance }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Interest 234c:</label>
|
||||
<input type="number" name="interest_234c" step="any" value="{{ record.interest_234c}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total Tax:</label>
|
||||
<input type="number" name="total_tax" step="any" class="auto" value="{{ record.total_tax}}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Advance Tax:</label>
|
||||
<input type="number" name="advance_tax" step="any" value="{{ record.advance_tax}}" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
<div>
|
||||
<label>TDS :</label>
|
||||
<input type="number" name="tds" step="any" value="{{ record.tds}}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>TCS :</label>
|
||||
<input type="number" name="tcs" step="any" value="{{ record.tcs}}" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>SAT :</label>
|
||||
<input type="number" name="sat" step="any" value="{{ record.sat}}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax on Regular Assessment:</label>
|
||||
<input type="number" name="tax_on_assessment" step="any" value="{{ record.tax_on_assessment}}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label>Refund:</label>
|
||||
<input type="number" name="refund" class="auto" step="any" value="{{ record.refund}}" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Add : Interest u/s 244A as per 143:</label>
|
||||
<input type="number" name="interest_244a_per143" step="any" value="{{ record.interest_244a_per143 }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Less : Refund Received on:</label>
|
||||
<input type="number" name="refund_received" step="any" value="{{ record.refund_received }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Balance Receivable:</label>
|
||||
<input type="number" name="balance_receivable" class="auto" step="any"
|
||||
value="{{ record.balance_receivable }}" oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks" value="{{ record.Remarks }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Update Record</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -3,32 +3,286 @@
|
||||
{% block title %}Update ITR Record{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_itr.css') }}">
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/add_model.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="container">
|
||||
<h2>Update ITR Record for Year {{record.year}} - {{record.year+1}}</h2>
|
||||
<form method="POST" action="{{ url_for('update_itr', id=record.id) }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Year:</label>
|
||||
<input type="tex" name="year" value="{{record.year}}" class="auto" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Created Date:</label>
|
||||
<input type="date" name="created_at"
|
||||
value="{{ record.created_at.strftime('%Y-%m-%d') if record.created_at else current_date }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Last Updated:</label>
|
||||
<input type="date" name="updated_at"
|
||||
value="{{ record.updated_at.strftime('%Y-%m-%d') if record.updated_at else current_date }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Update ITR Record for Year {{ record.year }}</h2>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Gross Total Income:</label>
|
||||
<input type="number" name="gross_total_income" step="any" value="{{ record.gross_total_income }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 14A:</label>
|
||||
<input type="number" name="disallowance_14a" step="any" value="{{ record.disallowance_14a }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Disallowance u/s 37:</label>
|
||||
<input type="number" name="disallowance_37" step="any" value="{{ record.disallowance_37 }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ url_for('update_itr', id=record.id) }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>GTI as per AO</label>
|
||||
<input type="number" name="gti_as_per_ao" class="auto" step="any"
|
||||
value="{{ record.gross_total_income + record.disallowance_37 + record.disallowance_14a }}"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="year">Year:</label>
|
||||
<input type="text" id="year" name="year" value="{{ record.year }}" readonly class="readonly-field">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Business Income:</label>
|
||||
<input type="number" name="deduction_80ia_business" step="any"
|
||||
value="{{ record.deduction_80ia_business }}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Misc:</label>
|
||||
<input type="number" name="deduction_80ia_misc" step="any" value="{{ record.deduction_80ia_misc }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Deduction 80IA Other Operating Revenue:</label>
|
||||
<input type="number" name="deduction_80ia_other" step="any" value="{{ record.deduction_80ia_other }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% for field in record.keys() if field not in ['id', 'year', 'Remarks'] %}
|
||||
<label for="{{ field }}">{{ field.replace("_", " ").title() }}:</label>
|
||||
<input type="number" id="{{ field }}" name="{{ field }}" step="any" value="{{ record[field] }}" required>
|
||||
{% endfor %}
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Deduction Sec 37 Disallowance:</label>
|
||||
<input type="number" name="deduction_sec37_disallowance" step="any"
|
||||
value="{{ record.deduction_sec37_disallowance }}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less: Deduction 80G: </label>
|
||||
<input type="number" name="deduction_80g" step="any" value="{{ record.deduction_80g }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="Remarks">Remarks:</label>
|
||||
<input type="text" id="Remarks" name="Remarks" value="{{ record.Remarks }}">
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Net Taxable Income:</label>
|
||||
<input type="number" name="net_taxable_income" class="auto" step="any"
|
||||
value="{{ record.net_taxable_income }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Update Record</button>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(A):</label>
|
||||
<input type="number" name="per_tax_a" step="any" value="{{ record.per_tax_a }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @(A):</label>
|
||||
<input type="number" name="tax_a_cal" step="any" value="{{ record.tax_a_cal }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) calculate: Tax(B):</label>
|
||||
<input type="number" name="per_tax_b" step="any" value="{{ record.per_tax_b }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax @ 18.5% on Book Profit (B):</label>
|
||||
<input type="number" name="tax_b_cal" step="any" value="{{ record.tax_b_cal }}" oninput="calculate()"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(A):</label>
|
||||
<input type="number" name="per_surcharge_a" step="any" value="{{ record.per_surcharge_a }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(A):</label>
|
||||
<input type="number" name="surcharge_a_cal" class="auto" value="{{ record.surcharge_a_cal }}" readonly>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Surcharge:Tax(B)</label>
|
||||
<input type="number" name="per_surcharge_b" step="any" value="{{ record.per_surcharge_b}}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Surcharge on Tax(B):</label>
|
||||
<input type="number" name="surcharge_b_cal" class="auto" value="{{ record.surcharge_b_cal }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(A):</label>
|
||||
<input type="number" name="per_cess_a" step="any" value="{{ record.per_cess_a }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(A): </label>
|
||||
<input type="number" name="edu_cess_a_cal" class="auto" step="any" value="{{ record.edu_cess_a_cal }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Enter Percentage(%) Cess:Tax(B):</label>
|
||||
<input type="number" name="per_cess_b" step="any" value="{{ record.per_cess_b }}" oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Education Cess:Tax(B): </label>
|
||||
<input type="number" name="edu_cess_b_cal" class="auto" step="any" value="{{ record.edu_cess_b_cal }}"
|
||||
readonly>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total cal Tax(A): </label>
|
||||
<input type="number" name="sum_of_a" class="auto" step="any" value="{{ record.sum_of_a }}" readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total cal Tax(B): </label>
|
||||
<input type="number" name="sum_of_b" class="auto" step="any" value="{{ record.sum_of_b }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Tax Payable (Higher of A or B):</label>
|
||||
<input type="number" name="tax_payable" class="auto" step="any" value="{{ record.tax_payable }}"
|
||||
readonly>
|
||||
</div>
|
||||
<div>
|
||||
<label>Total tax Payable:</label>
|
||||
<input type="number" name="total_tax_payable" class="auto" step="any"
|
||||
value="{{ record.total_tax_payable }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Opening Balance:</label>
|
||||
<input type="number" name="opening_balance" step="any" value="{{ record.opening_balance }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Less :Mat Credit Created:</label>
|
||||
<input type="number" name="mat_credit_created" step="any" value="{{ record.mat_credit_created }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Less :Mat Credit Utilized:</label>
|
||||
<input type="number" name="mat_credit_utilized" step="any" value="{{ record.mat_credit_utilized }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Closing Balance:</label>
|
||||
<input type="number" name="closing_balance" step="any" value="{{ record.closing_balance }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div>
|
||||
<label>Add :Interest 234c:</label>
|
||||
<input type="number" name="interest_234c" step="any" value="{{ record.interest_234c }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Total Tax:</label>
|
||||
<input type="number" name="total_tax" step="any" class="auto" value="{{ record.total_tax }}" readonly>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>Advance Tax:</label>
|
||||
<input type="number" name="advance_tax" step="any" value="{{ record.advance_tax }}"
|
||||
oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>TDS :</label>
|
||||
<input type="number" name="tds" step="any" value="{{ record.tds }}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>TCS :</label>
|
||||
<input type="number" name="tcs" step="any" value="{{ record.tcs }}" oninput="calculate()" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div>
|
||||
<label>SAT :</label>
|
||||
<input type="number" name="sat" step="any" value="{{ record.sat }}" oninput="calculate()" required>
|
||||
</div>
|
||||
<div>
|
||||
<label>Tax on Regular Assessment:</label>
|
||||
<input type="number" name="tax_on_assessment" step="any" value="{{ record.tax_on_assessment }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Refund:</label>
|
||||
<input type="number" name="refund" class="auto" step="any" value="{{ record.refund }}" readonly>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Add : Interest u/s 244A as per 143:</label>
|
||||
<input type="number" name="interest_244a_per143" step="any" value="{{ record.interest_244a_per143 }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Less : Refund Received on:</label>
|
||||
<input type="number" name="refund_received" step="any" value="{{ record.refund_received }}"
|
||||
oninput="calculate()">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Balance Receivable:</label>
|
||||
<input type="number" name="balance_receivable" class="auto" step="any"
|
||||
value="{{ record.balance_receivable }}" oninput="calculate()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group full-width inline-2">
|
||||
<div class="form-group">
|
||||
<label>Remarks:</label>
|
||||
<input type="text" name="Remarks" value="{{ record.Remarks }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit">Update Record</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/itr_calc.js') }}"></script>
|
||||
{% endblock %}
|
||||
@@ -7,33 +7,24 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="container">
|
||||
<h2>Upload Income Tax Documents</h2>
|
||||
<form id="documents" method="POST" enctype="multipart/form-data">
|
||||
<label>Year:</label>
|
||||
<select id="year" name="year" required></select>
|
||||
<div id="yearError" style="color: red; display: none; margin-bottom: 10px;"></div>
|
||||
<label>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>Select Documents:</label>
|
||||
<input type="file" name="documents" multiple required>
|
||||
|
||||
<h2>Upload Income Tax Documents</h2>
|
||||
|
||||
<form id="income_tax_documents" method="POST" enctype="multipart/form-data">
|
||||
|
||||
<label>Year:</label>
|
||||
<select id="year" name="year" required></select>
|
||||
|
||||
<div id="yearError" style="color: red; display: none; margin-bottom: 10px;"></div>
|
||||
|
||||
<label>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>Select Documents:</label>
|
||||
<input type="file" name="documents" multiple required>
|
||||
|
||||
<button type="submit">Upload</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
<button type="submit">Upload</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
@@ -1,41 +1,39 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Document Records{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/documents.css') }}">
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<div class="container">
|
||||
<h2>Document Records</h2>
|
||||
<!-- FILTER FORM -->
|
||||
<form method="GET">
|
||||
<label for="year">Filter by Year:</label>
|
||||
<select name="year">
|
||||
<option value="">All</option>
|
||||
{% for y in years %}
|
||||
<option value="{{ y }}">AY {{ y }}-{{ y+1 }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<h2>Document Records</h2>
|
||||
|
||||
<!-- FILTER FORM -->
|
||||
<form method="GET">
|
||||
<label for="year">Filter by Year:</label>
|
||||
<select name="year">
|
||||
<option value="">All</option>
|
||||
{% for y in years %}
|
||||
<option value="{{ y }}">AY {{ y }}-{{ y+1 }}</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>
|
||||
|
||||
<!-- DOCUMENT TABLE -->
|
||||
<label for="stage">Filter by Stage:</label>
|
||||
<select name="stage">
|
||||
<option value="">All</option>
|
||||
{% set stages = ['ITR','AO','CIT','ITAT'] %}
|
||||
{% for stage in stages %}
|
||||
<option value="{{stage}}">{{stage}}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="submit">Apply</button>
|
||||
</form>
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% for category, message in messages %}
|
||||
<div class="alert alert-{{ category }}">{{ message }}</div>
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
<!-- DOCUMENT TABLE -->
|
||||
<div class="table-responsive">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -58,23 +56,15 @@
|
||||
<td>AY {{ doc.year }}-{{ doc.year +1 }}</td>
|
||||
<td>{{ doc.uploaded_at }}</td>
|
||||
|
||||
<td>
|
||||
<a href="{{ url_for('uploaded_file', filename=doc.filename) }}?mode=download">
|
||||
Download
|
||||
</a>
|
||||
<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>
|
||||
<td><a href="{{ url_for('uploaded_file', filename=doc.filename) }}?mode=view"
|
||||
target="_blank">View</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user