170 lines
6.0 KiB
PHP
170 lines
6.0 KiB
PHP
<?php
|
|
// models/User.php
|
|
require_once dirname(__DIR__) . '/config/database.php';
|
|
|
|
class User {
|
|
private $conn;
|
|
private $table_name = "users";
|
|
|
|
public $id;
|
|
public $username;
|
|
public $password;
|
|
public $full_name;
|
|
public $role;
|
|
public $department_id;
|
|
public $status;
|
|
|
|
public function __construct() {
|
|
$this->conn = Database::getInstance();
|
|
}
|
|
|
|
public function login($username, $password) {
|
|
$query = "SELECT id, username, password, full_name, role, department_id
|
|
FROM " . $this->table_name . "
|
|
WHERE username = :username LIMIT 0,1";
|
|
|
|
$stmt = $this->conn->prepare($query);
|
|
$stmt->bindParam(':username', $username);
|
|
$stmt->execute();
|
|
|
|
if ($stmt->rowCount() > 0) {
|
|
$row = $stmt->fetch();
|
|
if (password_verify($password, $row['password'])) {
|
|
// Set object properties
|
|
$this->id = $row['id'];
|
|
$this->username = $row['username'];
|
|
$this->full_name = $row['full_name'];
|
|
$this->role = $row['role'];
|
|
$this->department_id = $row['department_id'];
|
|
|
|
// Update status to online
|
|
$this->updateStatus($this->id, 'online');
|
|
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function updateStatus($user_id, $status) {
|
|
$query = "UPDATE " . $this->table_name . " SET status = :status WHERE id = :id";
|
|
$stmt = $this->conn->prepare($query);
|
|
$stmt->bindParam(':status', $status);
|
|
$stmt->bindParam(':id', $user_id);
|
|
$stmt->execute();
|
|
}
|
|
|
|
public function getById($id) {
|
|
$query = "SELECT * FROM " . $this->table_name . " WHERE id = :id LIMIT 1";
|
|
$stmt = $this->conn->prepare($query);
|
|
$stmt->bindParam(':id', $id);
|
|
$stmt->execute();
|
|
|
|
if ($stmt->rowCount() > 0) {
|
|
return $stmt->fetch();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public function getAll() {
|
|
$query = "SELECT u.*, d.name as department_name
|
|
FROM " . $this->table_name . " u
|
|
LEFT JOIN departments d ON u.department_id = d.id
|
|
ORDER BY u.created_at DESC";
|
|
$stmt = $this->conn->prepare($query);
|
|
$stmt->execute();
|
|
return $stmt->fetchAll();
|
|
}
|
|
|
|
public function add($username, $password, $full_name, $role, $department_id = null) {
|
|
$query = "INSERT INTO " . $this->table_name . " (username, password, full_name, role, department_id, status)
|
|
VALUES (:username, :password, :full_name, :role, :department_id, 'offline')";
|
|
|
|
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
|
|
|
$stmt = $this->conn->prepare($query);
|
|
$stmt->bindParam(':username', $username);
|
|
$stmt->bindParam(':password', $hashed_password);
|
|
$stmt->bindParam(':full_name', $full_name);
|
|
$stmt->bindParam(':role', $role);
|
|
|
|
if ($department_id) {
|
|
$stmt->bindParam(':department_id', $department_id);
|
|
} else {
|
|
$stmt->bindValue(':department_id', null, PDO::PARAM_NULL);
|
|
}
|
|
|
|
return $stmt->execute();
|
|
}
|
|
|
|
public function update($id, $full_name, $role, $department_id = null) {
|
|
$query = "UPDATE " . $this->table_name . "
|
|
SET full_name = :full_name, role = :role, department_id = :department_id
|
|
WHERE id = :id";
|
|
|
|
$stmt = $this->conn->prepare($query);
|
|
$stmt->bindParam(':full_name', $full_name);
|
|
$stmt->bindParam(':role', $role);
|
|
$stmt->bindParam(':id', $id);
|
|
|
|
if ($department_id) {
|
|
$stmt->bindParam(':department_id', $department_id);
|
|
} else {
|
|
$stmt->bindValue(':department_id', null, PDO::PARAM_NULL);
|
|
}
|
|
|
|
return $stmt->execute();
|
|
}
|
|
|
|
public function updatePassword($id, $password) {
|
|
$query = "UPDATE " . $this->table_name . " SET password = :password WHERE id = :id";
|
|
$hashed_password = password_hash($password, PASSWORD_DEFAULT);
|
|
|
|
$stmt = $this->conn->prepare($query);
|
|
$stmt->bindParam(':password', $hashed_password);
|
|
$stmt->bindParam(':id', $id);
|
|
return $stmt->execute();
|
|
}
|
|
|
|
public function delete($id) {
|
|
// Since we have foreign keys, we might want to just set status or delete.
|
|
// Assuming delete for now based on schema constraints (SET NULL or CASCADE might be needed)
|
|
// Schema has jobs.requester_id and jobs.assigned_to referencing users(id).
|
|
// Deleting a user with jobs will fail unless we handle it, or we can soft delete.
|
|
// For simplicity, let's hard delete, but if it fails it throws PDOException.
|
|
$query = "DELETE FROM " . $this->table_name . " WHERE id = :id";
|
|
$stmt = $this->conn->prepare($query);
|
|
$stmt->bindParam(':id', $id);
|
|
return $stmt->execute();
|
|
}
|
|
|
|
public function getAvailableStaff() {
|
|
// Find staff who are online and NOT currently handling an active job
|
|
// Order by who has been idle the longest today
|
|
$query = "
|
|
SELECT u.id, u.full_name, MAX(j.completed_at) as last_job
|
|
FROM " . $this->table_name . " u
|
|
LEFT JOIN jobs j ON u.id = j.assigned_to
|
|
AND j.status = 'completed'
|
|
AND DATE(j.created_at) = CURDATE()
|
|
WHERE u.role = 'staff'
|
|
AND u.status = 'online'
|
|
AND u.id NOT IN (
|
|
SELECT assigned_to
|
|
FROM jobs
|
|
WHERE status IN ('assigned', 'accepted', 'in_progress')
|
|
AND assigned_to IS NOT NULL
|
|
)
|
|
GROUP BY u.id
|
|
ORDER BY last_job ASC
|
|
LIMIT 1
|
|
";
|
|
|
|
$stmt = $this->conn->query($query);
|
|
if ($stmt->rowCount() > 0) {
|
|
return $stmt->fetch(PDO::FETCH_ASSOC);
|
|
}
|
|
return false;
|
|
}
|
|
}
|