Compare commits
4 Commits
f184d6cecc
...
7146391c18
| Author | SHA1 | Date | |
|---|---|---|---|
| 7146391c18 | |||
| 94b5563d15 | |||
| 937018dc16 | |||
| eda238c235 |
@@ -86,12 +86,12 @@ def edit_payment(payment_id):
|
|||||||
|
|
||||||
return render_template('edit_payment.html', payment_data=payment_data)
|
return render_template('edit_payment.html', payment_data=payment_data)
|
||||||
|
|
||||||
|
|
||||||
# ------------------- Delete Payment -------------------
|
# ------------------- Delete Payment -------------------
|
||||||
@payment_bp.route('/delete_payment/<int:payment_id>', methods=['POST'])
|
@payment_bp.route('/delete_payment/<int:payment_id>', methods=['GET'])
|
||||||
@login_required
|
@login_required
|
||||||
def delete_payment(payment_id):
|
def delete_payment(payment_id):
|
||||||
success, pmc_no, invoice_no = Paymentmodel.delete_payment(payment_id)
|
success, pmc_no, invoice_no = Paymentmodel.delete_payment(payment_id)
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
flash("Payment not found or failed to delete", "error")
|
flash("Payment not found or failed to delete", "error")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -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,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,91 +9,104 @@
|
|||||||
<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 id="addForm" style="display: none;">
|
|
||||||
<h2>Add Payment</h2>
|
|
||||||
|
|
||||||
<form action="/add_payment" method="POST" onsubmit="showSuccessAlert(event)">
|
|
||||||
<div class="row1">
|
|
||||||
<div>
|
|
||||||
<label for="subcontractor">Subcontractor Name:</label>
|
|
||||||
<input type="text" id="subcontractor" name="subcontractor" required autocomplete="off"/>
|
|
||||||
<input type="hidden" id="subcontractor_id" name="subcontractor_id"/>
|
|
||||||
<div id="subcontractor_list" class="autocomplete-items"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<label for="PMC_No">PMC No:</label><br>
|
|
||||||
<select id="PMC_No" name="PMC_No" required>
|
|
||||||
<option value="">Select PMC No</option>
|
|
||||||
</select><br><br>
|
|
||||||
|
|
||||||
<label for="invoice_No">Invoice No:</label><br>
|
|
||||||
<input type="number" step="0.01" id="invoice_No" name="invoice_No" ><br><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>
|
|
||||||
|
|
||||||
<label for="TDS_Percentage">TDS Percentage (%):</label><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>
|
|
||||||
<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>
|
|
||||||
<input type="number" step="0.01" id="total_amount" name="total_amount" required readonly><br><br>
|
|
||||||
|
|
||||||
|
|
||||||
<label for="utr">UTR:</label><br>
|
|
||||||
<input type="text" id="utr" name="utr"><br><br>
|
|
||||||
|
|
||||||
<button type="submit">Submit Payment</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="successPopup" class="success-popup">
|
|
||||||
<i>✔</i> Payment added successfully!
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="addTable" style="display: none;">
|
|
||||||
<div class="search-container">
|
|
||||||
<h2>Payment History</h2>
|
|
||||||
<input type="text" id="searchBar" placeholder="Searching..." onkeyup="searchTable()">
|
|
||||||
</div>
|
</div>
|
||||||
<table id="sortableTable" border="1">
|
|
||||||
<thead>
|
<div id="addForm" style="display: none;">
|
||||||
<tr>
|
<h2>Add Payment</h2>
|
||||||
<th class="sortable-header">Payment ID</th>
|
|
||||||
<th class="sortable-header">PMC No</th>
|
<form action="/add_payment" method="POST" onsubmit="showSuccessAlert(event)">
|
||||||
<th>Invoice No</th>
|
<div class="row1">
|
||||||
<th>Payment Amount</th>
|
<div>
|
||||||
<th>TDS Amount</th>
|
<label for="subcontractor">Subcontractor Name:</label>
|
||||||
<th>Total Amount</th>
|
<input type="text" id="subcontractor" name="subcontractor" required autocomplete="off" />
|
||||||
<th>UTR</th>
|
<input type="hidden" id="subcontractor_id" name="subcontractor_id" />
|
||||||
<th>Update</th>
|
<div id="subcontractor_list" class="autocomplete-items"></div>
|
||||||
<th>Delete</th>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
</thead>
|
|
||||||
<tbody>
|
<label for="PMC_No">PMC No:</label><br>
|
||||||
{% for payment in payments %}
|
<select id="PMC_No" name="PMC_No" required>
|
||||||
<tr>
|
<option value="">Select PMC No</option>
|
||||||
<td>{{ payment[0] }}</td>
|
</select><br><br>
|
||||||
<td>{{ payment[1] }}</td>
|
|
||||||
<td>{{ payment[2] }}</td>
|
<label for="invoice_No">Invoice No:</label><br>
|
||||||
<td>{{ payment[3] }}</td>
|
<input type="number" step="0.01" id="invoice_No" name="invoice_No"><br><br>
|
||||||
<td>{{ payment[4] }}</td>
|
|
||||||
<td>{{ payment[5] }}</td>
|
<label for="Payment_Amount">Amount:</label><br>
|
||||||
<td>{{ payment[6] }}</td>
|
<input type="number" step="0.01" id="Payment_Amount" name="Payment_Amount" required
|
||||||
<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>
|
oninput="calculateTDSAndTotal()"><br><br>
|
||||||
<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>
|
|
||||||
</tr>
|
<label for="TDS_Percentage">TDS Percentage (%):</label><br>
|
||||||
<!-- <tr>
|
<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>
|
||||||
|
<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>
|
||||||
|
<input type="number" step="0.01" id="total_amount" name="total_amount" required readonly><br><br>
|
||||||
|
|
||||||
|
|
||||||
|
<label for="utr">UTR:</label><br>
|
||||||
|
<input type="text" id="utr" name="utr"><br><br>
|
||||||
|
|
||||||
|
<button type="submit">Submit Payment</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="successPopup" class="success-popup">
|
||||||
|
<i>✔</i> Payment added successfully!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="addTable" style="display: none;">
|
||||||
|
<div class="search-container">
|
||||||
|
<h2>Payment History</h2>
|
||||||
|
<input type="text" id="searchBar" placeholder="Searching..." onkeyup="searchTable()">
|
||||||
|
</div>
|
||||||
|
<table id="sortableTable" border="1">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="sortable-header">Payment ID</th>
|
||||||
|
<th class="sortable-header">PMC No</th>
|
||||||
|
<th>Invoice No</th>
|
||||||
|
<th>Payment Amount</th>
|
||||||
|
<th>TDS Amount</th>
|
||||||
|
<th>Total Amount</th>
|
||||||
|
<th>UTR</th>
|
||||||
|
<th>Update</th>
|
||||||
|
<th>Delete</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for payment in payments %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ payment[0] }}</td>
|
||||||
|
<td>{{ payment[1] }}</td>
|
||||||
|
<td>{{ payment[2] }}</td>
|
||||||
|
<td>{{ payment[3] }}</td>
|
||||||
|
<td>{{ payment[4] }}</td>
|
||||||
|
<td>{{ payment[5] }}</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="{{ url_for('payment_bp.delete_payment', payment_id=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>
|
||||||
|
</tr>
|
||||||
|
<!-- <tr>
|
||||||
<td>{{ payment['Payment_Id'] }}</td>
|
<td>{{ payment['Payment_Id'] }}</td>
|
||||||
<td>{{ payment['PMC_No'] }}</td>
|
<td>{{ payment['PMC_No'] }}</td>
|
||||||
<td>{{ payment['invoice_no'] }}</td>
|
<td>{{ payment['invoice_no'] }}</td>
|
||||||
@@ -103,91 +117,91 @@
|
|||||||
<td><a href="/edit_payment/{{ payment['Payment_Id'] }}"><img src="{{ url_for('static', filename='images/icons/pen_blue_icon.png') }}" alt="Edit" class="icon"></a></td>
|
<td><a href="/edit_payment/{{ payment['Payment_Id'] }}"><img src="{{ url_for('static', filename='images/icons/pen_blue_icon.png') }}" alt="Edit" class="icon"></a></td>
|
||||||
<td><a href="/delete_payment/{{ payment['Payment_Id'] }}" 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>
|
<td><a href="/delete_payment/{{ payment['Payment_Id'] }}" 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>
|
||||||
</tr> -->
|
</tr> -->
|
||||||
{% 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");
|
||||||
|
|
||||||
if (query.length < 2) {
|
if (query.length < 2) {
|
||||||
list.innerHTML = '';
|
list.innerHTML = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch(`/search_subcontractor?query=${encodeURIComponent(query)}`)
|
fetch(`/search_subcontractor?query=${encodeURIComponent(query)}`)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
list.innerHTML = '';
|
list.innerHTML = '';
|
||||||
data.results.forEach(item => {
|
data.results.forEach(item => {
|
||||||
const div = document.createElement("div");
|
const div = document.createElement("div");
|
||||||
div.setAttribute("data-id", item.id);
|
div.setAttribute("data-id", item.id);
|
||||||
div.textContent = item.name;
|
div.textContent = item.name;
|
||||||
list.appendChild(div);
|
list.appendChild(div);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("subcontractor_list").addEventListener("click", function (e) {
|
|
||||||
const selectedId = e.target.getAttribute("data-id");
|
|
||||||
const selectedName = e.target.textContent;
|
|
||||||
|
|
||||||
if (selectedId) {
|
|
||||||
document.getElementById("subcontractor_id").value = selectedId;
|
|
||||||
document.getElementById("subcontractor").value = selectedName;
|
|
||||||
document.getElementById("subcontractor_list").innerHTML = ""; // hide the list
|
|
||||||
|
|
||||||
console.log("Contractor id is", selectedId);
|
|
||||||
|
|
||||||
// Fetch PMC numbers
|
|
||||||
fetch(`/get_pmc_nos_by_subcontractor/${encodeURIComponent(selectedId)}`)
|
|
||||||
.then(response => response.json())
|
|
||||||
.then(data => {
|
|
||||||
console.log("Fetched PMC Nos:", data.pmc_nos);
|
|
||||||
const pmcDropdown = document.getElementById("PMC_No");
|
|
||||||
pmcDropdown.innerHTML = "";
|
|
||||||
|
|
||||||
const defaultOption = document.createElement("option");
|
|
||||||
defaultOption.value = "";
|
|
||||||
defaultOption.textContent = "Select PMC No";
|
|
||||||
pmcDropdown.appendChild(defaultOption);
|
|
||||||
|
|
||||||
data.pmc_nos.forEach(pmc => {
|
|
||||||
const option = document.createElement("option");
|
|
||||||
option.value = pmc;
|
|
||||||
option.textContent = pmc;
|
|
||||||
pmcDropdown.appendChild(option);
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
if (data.pmc_nos.length === 0) {
|
document.getElementById("subcontractor_list").addEventListener("click", function (e) {
|
||||||
alert("No PMC Nos found for this subcontractor.");
|
const selectedId = e.target.getAttribute("data-id");
|
||||||
}
|
const selectedName = e.target.textContent;
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error("Error fetching PMC Nos:", error);
|
|
||||||
alert("Failed to fetch PMC numbers.");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
if (selectedId) {
|
||||||
function calculateTDSAndTotal() {
|
document.getElementById("subcontractor_id").value = selectedId;
|
||||||
const amount = parseFloat(document.getElementById("Payment_Amount").value) || 0;
|
document.getElementById("subcontractor").value = selectedName;
|
||||||
const tdsPercent = parseFloat(document.getElementById("TDS_Percentage").value) || 0;
|
document.getElementById("subcontractor_list").innerHTML = ""; // hide the list
|
||||||
|
|
||||||
const tdsAmount = (amount * tdsPercent / 100).toFixed(2);
|
console.log("Contractor id is", selectedId);
|
||||||
const totalAmount = (amount - tdsAmount).toFixed(2);
|
|
||||||
|
|
||||||
document.getElementById("TDS_Payment_Amount").value = tdsAmount;
|
// Fetch PMC numbers
|
||||||
document.getElementById("total_amount").value = totalAmount;
|
fetch(`/get_pmc_nos_by_subcontractor/${encodeURIComponent(selectedId)}`)
|
||||||
}
|
.then(response => response.json())
|
||||||
</script>
|
.then(data => {
|
||||||
|
console.log("Fetched PMC Nos:", data.pmc_nos);
|
||||||
|
const pmcDropdown = document.getElementById("PMC_No");
|
||||||
|
pmcDropdown.innerHTML = "";
|
||||||
|
|
||||||
|
const defaultOption = document.createElement("option");
|
||||||
|
defaultOption.value = "";
|
||||||
|
defaultOption.textContent = "Select PMC No";
|
||||||
|
pmcDropdown.appendChild(defaultOption);
|
||||||
|
|
||||||
|
data.pmc_nos.forEach(pmc => {
|
||||||
|
const option = document.createElement("option");
|
||||||
|
option.value = pmc;
|
||||||
|
option.textContent = pmc;
|
||||||
|
pmcDropdown.appendChild(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (data.pmc_nos.length === 0) {
|
||||||
|
alert("No PMC Nos found for this subcontractor.");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error("Error fetching PMC Nos:", error);
|
||||||
|
alert("Failed to fetch PMC numbers.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function calculateTDSAndTotal() {
|
||||||
|
const amount = parseFloat(document.getElementById("Payment_Amount").value) || 0;
|
||||||
|
const tdsPercent = parseFloat(document.getElementById("TDS_Percentage").value) || 0;
|
||||||
|
|
||||||
|
const tdsAmount = (amount * tdsPercent / 100).toFixed(2);
|
||||||
|
const totalAmount = (amount - tdsAmount).toFixed(2);
|
||||||
|
|
||||||
|
document.getElementById("TDS_Payment_Amount").value = tdsAmount;
|
||||||
|
document.getElementById("total_amount").value = totalAmount;
|
||||||
|
}
|
||||||
|
</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 %}
|
||||||
Reference in New Issue
Block a user