@@ -91,7 +113,9 @@
{ id: 4, billingDate: "2025/03/01", payer: "李四 (A102)", amountDue: 500, feeItem: "公設修繕分攤", billNumber: "FEE20250301003", paymentStatus: "已逾期", notes: "多次催繳未付", dueDate: "2025/03/15" },
{ id: 5, billingDate: "2025/05/05", payer: "張三 (D301)", amountDue: 150, feeItem: "腳踏車位租金", billNumber: "FEE20250505001", paymentStatus: "待繳費", notes: "", dueDate: "2025/05/20" },
{ id: 6, billingDate: "2025/05/10", payer: "趙六 (B205)", amountDue: 2000, feeItem: "預繳上半年管理費", billNumber: "FEE20250510001", paymentStatus: "已繳費", notes: "一次付清", dueDate: "2025/05/25" },
- { id: 7, billingDate: "2025/04/15", payer: "孫七 (E101)", amountDue: 750, feeItem: "社區活動費", billNumber: "FEE20250415001", paymentStatus: "待繳費", notes: "母親節活動", dueDate: "2025/04/30" }
+ { id: 7, billingDate: "2025/04/15", payer: "孫七 (E101)", amountDue: 750, feeItem: "社區活動費", billNumber: "FEE20250415001", paymentStatus: "待繳費", notes: "母親節活動", dueDate: "2025/04/30" },
+ { id: 8, billingDate: "2025/06/01", payer: "吳九 (F202)", amountDue: 1200, feeItem: "管理費 2025年6月", billNumber: "FEE20250601001", paymentStatus: "待繳費", notes: "", dueDate: "" }, // Example with empty due date
+ { id: 9, billingDate: "2025/06/05", payer: "鄭十 (G303)", amountDue: 350, feeItem: "游泳池維護", billNumber: "FEE20250605001", paymentStatus: "待繳費", notes: "", dueDate: "2025/06/15" }
];
function renderTable(dataToRender) {
@@ -100,19 +124,22 @@
const start = (currentPage - 1) * pageSize;
const pageData = dataToRender.slice(start, start + pageSize);
+ let currentListTotal = 0;
+ dataToRender.forEach(fee => {
+ currentListTotal += fee.amountDue;
+ });
+ const totalAmountDisplay = document.getElementById("currentListTotalAmount");
+ if (totalAmountDisplay) {
+ totalAmountDisplay.textContent = '$' + currentListTotal;
+ }
+
pageData.forEach(fee => {
const row = document.createElement("tr");
- let statusBadgeClass = 'bg-secondary'; // Default badge
+ let statusBadgeClass = 'bg-secondary';
switch (fee.paymentStatus) {
- case '待繳費':
- statusBadgeClass = 'bg-warning text-dark';
- break;
- case '已繳費':
- statusBadgeClass = 'bg-success';
- break;
- case '已逾期':
- statusBadgeClass = 'bg-danger';
- break;
+ case '待繳費': statusBadgeClass = 'bg-warning text-dark'; break;
+ case '已繳費': statusBadgeClass = 'bg-success'; break;
+ case '已逾期': statusBadgeClass = 'bg-danger'; break;
}
row.innerHTML = `
@@ -123,6 +150,7 @@
$${fee.amountDue} |
${fee.feeItem} |
${fee.billNumber} |
+
${fee.dueDate || '---'} |
${fee.paymentStatus} |
編輯
@@ -160,6 +188,10 @@
if (totalPagesDisplay) totalPagesDisplay.textContent = 1;
if (prevButton) prevButton.disabled = true;
if (nextButton) nextButton.disabled = true;
+ const totalAmountDisplay = document.getElementById("currentListTotalAmount");
+ if (totalAmountDisplay) {
+ totalAmountDisplay.textContent = '$0';
+ }
}
}
@@ -184,19 +216,57 @@
const payerInput = document.getElementById("searchPayer").value.toLowerCase();
const billNumberInput = document.getElementById("searchBillNumber").value.toLowerCase();
const paymentStatusInput = document.getElementById("searchPaymentStatus").value;
+ const dueDateStartInput = document.getElementById("searchDueDateStart").value; // "YYYY-MM-DD" or ""
+ const dueDateEndInput = document.getElementById("searchDueDateEnd").value; // "YYYY-MM-DD" or ""
- // Load from localStorage if available
const storedFees = JSON.parse(localStorage.getItem('fees_data_temp'));
if (storedFees) {
fees_data = storedFees;
}
+ currentFilteredData = fees_data.filter(fee => {
+ const payerMatch = fee.payer.toLowerCase().includes(payerInput);
+ const billNumberMatch = fee.billNumber.toLowerCase().includes(billNumberInput);
+ const statusMatch = (paymentStatusInput === "" || fee.paymentStatus === paymentStatusInput);
- currentFilteredData = fees_data.filter(fee =>
- fee.payer.toLowerCase().includes(payerInput) &&
- fee.billNumber.toLowerCase().includes(billNumberInput) &&
- (paymentStatusInput === "" || fee.paymentStatus === paymentStatusInput)
- );
+ let dateRangeMatch = true;
+ const feeDueDateStr = fee.dueDate; // format "YYYY/MM/DD" or empty
+
+ if (dueDateStartInput || dueDateEndInput) { // Apply date filter only if at least one date is entered
+ if (!feeDueDateStr || feeDueDateStr.trim() === "") { // If fee has no valid due date string
+ dateRangeMatch = false;
+ } else {
+ try {
+ // Convert fee's due date "YYYY/MM/DD" to a Date object
+ const itemDate = new Date(feeDueDateStr.replace(/\//g, '-'));
+ if (isNaN(itemDate.getTime())) { // Check for invalid date
+ dateRangeMatch = false;
+ } else {
+ itemDate.setHours(0, 0, 0, 0); // Normalize to compare dates only
+
+ if (dueDateStartInput) {
+ const startDate = new Date(dueDateStartInput); // Input is "YYYY-MM-DD"
+ startDate.setHours(0, 0, 0, 0);
+ if (itemDate < startDate) {
+ dateRangeMatch = false;
+ }
+ }
+ if (dateRangeMatch && dueDateEndInput) { // Only check end if start was okay
+ const endDate = new Date(dueDateEndInput); // Input is "YYYY-MM-DD"
+ endDate.setHours(0, 0, 0, 0);
+ if (itemDate > endDate) {
+ dateRangeMatch = false;
+ }
+ }
+ }
+ } catch (e) {
+ console.error("Error parsing due date:", feeDueDateStr, e);
+ dateRangeMatch = false; // Error during parsing, treat as non-match
+ }
+ }
+ }
+ return payerMatch && billNumberMatch && statusMatch && dateRangeMatch;
+ });
currentPage = 1;
renderTable(currentFilteredData);
}
@@ -215,27 +285,29 @@
}
const idsToDelete = Array.from(selected).map(cb => parseInt(cb.dataset.id));
fees_data = fees_data.filter(fee => !idsToDelete.includes(fee.id));
- localStorage.setItem('fees_data_temp', JSON.stringify(fees_data)); // Update localStorage
+ localStorage.setItem('fees_data_temp', JSON.stringify(fees_data));
- performSearch(); // Re-filter and re-render
+ performSearch();
}
function deleteFee(id) {
if (!confirm("確定要刪除此筆繳費通知嗎?")) return;
fees_data = fees_data.filter(fee => fee.id !== id);
- localStorage.setItem('fees_data_temp', JSON.stringify(fees_data)); // Update localStorage
+ localStorage.setItem('fees_data_temp', JSON.stringify(fees_data));
- performSearch(); // Re-filter and re-render
+ performSearch();
}
function exportFees() {
const payerInput = document.getElementById("searchPayer").value.toLowerCase();
const billNumberInput = document.getElementById("searchBillNumber").value.toLowerCase();
const paymentStatusInput = document.getElementById("searchPaymentStatus").value;
+ // Note: Due date range from inputs could also be used to pre-filter dataToExport
+ // but current logic exports based on `currentFilteredData` if any filter is active,
+ // which now includes date range.
let dataToExport = fees_data;
- // If any search criteria is active, export filtered data
- if (payerInput || billNumberInput || paymentStatusInput) {
+ if (payerInput || billNumberInput || paymentStatusInput || document.getElementById("searchDueDateStart").value || document.getElementById("searchDueDateEnd").value) {
dataToExport = currentFilteredData;
}
@@ -244,7 +316,7 @@
return;
}
- let csvContent = "data:text/csv;charset=utf-8,\uFEFF"; // \uFEFF for BOM
+ let csvContent = "data:text/csv;charset=utf-8,\uFEFF";
csvContent += "ID,開單日期,住戶/繳費人,應繳金額,繳費項目,繳費單號,繳費狀態,繳費截止日,備註,提醒次數\n";
dataToExport.forEach(fee => {
const cleanPayer = `"${fee.payer.replace(/"/g, '""')}"`;
@@ -267,11 +339,16 @@
link.click();
document.body.removeChild(link);
- alert(`準備匯出 ${dataToExport.length} 筆繳費資料(${payerInput || billNumberInput || paymentStatusInput ? "依搜尋條件" : "全部"})`);
+ const filterActive = payerInput || billNumberInput || paymentStatusInput || document.getElementById("searchDueDateStart").value || document.getElementById("searchDueDateEnd").value;
+ alert(`準備匯出 ${dataToExport.length} 筆繳費資料(${filterActive ? "依搜尋條件" : "全部"})`);
}
- // Initial load: apply no filters (show all) and render
document.addEventListener('DOMContentLoaded', () => {
+ // Initialize date input types correctly if they have values (e.g. from browser cache)
+ ['searchDueDateStart', 'searchDueDateEnd'].forEach(id => {
+ const el = document.getElementById(id);
+ if (el.value) el.type = 'date';
+ });
performSearch();
});
diff --git a/Backstage/login.html b/Backstage/login.html
index 9f8df0d..0314dd5 100644
--- a/Backstage/login.html
+++ b/Backstage/login.html
@@ -11,27 +11,43 @@
- 
-
+
+
+
+
|