Initial commit
This commit is contained in:
46
controllers/auth_controller.py
Normal file
46
controllers/auth_controller.py
Normal file
@@ -0,0 +1,46 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash, session
|
||||
from flask_login import login_user, logout_user, login_required, current_user
|
||||
|
||||
from model.Auth import LoginLDAP, User
|
||||
from model.Log import LogHelper
|
||||
|
||||
auth_bp = Blueprint('auth', __name__)
|
||||
|
||||
|
||||
@auth_bp.route('/login', methods=['GET', 'POST'])
|
||||
def login():
|
||||
|
||||
if request.method == 'POST':
|
||||
|
||||
loginData = LoginLDAP(request)
|
||||
|
||||
if loginData.isValidLogin:
|
||||
|
||||
if loginData.isDefaultCredentials:
|
||||
LogHelper.log_action('Login', f"User {loginData.username} logged in (static user)")
|
||||
else:
|
||||
LogHelper.log_action('Login', f"User {loginData.username} logged in (LDAP)")
|
||||
|
||||
session['username'] = loginData.username
|
||||
|
||||
login_user(User(loginData.username))
|
||||
|
||||
return redirect(url_for('index'))
|
||||
|
||||
else:
|
||||
flash(loginData.errorMessage, 'danger')
|
||||
|
||||
return render_template("login.html")
|
||||
|
||||
|
||||
@auth_bp.route('/logout')
|
||||
@login_required
|
||||
def logout():
|
||||
|
||||
LogHelper.log_action('Logout', f"User {current_user.id} logged out")
|
||||
|
||||
logout_user()
|
||||
|
||||
flash('You have been logged out.', 'info')
|
||||
|
||||
return redirect(url_for('auth.login'))
|
||||
119
controllers/block_controller.py
Normal file
119
controllers/block_controller.py
Normal file
@@ -0,0 +1,119 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, jsonify
|
||||
from flask_login import login_required
|
||||
|
||||
import config
|
||||
import mysql.connector
|
||||
|
||||
from model.Block import Block
|
||||
from model.Utilities import HtmlHelper
|
||||
|
||||
block_bp = Blueprint('block', __name__)
|
||||
|
||||
|
||||
@block_bp.route('/add_block', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_block():
|
||||
|
||||
block = Block()
|
||||
|
||||
if request.method == 'POST':
|
||||
block.AddBlock(request)
|
||||
return block.resultMessage
|
||||
|
||||
connection = config.get_db_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.callproc("GetAllStates")
|
||||
for rs in cursor.stored_results():
|
||||
states = rs.fetchall()
|
||||
|
||||
block_data = block.GetAllBlocks(request)
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
return render_template(
|
||||
'add_block.html',
|
||||
states=states,
|
||||
block_data=block_data
|
||||
)
|
||||
|
||||
|
||||
# ✅ NEW ROUTE (FIX FOR DISTRICT FETCH)
|
||||
@block_bp.route('/get_districts/<int:state_id>')
|
||||
@login_required
|
||||
def get_districts(state_id):
|
||||
|
||||
connection = config.get_db_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.callproc("GetDistrictsByStateId", (state_id,))
|
||||
|
||||
districts = []
|
||||
for rs in cursor.stored_results():
|
||||
districts = rs.fetchall()
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
district_list = []
|
||||
|
||||
for district in districts:
|
||||
district_list.append({
|
||||
"id": district[0],
|
||||
"name": district[1]
|
||||
})
|
||||
|
||||
return jsonify(district_list)
|
||||
|
||||
|
||||
@block_bp.route('/check_block', methods=['POST'])
|
||||
@login_required
|
||||
def check_block():
|
||||
|
||||
block = Block()
|
||||
return block.CheckBlock(request)
|
||||
|
||||
|
||||
@block_bp.route('/edit_block/<int:block_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_block(block_id):
|
||||
|
||||
block = Block()
|
||||
|
||||
if request.method == 'POST':
|
||||
block.EditBlock(request, block_id)
|
||||
return block.resultMessage
|
||||
|
||||
connection = config.get_db_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.callproc("GetAllStates")
|
||||
for rs in cursor.stored_results():
|
||||
states = rs.fetchall()
|
||||
|
||||
cursor.callproc("GetAllDistrictsData")
|
||||
for rs in cursor.stored_results():
|
||||
districts = rs.fetchall()
|
||||
|
||||
block_data = block.GetBlockByID(block_id)
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
return render_template(
|
||||
'edit_block.html',
|
||||
block_data=block_data,
|
||||
states=states,
|
||||
districts=districts
|
||||
)
|
||||
|
||||
|
||||
@block_bp.route('/delete_block/<int:block_id>')
|
||||
@login_required
|
||||
def delete_block(block_id):
|
||||
|
||||
block = Block()
|
||||
block.DeleteBlock(request, block_id)
|
||||
|
||||
return redirect(url_for('block.add_block'))
|
||||
84
controllers/district_controller.py
Normal file
84
controllers/district_controller.py
Normal file
@@ -0,0 +1,84 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash
|
||||
from flask_login import login_required
|
||||
|
||||
from model.District import District
|
||||
from model.State import State
|
||||
|
||||
district_bp = Blueprint('district', __name__)
|
||||
|
||||
|
||||
@district_bp.route('/add_district', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_district():
|
||||
|
||||
district = District()
|
||||
|
||||
if request.method == 'POST':
|
||||
district.AddDistrict(request=request)
|
||||
return district.resultMessage
|
||||
|
||||
state = State()
|
||||
states = state.GetAllStates(request=request)
|
||||
|
||||
districtdata = district.GetAllDistricts(request=request)
|
||||
|
||||
return render_template(
|
||||
'add_district.html',
|
||||
districtdata=districtdata,
|
||||
states=states
|
||||
)
|
||||
|
||||
|
||||
@district_bp.route('/check_district', methods=['POST'])
|
||||
@login_required
|
||||
def check_district():
|
||||
|
||||
district = District()
|
||||
|
||||
return district.CheckDistrict(request=request)
|
||||
|
||||
|
||||
@district_bp.route('/delete_district/<int:district_id>')
|
||||
@login_required
|
||||
def delete_district(district_id):
|
||||
|
||||
district = District()
|
||||
|
||||
district.DeleteDistrict(request=request, district_id=district_id)
|
||||
|
||||
if not district.isSuccess:
|
||||
return district.resultMessage
|
||||
else:
|
||||
return redirect(url_for('district.add_district'))
|
||||
|
||||
|
||||
@district_bp.route('/edit_district/<int:district_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_district(district_id):
|
||||
|
||||
district = District()
|
||||
state = State()
|
||||
|
||||
if request.method == 'POST':
|
||||
|
||||
district.EditDistrict(request=request, district_id=district_id)
|
||||
|
||||
if district.isSuccess:
|
||||
flash("District updated successfully!", "success")
|
||||
return redirect(url_for('district.add_district'))
|
||||
else:
|
||||
flash(district.resultMessage, "error")
|
||||
|
||||
districtdata = district.GetDistrictByID(request=request, district_id=district_id)
|
||||
|
||||
if not districtdata:
|
||||
flash("District not found", "error")
|
||||
return redirect(url_for('district.add_district'))
|
||||
|
||||
states = state.GetAllStates(request=request)
|
||||
|
||||
return render_template(
|
||||
'edit_district.html',
|
||||
districtdata=districtdata,
|
||||
states=states
|
||||
)
|
||||
389
controllers/excel_upload_controller.py
Normal file
389
controllers/excel_upload_controller.py
Normal file
@@ -0,0 +1,389 @@
|
||||
import os
|
||||
import ast
|
||||
import re
|
||||
from flask_login import login_required
|
||||
import openpyxl
|
||||
from flask import Blueprint, request, render_template, redirect, url_for, jsonify, current_app
|
||||
from flask_login import current_user
|
||||
from model.Log import LogHelper
|
||||
import config # your database connection module
|
||||
|
||||
excel_bp = Blueprint('excel', __name__)
|
||||
|
||||
# Default folder in case config not set
|
||||
DEFAULT_UPLOAD_FOLDER = 'uploads'
|
||||
|
||||
|
||||
def get_upload_folder():
|
||||
"""Returns the upload folder from Flask config or default, ensures it exists."""
|
||||
folder = current_app.config.get('UPLOAD_FOLDER', DEFAULT_UPLOAD_FOLDER)
|
||||
if not os.path.exists(folder):
|
||||
os.makedirs(folder)
|
||||
return folder
|
||||
|
||||
|
||||
# ---------------- Upload Excel File ----------------
|
||||
@excel_bp.route('/upload_excel_file', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def upload():
|
||||
if request.method == 'POST':
|
||||
file = request.files.get('file')
|
||||
if file and file.filename.endswith('.xlsx'):
|
||||
upload_folder = get_upload_folder()
|
||||
filepath = os.path.join(upload_folder, file.filename)
|
||||
file.save(filepath)
|
||||
|
||||
LogHelper.log_action(
|
||||
"Upload Excel File",
|
||||
f"User {current_user.id} Upload Excel File '{file.filename}'"
|
||||
)
|
||||
return redirect(url_for('excel.show_table', filename=file.filename))
|
||||
return render_template('uploadExcelFile.html')
|
||||
|
||||
|
||||
# ---------------- Show Excel Table ----------------
|
||||
@excel_bp.route('/show_table/<filename>')
|
||||
def show_table(filename):
|
||||
global data
|
||||
data = []
|
||||
|
||||
filepath = os.path.join(get_upload_folder(), filename)
|
||||
wb = openpyxl.load_workbook(filepath, data_only=True)
|
||||
sheet = wb.active
|
||||
|
||||
file_info = {
|
||||
"Subcontractor": sheet.cell(row=1, column=2).value,
|
||||
"State": sheet.cell(row=2, column=2).value,
|
||||
"District": sheet.cell(row=3, column=2).value,
|
||||
"Block": sheet.cell(row=4, column=2).value,
|
||||
}
|
||||
|
||||
errors = []
|
||||
subcontractor_data = None
|
||||
state_data = None
|
||||
district_data = None
|
||||
block_data = None
|
||||
|
||||
connection = config.get_db_connection()
|
||||
if connection:
|
||||
try:
|
||||
cursor = connection.cursor(dictionary=True)
|
||||
|
||||
print(f"Calling GetStateByName with: {file_info['State']}")
|
||||
cursor.callproc('GetStateByName', [file_info['State']])
|
||||
for result in cursor.stored_results():
|
||||
state_data = result.fetchone()
|
||||
if not state_data:
|
||||
errors.append(f"State '{file_info['State']}' is not valid. Please add it.")
|
||||
|
||||
if state_data:
|
||||
print(f"Calling GetDistrictByNameAndStates with: {file_info['District']}, {state_data['State_ID']}")
|
||||
cursor.callproc('GetDistrictByNameAndStates', [file_info['District'], state_data['State_ID']])
|
||||
for result in cursor.stored_results():
|
||||
district_data = result.fetchone()
|
||||
if not district_data:
|
||||
errors.append(f"District '{file_info['District']}' is not valid under state '{file_info['State']}'.")
|
||||
|
||||
if district_data:
|
||||
print(f"Calling GetBlockByNameAndDistricts with: {file_info['Block']}, {district_data['District_ID']}")
|
||||
cursor.callproc('GetBlockByNameAndDistricts', [file_info['Block'], district_data['District_ID']])
|
||||
for result in cursor.stored_results():
|
||||
block_data = result.fetchone()
|
||||
if not block_data:
|
||||
errors.append(f"Block '{file_info['Block']}' is not valid under district '{file_info['District']}'.")
|
||||
|
||||
print(f"Calling GetSubcontractorByName with: {file_info['Subcontractor']}")
|
||||
cursor.callproc('GetSubcontractorByName', [file_info['Subcontractor']])
|
||||
for result in cursor.stored_results():
|
||||
subcontractor_data = result.fetchone()
|
||||
|
||||
if not subcontractor_data:
|
||||
print(f"Inserting subcontractor: {file_info['Subcontractor']}")
|
||||
cursor.callproc('InsertSubcontractor', [file_info['Subcontractor']])
|
||||
connection.commit()
|
||||
cursor.callproc('GetSubcontractorByName', [file_info['Subcontractor']])
|
||||
for result in cursor.stored_results():
|
||||
subcontractor_data = result.fetchone()
|
||||
|
||||
print("Calling GetAllHoldTypes")
|
||||
cursor.callproc("GetAllHoldTypes")
|
||||
hold_types_data = []
|
||||
for ht in cursor.stored_results():
|
||||
hold_types_data = ht.fetchall()
|
||||
hold_types_lookup = {row['hold_type'].lower(): row['hold_type_id'] for row in hold_types_data if row['hold_type']}
|
||||
|
||||
cursor.close()
|
||||
except Exception as e:
|
||||
print(f"Database error: {e}")
|
||||
return f"Database operation failed: {e}", 500
|
||||
finally:
|
||||
connection.close()
|
||||
|
||||
variables = {}
|
||||
hold_columns = []
|
||||
hold_counter = 0
|
||||
|
||||
for j in range(1, sheet.max_column + 1):
|
||||
col_value = sheet.cell(row=5, column=j).value
|
||||
if col_value:
|
||||
variables[col_value] = j
|
||||
if 'hold' in str(col_value).lower():
|
||||
hold_counter += 1
|
||||
hold_type_key = str(col_value).lower().strip()
|
||||
hold_type_id = hold_types_lookup.get(hold_type_key)
|
||||
hold_columns.append({
|
||||
'column_name': col_value,
|
||||
'column_number': j,
|
||||
'hold_type_id': hold_type_id
|
||||
})
|
||||
|
||||
for i in range(6, sheet.max_row + 1):
|
||||
row_data = {}
|
||||
if sheet.cell(row=i, column=1).value:
|
||||
row_data["Row Number"] = i
|
||||
for var_name, col_num in variables.items():
|
||||
row_data[var_name] = sheet.cell(row=i, column=col_num).value
|
||||
if sum(1 for value in row_data.values() if value) >= 4:
|
||||
data.append(row_data)
|
||||
|
||||
for hold in hold_columns:
|
||||
if hold['hold_type_id']:
|
||||
print(f" if Column: {hold['column_name']}, Column Number: {hold['column_number']}, Hold Type ID: {hold['hold_type_id']}")
|
||||
else:
|
||||
errors.append(f"Hold Type not added ! Column name '{hold['column_name']}'.")
|
||||
print(f" else Column: {hold['column_name']}, Column Number: {hold['column_number']}, Hold Type ID: {hold['hold_type_id']}")
|
||||
|
||||
return render_template(
|
||||
'show_excel_file.html',
|
||||
file_info=file_info,
|
||||
variables=variables,
|
||||
data=data,
|
||||
subcontractor_data=subcontractor_data,
|
||||
state_data=state_data,
|
||||
district_data=district_data,
|
||||
block_data=block_data,
|
||||
errors=errors,
|
||||
hold_columns=hold_columns,
|
||||
hold_counter=hold_counter
|
||||
)
|
||||
|
||||
|
||||
# save Excel data
|
||||
@excel_bp.route('/save_data', methods=['POST'])
|
||||
def save_data():
|
||||
# Extract form data
|
||||
subcontractor_id = request.form.get("subcontractor_data")
|
||||
state_id = request.form.get("state_data")
|
||||
district_id = request.form.get("district_data")
|
||||
block_id = request.form.get("block_data")
|
||||
variables = request.form.getlist('variables[]')
|
||||
hold_columns = request.form.get("hold_columns")
|
||||
hold_counter = request.form.get("hold_counter")
|
||||
if not data:
|
||||
return jsonify({"error": "No data provided to save"}), 400
|
||||
if data:
|
||||
connection = config.get_db_connection()
|
||||
cursor = connection.cursor()
|
||||
try:
|
||||
for entry in data:
|
||||
save_data = {
|
||||
"PMC_No": entry.get("PMC_No"),
|
||||
"Invoice_Details": entry.get("Invoice_Details", ''),
|
||||
"Work_Type": 'none',
|
||||
"Invoice_Date": entry.get("Invoice_Date").strftime('%Y-%m-%d') if entry.get(
|
||||
"Invoice_Date") else None,
|
||||
"Invoice_No": entry.get("Invoice_No", ''),
|
||||
"Basic_Amount": entry.get("Basic_Amount", 0.00),
|
||||
"Debit_Amount": entry.get("Debit_Amount", 0.00),
|
||||
"After_Debit_Amount": entry.get("After_Debit_Amount", 0.00),
|
||||
"Amount": entry.get("Amount", 0.00),
|
||||
"GST_Amount": entry.get("GST_Amount", 0.00),
|
||||
"TDS_Amount": entry.get("TDS_Amount", 0.00),
|
||||
"SD_Amount": entry.get("SD_Amount", 0.00),
|
||||
"On_Commission": entry.get("On_Commission", 0.00),
|
||||
"Hydro_Testing": entry.get("Hydro_Testing", 0.00),
|
||||
"Hold_Amount": 0,
|
||||
"GST_SD_Amount": entry.get("GST_SD_Amount", 0.00),
|
||||
"Final_Amount": entry.get("Final_Amount", 0.00),
|
||||
"Payment_Amount": entry.get("Payment_Amount", 0.00),
|
||||
"Total_Amount": entry.get("Total_Amount", 0.00),
|
||||
"TDS_Payment_Amount": entry.get("TDS_Payment_Amount", 0.00),
|
||||
"UTR": entry.get("UTR", ''),
|
||||
}
|
||||
village_name, work_type = None, None
|
||||
village_id = 0
|
||||
LogHelper.log_action("Data saved", f"User {current_user.id} Data saved'{ village_name}'")
|
||||
PMC_No = save_data.get('PMC_No')
|
||||
Invoice_Details = save_data.get('Invoice_Details')
|
||||
Invoice_Date = save_data.get('Invoice_Date')
|
||||
Invoice_No = save_data.get('Invoice_No')
|
||||
Basic_Amount = save_data.get('Basic_Amount')
|
||||
Debit_Amount = save_data.get('Debit_Amount')
|
||||
After_Debit_Amount = save_data.get('After_Debit_Amount')
|
||||
Amount = save_data.get('Amount')
|
||||
GST_Amount = save_data.get('GST_Amount')
|
||||
TDS_Amount = save_data.get('TDS_Amount')
|
||||
SD_Amount = save_data.get('SD_Amount')
|
||||
On_Commission = save_data.get('On_Commission')
|
||||
Hydro_Testing = save_data.get('Hydro_Testing')
|
||||
GST_SD_Amount = save_data.get('GST_SD_Amount')
|
||||
Final_Amount = save_data.get('Final_Amount')
|
||||
Payment_Amount = save_data.get('Payment_Amount')
|
||||
Total_Amount = save_data.get('Total_Amount')
|
||||
TDS_Payment_Amount = save_data.get('TDS_Payment_Amount')
|
||||
UTR = save_data.get('UTR')
|
||||
|
||||
if Invoice_Details:
|
||||
words = Invoice_Details.lower().split()
|
||||
if 'village' in words:
|
||||
village_pos = words.index('village')
|
||||
village_name = " ".join(words[:village_pos])
|
||||
if 'work' in words:
|
||||
work_pos = words.index('work')
|
||||
if village_name:
|
||||
work_type = " ".join(words[village_pos + 1:work_pos + 1])
|
||||
else:
|
||||
work_type = " ".join(words[:work_pos + 1])
|
||||
if Invoice_Details and 'village' in Invoice_Details.lower() and 'work' in Invoice_Details.lower():
|
||||
print("village_name ::", village_name, "|| work_type ::", work_type)
|
||||
if block_id and village_name:
|
||||
village_id = None
|
||||
cursor.callproc("GetVillageId", (block_id, village_name))
|
||||
for result in cursor.stored_results():
|
||||
result = result.fetchone()
|
||||
village_id = result[0] if result else None
|
||||
if not village_id:
|
||||
cursor.callproc("SaveVillage", (village_name, block_id))
|
||||
cursor.callproc("GetVillageId", (block_id, village_name))
|
||||
for result in cursor.stored_results():
|
||||
result = result.fetchone()
|
||||
village_id = result[0] if result else None
|
||||
print("village_id :", village_id)
|
||||
print("block_id :", block_id)
|
||||
print("invoice :", PMC_No, village_id, work_type, Invoice_Details, Invoice_Date, Invoice_No,
|
||||
Basic_Amount, Debit_Amount, After_Debit_Amount, Amount, GST_Amount, TDS_Amount,
|
||||
SD_Amount, On_Commission, Hydro_Testing, GST_SD_Amount, Final_Amount)
|
||||
|
||||
args = (
|
||||
PMC_No, village_id, work_type, Invoice_Details, Invoice_Date, Invoice_No,
|
||||
Basic_Amount, Debit_Amount, After_Debit_Amount, Amount, GST_Amount, TDS_Amount,
|
||||
SD_Amount, On_Commission, Hydro_Testing, GST_SD_Amount, Final_Amount,
|
||||
subcontractor_id, 0
|
||||
)
|
||||
|
||||
print("All invoice Details ",args)
|
||||
results = cursor.callproc('SaveInvoice', args)
|
||||
invoice_id = results[-1]
|
||||
print("invoice id from the excel ", invoice_id)
|
||||
if isinstance(hold_columns, str):
|
||||
hold_columns = ast.literal_eval(hold_columns)
|
||||
if isinstance(hold_columns, list) and all(isinstance(hold, dict) for hold in hold_columns):
|
||||
for hold in hold_columns:
|
||||
print(f"Processing hold: {hold}")
|
||||
hold_column_name = hold.get('column_name') # Get column name
|
||||
hold_type_id = hold.get('hold_type_id') # Get hold_type_id
|
||||
if hold_column_name:
|
||||
hold_amount = entry.get(
|
||||
hold_column_name) # Get the value for that specific hold column
|
||||
if hold_amount is not None:
|
||||
print(f"Processing hold type: {hold_column_name}, Hold Amount: {hold_amount}")
|
||||
hold_join_data = {
|
||||
"Contractor_Id": subcontractor_id,
|
||||
"Invoice_Id": invoice_id,
|
||||
"hold_type_id": hold_type_id,
|
||||
"hold_amount": hold_amount
|
||||
}
|
||||
cursor.callproc('InsertHoldJoinData', [
|
||||
hold_join_data['Contractor_Id'], hold_join_data['Invoice_Id'],
|
||||
hold_join_data['hold_type_id'], hold_join_data['hold_amount']
|
||||
])
|
||||
connection.commit()
|
||||
print(f"Inserted hold join data: {hold_join_data}")
|
||||
else:
|
||||
print(f"Invalid hold entry: {hold}")
|
||||
else:
|
||||
print("Hold columns data is not a valid list of dictionaries.")
|
||||
#---------------------------------------------Credit Note---------------------------------------------------------------------------
|
||||
elif any(keyword in Invoice_Details.lower() for keyword in ['credit note','logging report']):
|
||||
print("Credit note found:", PMC_No, Invoice_No, Basic_Amount, Debit_Amount, Final_Amount,
|
||||
After_Debit_Amount, GST_Amount, Amount, Final_Amount, Payment_Amount, Total_Amount, UTR, Invoice_No)
|
||||
cursor.callproc(
|
||||
'AddCreditNoteFromExcel',
|
||||
[
|
||||
PMC_No, Invoice_Details, Basic_Amount, Debit_Amount, After_Debit_Amount,
|
||||
GST_Amount, Amount, Final_Amount, Payment_Amount, Total_Amount, UTR,
|
||||
subcontractor_id, Invoice_No
|
||||
]
|
||||
)
|
||||
#-----------------------------------------------Hold Amount----------------------------------------------------------------------
|
||||
# Step 1: Normalize Invoice_Details: lowercase, trim, remove extra spaces
|
||||
normalized_details = re.sub(r'\s+', ' ', Invoice_Details.strip()).lower()
|
||||
# Step 2: Define lowercase keywords
|
||||
keywords = [
|
||||
'excess hold',
|
||||
'ht',
|
||||
'hold release amount',
|
||||
'dpr excess hold amount',
|
||||
'excess hold amount',
|
||||
'Multi to Single layer bill',
|
||||
'hold amount',
|
||||
'logging report'
|
||||
]
|
||||
# Step 3: Matching condition
|
||||
if any(kw in normalized_details for kw in keywords):
|
||||
print("✅ Match found. Inserting hold release for:", Invoice_Details)
|
||||
cursor.callproc(
|
||||
'AddHoldReleaseFromExcel',
|
||||
[PMC_No, Invoice_No, Invoice_Details, Basic_Amount, Final_Amount, UTR, subcontractor_id]
|
||||
)
|
||||
connection.commit()
|
||||
print("✅ Hold release inserted for:", PMC_No, Invoice_Details)
|
||||
#------------------------------------------------------------------------------------------------------------------
|
||||
elif Invoice_Details and any(
|
||||
keyword in Invoice_Details.lower() for keyword in ['gst', 'release', 'note']):
|
||||
print("Gst rels :", PMC_No, Invoice_No, Basic_Amount, Final_Amount,Total_Amount,UTR, subcontractor_id)
|
||||
cursor.callproc(
|
||||
'AddGSTReleaseFromExcel',
|
||||
[PMC_No, Invoice_No, Basic_Amount, Final_Amount, Total_Amount, UTR, subcontractor_id]
|
||||
)
|
||||
|
||||
if PMC_No and Total_Amount and UTR:
|
||||
print("Payment :", PMC_No, Invoice_No, Payment_Amount, TDS_Payment_Amount, Total_Amount, UTR )
|
||||
cursor.callproc("SavePayment",(PMC_No, Invoice_No, Payment_Amount, TDS_Payment_Amount, Total_Amount, UTR ))
|
||||
if not village_id:
|
||||
village_id = None
|
||||
cursor.callproc('InsertOrUpdateInPayment', (
|
||||
PMC_No,
|
||||
village_id,
|
||||
work_type,
|
||||
Invoice_Details,
|
||||
Invoice_Date,
|
||||
Invoice_No,
|
||||
Basic_Amount,
|
||||
Debit_Amount,
|
||||
After_Debit_Amount,
|
||||
Amount,
|
||||
GST_Amount,
|
||||
TDS_Amount,
|
||||
SD_Amount,
|
||||
On_Commission,
|
||||
Hydro_Testing,
|
||||
0,
|
||||
GST_SD_Amount,
|
||||
Final_Amount,
|
||||
Payment_Amount,
|
||||
TDS_Payment_Amount,
|
||||
Total_Amount,
|
||||
UTR,
|
||||
subcontractor_id
|
||||
))
|
||||
connection.commit()
|
||||
return jsonify({"success": "Data saved successfully!"}), 200
|
||||
except Exception as e:
|
||||
connection.rollback()
|
||||
return jsonify({"error": f"An unexpected error occurred: {e}"}), 500
|
||||
finally:
|
||||
cursor.close()
|
||||
connection.close()
|
||||
return render_template('index.html')
|
||||
# ---------------------- Report --------------------------------
|
||||
70
controllers/gst_release_controller.py
Normal file
70
controllers/gst_release_controller.py
Normal file
@@ -0,0 +1,70 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, jsonify
|
||||
from flask_login import login_required, current_user
|
||||
from model.gst_release import GSTReleasemodel
|
||||
from model.Log import LogHelper
|
||||
|
||||
gst_release_bp = Blueprint('gst_release_bp', __name__)
|
||||
|
||||
# ------------------- Add GST Release -------------------
|
||||
@gst_release_bp.route('/add_gst_release', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_gst_release():
|
||||
gst_releases_dict = GSTReleasemodel.fetch_all_gst_releases()
|
||||
gst_releases = [
|
||||
[
|
||||
g['GST_Release_Id'], g['PMC_No'], g['invoice_no'],
|
||||
g['Basic_Amount'], g['Final_Amount'], g['Total_Amount'], g['UTR']
|
||||
] for g in gst_releases_dict
|
||||
] if gst_releases_dict else []
|
||||
|
||||
if request.method == 'POST':
|
||||
pmc_no = request.form['PMC_No']
|
||||
invoice_no = request.form['invoice_No']
|
||||
basic_amount = request.form['basic_amount']
|
||||
final_amount = request.form['final_amount']
|
||||
total_amount = request.form['total_amount']
|
||||
utr = request.form['utr']
|
||||
contractor_id = request.form['subcontractor_id']
|
||||
|
||||
LogHelper.log_action("Add GST Release", f"User {current_user.id} added GST release '{pmc_no}'")
|
||||
GSTReleasemodel.insert_gst_release(pmc_no, invoice_no, basic_amount, final_amount, total_amount, utr, contractor_id)
|
||||
|
||||
return redirect(url_for('gst_release_bp.add_gst_release'))
|
||||
|
||||
return render_template('add_gst_release.html', gst_releases=gst_releases, invoices=[])
|
||||
|
||||
|
||||
# ------------------- Edit GST Release -------------------
|
||||
@gst_release_bp.route('/edit_gst_release/<int:gst_release_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_gst_release(gst_release_id):
|
||||
gst_release_data = GSTReleasemodel.fetch_gst_release_by_id(gst_release_id)
|
||||
if not gst_release_data:
|
||||
return "GST Release not found", 404
|
||||
|
||||
if request.method == 'POST':
|
||||
pmc_no = request.form['PMC_No']
|
||||
invoice_no = request.form['invoice_No']
|
||||
basic_amount = request.form['basic_amount']
|
||||
final_amount = request.form['final_amount']
|
||||
total_amount = request.form['total_amount']
|
||||
utr = request.form['utr']
|
||||
|
||||
LogHelper.log_action("Edit GST Release", f"User {current_user.id} edited GST release '{pmc_no}'")
|
||||
GSTReleasemodel.update_gst_release(gst_release_id, pmc_no, invoice_no, basic_amount, final_amount, total_amount, utr)
|
||||
|
||||
return redirect(url_for('gst_release_bp.add_gst_release'))
|
||||
|
||||
return render_template('edit_gst_release.html', gst_release_data=gst_release_data, invoices=[])
|
||||
|
||||
|
||||
# ------------------- Delete GST Release -------------------
|
||||
@gst_release_bp.route('/delete_gst_release/<int:gst_release_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_gst_release(gst_release_id):
|
||||
success, utr = GSTReleasemodel.delete_gst_release(gst_release_id)
|
||||
if not success:
|
||||
return jsonify({"message": "GST Release not found or failed to delete", "status": "error"}), 404
|
||||
|
||||
LogHelper.log_action("Delete GST Release", f"User {current_user.id} deleted GST release '{gst_release_id}'")
|
||||
return jsonify({"message": f"GST Release {gst_release_id} deleted successfully.", "status": "success"}), 200
|
||||
77
controllers/hold_types_controller.py
Normal file
77
controllers/hold_types_controller.py
Normal file
@@ -0,0 +1,77 @@
|
||||
from flask import Blueprint, render_template, request, jsonify, redirect, url_for
|
||||
from flask_login import login_required
|
||||
from model.HoldTypes import HoldTypes
|
||||
from model.GST import GST
|
||||
|
||||
hold_bp = Blueprint("hold_types", __name__)
|
||||
|
||||
|
||||
# ---------------- ADD HOLD TYPE ----------------
|
||||
@hold_bp.route('/add_hold_type', methods=['GET','POST'])
|
||||
@login_required
|
||||
def add_hold_type():
|
||||
|
||||
hold = HoldTypes()
|
||||
|
||||
if request.method == 'POST':
|
||||
hold.AddHoldType(request) # ✅
|
||||
return hold.resultMessage
|
||||
|
||||
hold_types = hold.GetAllHoldTypes() # ✅
|
||||
|
||||
return render_template(
|
||||
"add_hold_type.html",
|
||||
Hold_Types_data=hold_types
|
||||
)
|
||||
|
||||
|
||||
# ---------------- CHECK HOLD TYPE (OPTIONAL LIKE BLOCK) ----------------
|
||||
@hold_bp.route('/check_hold_type', methods=['POST'])
|
||||
@login_required
|
||||
def check_hold_type():
|
||||
|
||||
hold = HoldTypes()
|
||||
return hold.CheckHoldType(request) # if exists
|
||||
|
||||
|
||||
# ---------------- EDIT HOLD TYPE ----------------
|
||||
@hold_bp.route('/edit_hold_type/<int:id>', methods=['GET','POST'])
|
||||
@login_required
|
||||
def edit_hold_type(id):
|
||||
|
||||
hold = HoldTypes()
|
||||
|
||||
if request.method == 'POST':
|
||||
hold.EditHoldType(request, id) # ✅
|
||||
return hold.resultMessage
|
||||
|
||||
hold_data = hold.GetHoldTypeByID(id) # ✅
|
||||
|
||||
return render_template(
|
||||
"edit_hold_type.html",
|
||||
hold_type=hold_data
|
||||
)
|
||||
|
||||
|
||||
# ---------------- DELETE HOLD TYPE ----------------
|
||||
@hold_bp.route('/delete_hold_type/<int:id>')
|
||||
@login_required
|
||||
def delete_hold_type(id):
|
||||
|
||||
hold = HoldTypes()
|
||||
hold.DeleteHoldType(request, id) # ✅
|
||||
|
||||
return redirect(url_for("hold_types.add_hold_type"))
|
||||
|
||||
|
||||
# ---------------- GST ----------------
|
||||
@hold_bp.route('/unreleased_gst')
|
||||
@login_required
|
||||
def unreleased_gst():
|
||||
|
||||
data = GST.get_unreleased_gst()
|
||||
|
||||
return render_template(
|
||||
"unreleased_gst.html",
|
||||
data=data
|
||||
)
|
||||
200
controllers/invoice_controller.py
Normal file
200
controllers/invoice_controller.py
Normal file
@@ -0,0 +1,200 @@
|
||||
# # controllers/invoice_controller.py
|
||||
|
||||
# from flask import Blueprint, request, jsonify, render_template
|
||||
# from flask_login import login_required, current_user
|
||||
# from model.Invoice import *
|
||||
# from model.Log import LogHelper
|
||||
|
||||
# invoice_bp = Blueprint('invoice', __name__)
|
||||
|
||||
# # -------------------------------- Add Invoice ---------------------------------
|
||||
# @invoice_bp.route('/add_invoice', methods=['GET', 'POST'])
|
||||
# @login_required
|
||||
# def add_invoice():
|
||||
# if request.method == 'POST':
|
||||
# try:
|
||||
# village_name = request.form.get('village')
|
||||
# village_result = get_village_id(village_name)
|
||||
|
||||
# if not village_result:
|
||||
# return jsonify({"status": "error", "message": f"Village '{village_name}' not found"}), 400
|
||||
|
||||
# village_id = village_result['Village_Id']
|
||||
# data = request.form
|
||||
|
||||
# invoice_id = insert_invoice(data, village_id)
|
||||
# assign_subcontractor(data, village_id)
|
||||
# insert_hold_types(data, invoice_id)
|
||||
|
||||
# LogHelper.log_action("Add invoice", f"User {current_user.id} Added invoice '{data.get('pmc_no')}'")
|
||||
|
||||
# return jsonify({"status": "success", "message": "Invoice added successfully"}), 201
|
||||
|
||||
# except Exception as e:
|
||||
# return jsonify({"status": "error", "message": str(e)}), 500
|
||||
|
||||
# invoices = get_all_invoice_details()
|
||||
# villages = get_all_villages()
|
||||
# return render_template('add_invoice.html', invoices=invoices, villages=villages)
|
||||
|
||||
|
||||
# # ------------------- Search Subcontractor -------------------
|
||||
# @invoice_bp.route('/search_subcontractor', methods=['POST'])
|
||||
# @login_required
|
||||
# def search_subcontractor():
|
||||
# sub_query = request.form.get("query")
|
||||
# results = search_contractors(sub_query)
|
||||
|
||||
# if not results:
|
||||
# return "<li>No subcontractor found</li>"
|
||||
|
||||
# output = "".join(
|
||||
# f"<li data-id='{row['Contractor_Id']}'>{row['Contractor_Name']}</li>"
|
||||
# for row in results
|
||||
# )
|
||||
# return output
|
||||
|
||||
|
||||
# # ------------------- Get Hold Types -------------------
|
||||
# @invoice_bp.route('/get_hold_types', methods=['GET'])
|
||||
# @login_required
|
||||
# def get_hold_types():
|
||||
# hold_types = get_all_hold_types()
|
||||
# LogHelper.log_action("Get hold type", f"User {current_user.id} Get hold type '{hold_types}'")
|
||||
# return jsonify(hold_types)
|
||||
|
||||
|
||||
# # ------------------- Edit Invoice -------------------
|
||||
# @invoice_bp.route('/edit_invoice/<int:invoice_id>', methods=['GET', 'POST'])
|
||||
# @login_required
|
||||
# def edit_invoice(invoice_id):
|
||||
# if request.method == 'POST':
|
||||
# data = request.form
|
||||
# update_invoice(data, invoice_id)
|
||||
# update_inpayment(data)
|
||||
|
||||
# LogHelper.log_action("Edit invoice", f"User {current_user.id} Edit invoice '{invoice_id}'")
|
||||
# return jsonify({"status": "success", "message": "Invoice updated successfully"}), 200
|
||||
|
||||
# invoice = get_invoice_by_id(invoice_id)
|
||||
# return render_template('edit_invoice.html', invoice=invoice)
|
||||
|
||||
|
||||
# # ------------------- Delete Invoice -------------------
|
||||
# @invoice_bp.route('/delete_invoice/<int:invoice_id>', methods=['GET'])
|
||||
# @login_required
|
||||
# def delete_invoice_route(invoice_id):
|
||||
# try:
|
||||
# delete_invoice_data(invoice_id, current_user.id)
|
||||
# LogHelper.log_action("Delete Invoice", f"User {current_user.id} deleted Invoice '{invoice_id}'")
|
||||
# return jsonify({
|
||||
# "message": f"Invoice {invoice_id} deleted successfully.",
|
||||
# "status": "success"
|
||||
# })
|
||||
# except Exception as e:
|
||||
# return jsonify({
|
||||
# "message": str(e),
|
||||
# "status": "error"
|
||||
# }), 500
|
||||
|
||||
|
||||
|
||||
|
||||
# controllers/invoice_controller.py
|
||||
|
||||
from flask import Blueprint, request, jsonify, render_template
|
||||
from flask_login import login_required, current_user
|
||||
from model.Invoice import *
|
||||
from model.Log import LogHelper
|
||||
|
||||
invoice_bp = Blueprint('invoice', __name__)
|
||||
|
||||
# ------------------------------- Helpers -------------------------------
|
||||
def handle_exception(func):
|
||||
"""Decorator to handle exceptions and return JSON error responses."""
|
||||
def wrapper(*args, **kwargs):
|
||||
try:
|
||||
return func(*args, **kwargs)
|
||||
except Exception as e:
|
||||
return jsonify({"status": "error", "message": str(e)}), 500
|
||||
wrapper.__name__ = func.__name__
|
||||
return wrapper
|
||||
|
||||
def log_action(action: str, detail: str):
|
||||
LogHelper.log_action(action, f"User {current_user.id} {detail}")
|
||||
|
||||
|
||||
# ------------------------------- Add Invoice -------------------------------
|
||||
@invoice_bp.route('/add_invoice', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@handle_exception
|
||||
def add_invoice():
|
||||
if request.method == 'POST':
|
||||
data = request.form
|
||||
village_name = data.get('village')
|
||||
village_result = get_village_id(village_name)
|
||||
|
||||
if not village_result:
|
||||
return jsonify({"status": "error", "message": f"Village '{village_name}' not found"}), 400
|
||||
|
||||
village_id = village_result['Village_Id']
|
||||
invoice_id = insert_invoice(data, village_id)
|
||||
assign_subcontractor(data, village_id)
|
||||
insert_hold_types(data, invoice_id)
|
||||
|
||||
log_action("Add invoice", f"added invoice '{data.get('pmc_no')}'")
|
||||
return jsonify({"status": "success", "message": "Invoice added successfully"}), 201
|
||||
|
||||
invoices = get_all_invoice_details()
|
||||
villages = get_all_villages()
|
||||
return render_template('add_invoice.html', invoices=invoices, villages=villages)
|
||||
|
||||
|
||||
# ------------------------------- Search Subcontractor -------------------------------
|
||||
@invoice_bp.route('/search_subcontractor', methods=['POST'])
|
||||
@login_required
|
||||
@handle_exception
|
||||
def search_subcontractor():
|
||||
query = request.form.get("query", "").strip()
|
||||
results = search_contractors(query)
|
||||
|
||||
if not results:
|
||||
return "<li>No subcontractor found</li>"
|
||||
|
||||
return "".join(f"<li data-id='{r['Contractor_Id']}'>{r['Contractor_Name']}</li>" for r in results)
|
||||
|
||||
|
||||
# ------------------------------- Get Hold Types -------------------------------
|
||||
@invoice_bp.route('/get_hold_types', methods=['GET'])
|
||||
@login_required
|
||||
@handle_exception
|
||||
def get_hold_types():
|
||||
hold_types = get_all_hold_types()
|
||||
log_action("Get hold type", f"retrieved hold types '{hold_types}'")
|
||||
return jsonify(hold_types)
|
||||
|
||||
|
||||
# ------------------------------- Edit Invoice -------------------------------
|
||||
@invoice_bp.route('/edit_invoice/<int:invoice_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
@handle_exception
|
||||
def edit_invoice(invoice_id):
|
||||
if request.method == 'POST':
|
||||
data = request.form
|
||||
update_invoice(data, invoice_id)
|
||||
update_inpayment(data)
|
||||
log_action("Edit invoice", f"edited invoice '{invoice_id}'")
|
||||
return jsonify({"status": "success", "message": "Invoice updated successfully"}), 200
|
||||
|
||||
invoice = get_invoice_by_id(invoice_id)
|
||||
return render_template('edit_invoice.html', invoice=invoice)
|
||||
|
||||
|
||||
# ------------------------------- Delete Invoice -------------------------------
|
||||
@invoice_bp.route('/delete_invoice/<int:invoice_id>', methods=['GET'])
|
||||
@login_required
|
||||
@handle_exception
|
||||
def delete_invoice_route(invoice_id):
|
||||
delete_invoice_data(invoice_id, current_user.id)
|
||||
log_action("Delete invoice", f"deleted invoice '{invoice_id}'")
|
||||
return jsonify({"status": "success", "message": f"Invoice {invoice_id} deleted successfully."})
|
||||
31
controllers/log_controller.py
Normal file
31
controllers/log_controller.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from flask import Blueprint, render_template, request
|
||||
from flask_login import login_required
|
||||
|
||||
from model.Log import LogData
|
||||
|
||||
log_bp = Blueprint('log', __name__)
|
||||
|
||||
|
||||
@log_bp.route('/activity_log', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def activity_log():
|
||||
|
||||
start_date = request.values.get("start_date")
|
||||
end_date = request.values.get("end_date")
|
||||
user_name = request.values.get("username")
|
||||
|
||||
logData = LogData()
|
||||
|
||||
filtered_logs = logData.GetFilteredActivitiesLog(
|
||||
start_date,
|
||||
end_date,
|
||||
user_name
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"activity_log.html",
|
||||
logs=filtered_logs,
|
||||
start_date=start_date,
|
||||
end_date=end_date,
|
||||
username=user_name
|
||||
)
|
||||
103
controllers/payment_controller.py
Normal file
103
controllers/payment_controller.py
Normal file
@@ -0,0 +1,103 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, jsonify
|
||||
from flask_login import login_required, current_user
|
||||
from model.payment import Paymentmodel
|
||||
from model.Log import LogHelper
|
||||
|
||||
payment_bp = Blueprint('payment_bp', __name__)
|
||||
|
||||
# ------------------- Add Payment -------------------
|
||||
@payment_bp.route('/add_payment', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_payment():
|
||||
payments_dicts = Paymentmodel.fetch_all_payments()
|
||||
# Convert to array for template
|
||||
payments = [
|
||||
[
|
||||
p['Payment_Id'], p['PMC_No'], p['Invoice_No'],
|
||||
p['Payment_Amount'], p['TDS_Payment_Amount'], p['Total_Amount'], p['UTR']
|
||||
] for p in payments_dicts
|
||||
] if payments_dicts else []
|
||||
|
||||
if request.method == 'POST':
|
||||
subcontractor_id = request.form.get('subcontractor_id')
|
||||
pmc_no = request.form['PMC_No']
|
||||
invoice_no = request.form['invoice_No']
|
||||
amount = request.form['Payment_Amount']
|
||||
tds_amount = request.form['TDS_Payment_Amount']
|
||||
total_amount = request.form['total_amount']
|
||||
utr = request.form['utr']
|
||||
|
||||
LogHelper.log_action("Add Payment", f"User {current_user.id} Add Payment '{pmc_no}'")
|
||||
Paymentmodel.insert_payment(pmc_no, invoice_no, amount, tds_amount, total_amount, utr)
|
||||
Paymentmodel.update_inpayment(subcontractor_id, pmc_no, invoice_no, amount, tds_amount, total_amount, utr)
|
||||
|
||||
return redirect(url_for('payment_bp.add_payment'))
|
||||
|
||||
return render_template('add_payment.html', payments=payments)
|
||||
|
||||
|
||||
# ------------------- Get PMC Nos -------------------
|
||||
@payment_bp.route('/get_pmc_nos_by_subcontractor/<subcontractorId>')
|
||||
@login_required
|
||||
def get_pmc_nos_by_subcontractor(subcontractorId):
|
||||
connection = Paymentmodel.get_connection()
|
||||
cur = connection.cursor()
|
||||
cur.callproc('GetDistinctPMCNoByContractorId', [subcontractorId])
|
||||
results = []
|
||||
for result in cur.stored_results():
|
||||
results = result.fetchall()
|
||||
cur.close()
|
||||
pmc_nos = [row[0] for row in results]
|
||||
return jsonify({'pmc_nos': pmc_nos})
|
||||
|
||||
|
||||
# ------------------- Edit Payment -------------------
|
||||
@payment_bp.route('/edit_payment/<int:payment_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_payment(payment_id):
|
||||
payment_data = Paymentmodel.fetch_payment_by_id(payment_id)
|
||||
|
||||
if not payment_data:
|
||||
return "Payment not found", 404
|
||||
|
||||
if request.method == 'POST':
|
||||
pmc_no = request.form['PMC_No']
|
||||
invoice_no = request.form['invoice_No']
|
||||
amount = request.form['Payment_Amount']
|
||||
tds_amount = request.form['TDS_Payment_Amount']
|
||||
total_amount = request.form['total_amount']
|
||||
utr = request.form['utr']
|
||||
|
||||
LogHelper.log_action("Edit Payment", f"User {current_user.id} Edit Payment '{pmc_no}'")
|
||||
Paymentmodel.call_update_payment_proc(payment_id, pmc_no, invoice_no, amount, tds_amount, total_amount, utr)
|
||||
|
||||
# Update inpayment
|
||||
connection = Paymentmodel.get_connection()
|
||||
cursor = connection.cursor()
|
||||
cursor.callproc(
|
||||
'UpdateInpaymentByPMCInvoiceUTR',
|
||||
[amount, tds_amount, total_amount, pmc_no, invoice_no, utr]
|
||||
)
|
||||
connection.commit()
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
return redirect(url_for('payment_bp.add_payment'))
|
||||
|
||||
return render_template('edit_payment.html', payment_data=payment_data)
|
||||
|
||||
|
||||
# ------------------- Delete Payment -------------------
|
||||
@payment_bp.route('/delete_payment/<int:payment_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def delete_payment(payment_id):
|
||||
success, pmc_no, invoice_no = Paymentmodel.delete_payment(payment_id)
|
||||
if not success:
|
||||
return jsonify({"message": "Payment not found or failed to delete", "status": "error"}), 404
|
||||
|
||||
LogHelper.log_action("Delete Payment", f"User {current_user.id} deleted Payment '{payment_id}'")
|
||||
|
||||
return jsonify({
|
||||
"message": f"Payment ID {payment_id} deleted successfully.",
|
||||
"status": "success"
|
||||
}), 200
|
||||
36
controllers/pmc_report_controller.py
Normal file
36
controllers/pmc_report_controller.py
Normal file
@@ -0,0 +1,36 @@
|
||||
from flask import Blueprint, render_template, send_from_directory
|
||||
from model.PmcReport import PmcReport
|
||||
|
||||
pmc_report_bp = Blueprint("pmc_report", __name__)
|
||||
|
||||
@pmc_report_bp.route("/pmc_report/<pmc_no>")
|
||||
def pmc_report(pmc_no):
|
||||
|
||||
data = PmcReport.get_pmc_report(pmc_no)
|
||||
|
||||
if not data:
|
||||
return "No PMC found with this number", 404
|
||||
|
||||
return render_template(
|
||||
"pmc_report.html",
|
||||
info=data["info"],
|
||||
invoices=data["invoices"],
|
||||
hold_types=data["hold_types"],
|
||||
gst_rel=data["gst_rel"],
|
||||
payments=data["payments"],
|
||||
credit_note=data["credit_note"],
|
||||
hold_release=data["hold_release"],
|
||||
total=data["total"]
|
||||
)
|
||||
|
||||
@pmc_report_bp.route("/download_pmc_report/<pmc_no>")
|
||||
def download_pmc_report(pmc_no):
|
||||
|
||||
result = PmcReport.download_pmc_report(pmc_no)
|
||||
|
||||
if not result:
|
||||
return "No contractor found for this PMC No", 404
|
||||
|
||||
output_folder, file_name = result
|
||||
|
||||
return send_from_directory(output_folder, file_name, as_attachment=True)
|
||||
202
controllers/report_controller.py
Normal file
202
controllers/report_controller.py
Normal file
@@ -0,0 +1,202 @@
|
||||
from flask import Blueprint, render_template, request, jsonify, send_file
|
||||
from flask_login import login_required, current_user
|
||||
from model.Report import ReportHelper
|
||||
from model.Log import LogHelper
|
||||
import config
|
||||
from datetime import datetime
|
||||
import os
|
||||
import openpyxl
|
||||
from openpyxl.styles import Font
|
||||
from model.ContractorInfo import ContractorInfo
|
||||
|
||||
|
||||
report_bp = Blueprint("report", __name__)
|
||||
|
||||
|
||||
# ---------------- Report Page ----------------
|
||||
@report_bp.route("/report")
|
||||
@login_required
|
||||
def report_page():
|
||||
return render_template("/report.html")
|
||||
|
||||
|
||||
# ---------------- Search Contractor ----------------
|
||||
@report_bp.route("/search_contractor", methods=["POST"])
|
||||
@login_required
|
||||
def search_contractor():
|
||||
|
||||
subcontractor_name = request.form.get("subcontractor_name")
|
||||
pmc_no = request.form.get("pmc_no")
|
||||
state = request.form.get("state")
|
||||
district = request.form.get("district")
|
||||
block = request.form.get("block")
|
||||
village = request.form.get("village")
|
||||
year_from = request.form.get("year_from")
|
||||
year_to = request.form.get("year_to")
|
||||
|
||||
LogHelper.log_action(
|
||||
"Search Contractor",
|
||||
f"User {current_user.id} Search contractor '{subcontractor_name}'"
|
||||
)
|
||||
|
||||
data = ReportHelper.search_contractor(
|
||||
subcontractor_name,
|
||||
pmc_no,
|
||||
state,
|
||||
district,
|
||||
block,
|
||||
village,
|
||||
year_from,
|
||||
year_to
|
||||
)
|
||||
|
||||
return jsonify(data)
|
||||
|
||||
|
||||
# ---------------- Contractor Report ----------------
|
||||
|
||||
@report_bp.route('/contractor_report/<int:contractor_id>')
|
||||
@login_required
|
||||
def contractor_report(contractor_id):
|
||||
|
||||
data = ReportHelper.get_contractor_report(contractor_id)
|
||||
|
||||
return render_template(
|
||||
'subcontractor_report.html',
|
||||
contractor_id=contractor_id,
|
||||
**data
|
||||
)
|
||||
|
||||
class FilePathData:
|
||||
downloadReportFolder = "static/download"
|
||||
|
||||
@report_bp.route('/download_report/<int:contractor_id>')
|
||||
@login_required
|
||||
def download_report(contractor_id):
|
||||
try:
|
||||
connection = config.get_db_connection()
|
||||
cursor = connection.cursor(dictionary=True)
|
||||
|
||||
# -------- Contractor Info --------
|
||||
contractor = ContractorInfo(contractor_id)
|
||||
contInfo = contractor.contInfo
|
||||
|
||||
if not contInfo:
|
||||
return "No contractor found", 404
|
||||
|
||||
# -------- Invoice Data --------
|
||||
cursor.callproc('FetchInvoicesByContractor', [contractor_id])
|
||||
|
||||
invoices = []
|
||||
for result in cursor.stored_results():
|
||||
invoices.extend(result.fetchall())
|
||||
|
||||
if not invoices:
|
||||
return "No invoice data found"
|
||||
|
||||
# -------- Create Workbook --------
|
||||
workbook = openpyxl.Workbook()
|
||||
sheet = workbook.active
|
||||
sheet.title = "Contractor Report"
|
||||
|
||||
# ================= CONTRACTOR DETAILS =================
|
||||
sheet.append(["SUB CONTRACTOR DETAILS"])
|
||||
sheet.cell(row=sheet.max_row, column=1).font = Font(bold=True)
|
||||
sheet.append([])
|
||||
|
||||
sheet.append(["Name", contInfo.get("Contractor_Name") or ""])
|
||||
sheet.append(["Mobile No", contInfo.get("Mobile_No") or ""])
|
||||
sheet.append(["Email", contInfo.get("Email") or ""])
|
||||
sheet.append(["Village", contInfo.get("Village_Name") or ""])
|
||||
sheet.append(["Block", contInfo.get("Block_Name") or ""])
|
||||
sheet.append(["District", contInfo.get("District_Name") or ""])
|
||||
sheet.append(["State", contInfo.get("State_Name") or ""])
|
||||
sheet.append(["Address", contInfo.get("Address") or ""])
|
||||
sheet.append(["GST No", contInfo.get("GST_No") or ""])
|
||||
sheet.append(["PAN No", contInfo.get("PAN_No") or ""])
|
||||
sheet.append([])
|
||||
sheet.append([])
|
||||
|
||||
# ================= TABLE HEADERS =================
|
||||
headers = [
|
||||
"PMC No", "Village", "Invoice No", "Invoice Date", "Work Type","Invoice_Details",
|
||||
"Basic Amount", "Debit Amount", "After Debit Amount",
|
||||
"Amount", "GST Amount", "TDS Amount", "SD Amount",
|
||||
"On Commission", "Hydro Testing", "Hold Amount",
|
||||
"GST SD Amount", "Final Amount",
|
||||
"Payment Amount", "TDS Payment",
|
||||
"Total Amount", "UTR"
|
||||
]
|
||||
sheet.append(headers)
|
||||
for col in range(1, len(headers) + 1):
|
||||
sheet.cell(row=sheet.max_row, column=col).font = Font(bold=True)
|
||||
|
||||
# ================= DATA =================
|
||||
total_final = 0
|
||||
total_payment = 0
|
||||
total_amount = 0
|
||||
|
||||
for inv in invoices:
|
||||
row = [
|
||||
inv.get("PMC_No"),
|
||||
inv.get("Village_Name"),
|
||||
inv.get("invoice_no"),
|
||||
inv.get("Invoice_Date"),
|
||||
inv.get("Work_Type"),
|
||||
inv.get("Invoice_Details"),
|
||||
inv.get("Basic_Amount"),
|
||||
inv.get("Debit_Amount"),
|
||||
inv.get("After_Debit_Amount"),
|
||||
inv.get("Amount"),
|
||||
inv.get("GST_Amount"),
|
||||
inv.get("TDS_Amount"),
|
||||
inv.get("SD_Amount"),
|
||||
inv.get("On_Commission"),
|
||||
inv.get("Hydro_Testing"),
|
||||
inv.get("Hold_Amount"),
|
||||
inv.get("GST_SD_Amount"),
|
||||
inv.get("Final_Amount"),
|
||||
inv.get("Payment_Amount"),
|
||||
inv.get("TDS_Payment_Amount"),
|
||||
inv.get("Total_Amount"),
|
||||
inv.get("UTR")
|
||||
]
|
||||
|
||||
total_final += float(inv.get("Final_Amount") or 0)
|
||||
total_payment += float(inv.get("Payment_Amount") or 0)
|
||||
total_amount += float(inv.get("Total_Amount") or 0)
|
||||
|
||||
sheet.append(row)
|
||||
|
||||
# ================= TOTAL ROW =================
|
||||
sheet.append([])
|
||||
sheet.append([
|
||||
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
|
||||
"TOTAL",
|
||||
total_final,
|
||||
total_payment,
|
||||
"",
|
||||
total_amount,
|
||||
""
|
||||
])
|
||||
|
||||
# ================= AUTO WIDTH =================
|
||||
for column in sheet.columns:
|
||||
max_length = 0
|
||||
column_letter = column[0].column_letter
|
||||
for cell in column:
|
||||
if cell.value:
|
||||
max_length = max(max_length, len(str(cell.value)))
|
||||
sheet.column_dimensions[column_letter].width = max_length + 2
|
||||
|
||||
# ================= SAVE FILE =================
|
||||
output_folder = "downloads"
|
||||
os.makedirs(output_folder, exist_ok=True)
|
||||
filename = f"Contractor_Report_{contInfo.get('Contractor_Name')}.xlsx"
|
||||
output_file = os.path.join(output_folder, filename)
|
||||
workbook.save(output_file)
|
||||
|
||||
return send_file(output_file, as_attachment=True)
|
||||
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
69
controllers/state_controller.py
Normal file
69
controllers/state_controller.py
Normal file
@@ -0,0 +1,69 @@
|
||||
from flask import Blueprint, render_template, request, redirect, url_for
|
||||
from flask_login import login_required
|
||||
from model.State import State
|
||||
|
||||
state_bp = Blueprint('state', __name__)
|
||||
|
||||
|
||||
@state_bp.route('/add_state', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_state():
|
||||
|
||||
state = State()
|
||||
|
||||
if request.method == 'POST':
|
||||
state.AddState(request=request)
|
||||
return state.resultMessage
|
||||
|
||||
statedata = state.GetAllStates(request=request)
|
||||
|
||||
return render_template('add_state.html', statedata=statedata)
|
||||
|
||||
|
||||
@state_bp.route('/check_state', methods=['POST'])
|
||||
@login_required
|
||||
def check_state():
|
||||
|
||||
state = State()
|
||||
|
||||
return state.CheckState(request=request)
|
||||
|
||||
|
||||
@state_bp.route('/delete_state/<int:id>')
|
||||
@login_required
|
||||
def deleteState(id):
|
||||
|
||||
state = State()
|
||||
|
||||
msg = state.DeleteState(request=request, id=id)
|
||||
|
||||
if not state.isSuccess:
|
||||
return state.resultMessage
|
||||
else:
|
||||
return redirect(url_for('state.add_state'))
|
||||
|
||||
|
||||
@state_bp.route('/edit_state/<int:id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def editState(id):
|
||||
|
||||
state = State()
|
||||
|
||||
if request.method == 'POST':
|
||||
|
||||
state.EditState(request=request, id=id)
|
||||
|
||||
if state.isSuccess:
|
||||
return redirect(url_for('state.add_state'))
|
||||
else:
|
||||
return state.resultMessage
|
||||
|
||||
statedata = state.GetStateByID(request=request, id=id)
|
||||
|
||||
if not state.isSuccess:
|
||||
return state.resultMessage
|
||||
|
||||
if statedata is None:
|
||||
statedata = []
|
||||
|
||||
return render_template('edit_state.html', state=statedata)
|
||||
100
controllers/subcontractor_controller.py
Normal file
100
controllers/subcontractor_controller.py
Normal file
@@ -0,0 +1,100 @@
|
||||
# controllers/subcontractor_controller.py
|
||||
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, jsonify
|
||||
from flask_login import login_required
|
||||
from model.Subcontractor import Subcontractor
|
||||
from model.Log import LogHelper
|
||||
subcontractor_bp = Blueprint('subcontractor', __name__)
|
||||
|
||||
# Simple replacements for missing HtmlHelper and ResponseHandler
|
||||
class HtmlHelper:
|
||||
@staticmethod
|
||||
def json_response(data, status=200):
|
||||
return jsonify(data), status
|
||||
|
||||
class ResponseHandler:
|
||||
@staticmethod
|
||||
def fetch_failure(entity):
|
||||
return {"status": "error", "message": f"Failed to fetch {entity}"}
|
||||
|
||||
@staticmethod
|
||||
def add_failure(entity):
|
||||
return {"status": "error", "message": f"Failed to add {entity}"}
|
||||
|
||||
@staticmethod
|
||||
def update_failure(entity):
|
||||
return {"status": "error", "message": f"Failed to update {entity}"}
|
||||
|
||||
@staticmethod
|
||||
def delete_failure(entity):
|
||||
return {"status": "error", "message": f"Failed to delete {entity}"}
|
||||
|
||||
|
||||
@subcontractor_bp.route('/subcontractor', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def subcontract():
|
||||
subcontractor = []
|
||||
|
||||
if request.method == 'GET':
|
||||
subcontractor, error = Subcontractor.get_all_subcontractors()
|
||||
if error:
|
||||
return HtmlHelper.json_response(ResponseHandler.fetch_failure("Subcontractor"), 500)
|
||||
|
||||
if request.method == 'POST':
|
||||
contractor_data = {
|
||||
'Contractor_Name': request.form['Contractor_Name'],
|
||||
'Address': request.form['Address'],
|
||||
'Mobile_No': request.form['Mobile_No'],
|
||||
'PAN_No': request.form['PAN_No'],
|
||||
'Email': request.form['Email'],
|
||||
'Gender': request.form['Gender'],
|
||||
'GST_Registration_Type': request.form['GST_Registration_Type'],
|
||||
'GST_No': request.form['GST_No'],
|
||||
'Contractor_password': request.form['Contractor_password'],
|
||||
}
|
||||
error = Subcontractor.save_subcontractor(contractor_data)
|
||||
if error:
|
||||
return HtmlHelper.json_response(ResponseHandler.add_failure("Subcontractor"), 500)
|
||||
subcontractor, _ = Subcontractor.get_all_subcontractors()
|
||||
|
||||
return render_template('add_subcontractor.html', subcontractor=subcontractor)
|
||||
|
||||
|
||||
@subcontractor_bp.route('/edit_subcontractor/<int:id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_subcontractor(id):
|
||||
subcontractor, error = Subcontractor.get_subcontractor_by_id(id)
|
||||
if error:
|
||||
return HtmlHelper.json_response(ResponseHandler.fetch_failure("Subcontractor"), 500)
|
||||
if not subcontractor:
|
||||
return HtmlHelper.json_response(ResponseHandler.fetch_failure("Subcontractor"), 404)
|
||||
|
||||
if request.method == 'POST':
|
||||
updated_data = {
|
||||
'Contractor_Name': request.form['Contractor_Name'],
|
||||
'Address': request.form['Address'],
|
||||
'Mobile_No': request.form['Mobile_No'],
|
||||
'PAN_No': request.form['PAN_No'],
|
||||
'Email': request.form['Email'],
|
||||
'Gender': request.form['Gender'],
|
||||
'GST_Registration_Type': request.form['GST_Registration_Type'],
|
||||
'GST_No': request.form['GST_No'],
|
||||
'Contractor_password': request.form['Contractor_password'],
|
||||
}
|
||||
error = Subcontractor.update_subcontractor(id, updated_data)
|
||||
if error:
|
||||
return HtmlHelper.json_response(ResponseHandler.update_failure("Subcontractor"), 500)
|
||||
return redirect(url_for('subcontractor.subcontract'))
|
||||
|
||||
return render_template('edit_subcontractor.html', subcontractor=subcontractor)
|
||||
|
||||
|
||||
@subcontractor_bp.route('/deleteSubContractor/<int:id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def deleteSubContractor(id):
|
||||
error, affected_rows = Subcontractor.delete_subcontractor(id)
|
||||
if error:
|
||||
return HtmlHelper.json_response(ResponseHandler.delete_failure("Subcontractor"), 500)
|
||||
if affected_rows == 0:
|
||||
return HtmlHelper.json_response(ResponseHandler.fetch_failure("Subcontractor not deleted"), 404)
|
||||
return redirect(url_for('subcontractor.subcontract'))
|
||||
305
controllers/village_controller.py
Normal file
305
controllers/village_controller.py
Normal file
@@ -0,0 +1,305 @@
|
||||
# from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
|
||||
# from flask_login import login_required
|
||||
|
||||
# import config
|
||||
|
||||
# from model.Village import Village
|
||||
# from model.State import State
|
||||
|
||||
# # Create Blueprint
|
||||
# village_bp = Blueprint('village', __name__)
|
||||
|
||||
|
||||
# # ------------------------- Add Village -------------------------
|
||||
# @village_bp.route('/add_village', methods=['GET', 'POST'])
|
||||
# @login_required
|
||||
# def add_village():
|
||||
|
||||
# village = Village()
|
||||
|
||||
# if request.method == 'POST':
|
||||
# village.AddVillage(request=request)
|
||||
# return village.resultMessage
|
||||
|
||||
# state = State()
|
||||
# states = state.GetAllStates(request=request)
|
||||
|
||||
# villages = village.GetAllVillages(request=request)
|
||||
|
||||
# return render_template(
|
||||
# 'add_village.html',
|
||||
# states=states,
|
||||
# villages=villages
|
||||
# )
|
||||
|
||||
|
||||
# # ------------------------- Fetch Districts -------------------------
|
||||
# @village_bp.route('/get_districts/<int:state_id>')
|
||||
# @login_required
|
||||
# def get_districts(state_id):
|
||||
|
||||
# connection = config.get_db_connection()
|
||||
# cursor = connection.cursor()
|
||||
|
||||
# cursor.callproc("GetDistrictByStateID", [state_id])
|
||||
|
||||
# districts = []
|
||||
|
||||
# for rs in cursor.stored_results():
|
||||
# districts = rs.fetchall()
|
||||
|
||||
# cursor.close()
|
||||
# connection.close()
|
||||
|
||||
# district_list = []
|
||||
|
||||
# for d in districts:
|
||||
# district_list.append({
|
||||
# "id": d[0],
|
||||
# "name": d[1]
|
||||
# })
|
||||
|
||||
# return jsonify(district_list)
|
||||
|
||||
|
||||
# # ------------------------- Fetch Blocks -------------------------
|
||||
# @village_bp.route('/get_blocks/<int:district_id>')
|
||||
# @login_required
|
||||
# def get_blocks(district_id):
|
||||
|
||||
# connection = config.get_db_connection()
|
||||
# cursor = connection.cursor()
|
||||
|
||||
# cursor.callproc("GetBlocksByDistrictID", [district_id])
|
||||
|
||||
# blocks = []
|
||||
|
||||
# for rs in cursor.stored_results():
|
||||
# blocks = rs.fetchall()
|
||||
|
||||
# cursor.close()
|
||||
# connection.close()
|
||||
|
||||
# block_list = []
|
||||
|
||||
# for b in blocks:
|
||||
# block_list.append({
|
||||
# "id": b[0],
|
||||
# "name": b[1]
|
||||
# })
|
||||
|
||||
# return jsonify(block_list)
|
||||
|
||||
|
||||
# # ------------------------- Check Village -------------------------
|
||||
# @village_bp.route('/check_village', methods=['POST'])
|
||||
# @login_required
|
||||
# def check_village():
|
||||
|
||||
# village = Village()
|
||||
# return village.CheckVillage(request=request)
|
||||
|
||||
|
||||
# # ------------------------- Delete Village -------------------------
|
||||
# @village_bp.route('/delete_village/<int:village_id>')
|
||||
# @login_required
|
||||
# def delete_village(village_id):
|
||||
|
||||
# village = Village()
|
||||
|
||||
# village.DeleteVillage(request=request, village_id=village_id)
|
||||
|
||||
# if not village.isSuccess:
|
||||
# flash(village.resultMessage, "error")
|
||||
# else:
|
||||
# flash(village.resultMessage, "success")
|
||||
|
||||
# return redirect(url_for('village.add_village'))
|
||||
|
||||
|
||||
# # ------------------------- Edit Village -------------------------
|
||||
# @village_bp.route('/edit_village/<int:village_id>', methods=['GET', 'POST'])
|
||||
# @login_required
|
||||
# def edit_village(village_id):
|
||||
|
||||
# village = Village()
|
||||
|
||||
# if request.method == 'POST':
|
||||
|
||||
# village.EditVillage(request=request, village_id=village_id)
|
||||
|
||||
# if village.isSuccess:
|
||||
# flash(village.resultMessage, "success")
|
||||
# return redirect(url_for('village.add_village'))
|
||||
|
||||
# else:
|
||||
# flash(village.resultMessage, "error")
|
||||
|
||||
# village_data = village.GetVillageByID(id=village_id)
|
||||
# blocks = village.GetAllBlocks()
|
||||
|
||||
# return render_template(
|
||||
# 'edit_village.html',
|
||||
# village_data=village_data,
|
||||
# blocks=blocks
|
||||
# )
|
||||
|
||||
# else:
|
||||
|
||||
# village_data = village.GetVillageByID(request=request, id=village_id)
|
||||
|
||||
# if not village.isSuccess:
|
||||
# flash(village.resultMessage, "error")
|
||||
# return redirect(url_for('village.add_village'))
|
||||
|
||||
# blocks = village.GetAllBlocks(request=request)
|
||||
|
||||
# if village_data is None:
|
||||
# village_data = []
|
||||
|
||||
# if blocks is None:
|
||||
# blocks = []
|
||||
|
||||
# return render_template(
|
||||
# 'edit_village.html',
|
||||
# village_data=village_data,
|
||||
# blocks=blocks
|
||||
# )
|
||||
|
||||
|
||||
|
||||
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
|
||||
from flask_login import login_required
|
||||
|
||||
import config
|
||||
from model.Village import Village
|
||||
from model.State import State
|
||||
|
||||
# Create Blueprint
|
||||
village_bp = Blueprint('village', __name__)
|
||||
|
||||
|
||||
# ------------------------- Add Village -------------------------
|
||||
@village_bp.route('/add_village', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def add_village():
|
||||
|
||||
village = Village()
|
||||
|
||||
if request.method == 'POST':
|
||||
village.AddVillage(request=request)
|
||||
return village.resultMessage
|
||||
|
||||
state = State()
|
||||
states = state.GetAllStates(request=request)
|
||||
villages = village.GetAllVillages(request=request)
|
||||
|
||||
return render_template(
|
||||
'add_village.html',
|
||||
states=states,
|
||||
villages=villages
|
||||
)
|
||||
|
||||
|
||||
# ------------------------- Fetch Districts -------------------------
|
||||
@village_bp.route('/get_districts/<int:state_id>')
|
||||
@login_required
|
||||
def get_districts(state_id):
|
||||
|
||||
connection = config.get_db_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.callproc("GetDistrictByStateID", [state_id])
|
||||
districts = []
|
||||
|
||||
for rs in cursor.stored_results():
|
||||
districts = rs.fetchall()
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
return jsonify([{"id": d[0], "name": d[1]} for d in districts])
|
||||
|
||||
|
||||
# ------------------------- Fetch Blocks -------------------------
|
||||
@village_bp.route('/get_blocks/<int:district_id>')
|
||||
@login_required
|
||||
def get_blocks(district_id):
|
||||
|
||||
connection = config.get_db_connection()
|
||||
cursor = connection.cursor()
|
||||
|
||||
cursor.callproc("GetBlocksByDistrictID", [district_id])
|
||||
blocks = []
|
||||
|
||||
for rs in cursor.stored_results():
|
||||
blocks = rs.fetchall()
|
||||
|
||||
cursor.close()
|
||||
connection.close()
|
||||
|
||||
return jsonify([{"id": b[0], "name": b[1]} for b in blocks])
|
||||
|
||||
|
||||
# ------------------------- Check Village -------------------------
|
||||
@village_bp.route('/check_village', methods=['POST'])
|
||||
@login_required
|
||||
def check_village():
|
||||
village = Village()
|
||||
return village.CheckVillage(request=request)
|
||||
|
||||
|
||||
# ------------------------- Delete Village -------------------------
|
||||
@village_bp.route('/delete_village/<int:village_id>')
|
||||
@login_required
|
||||
def delete_village(village_id):
|
||||
|
||||
village = Village()
|
||||
village.DeleteVillage(request=request, village_id=village_id)
|
||||
|
||||
flash(village.resultMessage, "success" if village.isSuccess else "error")
|
||||
return redirect(url_for('village.add_village'))
|
||||
|
||||
|
||||
# ------------------------- Edit Village -------------------------
|
||||
@village_bp.route('/edit_village/<int:village_id>', methods=['GET', 'POST'])
|
||||
@login_required
|
||||
def edit_village(village_id):
|
||||
|
||||
village = Village()
|
||||
|
||||
if request.method == 'POST':
|
||||
|
||||
village.EditVillage(request=request, village_id=village_id)
|
||||
|
||||
if village.isSuccess:
|
||||
flash(village.resultMessage, "success")
|
||||
return redirect(url_for('village.add_village'))
|
||||
|
||||
else:
|
||||
flash(village.resultMessage, "error")
|
||||
|
||||
village_data = village.GetVillageByID(id=village_id) or []
|
||||
blocks = village.GetAllBlocks() or []
|
||||
|
||||
return render_template(
|
||||
'edit_village.html',
|
||||
village_data=village_data,
|
||||
blocks=blocks
|
||||
)
|
||||
|
||||
else:
|
||||
# ✅ FIXED HERE (removed request)
|
||||
village_data = village.GetVillageByID(id=village_id)
|
||||
|
||||
if not village.isSuccess:
|
||||
flash(village.resultMessage, "error")
|
||||
return redirect(url_for('village.add_village'))
|
||||
|
||||
blocks = village.GetAllBlocks() or []
|
||||
|
||||
return render_template(
|
||||
'edit_village.html',
|
||||
village_data=village_data or [],
|
||||
blocks=blocks
|
||||
)
|
||||
Reference in New Issue
Block a user