diff --git a/.env b/.env new file mode 100644 index 0000000..8d571af --- /dev/null +++ b/.env @@ -0,0 +1,24 @@ +# ----------------------------- +# 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_PORT=3306 +DB_NAME=test_income_taxdb +DB_USER=root +DB_PASSWORD=root + diff --git a/AppCode/AOHandler.py b/AppCode/AOHandler.py index d7535df..d88cacc 100644 --- a/AppCode/AOHandler.py +++ b/AppCode/AOHandler.py @@ -4,8 +4,6 @@ import pandas as pd import io - - class AOHandler: def __init__(self): @@ -45,8 +43,7 @@ class AOHandler: ] values = [data.get(f, 0) for f in fields] - print("---- values ---- ",values) - + self.cursor.callproc("InsertAO", values) self.conn.commit() @@ -65,8 +62,6 @@ class AOHandler: values = [id] + [data.get(f, 0) for f in fields] - print("AO update values:", values) - self.cursor.callproc("UpdateAOById", values) self.conn.commit() diff --git a/AppCode/Config.py b/AppCode/Config.py index c238712..1d21e3a 100644 --- a/AppCode/Config.py +++ b/AppCode/Config.py @@ -3,10 +3,10 @@ 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") + 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(): diff --git a/AppCode/ITRHandler.py b/AppCode/ITRHandler.py index 997e5e8..2c939b0 100644 --- a/AppCode/ITRHandler.py +++ b/AppCode/ITRHandler.py @@ -24,8 +24,6 @@ class ITRHandler: # 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(): @@ -80,9 +78,6 @@ class ITRHandler: ] values = [id] + [data.get(col, 0) for col in columns] - - print("Final values:", values) - self.cursor.callproc("UpdateITR", values) self.conn.commit() @@ -95,7 +90,6 @@ class ITRHandler: # report download by year def itr_report_download(self, selected_year): - try: # Call stored procedure self.cursor.callproc("GetITRByYear", [selected_year]) @@ -109,14 +103,10 @@ class ITRHandler: # 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) @@ -139,7 +129,6 @@ class ITRHandler: print("MySQL Error →", e) return None - # CLOSE CONNECTION def close(self): self.cursor.close() diff --git a/AppCode/MatCreditHandler.py b/AppCode/MatCreditHandler.py index 167163c..076ea5e 100644 --- a/AppCode/MatCreditHandler.py +++ b/AppCode/MatCreditHandler.py @@ -1,8 +1,6 @@ from AppCode.Config import DBConfig import mysql.connector - - class MatCreditHandler: def __init__(self): diff --git a/AppCode/YearGet.py b/AppCode/YearGet.py index 4aca65a..269a963 100644 --- a/AppCode/YearGet.py +++ b/AppCode/YearGet.py @@ -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() diff --git a/AppCode/__pycache__/AOHandler.cpython-313.pyc b/AppCode/__pycache__/AOHandler.cpython-313.pyc index f57f9d9..020cfa2 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 cabdc72..9203dce 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 7ec5dcf..5c0a828 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 8817cf1..c079e32 100644 Binary files a/AppCode/__pycache__/DocumentHandler.cpython-313.pyc and b/AppCode/__pycache__/DocumentHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/ITATHandler.cpython-313.pyc b/AppCode/__pycache__/ITATHandler.cpython-313.pyc index b2302ac..d3955a7 100644 Binary files a/AppCode/__pycache__/ITATHandler.cpython-313.pyc and b/AppCode/__pycache__/ITATHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/ITRHandler.cpython-313.pyc b/AppCode/__pycache__/ITRHandler.cpython-313.pyc index 7506a52..b9ded7f 100644 Binary files a/AppCode/__pycache__/ITRHandler.cpython-313.pyc and b/AppCode/__pycache__/ITRHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/YearGet.cpython-313.pyc b/AppCode/__pycache__/YearGet.cpython-313.pyc index 0a977cf..9f34ccd 100644 Binary files a/AppCode/__pycache__/YearGet.cpython-313.pyc and b/AppCode/__pycache__/YearGet.cpython-313.pyc differ diff --git a/main.py b/main.py index 5985e0b..8b0eddd 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,9 @@ 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 AppCode.Config import DBConfig from AppCode.FileHandler import FileHandler @@ -22,8 +20,8 @@ from AppCode.MatCreditHandler import MatCreditHandler # 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 +38,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,6 +53,7 @@ def upload_file(): # View all documents with filters @app.route('/documents') +@auth.login_required def view_documents(): docHandler = DocumentHandler() docHandler.View(request=request) @@ -66,15 +62,15 @@ def view_documents(): # Upload file documents @app.route('/uploads/') +@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) file_ext = filename.rsplit('.', 1)[-1].lower() - # --- View Mode --- if mode == 'view': if file_ext == 'pdf': @@ -95,6 +91,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,6 +101,7 @@ 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() @@ -116,6 +114,7 @@ def add_itr(): ## 4. DELETE an ITR record @app.route('/itr/delete/', methods=['POST']) +@auth.login_required def delete_itr(id): itr = ITRHandler() itr.delete_itr_by_id(id=id) @@ -124,12 +123,13 @@ def delete_itr(id): ## 3. UPDATE an existing ITR record @app.route('/itr/update/', 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) + # data = {k: request.form.get(k, 0) for k in request.form} + itr.update(id, request.form) itr.close() return redirect(url_for('display_itr')) @@ -146,6 +146,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,6 +156,7 @@ 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() @@ -166,6 +168,7 @@ def add_ao(): # 3. UPDATE AO record @app.route('/ao/update/', methods=['GET', 'POST']) +@auth.login_required def update_ao(id): ao = AOHandler() record = ao.get_ao_by_id(id) @@ -186,6 +189,7 @@ def update_ao(id): # 4. DELETE AO record safely @app.route('/ao/delete/', methods=['POST']) +@auth.login_required def delete_ao(id): ao = AOHandler() ao.delete_ao_by_id(id=id) @@ -201,6 +205,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,6 +214,7 @@ 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() @@ -221,6 +227,7 @@ def add_cit(): # 3 delete CIT records by id @app.route('/cit/delete/', methods=['POST']) +@auth.login_required def delete_cit(id): cit = CITHandler() cit.delete_cit(id) @@ -230,6 +237,7 @@ def delete_cit(id): # 4 update CIT records by id @app.route('/cit/update/', methods=['GET', 'POST']) +@auth.login_required def update_cit(id): cit = CITHandler() record = cit.get_cit_by_id(id) @@ -239,8 +247,8 @@ def update_cit(id): return "CIT record not found", 404 if request.method == 'POST': - data = {k: request.form.get(k, 0) for k in request.form} - cit.update_cit(id, data) + # data = {k: request.form.get(k, 0) for k in request.form} + cit.update_cit(id, request.form) cit.close() return redirect(url_for('display_cit')) @@ -254,6 +262,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,6 +271,7 @@ 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() @@ -275,6 +285,7 @@ def add_itat(): # 3.Update ITAT records by id @app.route('/itat/update/', methods=['GET', 'POST']) +@auth.login_required def update_itat(id): itat = ITATHandler() record = itat.get_itat_by_id(id) @@ -294,6 +305,7 @@ def update_itat(id): # 3.delete ITAT records by id @app.route('/itat/delete/', methods=['POST']) +@auth.login_required def delete_itat(id): itat = ITATHandler() itat.delete_itat_by_id(id) @@ -307,11 +319,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 +352,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 +380,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 +409,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,34 +438,28 @@ 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) -# 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") - year = request.json.get("year") +# 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") - conn = DBConfig.get_db_connection() - cursor = conn.cursor() - - sqlstr = f"SELECT COUNT(*) FROM {table_name} WHERE year = %s" - cursor.execute(sqlstr, (year,)) - result = cursor.fetchone()[0] - - cursor.close() - conn.close() - - return {"exists": result > 0} - -# new new +# check_year_obj = YearGet() +# result = check_year_obj.CheckYearExists(table_name, year) +# check_year_obj.close() # Mat credit from @app.route("/mat_credit", methods=["GET"]) +@auth.login_required def mat_credit(): mat= MatCreditHandler() @@ -473,6 +484,7 @@ def mat_credit(): # save mat credit row data @app.route("/save_mat_row", methods=["POST"]) +@auth.login_required def save_mat_row(): mat= MatCreditHandler() try: @@ -483,6 +495,7 @@ def save_mat_row(): # save mat credit bulk data @app.route("/save_mat_all", methods=["POST"]) +@auth.login_required def save_mat_all(): mat= MatCreditHandler() try: @@ -492,6 +505,10 @@ def save_mat_all(): return jsonify({"error": str(e)}), 500 -# run +# run server if __name__ == '__main__': - app.run(host='0.0.0.0', port=5003, debug=True) \ No newline at end of file + app.run( + host=os.getenv("FLASK_HOST"), + port=int(os.getenv("FLASK_PORT")), + debug=os.getenv("FLASK_DEBUG") == "true" + ) \ No newline at end of file diff --git a/static/uploads/AY_18-19_REfund_Working.xlsx b/static/uploads/AY_18-19_REfund_Working.xlsx deleted file mode 100644 index a07486c..0000000 Binary files a/static/uploads/AY_18-19_REfund_Working.xlsx and /dev/null differ diff --git a/static/uploads/Income_Tax_System.docx b/static/uploads/Income_Tax_System.docx index 597d5f6..b1b2cfe 100644 Binary files a/static/uploads/Income_Tax_System.docx and b/static/uploads/Income_Tax_System.docx differ diff --git a/static/uploads/unmatched_result_1.xlsx b/static/uploads/unmatched_result_1.xlsx deleted file mode 100644 index c585782..0000000 Binary files a/static/uploads/unmatched_result_1.xlsx and /dev/null differ diff --git a/templates/mat_credit.html b/templates/mat_credit.html index 57936b4..6e8ac91 100644 --- a/templates/mat_credit.html +++ b/templates/mat_credit.html @@ -61,7 +61,7 @@
- +