diff --git a/AppCode/AOHandler.py b/AppCode/AOHandler.py new file mode 100644 index 0000000..55ddafd --- /dev/null +++ b/AppCode/AOHandler.py @@ -0,0 +1,95 @@ +from AppCode.Config import DBConfig +import mysql.connector + + + +class AOHandler: + + def __init__(self): + self.conn = DBConfig.get_db_connection() + self.cursor = self.conn.cursor(dictionary=True) + + + # GET ALL AO RECORDS using stored procedure "GetAllItr" + def get_all_ao(self): + + self.cursor.callproc("GetAllAO") + records = [] + + for result in self.cursor.stored_results(): + records = result.fetchall() + + return records + + + def get_ao_by_id(self, id): + # Call stored procedure + self.cursor.callproc('GetAORById', [id]) + + # Fetch result + records = [] + for result in self.cursor.stored_results(): + records = result.fetchall() + + if records: + print(records[0]) + return records[0] # return single record + + return None + + + + + # INSERT ITR RECORD using procedure "add_itr" + # def add_itr(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', 'tax_on_assessment', 'refund' + # ] + + # values = [data.get(col, 0) for col in columns] + + # # Call your stored procedure + # self.cursor.callproc("InsertITR", values) + # self.conn.commit() + + + # UPDATE ITR RECORD by ITR 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', 'tax_on_assessment', 'refund' + # ] + + # set_clause = ", ".join([f"{col}=%s" for col in columns]) + + # query = f"UPDATE itr SET {set_clause} WHERE id = %s" + + # values = [data.get(col, 0) for col in columns] + # values.append(id) + + # self.cursor.execute(query, tuple(values)) + # self.conn.commit() + + + # # DELETE RECORD by ITR id + # def delete_itr_by_id(self, id): + # # Call the stored procedure + # self.cursor.callproc('DeleteITRById', [id]) + # self.conn.commit() + + + # CLOSE CONNECTION + def close(self): + self.cursor.close() + self.conn.close() diff --git a/AppCode/Config.py b/AppCode/Config.py new file mode 100644 index 0000000..06b8d74 --- /dev/null +++ b/AppCode/Config.py @@ -0,0 +1,21 @@ +import mysql.connector +import os + +class DBConfig: + # Database credentials (can also be read from environment variables) + 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", "income_tax") + + @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 + ) diff --git a/AppCode/DocumentHandler.py b/AppCode/DocumentHandler.py new file mode 100644 index 0000000..189857c --- /dev/null +++ b/AppCode/DocumentHandler.py @@ -0,0 +1,99 @@ +import os +from AppCode.Config import DBConfig +from AppCode.FileHandler import FileHandler +from werkzeug.utils import secure_filename + +class DocumentHandler: + + def __init__(self): + self.years = [] + self.documents = [] + self.isSuccess = False + self.resultMessage = "" + + # VIEW DOCUMENTS + def View(self, request): + year = request.args.get('year', '') + stage = request.args.get('stage', '') + + dbconfig = DBConfig() + connection = dbconfig.get_db_connection() + + if not connection: + self.isSuccess = False + return + + cursor = connection.cursor(dictionary=True) + + # --- FILTER QUERY --- + query = "SELECT * FROM documents WHERE 1=1" + params = [] + + if year != "": + query += " AND year = %s" + params.append(year) + + if stage != "": + query += " AND stage = %s" + params.append(stage) + + + cursor.execute(query, params) + self.documents = cursor.fetchall() + + # ---- GET YEARS FROM STORED PROCEDURE ---- + cursor.callproc("GetYear") + + for result in cursor.stored_results(): + year_rows = result.fetchall() + break # only first result set + + self.years = [row['year'] for row in year_rows] + + cursor.close() + connection.close() + self.isSuccess = True + + # UPLOAD DOCUMENTS + def Upload(self, request): + """Log user actions with timestamp, user, action, and details.""" + + 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'] + + for file in files: + if file is not FileHandler.ALLOWED_EXTENSIONS: + continue + + + filename = secure_filename(file.filename) + filepath = os.path.join(FileHandler.UPLOAD_FOLDER, filename) + extension = file.filename.rsplit('.', 1)[1] + # Need to Check whetehr all three items are required + + file.save(filepath) + + # cursor.execute(""" + # INSERT INTO documents (filename, filepath, filetype, year, stage) + # VALUES (%s, %s, %s, %s, %s) + # """, (filename, filepath, file.filename.rsplit('.', 1)[1], year, stage)) + + + cursor.callproc('InsertDocument', [ + filename, + filepath, + extension, + year, + stage + ]) + + connection.commit() + cursor.close() + connection.close() + # return redirect(url_for('view_documents')) diff --git a/AppCode/FileHandler.py b/AppCode/FileHandler.py new file mode 100644 index 0000000..77a1b72 --- /dev/null +++ b/AppCode/FileHandler.py @@ -0,0 +1,12 @@ +import os + +class FileHandler: + ALLOWED_EXTENSIONS = {'pdf', 'docx', 'doc', 'xlsx', 'xls'} + UPLOAD_FOLDER = os.path.join('static', 'uploads') + + + @staticmethod + def CHeckExistingOrCreateNewUploadFolder(): + #Wheteher path exists + os.makedirs(FileHandler.UPLOAD_FOLDER, exist_ok=True) + return \ No newline at end of file diff --git a/AppCode/ITRHandler.py b/AppCode/ITRHandler.py new file mode 100644 index 0000000..c3d3c1c --- /dev/null +++ b/AppCode/ITRHandler.py @@ -0,0 +1,96 @@ +from AppCode.Config import DBConfig +import mysql.connector + + + +class ITRHandler: + + def __init__(self): + 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(): + records = result.fetchall() + + return records + + + def get_itr_by_id(self, id): + # Call stored procedure + self.cursor.callproc('GetITRById', [id]) + + # Fetch result + records = [] + for result in self.cursor.stored_results(): + records = result.fetchall() + + if records: + print(records[0]) + return records[0] # return single record + + return None + + + + + # INSERT ITR RECORD using procedure "add_itr" + def add_itr(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', 'tax_on_assessment', 'refund' + ] + + values = [data.get(col, 0) for col in columns] + + # Call your stored procedure + self.cursor.callproc("InsertITR", values) + self.conn.commit() + + + # UPDATE ITR RECORD by ITR 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', 'tax_on_assessment', 'refund' + ] + + set_clause = ", ".join([f"{col}=%s" for col in columns]) + + query = f"UPDATE itr SET {set_clause} WHERE id = %s" + + values = [data.get(col, 0) for col in columns] + values.append(id) + + self.cursor.execute(query, tuple(values)) + self.conn.commit() + + + # DELETE RECORD by ITR id + def delete_itr_by_id(self, id): + # Call the stored procedure + self.cursor.callproc('DeleteITRById', [id]) + self.conn.commit() + + + # CLOSE CONNECTION + def close(self): + self.cursor.close() + self.conn.close() diff --git a/AppCode/Log.py b/AppCode/Log.py new file mode 100644 index 0000000..3c994f8 --- /dev/null +++ b/AppCode/Log.py @@ -0,0 +1,25 @@ +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 + def log_action(action, details=""): + """Log user actions with timestamp, user, action, and details.""" + logData = LogData() + logData.WriteLog(action, details="") + + + +class LogData: + + filepath = "" + timestamp = None + + def __init__(self): + self.filepath = os.path.join(current_app.root_path, 'activity.log') + self.timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S") diff --git a/AppCode/Utiliies.py b/AppCode/Utiliies.py new file mode 100644 index 0000000..f8c064f --- /dev/null +++ b/AppCode/Utiliies.py @@ -0,0 +1,58 @@ +from flask import flash, jsonify, json +from enum import Enum + + +class RegEx: + patternAlphabetOnly = "^[A-Za-z ]+$" + + +class ResponseHandler: + @staticmethod + def invalid_name(entity): + return {'status': 'error', 'message': f'Invalid {entity} name. Only letters are allowed!'} + + @staticmethod + def already_exists(entity): + return {'status': 'exists', 'message': f'{entity.capitalize()} already exists!'} + + @staticmethod + def add_success(entity): + return {'status': 'success', 'message': f'{entity.capitalize()} added successfully!'} + + @staticmethod + def add_failure(entity): + return {'status': 'error', 'message': f'Failed to add {entity}.'} + + @staticmethod + def is_available(entity): + return {'status': 'available', 'message': f'{entity.capitalize()} name is available!'} + + @staticmethod + def delete_success(entity): + return {'status': 'success', 'message': f'{entity.capitalize()} deleted successfully!'} + + @staticmethod + def delete_failure(entity): + return {'status': 'error', 'message': f'Failed to delete {entity}.'} + + @staticmethod + def update_success(entity): + return {'status': 'success', 'message': f'{entity.capitalize()} updated successfully!'} + + @staticmethod + def update_failure(entity): + return {'status': 'error', 'message': f'Failed to update {entity}.'} + + @staticmethod + def fetch_failure(entity): + return {'status': 'error', 'message': f'Failed to fetch {entity}.'} + + +class HtmlHelper: + # Helper: JSON Response Formatter + + @staticmethod + def json_response(message_obj, status_code): + return jsonify(message_obj), status_code + #May need to refactor further + diff --git a/AppCode/__pycache__/AOHandler.cpython-313.pyc b/AppCode/__pycache__/AOHandler.cpython-313.pyc new file mode 100644 index 0000000..28aa3ee Binary files /dev/null and b/AppCode/__pycache__/AOHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/Config.cpython-313.pyc b/AppCode/__pycache__/Config.cpython-313.pyc new file mode 100644 index 0000000..36af679 Binary files /dev/null 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 new file mode 100644 index 0000000..2153fb1 Binary files /dev/null and b/AppCode/__pycache__/DocumentHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/FileHandler.cpython-313.pyc b/AppCode/__pycache__/FileHandler.cpython-313.pyc new file mode 100644 index 0000000..841cee0 Binary files /dev/null and b/AppCode/__pycache__/FileHandler.cpython-313.pyc differ diff --git a/AppCode/__pycache__/ITRHandler.cpython-313.pyc b/AppCode/__pycache__/ITRHandler.cpython-313.pyc new file mode 100644 index 0000000..f54a111 Binary files /dev/null and b/AppCode/__pycache__/ITRHandler.cpython-313.pyc differ diff --git a/IncomeTaxSystem.code-workspace b/IncomeTaxSystem.code-workspace new file mode 100644 index 0000000..876a149 --- /dev/null +++ b/IncomeTaxSystem.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": {} +} \ No newline at end of file diff --git a/__pycache__/config.cpython-313.pyc b/__pycache__/config.cpython-313.pyc index f6387b5..f577797 100644 Binary files a/__pycache__/config.cpython-313.pyc and b/__pycache__/config.cpython-313.pyc differ diff --git a/__pycache__/config.cpython-314.pyc b/__pycache__/config.cpython-314.pyc new file mode 100644 index 0000000..2d9109a Binary files /dev/null and b/__pycache__/config.cpython-314.pyc differ diff --git a/config.py b/config.py index e80fc75..12e041d 100644 --- a/config.py +++ b/config.py @@ -1,7 +1,8 @@ db_config = { 'host': 'localhost', 'user': 'root', - 'password': 'admin', + 'password': 'root', 'database': 'income_tax', 'port': 3306 } + diff --git a/main.py b/main.py index a85fc47..dc53394 100644 --- a/main.py +++ b/main.py @@ -1,13 +1,22 @@ -from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort +from flask import Flask, render_template, request, redirect, url_for, send_from_directory, abort, flash,send_file import os import mysql.connector from werkzeug.utils import secure_filename +from AppCode.FileHandler import FileHandler +from AppCode.DocumentHandler import DocumentHandler +from AppCode.ITRHandler import ITRHandler +from AppCode.AOHandler import AOHandler from config import db_config +from AppCode.Config import DBConfig + app = Flask(__name__) -app.config['UPLOAD_FOLDER'] = os.path.join('static', 'uploads') -ALLOWED_EXTENSIONS = {'pdf', 'docx', 'doc', 'xlsx', 'xls'} +app.secret_key="secret1234" +app.config['UPLOAD_FOLDER'] = FileHandler.UPLOAD_FOLDER +#ALLOWED_EXTENSIONS = {'pdf', 'docx', 'doc', 'xlsx', 'xls'} + + @app.route('/') def welcome(): @@ -18,38 +27,19 @@ def index(): return render_template('index.html') # Your dashboard page # Ensure folder exists -os.makedirs(app.config['UPLOAD_FOLDER'], exist_ok=True) - def allowed_file(filename): - return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS + return '.' in filename and filename.rsplit('.', 1)[1].lower() in FileHandler.ALLOWED_EXTENSIONS # Upload route @app.route('/upload', methods=['GET', 'POST']) def upload_file(): + if request.method == 'POST': - files = request.files.getlist('documents') - year = request.form['year'] - stage = request.form['stage'] - - conn = mysql.connector.connect(**db_config) - cursor = conn.cursor() - - for file in files: - if file and allowed_file(file.filename): - filename = secure_filename(file.filename) - filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename) - file.save(filepath) - - cursor.execute(""" - INSERT INTO documents (filename, filepath, filetype, year, stage) - VALUES (%s, %s, %s, %s, %s) - """, (filename, filepath, file.filename.rsplit('.', 1)[1], year, stage)) - - conn.commit() - cursor.close() - conn.close() + FileHandler.CHeckExistingOrCreateNewUploadFolder() + docHandler = DocumentHandler() + docHandler.Upload(request=request) return redirect(url_for('view_documents')) return render_template('upload.html') @@ -58,37 +48,13 @@ def upload_file(): # View all documents with filters @app.route('/documents') def view_documents(): - year = request.args.get('year') - stage = request.args.get('stage') - conn = mysql.connector.connect(**db_config) - cursor = conn.cursor(dictionary=True) - - query = "SELECT * FROM documents WHERE 1=1" - params = [] - - if year: - query += " AND year = %s" - params.append(year) - if stage: - query += " AND stage = %s" - params.append(stage) - - cursor.execute(query, params) - documents = cursor.fetchall() - - cursor.execute("SELECT DISTINCT year FROM documents ORDER BY year DESC") - years = [row['year'] for row in cursor.fetchall()] - - cursor.close() - conn.close() - - return render_template('view_docs.html', documents=documents, years=years) + docHandler = DocumentHandler() + docHandler.View(request=request) + return render_template('view_docs.html', documents=docHandler.documents, years=docHandler.years) -# Serve uploaded file -from flask import send_file - +# Upload file documents @app.route('/uploads/') def uploaded_file(filename): mode = request.args.get('mode', 'view') @@ -117,47 +83,61 @@ def uploaded_file(filename): ## 1. READ/DISPLAY all ITR records # This page will show all records in a table with Edit and Delete buttons. -@app.route('/itr_records') -def display_itr(): - conn = get_db_connection() - cursor = conn.cursor(dictionary=True) - cursor.execute("SELECT * FROM itr ORDER BY year DESC, id DESC") - records = cursor.fetchall() - cursor.close() - conn.close() - return render_template('display_itr.html', records=records) +# @app.route('/itr_records') +# def display_itr(): +# conn = get_db_connection() +# cursor = conn.cursor(dictionary=True) +# # cursor.execute("SELECT * FROM itr ORDER BY year DESC, id DESC") +# # records = cursor.fetchall() + +# cursor.callproc("GetAllItr") +# records = [] +# for result in cursor.stored_results(): +# records = result.fetchall() + + +# cursor.close() +# conn.close() +# return render_template('display_itr.html', records=records) + + ## 2. CREATE/ADD a new ITR record # This route handles both showing the blank form and saving the new data. -@app.route('/itr/add', methods=['GET', 'POST']) -def add_itr(): - if request.method == 'POST': - conn = get_db_connection() - cursor = conn.cursor() +# @app.route('/itr/add', methods=['GET', 'POST']) +# def add_itr(): +# if request.method == 'POST': +# conn = get_db_connection() +# cursor = conn.cursor() - # A list of all columns in your form and database table - columns = [ - 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', - 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', - 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', - 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', - 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', - 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' - ] +# # A list of all columns in your form and database table +# columns = [ +# 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', +# 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', +# 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', +# 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', +# 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', +# 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' +# ] - query = f"INSERT INTO itr ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})" - values = [request.form.get(col, 0) for col in columns] +# values = [request.form.get(col, 0) for col in columns] +# # query = f"INSERT INTO itr ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})" + - cursor.execute(query, tuple(values)) - conn.commit() - cursor.close() - conn.close() - # After adding, redirect to the page that shows all records - return redirect(url_for('display_itr')) +# # cursor.execute(query, tuple(values)) - # If it's a GET request, just show the blank form to add a record - return render_template('add_itr.html') +# cursor.callproc('InsertITR', values) + +# conn.commit() +# cursor.close() +# conn.close() +# flash("ITAT record added successfully!", "success") +# # After adding, redirect to the page that shows all records +# return redirect(url_for('display_itr')) + +# # If it's a GET request, just show the blank form to add a record +# return render_template('add_itr.html') ## 3. UPDATE an existing ITR record @@ -201,52 +181,86 @@ def update_itr(id): ## 4. DELETE an ITR record # This route also needs an ID to know which record to delete. +# @app.route('/itr/delete/', methods=['POST']) +# def delete_itr(id): +# conn = get_db_connection() +# cursor = conn.cursor() +# cursor.execute("DELETE FROM itr WHERE id = %s", (id,)) +# conn.commit() +# cursor.close() +# conn.close() +# # After deleting, redirect back to the display page +# return redirect(url_for('display_itr')) + + +# @app.route('/itr', methods=['GET', 'POST']) +# def itr_form(): +# if request.method == 'POST': +# data = {key: request.form.get(key, 0) for key in request.form} +# conn = mysql.connector.connect(**db_config) +# cursor = conn.cursor() +# query = """ +# INSERT INTO itr ( +# year, gross_total_income, disallowance_14a, disallowance_37, +# deduction_80ia_business, deduction_80ia_misc, deduction_80ia_other, +# deduction_sec37_disallowance, deduction_80g, net_taxable_income, +# tax_30_percent, tax_book_profit_18_5, tax_payable, surcharge_12, +# edu_cess_3, total_tax_payable, mat_credit, interest_234c, +# total_tax, advance_tax, tds, tcs, tax_on_assessment, refund +# ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) +# """ +# values = tuple([ +# int(data.get('year', 0)) +# ] + [ +# float(data.get(col, 0)) for col in [ +# 'gross_total_income', 'disallowance_14a', 'disallowance_37', +# 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', +# 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', +# 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', +# 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', +# 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' +# ] +# ]) +# cursor.execute(query, values) +# conn.commit() +# flash("ITR record deleted successfully!", "success") +# cursor.close() +# conn.close() +# return redirect(url_for('index')) +# return render_template('itr_form.html') + + +# new new --- +@app.route('/itr_records') +def display_itr(): + itr = ITRHandler() + records = itr.get_all_itr() + itr.close() + return render_template('display_itr.html', records=records) + + +# new new --- +@app.route('/itr/add', methods=['GET', 'POST']) +def add_itr(): + if request.method == 'POST': + + itr = ITRHandler() + itr.add_itr(request.form) + itr.close() + flash("ITR record added successfully!", "success") + return redirect(url_for('display_itr')) + + return render_template('add_itr.html') + +# new new --- @app.route('/itr/delete/', methods=['POST']) def delete_itr(id): - conn = get_db_connection() - cursor = conn.cursor() - cursor.execute("DELETE FROM itr WHERE id = %s", (id,)) - conn.commit() - cursor.close() - conn.close() - # After deleting, redirect back to the display page + itr = ITRHandler() + itr.delete_itr_by_id(id=id) + itr.close() return redirect(url_for('display_itr')) -@app.route('/itr', methods=['GET', 'POST']) -def itr_form(): - if request.method == 'POST': - data = {key: request.form.get(key, 0) for key in request.form} - conn = mysql.connector.connect(**db_config) - cursor = conn.cursor() - query = """ - INSERT INTO itr ( - year, gross_total_income, disallowance_14a, disallowance_37, - deduction_80ia_business, deduction_80ia_misc, deduction_80ia_other, - deduction_sec37_disallowance, deduction_80g, net_taxable_income, - tax_30_percent, tax_book_profit_18_5, tax_payable, surcharge_12, - edu_cess_3, total_tax_payable, mat_credit, interest_234c, - total_tax, advance_tax, tds, tcs, tax_on_assessment, refund - ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) - """ - values = tuple([ - int(data.get('year', 0)) - ] + [ - float(data.get(col, 0)) for col in [ - 'gross_total_income', 'disallowance_14a', 'disallowance_37', - 'deduction_80ia_business', 'deduction_80ia_misc', 'deduction_80ia_other', - 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', - 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', - 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', - 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' - ] - ]) - cursor.execute(query, values) - conn.commit() - cursor.close() - conn.close() - return redirect(url_for('index')) - return render_template('itr_form.html') # @@ -258,17 +272,25 @@ def itr_form(): ## =============================================== # DISPLAY all AO records +# @app.route('/ao_records') +# def display_ao(): +# conn = get_db_connection() +# cursor = conn.cursor(dictionary=True) # dictionary=True to access fields by name +# cursor.execute("SELECT * FROM ao ORDER BY year DESC, id DESC") +# ao_records = cursor.fetchall() +# cursor.close() +# conn.close() +# return render_template('display_ao.html', ao_records=ao_records) + @app.route('/ao_records') def display_ao(): - conn = get_db_connection() - cursor = conn.cursor(dictionary=True) - # Note: Querying the 'ao' table - cursor.execute("SELECT * FROM ao ORDER BY year DESC, id DESC") - records = cursor.fetchall() - cursor.close() - conn.close() - # Note: Rendering the 'display_ao.html' template - return render_template('display_ao.html', records=records) + ao = AOHandler() + ao_records = ao.get_all_ao() + ao.close() + return render_template('display_ao.html', ao_records=ao_records) + + + # ADD a new AO record @@ -277,8 +299,6 @@ def add_ao(): if request.method == 'POST': conn = get_db_connection() cursor = conn.cursor() - - # Define the columns for the 'ao' table columns = [ 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', 'deduction_80ia_business', 'deduction_sec37_disallowance', 'deduction_80g', @@ -286,75 +306,82 @@ def add_ao(): 'surcharge_12', 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' - ] # Make sure these match your 'ao' table columns! - - # Note: Inserting into the 'ao' table - query = f"INSERT INTO ao ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})" + ] values = [request.form.get(col, 0) for col in columns] - + query = f"INSERT INTO ao ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})" cursor.execute(query, tuple(values)) conn.commit() cursor.close() conn.close() - # Note: Redirecting to the 'display_ao' function + + flash("AO record added successfully!", "success") return redirect(url_for('display_ao')) - # Note: Rendering the 'add_ao.html' template return render_template('add_ao.html') + # (You will also need to add update_ao and delete_ao functions later) +# UPDATE AO record +@app.route('/ao/update/', methods=['GET', 'POST']) +def update_ao(id): + conn = get_db_connection() + cursor = conn.cursor(dictionary=True) + cursor.execute("SELECT * FROM ao WHERE id = %s", (id,)) + ao_record = cursor.fetchone() + if not ao_record: + cursor.close() + conn.close() + return "AO record not found", 404 -@app.route('/ao', methods=['GET', 'POST']) -def ao_form(): if request.method == 'POST': - data = {key: request.form.get(key, 0) for key in request.form} - conn = mysql.connector.connect(**db_config) - cursor = conn.cursor() - - query = """ - INSERT INTO ao ( - year, gross_total_income, disallowance_14a, disallowance_37, - deduction_80ia_business, deduction_sec37_disallowance, deduction_80g, - net_taxable_income, tax_30_percent, tax_book_profit_18_5, - surcharge_12, edu_cess_3, total_tax_payable, mat_credit, - interest_234c, total_tax, advance_tax, tds, tcs, - tax_on_assessment, refund - ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) - """ - - values = tuple([ - data.get('year'), - float(data.get('gross_total_income', 0)), - float(data.get('disallowance_14a', 0)), - float(data.get('disallowance_37', 0)), - float(data.get('deduction_80ia_business', 0)), - float(data.get('deduction_sec37_disallowance', 0)), - float(data.get('deduction_80g', 0)), - float(data.get('net_taxable_income', 0)), - float(data.get('tax_30_percent', 0)), - float(data.get('tax_book_profit_18_5', 0)), - float(data.get('surcharge_12', 0)), - float(data.get('edu_cess_3', 0)), - float(data.get('total_tax_payable', 0)), - float(data.get('mat_credit', 0)), - float(data.get('interest_234c', 0)), - float(data.get('total_tax', 0)), - float(data.get('advance_tax', 0)), - float(data.get('tds', 0)), - float(data.get('tcs', 0)), - float(data.get('tax_on_assessment', 0)), - float(data.get('refund', 0)), - ]) - - cursor.execute(query, values) + columns = [ + 'year', 'gross_total_income', 'disallowance_14a', 'disallowance_37', + 'deduction_80ia_business', 'deduction_sec37_disallowance', 'deduction_80g', + 'net_taxable_income', 'tax_30_percent', 'tax_book_profit_18_5', + 'surcharge_12', 'edu_cess_3', 'total_tax_payable', 'mat_credit', + 'interest_234c', 'total_tax', 'advance_tax', 'tds', 'tcs', + 'tax_on_assessment', 'refund' + ] + values = [request.form.get(col, 0) for col in columns] + set_clause = ", ".join([f"{col}=%s" for col in columns]) + query = f"UPDATE ao SET {set_clause} WHERE id=%s" + cursor.execute(query, tuple(values) + (id,)) conn.commit() cursor.close() conn.close() - return redirect(url_for('index')) - - return render_template('ao_form.html') + flash("AO record updated successfully!", "success") + return redirect(url_for('display_ao')) + + cursor.close() + conn.close() + return render_template('update_ao.html', record=ao_record) + + + +# DELETE AO record safely +@app.route('/ao/delete/', methods=['POST']) +def delete_ao(id): + try: + conn = get_db_connection() + cursor = conn.cursor() + # Delete dependent CIT records first + cursor.execute("DELETE FROM ao WHERE id = %s", (id,)) + + + # Then delete AO record + cursor.execute("DELETE FROM ao WHERE id = %s", (id,)) + conn.commit() + flash("AO record deleted successfully!", "success") + except Exception as err: + flash(f"Error deleting AO: {err}", "danger") + finally: + cursor.close() + conn.close() + return redirect(url_for('display_ao')) + + # @@ -370,13 +397,12 @@ def ao_form(): def display_cit(): conn = get_db_connection() cursor = conn.cursor(dictionary=True) - # Querying the 'cit' table cursor.execute("SELECT * FROM cit ORDER BY year DESC, id DESC") - records = cursor.fetchall() + cit_records = cursor.fetchall() cursor.close() conn.close() - # Rendering the 'display_cit.html' template - return render_template('display_cit.html', records=records) + return render_template('display_cit.html', cit_records=cit_records) + # ADD a new CIT record @@ -386,28 +412,71 @@ def add_cit(): conn = get_db_connection() cursor = conn.cursor() - # IMPORTANT: These columns match your 'cit' table structure columns = [ - 'year', 'gross_total_income', 'deduction_80ia_business', - 'deduction_sec37_disallowance', 'deduction_80g', 'net_taxable_income', - 'tax_30_percent', 'tax_book_profit_18_5', 'tax_payable', 'surcharge_12', - 'edu_cess_3', 'total_tax_payable', 'mat_credit', 'interest_234c', - 'total_tax', 'advance_tax', 'tds', 'tcs', 'tax_on_assessment', 'refund' + "year", "gross_total_income", "deduction_80ia_business", "deduction_sec37_disallowance", + "deduction_80g", "net_taxable_income", "tax_30_percent", "tax_book_profit_18_5", + "tax_payable", "surcharge_12", "edu_cess_3", "total_tax_payable", "mat_credit", + "interest_234c", "total_tax", "advance_tax", "tds", "tcs", "tax_on_assessment", "refund" ] - # Inserting into the 'cit' table - query = f"INSERT INTO cit ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})" values = [request.form.get(col, 0) for col in columns] - + query = f"INSERT INTO cit ({', '.join(columns)}) VALUES ({', '.join(['%s']*len(columns))})" cursor.execute(query, tuple(values)) conn.commit() + flash("ITAT record added successfully!", "success") + cursor.close() + conn.close() + return redirect(url_for('display_cit')) + + return render_template('add_cit.html') + +@app.route('/cit/update/', methods=['GET', 'POST']) +def update_cit(id): + conn = get_db_connection() + cursor = conn.cursor(dictionary=True) + cursor.execute("SELECT * FROM cit WHERE id=%s", (id,)) + record = cursor.fetchone() + if not record: + cursor.close() + conn.close() + return "CIT record not found", 404 + + if request.method == 'POST': + columns = [ + "year", "gross_total_income", "deduction_80ia_business", "deduction_sec37_disallowance", + "deduction_80g", "net_taxable_income", "tax_30_percent", "tax_book_profit_18_5", + "tax_payable", "surcharge_12", "edu_cess_3", "total_tax_payable", "mat_credit", + "interest_234c", "total_tax", "advance_tax", "tds", "tcs", "tax_on_assessment", "refund" + ] + values = [request.form.get(col, 0) for col in columns] + set_clause = ", ".join([f"{col}=%s" for col in columns]) + query = f"UPDATE cit SET {set_clause} WHERE id=%s" + cursor.execute(query, tuple(values)+(id,)) + conn.commit() cursor.close() conn.close() - # Redirecting to the 'display_cit' function return redirect(url_for('display_cit')) - # Rendering the 'add_cit.html' template - return render_template('add_cit.html') + cursor.close() + conn.close() + return render_template('add_cit.html', record=record) + + +@app.route('/cit/delete/', methods=['POST']) +def delete_cit(id): + try: + conn = get_db_connection() + cursor = conn.cursor() + cursor.execute("DELETE FROM cit WHERE id=%s", (id,)) + conn.commit() + flash("ITR record deleted successfully!", "success") + except Exception as err: + print(f"Error deleting CIT record: {err}") + finally: + cursor.close() + conn.close() + return redirect(url_for('display_cit')) + # (You will also need to add update_cit and delete_cit functions later) @@ -438,28 +507,83 @@ def display_itat(): # ADD a new ITAT record @app.route('/itat/add', methods=['GET', 'POST']) def add_itat(): + conn = get_db_connection() + cursor = conn.cursor(dictionary=True) + + # Fetch all CIT records to choose from + cursor.execute("SELECT id, year FROM cit ORDER BY year DESC") + cit_records = cursor.fetchall() + if request.method == 'POST': - conn = get_db_connection() - cursor = conn.cursor() - - # NOTE: These are the specific columns for your 'itat' table - columns = [ - 'year', 'mat_tax_credit', 'surcharge', 'cess', 'total_credit' - ] - - # Inserting into the 'itat' table + cit_id = request.form.get('cit_id') # selected parent CIT id + columns = ['id', 'year','mat_tax_credit', 'surcharge', 'cess', 'total_credit'] + values = [cit_id, + request.form.get('year', 0), + request.form.get('mat_tax_credit', 0), + request.form.get('surcharge', 0), + request.form.get('cess', 0), + request.form.get('total_credit', 0)] query = f"INSERT INTO itat ({', '.join(columns)}) VALUES ({', '.join(['%s'] * len(columns))})" - values = [request.form.get(col, 0) for col in columns] - cursor.execute(query, tuple(values)) conn.commit() cursor.close() conn.close() - # Redirecting to the 'display_itat' function + flash("ITAT record added successfully!", "success") return redirect(url_for('display_itat')) - # Rendering the 'add_itat.html' template - return render_template('add_itat.html') + cursor.close() + conn.close() + return render_template('add_itat.html', cit_records=cit_records) + + +@app.route('/itat/update/', methods=['GET', 'POST']) +def update_itat(id): + conn = get_db_connection() + cursor = conn.cursor(dictionary=True) + + # Fetch the existing record + cursor.execute("SELECT * FROM itat WHERE id=%s", (id,)) + record = cursor.fetchone() + + if not record: + cursor.close() + conn.close() + flash("ITAT record not found!", "danger") + return redirect(url_for('display_itat')) + + if request.method == 'POST': + columns = ['year', 'mat_tax_credit', 'surcharge', 'cess', 'total_credit'] + values = [request.form.get(col, 0) for col in columns] + set_clause = ", ".join([f"{col}=%s" for col in columns]) + query = f"UPDATE itat SET {set_clause} WHERE id=%s" + cursor.execute(query, tuple(values) + (id,)) + conn.commit() + cursor.close() + conn.close() + flash("ITAT record updated successfully!", "success") + return redirect(url_for('display_itat')) + + cursor.close() + conn.close() + # Render a template with existing values filled in + return render_template('update_itat.html', record=record) + + +@app.route('/itat/delete/', methods=['POST']) +def delete_itat(id): + try: + conn = get_db_connection() + cursor = conn.cursor() + cursor.execute("DELETE FROM itat WHERE id=%s", (id,)) + conn.commit() + flash("ITAT record deleted successfully!", "success") + except Exception as err: + flash(f"Error deleting ITAT: {err}", "danger") + finally: + cursor.close() + conn.close() + return redirect(url_for('display_itat')) + # (You will also need to add update_itat and delete_itat functions later) diff --git a/static/uploads/AY_18-19_REfund_Working.xlsx b/static/uploads/AY_18-19_REfund_Working.xlsx new file mode 100644 index 0000000..920631b Binary files /dev/null and b/static/uploads/AY_18-19_REfund_Working.xlsx differ diff --git a/static/uploads/ITR_Report_2001_4.xlsx b/static/uploads/ITR_Report_2001_4.xlsx new file mode 100644 index 0000000..9d54499 Binary files /dev/null and b/static/uploads/ITR_Report_2001_4.xlsx differ diff --git a/static/uploads/LaxmiBrochure_Concept_VishalMistry_17Nov.pdf b/static/uploads/LaxmiBrochure_Concept_VishalMistry_17Nov.pdf new file mode 100644 index 0000000..73e2387 Binary files /dev/null and b/static/uploads/LaxmiBrochure_Concept_VishalMistry_17Nov.pdf differ diff --git a/templates/add_ao.html b/templates/add_ao.html new file mode 100644 index 0000000..af1e681 --- /dev/null +++ b/templates/add_ao.html @@ -0,0 +1,127 @@ + + + + AO Form Entry + + + + +
+

AO Form Entry

+
+ + + {% for field in [ + "gross_total_income", "disallowance_14a", "disallowance_37", + "deduction_80ia_business", "deduction_sec37_disallowance", "deduction_80g", + "net_taxable_income", "tax_30_percent", "tax_book_profit_18_5", + "surcharge_12", "edu_cess_3", "total_tax_payable", "mat_credit", + "interest_234c", "total_tax", "advance_tax", "tds", "tcs", + "tax_on_assessment", "refund" + ] %} + + + {% endfor %} + +
+
+ + + + + diff --git a/templates/add_cit.html b/templates/add_cit.html new file mode 100644 index 0000000..09af9b7 --- /dev/null +++ b/templates/add_cit.html @@ -0,0 +1,124 @@ + + + + CIT Form Entry + + + + +
+

CIT Form Entry

+
+ + + + {% for field in [ + "gross_total_income", "deduction_80ia_business", "deduction_sec37_disallowance", + "deduction_80g", "net_taxable_income", "tax_30_percent", "tax_book_profit_18_5", + "tax_payable", "surcharge_12", "edu_cess_3", "total_tax_payable", "mat_credit", + "interest_234c", "total_tax", "advance_tax", "tds", "tcs", "tax_on_assessment", "refund" + ] %} + + + {% endfor %} + +
+ +
+ + + + diff --git a/templates/add_itat.html b/templates/add_itat.html new file mode 100644 index 0000000..4d56bc0 --- /dev/null +++ b/templates/add_itat.html @@ -0,0 +1,126 @@ + + + + ITAT Form Entry + + + + +
+

ITAT Form Entry

+
+ + + + + + + + + + + + + + + + +
+
+ + + + diff --git a/templates/add_itr.html b/templates/add_itr.html index 983fa9c..ec64556 100644 --- a/templates/add_itr.html +++ b/templates/add_itr.html @@ -1,19 +1,133 @@ -
+ + + + + + Add New Income Tax Return Record + + + + +

Add New Income Tax Return Record

+
- {% for field in [ - "gross_total_income", "disallowance_14a", "disallowance_37", - "deduction_80ia_business", "deduction_80ia_misc", "deduction_80ia_other", - "deduction_sec37_disallowance", "deduction_80g", "net_taxable_income", - "tax_30_percent", "tax_book_profit_18_5", "tax_payable", "surcharge_12", - "edu_cess_3", "total_tax_payable", "mat_credit", "interest_234c", - "total_tax", "advance_tax", "tds", "tcs", "tax_on_assessment", "refund" - ] %} - - - {% endfor %} - +
+ + {% for field in [ + "gross_total_income", "disallowance_14a", "disallowance_37", + "deduction_80ia_business", "deduction_80ia_misc", "deduction_80ia_other", + "deduction_sec37_disallowance", "deduction_80g", "net_taxable_income", + "tax_30_percent", "tax_book_profit_18_5", "tax_payable", "surcharge_12", + "edu_cess_3", "total_tax_payable", "mat_credit", "interest_234c", + "total_tax", "advance_tax", "tds", "tcs", "tax_on_assessment", "refund" + ] %} +
+ + +
+ {% endfor %} + +
-
\ No newline at end of file +
+ + + \ No newline at end of file diff --git a/templates/display_ao.html b/templates/display_ao.html new file mode 100644 index 0000000..0797bec --- /dev/null +++ b/templates/display_ao.html @@ -0,0 +1,78 @@ + + + + + AO Records + + + +
+

Assessing Officer Records ๐Ÿ‘จโ€๐Ÿ’ผ

+ + + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} +
{{ message }}
+ {% endfor %} + {% endif %} + {% endwith %} + + โž• Add AO Record + + {% if ao_records %} +
+ + + + + + + + + + + + + {% for ao in ao_records %} + + + + + + + + + {% endfor %} + +
IDYearGross Total IncomeNet Taxable IncomeTotal TaxActions
{{ ao.id }}{{ ao.year }}{{ ao.gross_total_income }}{{ ao.net_taxable_income }}{{ ao.total_tax }} + Edit +
+ +
+
+
+ {% else %} +

No AO records found. Add one above!

+ {% endif %} +
+ + diff --git a/templates/display_cit.html b/templates/display_cit.html new file mode 100644 index 0000000..163fd1d --- /dev/null +++ b/templates/display_cit.html @@ -0,0 +1,66 @@ + + + + + CIT Records + + + +
+

CIT Records ๐Ÿงพ

+ โž• Add New Record + + {% if cit_records %} +
+ + + + + + + + + + + + + {% for record in cit_records %} + + + + + + + + + {% endfor %} + +
YearGross Total IncomeNet Taxable IncomeTotal Tax PayableRefundActions
{{ record.year }}{{ "{:,.2f}".format(record.gross_total_income) }}{{ "{:,.2f}".format(record.net_taxable_income) }}{{ "{:,.2f}".format(record.total_tax_payable) }}{{ "{:,.2f}".format(record.refund) }} + Edit + +
+ +
+
+
+ {% else %} +

No records found. Click the button above to add one!

+ {% endif %} +
+ + diff --git a/templates/display_itat.html b/templates/display_itat.html new file mode 100644 index 0000000..7362f76 --- /dev/null +++ b/templates/display_itat.html @@ -0,0 +1,75 @@ + + + + + ITAT Records + + + +
+

ITAT Records ๐Ÿ“„

+ โž• Add New Record + + {% with messages = get_flashed_messages(with_categories=true) %} + {% if messages %} + {% for category, message in messages %} +
{{ message }}
+ {% endfor %} + {% endif %} + {% endwith %} + + {% if records %} +
+ + + + + + + + + + + + + {% for record in records %} + + + + + + + + + {% endfor %} + +
YearMAT Tax CreditSurchargeCessTotal CreditActions
{{ record.year }}{{ "{:,.2f}".format(record.mat_tax_credit) }}{{ "{:,.2f}".format(record.surcharge) }}{{ "{:,.2f}".format(record.cess) }}{{ "{:,.2f}".format(record.total_credit) }} + Edit + + +
+ +
+
+
+ {% else %} +

No ITAT records found. Click the button above to add one!

+ {% endif %} +
+ + diff --git a/templates/itr_form.html b/templates/itr_form.html index f6b6d9d..da75292 100644 --- a/templates/itr_form.html +++ b/templates/itr_form.html @@ -4,247 +4,245 @@ -ITR Form Entry + ITR Form Entry - + - + } + -
+
-

Income Tax Return Form

+

Income Tax Return Form

-
+ - + - + -{% for field in [ + {% for field in [ -"gross_total_income", "disallowance_14a", "disallowance_37", + "gross_total_income", "disallowance_14a", "disallowance_37", -"deduction_80ia_business", "deduction_80ia_misc", "deduction_80ia_other", + "deduction_80ia_business", "deduction_80ia_misc", "deduction_80ia_other", -"deduction_sec37_disallowance", "deduction_80g", "net_taxable_income", + "deduction_sec37_disallowance", "deduction_80g", "net_taxable_income", -"tax_30_percent", "tax_book_profit_18_5", "tax_payable", "surcharge_12", + "tax_30_percent", "tax_book_profit_18_5", "tax_payable", "surcharge_12", -"edu_cess_3", "total_tax_payable", "mat_credit", "interest_234c", + "edu_cess_3", "total_tax_payable", "mat_credit", "interest_234c", -"total_tax", "advance_tax", "tds", "tcs", "tax_on_assessment", "refund" + "total_tax", "advance_tax", "tds", "tcs", "tax_on_assessment", "refund" -] %} + ] %} - + - + -{% endfor %} + {% endfor %} - + -
+ -
+
- + - + diff --git a/templates/update_ao.html b/templates/update_ao.html new file mode 100644 index 0000000..83a6c5a --- /dev/null +++ b/templates/update_ao.html @@ -0,0 +1,30 @@ + + + + + Update AO Record + + + + +
+

Update AO Record for Year {{ record.year }}

+
+ {% for field in record.keys() if field != 'id' %} + + + {% endfor %} + +
+ +
+ + diff --git a/templates/update_cit.html b/templates/update_cit.html new file mode 100644 index 0000000..7a32d7f --- /dev/null +++ b/templates/update_cit.html @@ -0,0 +1,29 @@ + + + + + Update CIT Record + + + + +
+

Update CIT Record for Year {{ record.year }}

+
+ {% for field in record.keys() if field != 'id' %} + + + {% endfor %} + +
+
+ + diff --git a/templates/update_itat.html b/templates/update_itat.html new file mode 100644 index 0000000..68dc3ea --- /dev/null +++ b/templates/update_itat.html @@ -0,0 +1,30 @@ + + + + Update ITAT Record + + + +
+

Update ITAT Record for Year {{ record.year }}

+
+ + + + + + + + + + + + + + + + +
+
+ + diff --git a/templates/view_docs.html b/templates/view_docs.html index 7fdec5f..cb926f0 100644 --- a/templates/view_docs.html +++ b/templates/view_docs.html @@ -1,5 +1,6 @@ + View Documents +

Document Records

@@ -154,11 +157,13 @@ {{ doc.year }} {{ doc.uploaded_at }} Download - View + View {% endfor %}
- + + \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..f9ddca0 --- /dev/null +++ b/test.py @@ -0,0 +1,103 @@ +import os +from AppCode.Config import DBConfig +from AppCode.FileHandler import FileHandler +from werkzeug.utils import secure_filename + +class DocumentHandler: + + years = "" + documents = "" + isSuccess = False + resultMessage = "" + + def View(self,request): + year = request.args.get('year') + stage = request.args.get('stage') + dbconfig = DBConfig() + connection = dbconfig.get_db_connection() + + if not connection: + self.isSuccess = False + return + cursor = connection.cursor() + + params = [] + query = "SELECT * FROM documents WHERE 1=1" + + if year: + query += " AND year = %s" + params.append(year) + if stage: + query += " AND stage = %s" + params.append(stage) + + + cursor.execute(query, params) + documentsdata = cursor.fetchall() + print("*************") + print(documentsdata) + cursor.callproc("GetYear") + + # records = [] + # for result in cursor.stored_results(): + # records = result.fetchall() + + yearsdata = "" + for res in cursor.stored_results(): + yearsdata = res.fetchall() + print(yearsdata) + + self.years = yearsdata + self.documents = documentsdata + self.isSuccess = True + + print("document --",documentsdata) + + cursor.close() + connection.close() + + + def Upload(self, request): + """Log user actions with timestamp, user, action, and details.""" + + 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'] + + for file in files: + if file is not FileHandler.ALLOWED_EXTENSIONS: + continue + + + filename = secure_filename(file.filename) + filepath = os.path.join(FileHandler.UPLOAD_FOLDER, filename) + extension = file.filename.rsplit('.', 1)[1] + # Need to Check whetehr all three items are required + + file.save(filepath) + + # cursor.execute(""" + # INSERT INTO documents (filename, filepath, filetype, year, stage) + # VALUES (%s, %s, %s, %s, %s) + # """, (filename, filepath, file.filename.rsplit('.', 1)[1], year, stage)) + + + cursor.callproc('InsertDocument', [ + filename, + filepath, + extension, + year, + stage + ]) + + connection.commit() + cursor.close() + connection.close() + # return redirect(url_for('view_documents')) + + #return render_template('upload.html')