8 Commits

6 changed files with 275 additions and 178 deletions

1
.gitignore vendored
View File

@@ -4,3 +4,4 @@ __pycache__/
static/downloads/ static/downloads/
static/uploads/ static/uploads/

View File

@@ -1,3 +1,5 @@
from model.Utilities import ResponseHandler, HtmlHelper, ItemCRUDType from model.Utilities import ResponseHandler, HtmlHelper, ItemCRUDType
import config import config
import mysql.connector import mysql.connector
@@ -11,11 +13,18 @@ class Village:
def __init__(self): def __init__(self):
self.isSuccess = False self.isSuccess = False
self.resultMessage = "" self.resultMessage = ""
self.response = {} # ✅ ADDED
self.village = ItemCRUD(itemType=ItemCRUDType.Village) self.village = ItemCRUD(itemType=ItemCRUDType.Village)
# 🔹 Helper: sync status # 🔹 Helper: sync status
def _set_status(self, village): def _set_status(self, village):
self.isSuccess = village.isSuccess self.isSuccess = village.isSuccess
# ✅ UPDATED (safe handling)
if hasattr(village, "response"):
self.response = village.response
self.resultMessage = village.response.get("message", "")
else:
self.resultMessage = village.resultMessage self.resultMessage = village.resultMessage
# 🔹 Helper: get request data # 🔹 Helper: get request data
@@ -28,8 +37,9 @@ class Village:
block_id, village_name = self._get_form_data(request) block_id, village_name = self._get_form_data(request)
if not village_name: if not village_name:
self.response = ResponseHandler.invalid_name("village") # ✅ UPDATED
self.resultMessage = self.response["message"]
self.isSuccess = False self.isSuccess = False
self.resultMessage = "Village name cannot be empty"
return return
try: try:
@@ -65,8 +75,9 @@ class Village:
block_id, village_name = self._get_form_data(request) block_id, village_name = self._get_form_data(request)
if not village_name: if not village_name:
self.response = ResponseHandler.invalid_name("village") # ✅ UPDATED
self.resultMessage = self.response["message"]
self.isSuccess = False self.isSuccess = False
self.resultMessage = "Village name cannot be empty"
return None return None
try: try:
@@ -102,8 +113,9 @@ class Village:
block_id, village_name = self._get_form_data(request) block_id, village_name = self._get_form_data(request)
if not village_name: if not village_name:
self.response = ResponseHandler.invalid_name("village") # ✅ UPDATED
self.resultMessage = self.response["message"]
self.isSuccess = False self.isSuccess = False
self.resultMessage = "Village name cannot be empty"
return return
try: try:
@@ -163,9 +175,11 @@ class Village:
except mysql.connector.Error as e: except mysql.connector.Error as e:
print(f"Error fetching blocks: {e}") print(f"Error fetching blocks: {e}")
self.isSuccess = False self.isSuccess = False
self.resultMessage = HtmlHelper.json_response(
ResponseHandler.fetch_failure("block"), 500 # ✅ FIXED (removed jsonify response)
) self.response = ResponseHandler.fetch_failure("block")
self.resultMessage = self.response["message"]
return [] return []
finally: finally:

View File

@@ -1,9 +1,40 @@
window.onload = function () { window.onload = function () {
document.getElementById('Village_Name').focus(); document.getElementById('Village_Name').focus();
}; };
$(document).ready(function () { $(document).ready(function () {
// 🔥 RESTORE VIEW MODE AFTER RELOAD
var viewMode = localStorage.getItem("viewMode");
if (viewMode === "table") {
$('#addForm').hide();
$('#addTable').show();
} else {
$('#addForm').show();
$('#addTable').hide();
}
// 🔥 BUTTON TOGGLE LOGIC
$('#addButton').click(function () {
$('#addForm').show();
$('#addTable').hide();
localStorage.setItem("viewMode", "form");
});
$('#displayButton').click(function () {
$('#addForm').hide();
$('#addTable').show();
localStorage.setItem("viewMode", "table");
});
// STATE → DISTRICT // STATE → DISTRICT
$('#state_Id').change(function () { $('#state_Id').change(function () {
@@ -179,7 +210,7 @@ $(document).ready(function () {
} else { } else {
alert('Error adding village. Please try again.'); alert(response.message || 'Error adding village. Please try again.');
} }
@@ -196,3 +227,38 @@ $(document).ready(function () {
}); });
}); });
// 🔥 DELETE FUNCTION (UPDATED)
function deleteVillage(villageId) {
if (!confirm("Are you sure you want to delete this village?")) {
return;
}
// ✅ save that user is on table
localStorage.setItem("viewMode", "table");
$.ajax({
url: '/delete_village/' + villageId,
type: 'GET',
success: function () {
setTimeout(function () {
alert("Village deleted successfully!");
// reload but stay on table
location.reload();
}, 1000);
},
error: function () {
alert("Error deleting village. Please try again.");
}
});
}

View File

@@ -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,22 +9,23 @@
<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">
<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;">
<h2>Add Payment</h2> <h2>Add Payment</h2>
<form action="/add_payment" method="POST" onsubmit="showSuccessAlert(event)"> <form action="/add_payment" method="POST" onsubmit="showSuccessAlert(event)">
<div class="row1"> <div class="row1">
<div> <div>
<label for="subcontractor">Subcontractor Name:</label> <label for="subcontractor">Subcontractor Name:</label>
<input type="text" id="subcontractor" name="subcontractor" required autocomplete="off"/> <input type="text" id="subcontractor" name="subcontractor" required autocomplete="off" />
<input type="hidden" id="subcontractor_id" name="subcontractor_id"/> <input type="hidden" id="subcontractor_id" name="subcontractor_id" />
<div id="subcontractor_list" class="autocomplete-items"></div> <div id="subcontractor_list" class="autocomplete-items"></div>
</div> </div>
</div> </div>
@@ -34,19 +36,22 @@
</select><br><br> </select><br><br>
<label for="invoice_No">Invoice No:</label><br> <label for="invoice_No">Invoice No:</label><br>
<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>
<label for="utr">UTR:</label><br> <label for="utr">UTR:</label><br>
@@ -54,13 +59,13 @@
<button type="submit">Submit Payment</button> <button type="submit">Submit Payment</button>
</form> </form>
</div> </div>
<div id="successPopup" class="success-popup"> <div id="successPopup" class="success-popup">
<i>&#10004;</i> Payment added successfully! <i>&#10004;</i> Payment added successfully!
</div> </div>
<div id="addTable" style="display: none;"> <div id="addTable" style="display: none;">
<div class="search-container"> <div class="search-container">
<h2>Payment History</h2> <h2>Payment History</h2>
<input type="text" id="searchBar" placeholder="Searching..." onkeyup="searchTable()"> <input type="text" id="searchBar" placeholder="Searching..." onkeyup="searchTable()">
@@ -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>
@@ -106,10 +122,10 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>
<script> <script>
document.getElementById("subcontractor").addEventListener("input", function () { document.getElementById("subcontractor").addEventListener("input", function () {
const query = this.value; const query = this.value;
const list = document.getElementById("subcontractor_list"); const list = document.getElementById("subcontractor_list");
@@ -129,9 +145,9 @@ document.getElementById("subcontractor").addEventListener("input", function () {
list.appendChild(div); list.appendChild(div);
}); });
}); });
}); });
document.getElementById("subcontractor_list").addEventListener("click", function (e) { document.getElementById("subcontractor_list").addEventListener("click", function (e) {
const selectedId = e.target.getAttribute("data-id"); const selectedId = e.target.getAttribute("data-id");
const selectedName = e.target.textContent; const selectedName = e.target.textContent;
@@ -171,11 +187,11 @@ document.getElementById("subcontractor_list").addEventListener("click", function
alert("Failed to fetch PMC numbers."); alert("Failed to fetch PMC numbers.");
}); });
} }
}); });
</script> </script>
<script> <script>
function calculateTDSAndTotal() { function calculateTDSAndTotal() {
const amount = parseFloat(document.getElementById("Payment_Amount").value) || 0; const amount = parseFloat(document.getElementById("Payment_Amount").value) || 0;
const tdsPercent = parseFloat(document.getElementById("TDS_Percentage").value) || 0; const tdsPercent = parseFloat(document.getElementById("TDS_Percentage").value) || 0;
@@ -184,10 +200,10 @@ function calculateTDSAndTotal() {
document.getElementById("TDS_Payment_Amount").value = tdsAmount; document.getElementById("TDS_Payment_Amount").value = tdsAmount;
document.getElementById("total_amount").value = totalAmount; document.getElementById("total_amount").value = totalAmount;
} }
</script> </script>
<script src="{{ url_for('static', filename='js/showSuccessAlert.js') }}"></script> <script src="{{ url_for('static', filename='js/showSuccessAlert.js') }}"></script>
</body> </body>
{% endblock %} {% endblock %}

View File

@@ -84,11 +84,11 @@
</a> </a>
</td> </td>
<td> <td>
<a href="{{ url_for('village.delete_village', village_id=village[0]) }}" <a href="#"
onclick="return confirm('Are you sure you want to delete this village?');"> onclick="deleteVillage({{ village[0] }}); return false;">
<img src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}" alt="Delete" <img src="{{ url_for('static', filename='images/icons/bin_red_icon.png') }}"
class="icon"> alt="Delete" class="icon">
</a> </a>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}