added docker and chnages of from model changes commits
This commit is contained in:
5
.dockerignore
Normal file
5
.dockerignore
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.git
|
||||||
|
.idea
|
||||||
|
venv
|
||||||
3
.env
3
.env
@@ -2,7 +2,7 @@
|
|||||||
# Flask App Configuration
|
# Flask App Configuration
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
FLASK_ENV=development
|
FLASK_ENV=development
|
||||||
FLASK_DEBUG=True
|
FLASK_DEBUG=true
|
||||||
FLASK_HOST=0.0.0.0
|
FLASK_HOST=0.0.0.0
|
||||||
FLASK_PORT=5010
|
FLASK_PORT=5010
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ SECRET_KEY=secret1234
|
|||||||
DB_DIALECT=mysql
|
DB_DIALECT=mysql
|
||||||
# DB_DRIVER=pymysql
|
# DB_DRIVER=pymysql
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
|
# DB_HOST=db # this is production for use docker
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
DB_NAME=test_income_taxdb
|
DB_NAME=test_income_taxdb
|
||||||
DB_USER=root
|
DB_USER=root
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import mysql.connector
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import io
|
import io
|
||||||
|
|
||||||
|
|
||||||
class AOHandler:
|
class AOHandler:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -49,7 +48,6 @@ class AOHandler:
|
|||||||
self.cursor.callproc("InsertAO", values)
|
self.cursor.callproc("InsertAO", values)
|
||||||
self.conn.commit()
|
self.conn.commit()
|
||||||
|
|
||||||
|
|
||||||
# UPDATE AO RECORD by AO id
|
# UPDATE AO RECORD by AO id
|
||||||
def update_ao(self, id, data):
|
def update_ao(self, id, data):
|
||||||
fields = [
|
fields = [
|
||||||
@@ -193,8 +191,6 @@ class AOHandler:
|
|||||||
print("MySQL Error →", e)
|
print("MySQL Error →", e)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# CLOSE CONNECTION
|
# CLOSE CONNECTION
|
||||||
def close(self):
|
def close(self):
|
||||||
self.cursor.close()
|
self.cursor.close()
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import mysql.connector
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import io
|
import io
|
||||||
|
|
||||||
|
|
||||||
class CITHandler:
|
class CITHandler:
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
@@ -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 mysql.connector
|
||||||
import os
|
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")
|
|
||||||
|
|
||||||
|
class DBConfig:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_db_connection():
|
def get_db_connection():
|
||||||
"""
|
"""
|
||||||
Returns a MySQL connection object.
|
Create and return a MySQL database connection
|
||||||
|
using environment variables.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return mysql.connector.connect(
|
return mysql.connector.connect(
|
||||||
host=DBConfig.MYSQL_HOST,
|
host=os.getenv("DB_HOST", "db"), # Docker service name
|
||||||
user=DBConfig.MYSQL_USER,
|
port=int(os.getenv("DB_PORT", 3306)),
|
||||||
password=DBConfig.MYSQL_PASSWORD,
|
user=os.getenv("DB_USER", "root"),
|
||||||
database=DBConfig.MYSQL_DB
|
password=os.getenv("DB_PASSWORD", "root"),
|
||||||
|
database=os.getenv("DB_NAME", "test_income_taxdb"),
|
||||||
|
autocommit=False
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
import mysql.connector
|
import mysql.connector
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pymysql
|
|
||||||
import io
|
import io
|
||||||
from flask import send_file, render_template, request
|
from flask import send_file, render_template, request
|
||||||
|
|
||||||
from AppCode.Config import DBConfig
|
from AppCode.Config import DBConfig
|
||||||
from AppCode.YearGet import YearGet
|
|
||||||
|
|
||||||
|
|
||||||
class ITRHandler:
|
class ITRHandler:
|
||||||
@@ -14,7 +12,6 @@ class ITRHandler:
|
|||||||
self.conn = DBConfig.get_db_connection()
|
self.conn = DBConfig.get_db_connection()
|
||||||
self.cursor = self.conn.cursor(dictionary=True)
|
self.cursor = self.conn.cursor(dictionary=True)
|
||||||
|
|
||||||
|
|
||||||
# GET ALL ITR RECORDS using stored procedure "GetAllItr"
|
# GET ALL ITR RECORDS using stored procedure "GetAllItr"
|
||||||
def get_all_itr(self):
|
def get_all_itr(self):
|
||||||
self.cursor.callproc("GetAllItr")
|
self.cursor.callproc("GetAllItr")
|
||||||
@@ -52,7 +49,7 @@ class ITRHandler:
|
|||||||
'tax_payable', 'surcharge', 'edu_cess',
|
'tax_payable', 'surcharge', 'edu_cess',
|
||||||
'total_tax_payable', 'mat_credit_created', 'mat_credit_utilized',
|
'total_tax_payable', 'mat_credit_created', 'mat_credit_utilized',
|
||||||
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs',
|
'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs',
|
||||||
'sat', 'tax_on_assessment', 'refund', 'Remarks'
|
'sat', 'tax_on_assessment', 'refund', 'Remarks','created_at'
|
||||||
]
|
]
|
||||||
values = [data.get(col, 0) for col in columns]
|
values = [data.get(col, 0) for col in columns]
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
from AppCode.Config import DBConfig
|
from AppCode.Config import DBConfig
|
||||||
import mysql.connector
|
|
||||||
|
|
||||||
class MatCreditHandler:
|
class MatCreditHandler:
|
||||||
|
|
||||||
|
|||||||
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:
|
||||||
14
main.py
14
main.py
@@ -4,7 +4,7 @@ from dotenv import load_dotenv
|
|||||||
load_dotenv()
|
load_dotenv()
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
from datetime import date
|
||||||
from AppCode.Config import DBConfig
|
from AppCode.Config import DBConfig
|
||||||
from AppCode.LoginAuth import LoginAuth
|
from AppCode.LoginAuth import LoginAuth
|
||||||
from AppCode.FileHandler import FileHandler
|
from AppCode.FileHandler import FileHandler
|
||||||
@@ -107,10 +107,16 @@ def add_itr():
|
|||||||
itr = ITRHandler()
|
itr = ITRHandler()
|
||||||
itr.add_itr(request.form)
|
itr.add_itr(request.form)
|
||||||
itr.close()
|
itr.close()
|
||||||
flash("ITR record added successfully!", "success")
|
|
||||||
|
if 'documents' in request.files:
|
||||||
|
doc = DocumentHandler()
|
||||||
|
doc.Upload(request)
|
||||||
|
|
||||||
|
# flash("ITR record added successfully!", "success")
|
||||||
|
flash("ITR record and documents uploaded successfully!", "success")
|
||||||
return redirect(url_for('display_itr'))
|
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 record
|
||||||
@app.route('/itr/delete/<int:id>', methods=['POST'])
|
@app.route('/itr/delete/<int:id>', methods=['POST'])
|
||||||
@@ -135,7 +141,7 @@ def update_itr(id):
|
|||||||
|
|
||||||
record = itr.get_itr_by_id(id)
|
record = itr.get_itr_by_id(id)
|
||||||
itr.close()
|
itr.close()
|
||||||
return render_template('update_itr.html', record=record)
|
return render_template('update_itr.html', record=record, current_date=date.today().isoformat())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
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
|
||||||
@@ -46,16 +46,6 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
var tax_payable = (tax30 > tax185) ? tax30 : tax185;
|
var tax_payable = (tax30 > tax185) ? tax30 : tax185;
|
||||||
setValue("tax_payable", tax_payable);
|
setValue("tax_payable", tax_payable);
|
||||||
|
|
||||||
// // --- SURCHARGE ---
|
|
||||||
// var percent = getValue("persentage");
|
|
||||||
// var surcharge = tax_payable * (percent / 100);
|
|
||||||
// setValue("surcharge", surcharge);
|
|
||||||
|
|
||||||
// // --- edu_cess ---
|
|
||||||
// var per_cess = getValue("persentage_cess")
|
|
||||||
// var edu_cess = (tax_payable + surcharge) * (per_cess / 100);
|
|
||||||
// setValue("edu_cess", edu_cess);
|
|
||||||
|
|
||||||
// --- SURCHARGE ---
|
// --- SURCHARGE ---
|
||||||
var percent = getValue("persentage");
|
var percent = getValue("persentage");
|
||||||
var surcharge = tax_payable * (percent / 100);
|
var surcharge = tax_payable * (percent / 100);
|
||||||
@@ -70,10 +60,16 @@ document.addEventListener("DOMContentLoaded", function () {
|
|||||||
var total_tax_payable = tax_payable + surcharge + edu_cess;
|
var total_tax_payable = tax_payable + surcharge + edu_cess;
|
||||||
setValue("total_tax_payable", total_tax_payable);
|
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));
|
||||||
|
|
||||||
// --- FINAL TAX ---
|
// --- FINAL TAX ---
|
||||||
var mat_credit = getValue("mat_credit_utilized");
|
var mat_credit = getValue("mat_credit_utilized");
|
||||||
var interest_234c = getValue("interest_234c");
|
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 + mat_credit + interest_234c;
|
||||||
setValue("total_tax", total_tax);
|
setValue("total_tax", total_tax);
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2 style="text-align:center;">New Income Tax Return Form</h2>
|
<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 class="form-group full-width inline-2">
|
||||||
<div>
|
<div>
|
||||||
<label>Assessment Year:</label>
|
<label>Assessment Year:</label>
|
||||||
@@ -21,6 +22,10 @@
|
|||||||
</select>
|
</select>
|
||||||
<div id="yearError" style="color:red; display:none; margin-bottom:10px;"></div>
|
<div id="yearError" style="color:red; display:none; margin-bottom:10px;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>Created Date:</label>
|
||||||
|
<input type="date" name="created_at" value="{{ current_date }}" required>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group full-width inline-2">
|
<div class="form-group full-width inline-2">
|
||||||
<div>
|
<div>
|
||||||
@@ -166,10 +171,16 @@
|
|||||||
<input type="number" name="refund" class="auto" step="any" value="0.00" readonly>
|
<input type="number" name="refund" class="auto" step="any" value="0.00" readonly>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group full-width inline-2">
|
||||||
|
<div>
|
||||||
|
<label>Select Documents:</label>
|
||||||
|
<input type="file" name="documents" multiple>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
<label>Remarks:</label>
|
<label>Remarks:</label>
|
||||||
<input type="text" name="Remarks">
|
<input type="text" name="Remarks">
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
<th>Net Taxable Income</th>
|
<th>Net Taxable Income</th>
|
||||||
<th>Total Tax Payable</th>
|
<th>Total Tax Payable</th>
|
||||||
<th>Refund</th>
|
<th>Refund</th>
|
||||||
|
<th>Created Record Date</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -33,6 +34,7 @@
|
|||||||
<td>{{ "{:,.2f}".format(record.net_taxable_income) }}</td>
|
<td>{{ "{:,.2f}".format(record.net_taxable_income) }}</td>
|
||||||
<td>{{ "{:,.2f}".format(record.total_tax_payable) }}</td>
|
<td>{{ "{:,.2f}".format(record.total_tax_payable) }}</td>
|
||||||
<td>{{ "{:,.2f}".format(record.refund) }}</td>
|
<td>{{ "{:,.2f}".format(record.refund) }}</td>
|
||||||
|
<td>{{ record.created_at.strftime('%Y-%m-%d') }}</td>
|
||||||
<td class="action-cell">
|
<td class="action-cell">
|
||||||
<a href="{{ url_for('update_itr', id=record.id) }}" class="btn btn-update">Edit</a>
|
<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"
|
<form action="{{ url_for('delete_itr', id=record.id) }}" method="post"
|
||||||
|
|||||||
@@ -169,6 +169,22 @@
|
|||||||
<label>Remarks:</label>
|
<label>Remarks:</label>
|
||||||
<input type="text" name="Remarks" value="{{ record.Remarks }}">
|
<input type="text" name="Remarks" value="{{ record.Remarks }}">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group full-width inline-2">
|
||||||
|
<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 }}"
|
||||||
|
readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button type="submit">Update Record</button>
|
<button type="submit">Update Record</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h2>Upload Income Tax Documents</h2>
|
<h2>Upload Income Tax Documents</h2>
|
||||||
<form id="income_tax_documents" method="POST" enctype="multipart/form-data">
|
<form id="documents" method="POST" enctype="multipart/form-data">
|
||||||
<label>Year:</label>
|
<label>Year:</label>
|
||||||
<select id="year" name="year" required></select>
|
<select id="year" name="year" required></select>
|
||||||
<div id="yearError" style="color: red; display: none; margin-bottom: 10px;"></div>
|
<div id="yearError" style="color: red; display: none; margin-bottom: 10px;"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user