diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..02215c9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +__pycache__/ +*.pyc +.git +.idea +venv diff --git a/.env b/.env index 8d571af..6ef70f0 100644 --- a/.env +++ b/.env @@ -2,7 +2,7 @@ # Flask App Configuration # ----------------------------- FLASK_ENV=development -FLASK_DEBUG=True +FLASK_DEBUG=true FLASK_HOST=0.0.0.0 FLASK_PORT=5010 @@ -17,6 +17,7 @@ SECRET_KEY=secret1234 DB_DIALECT=mysql # DB_DRIVER=pymysql DB_HOST=127.0.0.1 +# DB_HOST=db # this is production for use docker DB_PORT=3306 DB_NAME=test_income_taxdb DB_USER=root diff --git a/AppCode/AOHandler.py b/AppCode/AOHandler.py index bc5327a..7aa648c 100644 --- a/AppCode/AOHandler.py +++ b/AppCode/AOHandler.py @@ -3,7 +3,6 @@ import mysql.connector import pandas as pd import io - class AOHandler: def __init__(self): @@ -49,7 +48,6 @@ class AOHandler: self.cursor.callproc("InsertAO", values) self.conn.commit() - # UPDATE AO RECORD by AO id def update_ao(self, id, data): fields = [ @@ -193,8 +191,6 @@ class AOHandler: print("MySQL Error →", e) return None - - # CLOSE CONNECTION def close(self): self.cursor.close() diff --git a/AppCode/CITHandler.py b/AppCode/CITHandler.py index 96b9ed9..7762870 100644 --- a/AppCode/CITHandler.py +++ b/AppCode/CITHandler.py @@ -3,7 +3,6 @@ import mysql.connector import pandas as pd import io - class CITHandler: def __init__(self): diff --git a/AppCode/Config.py b/AppCode/Config.py index 1d21e3a..0a83119 100644 --- a/AppCode/Config.py +++ b/AppCode/Config.py @@ -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("DB_HOST") - MYSQL_USER = os.getenv("DB_USER") - MYSQL_PASSWORD = os.getenv("DB_PASSWORD") - MYSQL_DB = os.getenv("DB_NAME") +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 ) diff --git a/AppCode/ITRHandler.py b/AppCode/ITRHandler.py index 4cb6bf1..2cec0cb 100644 --- a/AppCode/ITRHandler.py +++ b/AppCode/ITRHandler.py @@ -1,11 +1,9 @@ import mysql.connector import pandas as pd -import pymysql import io from flask import send_file, render_template, request from AppCode.Config import DBConfig -from AppCode.YearGet import YearGet class ITRHandler: @@ -14,7 +12,6 @@ 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.callproc("GetAllItr") @@ -52,7 +49,7 @@ class ITRHandler: 'tax_payable', 'surcharge', 'edu_cess', 'total_tax_payable', 'mat_credit_created', 'mat_credit_utilized', 'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', - 'sat', 'tax_on_assessment', 'refund', 'Remarks' + 'sat', 'tax_on_assessment', 'refund', 'Remarks','created_at' ] values = [data.get(col, 0) for col in columns] diff --git a/AppCode/MatCreditHandler.py b/AppCode/MatCreditHandler.py index 2fa0a9b..e2cf3e6 100644 --- a/AppCode/MatCreditHandler.py +++ b/AppCode/MatCreditHandler.py @@ -1,5 +1,4 @@ from AppCode.Config import DBConfig -import mysql.connector class MatCreditHandler: diff --git a/AppCode/__pycache__/AOHandler.cpython-313.pyc b/AppCode/__pycache__/AOHandler.cpython-313.pyc index 3f90d31..d1b3df1 100644 Binary files a/AppCode/__pycache__/AOHandler.cpython-313.pyc and b/AppCode/__pycache__/AOHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/CITHandler.cpython-313.pyc b/AppCode/__pycache__/CITHandler.cpython-313.pyc index 3567079..6c03b4e 100644 Binary files a/AppCode/__pycache__/CITHandler.cpython-313.pyc and b/AppCode/__pycache__/CITHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/Config.cpython-313.pyc b/AppCode/__pycache__/Config.cpython-313.pyc index c2eec6e..45757f6 100644 Binary files a/AppCode/__pycache__/Config.cpython-313.pyc and b/AppCode/__pycache__/Config.cpython-313.pyc differ diff --git a/AppCode/__pycache__/DocumentHandler.cpython-313.pyc b/AppCode/__pycache__/DocumentHandler.cpython-313.pyc index 7e86f34..e8cf652 100644 Binary files a/AppCode/__pycache__/DocumentHandler.cpython-313.pyc and b/AppCode/__pycache__/DocumentHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/ITRHandler.cpython-313.pyc b/AppCode/__pycache__/ITRHandler.cpython-313.pyc index 351f0f8..7047dc7 100644 Binary files a/AppCode/__pycache__/ITRHandler.cpython-313.pyc and b/AppCode/__pycache__/ITRHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/LoginAuth.cpython-313.pyc b/AppCode/__pycache__/LoginAuth.cpython-313.pyc index aab7396..9f22f7c 100644 Binary files a/AppCode/__pycache__/LoginAuth.cpython-313.pyc and b/AppCode/__pycache__/LoginAuth.cpython-313.pyc differ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..42dac6e --- /dev/null +++ b/Dockerfile @@ -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"] + diff --git a/db/income_tax.sql b/db/income_tax.sql new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..62d4f52 --- /dev/null +++ b/docker-compose.yml @@ -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: diff --git a/main.py b/main.py index 57459f8..1b2dfa6 100644 --- a/main.py +++ b/main.py @@ -4,7 +4,7 @@ from dotenv import load_dotenv load_dotenv() import pandas as pd from werkzeug.utils import secure_filename - +from datetime import date from AppCode.Config import DBConfig from AppCode.LoginAuth import LoginAuth from AppCode.FileHandler import FileHandler @@ -107,10 +107,16 @@ def add_itr(): itr = ITRHandler() itr.add_itr(request.form) 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 render_template('add_itr.html') + return render_template('add_itr.html',current_date=date.today().isoformat()) ## 4. DELETE an ITR record @app.route('/itr/delete/', methods=['POST']) @@ -135,7 +141,7 @@ def update_itr(id): 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()) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..094b0db --- /dev/null +++ b/requirements.txt @@ -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 diff --git a/static/js/itr_calc.js b/static/js/itr_calc.js index 8e5b445..1ca7d5d 100644 --- a/static/js/itr_calc.js +++ b/static/js/itr_calc.js @@ -46,16 +46,6 @@ 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", surcharge); - - // // --- edu_cess --- - // var per_cess = getValue("persentage_cess") - // var edu_cess = (tax_payable + surcharge) * (per_cess / 100); - // setValue("edu_cess", edu_cess); - // --- SURCHARGE --- var percent = getValue("persentage"); var surcharge = tax_payable * (percent / 100); @@ -70,10 +60,16 @@ document.addEventListener("DOMContentLoaded", function () { var total_tax_payable = tax_payable + surcharge + edu_cess; 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 --- var mat_credit = 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; setValue("total_tax", total_tax); diff --git a/templates/add_itr.html b/templates/add_itr.html index 54f1378..c112eff 100644 --- a/templates/add_itr.html +++ b/templates/add_itr.html @@ -10,7 +10,8 @@ {% block content %}

New Income Tax Return Form

-
+ +
@@ -21,6 +22,10 @@
+
+ + +
@@ -166,9 +171,15 @@
-
- - +
+
+ + +
+
+ + +
diff --git a/templates/display_itr.html b/templates/display_itr.html index 9a8e774..9a1e6ac 100644 --- a/templates/display_itr.html +++ b/templates/display_itr.html @@ -22,6 +22,7 @@ Net Taxable Income Total Tax Payable Refund + Created Record Date Actions @@ -33,6 +34,7 @@ {{ "{:,.2f}".format(record.net_taxable_income) }} {{ "{:,.2f}".format(record.total_tax_payable) }} {{ "{:,.2f}".format(record.refund) }} + {{ record.created_at.strftime('%Y-%m-%d') }} Edit Remarks:
+
+
+ + +
+ +
+ + +
+
+
diff --git a/templates/upload.html b/templates/upload.html index 19c2c93..bf2100c 100644 --- a/templates/upload.html +++ b/templates/upload.html @@ -9,7 +9,7 @@ {% block content %}

Upload Income Tax Documents

-
+