Compare commits
6 Commits
6b4beb5af8
...
b78526ad9f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b78526ad9f | ||
| 937018dc16 | |||
| eda238c235 | |||
| f184d6cecc | |||
| e7646eee76 | |||
| 64ca39944b |
@@ -1,5 +1,5 @@
|
|||||||
import config
|
import config
|
||||||
from flask import Blueprint, render_template, request, redirect, url_for, jsonify
|
from flask import Blueprint, render_template, request, redirect, url_for, jsonify, flash
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
from model.State import State
|
from model.State import State
|
||||||
@@ -74,7 +74,14 @@ def edit_block(block_id):
|
|||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
block.EditBlock(request, block_id)
|
block.EditBlock(request, block_id)
|
||||||
return block.resultMessage
|
block.resultMessage
|
||||||
|
|
||||||
|
if block.resultMessage:
|
||||||
|
flash("Block updated successfully!", "success")
|
||||||
|
return redirect(url_for('block.add_block'))
|
||||||
|
else:
|
||||||
|
flash(block.resultMessage, "error")
|
||||||
|
|
||||||
|
|
||||||
connection = config.get_db_connection()
|
connection = config.get_db_connection()
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|||||||
@@ -83,17 +83,29 @@ def check_village():
|
|||||||
return village.CheckVillage(request=request)
|
return village.CheckVillage(request=request)
|
||||||
|
|
||||||
|
|
||||||
# ------------------------- Delete Village -------------------------
|
|
||||||
@village_bp.route('/delete_village/<int:village_id>')
|
@village_bp.route('/delete_village/<int:village_id>')
|
||||||
@login_required
|
@login_required
|
||||||
def delete_village(village_id):
|
def delete_village(village_id):
|
||||||
|
|
||||||
village = Village()
|
village = Village()
|
||||||
village.DeleteVillage(request=request, village_id=village_id)
|
village.DeleteVillage(request=request, village_id=village_id)
|
||||||
|
|
||||||
flash(village.resultMessage, "success" if village.isSuccess else "error")
|
# ✅ Convert resultMessage to string if it's a Response or tuple
|
||||||
return redirect(url_for('village.add_village'))
|
raw_msg = village.resultMessage
|
||||||
|
|
||||||
|
if isinstance(raw_msg, tuple):
|
||||||
|
# e.g., (<Response ...>, 200)
|
||||||
|
msg = "Village deleted successfully!"
|
||||||
|
elif hasattr(raw_msg, 'get_data'):
|
||||||
|
# Flask Response object
|
||||||
|
msg = raw_msg.get_data(as_text=True) # get raw text
|
||||||
|
else:
|
||||||
|
# fallback
|
||||||
|
msg = str(raw_msg) if raw_msg else "Village deleted successfully!"
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"status": "success" if village.isSuccess else "error",
|
||||||
|
"message": msg
|
||||||
|
})
|
||||||
|
|
||||||
# ------------------------- Edit Village -------------------------
|
# ------------------------- Edit Village -------------------------
|
||||||
@village_bp.route('/edit_village/<int:village_id>', methods=['GET', 'POST'])
|
@village_bp.route('/edit_village/<int:village_id>', methods=['GET', 'POST'])
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
|
from flask import Blueprint, render_template, request, redirect, url_for, jsonify
|
||||||
|
|
||||||
from model.Utilities import RegEx, ResponseHandler, HtmlHelper, ItemCRUDType
|
from model.Utilities import RegEx, ResponseHandler, HtmlHelper, ItemCRUDType
|
||||||
from model.Log import LogData, LogHelper
|
from model.Log import LogData, LogHelper
|
||||||
@@ -147,7 +147,7 @@ class Block:
|
|||||||
|
|
||||||
self.isSuccess = block.isSuccess
|
self.isSuccess = block.isSuccess
|
||||||
self.resultMessage = block.resultMessage
|
self.resultMessage = block.resultMessage
|
||||||
return render_template('add_block.html')
|
return
|
||||||
|
|
||||||
# ----------------------------------------------------------
|
# ----------------------------------------------------------
|
||||||
# Delete Block
|
# Delete Block
|
||||||
|
|||||||
@@ -1,6 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from model.Utilities import RegEx, ResponseHandler, HtmlHelper, ItemCRUDType
|
from model.Utilities import RegEx, ResponseHandler, HtmlHelper, ItemCRUDType
|
||||||
from model.Log import LogHelper
|
from model.Log import LogHelper
|
||||||
@@ -38,7 +35,6 @@ class ItemCRUD:
|
|||||||
def __init__(self, itemType):
|
def __init__(self, itemType):
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.resultMessage = ""
|
self.resultMessage = ""
|
||||||
self.response = {} # ✅ ADDED
|
|
||||||
self.itemCRUDType = itemType
|
self.itemCRUDType = itemType
|
||||||
self.itemCRUDMapping = itemCRUDMapping(itemType)
|
self.itemCRUDMapping = itemCRUDMapping(itemType)
|
||||||
|
|
||||||
@@ -60,14 +56,16 @@ class ItemCRUD:
|
|||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
self.isSuccess = True
|
self.isSuccess = True
|
||||||
self.response = ResponseHandler.delete_success(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.delete_success(self.itemCRUDMapping.name), 200
|
||||||
|
)
|
||||||
|
|
||||||
except mysql.connector.Error as e:
|
except mysql.connector.Error as e:
|
||||||
print(f"Error deleting {self.itemCRUDMapping.name}: {e}")
|
print(f"Error deleting {self.itemCRUDMapping.name}: {e}")
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.delete_failure(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.delete_failure(self.itemCRUDMapping.name), 500
|
||||||
|
)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
cursor.close()
|
cursor.close()
|
||||||
@@ -81,8 +79,9 @@ class ItemCRUD:
|
|||||||
connection = config.get_db_connection()
|
connection = config.get_db_connection()
|
||||||
if not connection:
|
if not connection:
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.add_failure(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.db_connection_failure(), 500
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
@@ -93,8 +92,12 @@ class ItemCRUD:
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# SUBCONTRACTOR
|
# ======================================================
|
||||||
|
# SUBCONTRACTOR (MULTI-FIELD)
|
||||||
|
# ======================================================
|
||||||
if data:
|
if data:
|
||||||
|
|
||||||
|
# Duplicate check
|
||||||
cursor.callproc(storedprocfetch, (data['Contractor_Name'],))
|
cursor.callproc(storedprocfetch, (data['Contractor_Name'],))
|
||||||
|
|
||||||
existing_item = None
|
existing_item = None
|
||||||
@@ -103,10 +106,12 @@ class ItemCRUD:
|
|||||||
|
|
||||||
if existing_item:
|
if existing_item:
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.already_exists(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.already_exists(self.itemCRUDMapping.name), 409
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Insert
|
||||||
cursor.callproc(storedprocadd, (
|
cursor.callproc(storedprocadd, (
|
||||||
data['Contractor_Name'],
|
data['Contractor_Name'],
|
||||||
data['Address'],
|
data['Address'],
|
||||||
@@ -122,17 +127,22 @@ class ItemCRUD:
|
|||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
self.isSuccess = True
|
self.isSuccess = True
|
||||||
self.response = ResponseHandler.add_success(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.add_success(self.itemCRUDMapping.name), 200
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
# NORMAL
|
# ======================================================
|
||||||
|
# NORMAL (Village / Block / State)
|
||||||
|
# ======================================================
|
||||||
if not re.match(RegEx.patternAlphabetOnly, childname):
|
if not re.match(RegEx.patternAlphabetOnly, childname):
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.invalid_name(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.invalid_name(self.itemCRUDMapping.name), 400
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Duplicate check
|
||||||
if parentid is None:
|
if parentid is None:
|
||||||
cursor.callproc(storedprocfetch, (childname,))
|
cursor.callproc(storedprocfetch, (childname,))
|
||||||
else:
|
else:
|
||||||
@@ -144,10 +154,12 @@ class ItemCRUD:
|
|||||||
|
|
||||||
if existing_item:
|
if existing_item:
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.already_exists(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.already_exists(self.itemCRUDMapping.name), 409
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Insert
|
||||||
if parentid is None:
|
if parentid is None:
|
||||||
cursor.callproc(storedprocadd, (childname,))
|
cursor.callproc(storedprocadd, (childname,))
|
||||||
else:
|
else:
|
||||||
@@ -156,14 +168,17 @@ class ItemCRUD:
|
|||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
self.isSuccess = True
|
self.isSuccess = True
|
||||||
self.response = ResponseHandler.add_success(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
|
||||||
|
ResponseHandler.add_success(self.itemCRUDMapping.name), 200
|
||||||
|
)
|
||||||
|
|
||||||
except mysql.connector.Error as e:
|
except mysql.connector.Error as e:
|
||||||
print(f"Database Error: {e}")
|
print(f"Database Error: {e}")
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.add_failure(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.add_failure(self.itemCRUDMapping.name), 500
|
||||||
|
)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
cursor.close()
|
cursor.close()
|
||||||
@@ -183,6 +198,9 @@ class ItemCRUD:
|
|||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
# ======================================================
|
||||||
|
# SUBCONTRACTOR (MULTI-FIELD)
|
||||||
|
# ======================================================
|
||||||
if data:
|
if data:
|
||||||
cursor.callproc(storedprocupdate, (
|
cursor.callproc(storedprocupdate, (
|
||||||
childid,
|
childid,
|
||||||
@@ -200,14 +218,17 @@ class ItemCRUD:
|
|||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
self.isSuccess = True
|
self.isSuccess = True
|
||||||
self.response = ResponseHandler.update_success(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.update_success(self.itemCRUDMapping.name), 200
|
||||||
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# ======================================================
|
||||||
|
# NORMAL
|
||||||
|
# ======================================================
|
||||||
if not re.match(RegEx.patternAlphabetOnly, childname):
|
if not re.match(RegEx.patternAlphabetOnly, childname):
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.update_failure(self.itemCRUDMapping.name)
|
self.resultMessage = ResponseHandler.update_failure(self.itemCRUDMapping.name)['message']
|
||||||
self.resultMessage = self.response["message"]
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if parentid is None:
|
if parentid is None:
|
||||||
@@ -218,14 +239,14 @@ class ItemCRUD:
|
|||||||
connection.commit()
|
connection.commit()
|
||||||
|
|
||||||
self.isSuccess = True
|
self.isSuccess = True
|
||||||
self.response = ResponseHandler.update_success(self.itemCRUDMapping.name)
|
self.resultMessage = ResponseHandler.update_success(self.itemCRUDMapping.name)['message']
|
||||||
self.resultMessage = self.response["message"]
|
|
||||||
|
|
||||||
except mysql.connector.Error as e:
|
except mysql.connector.Error as e:
|
||||||
print(f"Error updating {self.itemCRUDMapping.name}: {e}")
|
print(f"Error updating {self.itemCRUDMapping.name}: {e}")
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.update_failure(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.update_failure(self.itemCRUDMapping.name), 500
|
||||||
|
)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
cursor.close()
|
cursor.close()
|
||||||
@@ -255,8 +276,9 @@ class ItemCRUD:
|
|||||||
except mysql.connector.Error as e:
|
except mysql.connector.Error as e:
|
||||||
print(f"Error fetching {self.itemCRUDMapping.name}: {e}")
|
print(f"Error fetching {self.itemCRUDMapping.name}: {e}")
|
||||||
self.isSuccess = False
|
self.isSuccess = False
|
||||||
self.response = ResponseHandler.fetch_failure(self.itemCRUDMapping.name)
|
self.resultMessage = HtmlHelper.json_response(
|
||||||
self.resultMessage = self.response["message"]
|
ResponseHandler.fetch_failure(self.itemCRUDMapping.name), 500
|
||||||
|
)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
@@ -290,7 +312,7 @@ class ItemCRUD:
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
# ----------------------------------------------------------
|
# ----------------------------------------------------------
|
||||||
# CHECK ITEM (KEEP AS IS - API USE)
|
# CHECK ITEM
|
||||||
# ----------------------------------------------------------
|
# ----------------------------------------------------------
|
||||||
def CheckItem(self, request, parentid, childname, storedprocfetch):
|
def CheckItem(self, request, parentid, childname, storedprocfetch):
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,37 @@
|
|||||||
|
|
||||||
|
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
|
if (document.getElementById('Village_Name')) {
|
||||||
document.getElementById('Village_Name').focus();
|
document.getElementById('Village_Name').focus();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
|
||||||
// 🔥 RESTORE VIEW MODE AFTER RELOAD
|
// ✅ RUN ONLY IF THIS PAGE HAS FORM/TABLE
|
||||||
var viewMode = localStorage.getItem("viewMode");
|
if ($('#addForm').length && $('#addTable').length) {
|
||||||
|
|
||||||
if (viewMode === "table") {
|
// ✅ DEFAULT VIEW → SHOW FORM
|
||||||
$('#addForm').hide();
|
|
||||||
$('#addTable').show();
|
|
||||||
} else {
|
|
||||||
$('#addForm').show();
|
$('#addForm').show();
|
||||||
$('#addTable').hide();
|
$('#addTable').hide();
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 🔥 BUTTON TOGGLE LOGIC
|
// 🔥 BUTTON TOGGLE
|
||||||
|
|
||||||
$('#addButton').click(function () {
|
$('#addButton').click(function () {
|
||||||
$('#addForm').show();
|
$('#addForm').show();
|
||||||
$('#addTable').hide();
|
$('#addTable').hide();
|
||||||
|
|
||||||
localStorage.setItem("viewMode", "form");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#displayButton').click(function () {
|
$('#displayButton').click(function () {
|
||||||
$('#addForm').hide();
|
$('#addForm').hide();
|
||||||
$('#addTable').show();
|
$('#addTable').show();
|
||||||
|
|
||||||
localStorage.setItem("viewMode", "table");
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ===============================
|
||||||
// STATE → DISTRICT
|
// STATE → DISTRICT
|
||||||
|
// ===============================
|
||||||
|
if ($('#state_Id').length) {
|
||||||
|
|
||||||
$('#state_Id').change(function () {
|
$('#state_Id').change(function () {
|
||||||
|
|
||||||
var stateId = $(this).val();
|
var stateId = $(this).val();
|
||||||
@@ -54,25 +50,24 @@ $(document).ready(function () {
|
|||||||
districtDropdown.append('<option value="" disabled selected>Select District</option>');
|
districtDropdown.append('<option value="" disabled selected>Select District</option>');
|
||||||
|
|
||||||
data.forEach(function (district) {
|
data.forEach(function (district) {
|
||||||
|
|
||||||
districtDropdown.append(
|
districtDropdown.append(
|
||||||
'<option value="' + district.id + '">' + district.name + '</option>'
|
'<option value="' + district.id + '">' + district.name + '</option>'
|
||||||
);
|
);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
districtDropdown.prop('disabled', false);
|
districtDropdown.prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===============================
|
||||||
// DISTRICT → BLOCK
|
// DISTRICT → BLOCK
|
||||||
|
// ===============================
|
||||||
|
if ($('#district_Id').length) {
|
||||||
|
|
||||||
$('#district_Id').change(function () {
|
$('#district_Id').change(function () {
|
||||||
|
|
||||||
var districtId = $(this).val();
|
var districtId = $(this).val();
|
||||||
@@ -91,25 +86,24 @@ $(document).ready(function () {
|
|||||||
blockDropdown.append('<option value="" disabled selected>Select Block</option>');
|
blockDropdown.append('<option value="" disabled selected>Select Block</option>');
|
||||||
|
|
||||||
data.forEach(function (block) {
|
data.forEach(function (block) {
|
||||||
|
|
||||||
blockDropdown.append(
|
blockDropdown.append(
|
||||||
'<option value="' + block.id + '">' + block.name + '</option>'
|
'<option value="' + block.id + '">' + block.name + '</option>'
|
||||||
);
|
);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
blockDropdown.prop('disabled', false);
|
blockDropdown.prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===============================
|
||||||
// VILLAGE NAME VALIDATION
|
// VILLAGE NAME VALIDATION
|
||||||
|
// ===============================
|
||||||
|
if ($('#Village_Name').length) {
|
||||||
|
|
||||||
$('#Village_Name').on('input', function () {
|
$('#Village_Name').on('input', function () {
|
||||||
|
|
||||||
var villageName = $(this).val();
|
var villageName = $(this).val();
|
||||||
@@ -127,13 +121,16 @@ $(document).ready(function () {
|
|||||||
|
|
||||||
$('#villageMessage').text('');
|
$('#villageMessage').text('');
|
||||||
$('#submitVillage').prop('disabled', false);
|
$('#submitVillage').prop('disabled', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
// ===============================
|
||||||
// CHECK DUPLICATE VILLAGE
|
// CHECK DUPLICATE VILLAGE
|
||||||
|
// ===============================
|
||||||
|
if ($('#Village_Name').length && $('#block_Id').length) {
|
||||||
|
|
||||||
$('#Village_Name, #block_Id').on('change keyup', function () {
|
$('#Village_Name, #block_Id').on('change keyup', function () {
|
||||||
|
|
||||||
var blockId = $('#block_Id').val();
|
var blockId = $('#block_Id').val();
|
||||||
@@ -142,7 +139,6 @@ $(document).ready(function () {
|
|||||||
if (blockId && villageName) {
|
if (blockId && villageName) {
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
|
||||||
url: '/check_village',
|
url: '/check_village',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
|
|
||||||
@@ -168,9 +164,7 @@ $(document).ready(function () {
|
|||||||
.css('color', 'green');
|
.css('color', 'green');
|
||||||
|
|
||||||
$('#submitVillage').prop('disabled', false);
|
$('#submitVillage').prop('disabled', false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
error: function () {
|
error: function () {
|
||||||
@@ -180,85 +174,77 @@ $(document).ready(function () {
|
|||||||
.css('color', 'red');
|
.css('color', 'red');
|
||||||
|
|
||||||
$('#submitVillage').prop('disabled', true);
|
$('#submitVillage').prop('disabled', true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
// ===============================
|
||||||
|
// ADD VILLAGE (SAFE SCOPE FIX)
|
||||||
|
// ===============================
|
||||||
|
if ($('#villageForm').length) {
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// ADD VILLAGE
|
|
||||||
$('#villageForm').submit(function (event) {
|
$('#villageForm').submit(function (event) {
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
|
||||||
url: '/add_village',
|
url: '/add_village',
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
data: $(this).serialize(),
|
data: $(this).serialize(),
|
||||||
|
|
||||||
success: function (response) {
|
success: function (response) {
|
||||||
|
|
||||||
if (response.status === 'success') {
|
if (response && response.status === 'success') {
|
||||||
|
|
||||||
alert('Village added successfully!');
|
alert(response.message || 'Village added successfully!');
|
||||||
|
|
||||||
|
// ✅ clear form
|
||||||
|
$('#villageForm')[0].reset();
|
||||||
|
|
||||||
|
// ✅ switch to table
|
||||||
|
$('#addForm').hide();
|
||||||
|
$('#addTable').show();
|
||||||
|
|
||||||
|
// optional refresh
|
||||||
location.reload();
|
location.reload();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
alert(response.message || 'Error adding village. Please try again.');
|
alert(response.message || 'Error adding village. Please try again.');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
error: function () {
|
error: function () {
|
||||||
|
|
||||||
alert('An error occurred. Please try again.');
|
alert('An error occurred. Please try again.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// 🔥 DELETE FUNCTION (UPDATED)
|
|
||||||
function deleteVillage(villageId) {
|
|
||||||
|
|
||||||
if (!confirm("Are you sure you want to delete this village?")) {
|
// ===============================
|
||||||
return;
|
// DELETE FUNCTION (SAFE)
|
||||||
}
|
// ===============================
|
||||||
|
function deleteVillage(villageId, element) {
|
||||||
// ✅ save that user is on table
|
if (!confirm("Are you sure you want to delete this village?")) return;
|
||||||
localStorage.setItem("viewMode", "table");
|
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: '/delete_village/' + villageId,
|
url: '/delete_village/' + villageId,
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
|
dataType: 'json',
|
||||||
success: function () {
|
success: function (response) {
|
||||||
|
alert(response.message); // ✅ now shows "Village deleted successfully!"
|
||||||
setTimeout(function () {
|
if (element) $(element).closest("tr").remove();
|
||||||
|
|
||||||
alert("Village deleted successfully!");
|
|
||||||
|
|
||||||
// reload but stay on table
|
|
||||||
location.reload();
|
|
||||||
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
error: function () {
|
error: function () {
|
||||||
alert("Error deleting village. Please try again.");
|
alert("Error deleting village. Please try again.");
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
@@ -8,6 +9,7 @@
|
|||||||
<script src="{{ url_for('static', filename='js/search_on_table.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/search_on_table.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/invoice.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/invoice.js') }}"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
@@ -37,13 +39,16 @@
|
|||||||
<input type="number" step="0.01" id="invoice_No" name="invoice_No"><br><br>
|
<input type="number" step="0.01" id="invoice_No" name="invoice_No"><br><br>
|
||||||
|
|
||||||
<label for="Payment_Amount">Amount:</label><br>
|
<label for="Payment_Amount">Amount:</label><br>
|
||||||
<input type="number" step="0.01" id="Payment_Amount" name="Payment_Amount" required oninput="calculateTDSAndTotal()"><br><br>
|
<input type="number" step="0.01" id="Payment_Amount" name="Payment_Amount" required
|
||||||
|
oninput="calculateTDSAndTotal()"><br><br>
|
||||||
|
|
||||||
<label for="TDS_Percentage">TDS Percentage (%):</label><br>
|
<label for="TDS_Percentage">TDS Percentage (%):</label><br>
|
||||||
<input type="number" step="0.01" id="TDS_Percentage" name="TDS_Percentage" oninput="calculateTDSAndTotal()"><br><br>
|
<input type="number" step="0.01" id="TDS_Percentage" name="TDS_Percentage"
|
||||||
|
oninput="calculateTDSAndTotal()"><br><br>
|
||||||
|
|
||||||
<label for="TDS_Payment_Amount">TDS Amount:</label><br>
|
<label for="TDS_Payment_Amount">TDS Amount:</label><br>
|
||||||
<input type="number" step="0.01" id="TDS_Payment_Amount" name="TDS_Payment_Amount" required readonly><br><br>
|
<input type="number" step="0.01" id="TDS_Payment_Amount" name="TDS_Payment_Amount" required
|
||||||
|
readonly><br><br>
|
||||||
|
|
||||||
<label for="total_amount">Total Amount:</label><br>
|
<label for="total_amount">Total Amount:</label><br>
|
||||||
<input type="number" step="0.01" id="total_amount" name="total_amount" required readonly><br><br>
|
<input type="number" step="0.01" id="total_amount" name="total_amount" required readonly><br><br>
|
||||||
@@ -89,8 +94,19 @@
|
|||||||
<td>{{ payment[4] }}</td>
|
<td>{{ payment[4] }}</td>
|
||||||
<td>{{ payment[5] }}</td>
|
<td>{{ payment[5] }}</td>
|
||||||
<td>{{ payment[6] }}</td>
|
<td>{{ payment[6] }}</td>
|
||||||
<td><a href="/edit_payment/{{ payment[0] }}"><img src="{{ url_for('static', filename='images/icons/pen_blue_icon.png') }}" alt="Edit" class="icon"></a></td>
|
<td><a href="/edit_payment/{{ payment[0] }}"><img
|
||||||
<td><a href="/delete_payment/{{ payment[0] }}" onclick="return confirm('Are you sure you want to delete this payment?')"><img src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}" alt="Delete" class="icon"></a></td>
|
src="{{ url_for('static', filename='images/icons/pen_blue_icon.png') }}" alt="Edit"
|
||||||
|
class="icon"></a></td>
|
||||||
|
<td>
|
||||||
|
<form action="{{ url_for('payment_bp.delete_payment', payment_id=payment[0]) }}" method="POST"
|
||||||
|
style="display:inline;">
|
||||||
|
<button type="submit"
|
||||||
|
onclick="return confirm('Are you sure you want to delete this payment?')">
|
||||||
|
<img src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}"
|
||||||
|
alt="Delete" class="icon">
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- <tr>
|
<!-- <tr>
|
||||||
<td>{{ payment['Payment_Id'] }}</td>
|
<td>{{ payment['Payment_Id'] }}</td>
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% block content %}
|
||||||
{% block content %}
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Village Management</title>
|
<title>Village Management</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
type="text/css"
|
||||||
|
href="{{ url_for('static', filename='css/style.css') }}"
|
||||||
|
/>
|
||||||
<script src="{{ url_for('static', filename='js/village.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/village.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/search_on_table.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/search_on_table.js') }}"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<!-- Button Container to Center Buttons -->
|
<!-- Button Container to Center Buttons -->
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
<button id="addButton" class="action-button">Add</button>
|
<button id="addButton" class="action-button">Add</button>
|
||||||
<button id="displayButton" class="action-button">Display</button>
|
<button id="displayButton" class="action-button">Display</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="addForm" style="display: none;">
|
<div id="addForm" style="display: none">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="form-block">
|
<div class="form-block">
|
||||||
<h2>Add a New Village</h2>
|
<h2>Add a New Village</h2>
|
||||||
@@ -40,7 +42,13 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
<label for="Village_Name">Village Name:</label>
|
<label for="Village_Name">Village Name:</label>
|
||||||
<input type="text" id="Village_Name" name="Village_Name" placeholder="Enter Village Name" required>
|
<input
|
||||||
|
type="text"
|
||||||
|
id="Village_Name"
|
||||||
|
name="Village_Name"
|
||||||
|
placeholder="Enter Village Name"
|
||||||
|
required
|
||||||
|
/>
|
||||||
<span id="villageMessage"></span>
|
<span id="villageMessage"></span>
|
||||||
|
|
||||||
<button type="submit" id="submitVillage" disabled>Add Village</button>
|
<button type="submit" id="submitVillage" disabled>Add Village</button>
|
||||||
@@ -49,10 +57,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="addTable" style="display: none;">
|
<div id="addTable" style="display: none">
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
<h2>Display Villages</h2>
|
<h2>Display Villages</h2>
|
||||||
<input type="text" id="searchBar" placeholder="Searching..." onkeyup="searchTable()">
|
<input
|
||||||
|
type="text"
|
||||||
|
id="searchBar"
|
||||||
|
placeholder="Searching..."
|
||||||
|
onkeyup="searchTable()"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table id="sortableTable" border="1">
|
<table id="sortableTable" border="1">
|
||||||
@@ -63,12 +76,15 @@
|
|||||||
<span class="sort-buttons">
|
<span class="sort-buttons">
|
||||||
<span class="sort-asc">⬆️</span>
|
<span class="sort-asc">⬆️</span>
|
||||||
<span class="sort-desc">⬇️</span>
|
<span class="sort-desc">⬇️</span>
|
||||||
</span></th>
|
</span>
|
||||||
<th class="sortable-header">Block Name
|
</th>
|
||||||
|
<th class="sortable-header">
|
||||||
|
Block Name
|
||||||
<span class="sort-buttons">
|
<span class="sort-buttons">
|
||||||
<span class="sort-asc">⬆️</span>
|
<span class="sort-asc">⬆️</span>
|
||||||
<span class="sort-desc">⬇️</span>
|
<span class="sort-desc">⬇️</span>
|
||||||
</span></th>
|
</span>
|
||||||
|
</th>
|
||||||
<th>Update</th>
|
<th>Update</th>
|
||||||
<th>Delete</th>
|
<th>Delete</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -78,22 +94,36 @@
|
|||||||
<td>{{ village[1] }}</td>
|
<td>{{ village[1] }}</td>
|
||||||
<td>{{ village[2] }}</td>
|
<td>{{ village[2] }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ url_for('village.edit_village', village_id=village[0]) }}">
|
<a
|
||||||
<img src="{{ url_for('static', filename='images/icons/pen_blue_icon.png') }}" alt="Edit"
|
href="{{ url_for('village.edit_village', village_id=village[0]) }}"
|
||||||
class="icon">
|
>
|
||||||
|
<img
|
||||||
|
src="{{ url_for('static', filename='images/icons/pen_blue_icon.png') }}"
|
||||||
|
alt="Edit"
|
||||||
|
class="icon"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="#"
|
<a href="javascript:void(0);"
|
||||||
onclick="deleteVillage({{ village[0] }}); return false;">
|
onclick="deleteVillage({{ village[0] }}, this)">
|
||||||
<img src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}"
|
<img src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}"
|
||||||
alt="Delete" class="icon">
|
class="icon">
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Flash Alerts -->
|
||||||
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
|
{% if messages %}
|
||||||
|
<script>
|
||||||
|
{% for category, message in messages %}
|
||||||
|
alert("{{ message }}");
|
||||||
|
{% endfor %}
|
||||||
|
</script>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
</body>
|
</body>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -28,25 +28,17 @@
|
|||||||
|
|
||||||
<button type="submit">Update Village</button>
|
<button type="submit">Update Village</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
<!-- Flash Messages (hidden, used for JS popup) -->
|
||||||
|
<div id="flash-messages-container" style="display:none;">
|
||||||
<!-- Flash Message (Hidden, used for JS popup) -->
|
|
||||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
{% for category, message in messages %}
|
{% for category, message in messages %}
|
||||||
<div id="flash-message" data-category="{{ category }}" style="display:none;">{{ message }}</div>
|
<div class="flash-message" data-category="{{ category }}">{{ message }}</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
|
||||||
window.onload = function () {
|
|
||||||
const flash = document.getElementById('flash-message');
|
|
||||||
if (flash && flash.innerText.trim() !== "") {
|
|
||||||
alert(flash.innerText);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user