<?php
namespace App\Models;
use App\Core\Database;
use PDO;
// Import PDO for type hinting if needed, though Database class abstracts it
class Employee
{
private Database $db;
private string $table_name = "employees";
// Employee properties (matching table columns)
public ?int $id = null;
public string $employee_code;
public string $chat_user_id;
public string $first_name;
public string $last_name;
public string $email;
public ?int $manager_id = null;
public bool $is_manager = false;
public bool $is_hr = false;
public ?string $created_at = null;
public ?string $updated_at = null;
/**
* @param Database $db
*/
public function __construct(?Database $db = null)
{
$this->db = $db ?: Database::getInstance();
}
// Setter methods for properties to allow chaining or validation if needed
/**
* @param int $id
* @return mixed
*/
public function setId(int $id): self
{
$this->id = $id;
return $this;
}
/**
* @param string $employee_code
* @return mixed
*/
public function setEmployeeCode(string $employee_code): self
{
$this->employee_code = $employee_code;
return $this;
}
/**
* @param string $chat_user_id
* @return mixed
*/
public function setChatUserId(string $chat_user_id): self
{
$this->chat_user_id = $chat_user_id;
return $this;
}
/**
* @param string $first_name
* @return mixed
*/
public function setFirstName(string $first_name): self
{
$this->first_name = $first_name;
return $this;
}
/**
* @param string $last_name
* @return mixed
*/
public function setLastName(string $last_name): self
{
$this->last_name = $last_name;
return $this;
}
/**
* @param string $email
* @return mixed
*/
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
/**
* @param int $manager_id
* @return mixed
*/
public function setManagerId(?int $manager_id): self
{
$this->manager_id = $manager_id;
return $this;
}
/**
* @param bool $is_manager
* @return mixed
*/
public function setIsManager(bool $is_manager): self
{
$this->is_manager = $is_manager;
return $this;
}
/**
* @param bool $is_hr
* @return mixed
*/
public function setIsHr(bool $is_hr): self
{
$this->is_hr = $is_hr;
return $this;
}
/**
* Create a new employee record in the database.
* @return bool True on success, false on failure.
*/
public function create(): bool
{
$query = "INSERT INTO {$this->table_name}
(employee_code, chat_user_id, first_name, last_name, email, manager_id, is_manager, is_hr)
VALUES
(:employee_code, :chat_user_id, :first_name, :last_name, :email, :manager_id, :is_manager, :is_hr)";
$this->db->query($query);
$this->db->bind(':employee_code', $this->employee_code);
$this->db->bind(':chat_user_id', $this->chat_user_id);
$this->db->bind(':first_name', $this->first_name);
$this->db->bind(':last_name', $this->last_name);
$this->db->bind(':email', $this->email);
$this->db->bind(':manager_id', $this->manager_id, $this->manager_id === null ? PDO::PARAM_NULL : PDO::PARAM_INT);
$this->db->bind(':is_manager', $this->is_manager, PDO::PARAM_BOOL);
$this->db->bind(':is_hr', $this->is_hr, PDO::PARAM_BOOL);
if ($this->db->execute()) {
$this->id = (int) $this->db->lastInsertId();
return true;
}
return false;
}
/**
* Read all employees or a single employee by ID.
* @param ?int $id If null, fetches all employees. Otherwise, fetches employee by this ID.
* @return array|object|false Array of employees, a single employee object, or false on failure/not found.
*/
public function read(?int $id = null)
{
if ($id !== null) {
// Read single employee
$query = "SELECT * FROM {$this->table_name} WHERE id = :id LIMIT 1";
$this->db->query($query);
$this->db->bind(':id', $id, PDO::PARAM_INT);
$row = $this->db->single();
if ($row) {
// Populate object properties from the row
$this->id = (int) $row['id'];
$this->employee_code = $row['employee_code'];
$this->chat_user_id = $row['chat_user_id'];
$this->first_name = $row['first_name'];
$this->last_name = $row['last_name'];
$this->email = $row['email'];
$this->manager_id = $row['manager_id'] ? (int) $row['manager_id'] : null;
$this->is_manager = (bool) $row['is_manager'];
$this->is_hr = (bool) $row['is_hr'];
$this->created_at = $row['created_at'];
$this->updated_at = $row['updated_at'];
return $this; // Return the populated object
}
return false;
} else {
// Read all employees
$query = "SELECT * FROM {$this->table_name} ORDER BY created_at DESC";
$this->db->query($query);
return $this->db->resultSet();
}
}
/**
* Find an employee by their chat_user_id.
* @param string $chatUserId The chat_user_id to search for.
* @return self|false The Employee object if found, otherwise false.
*/
public function findByChatUserId(string $chatUserId)
{
$query = "SELECT * FROM {$this->table_name} WHERE chat_user_id = :chat_user_id LIMIT 1";
$this->db->query($query);
$this->db->bind(':chat_user_id', $chatUserId);
$row = $this->db->single();
if ($row) {
$this->id = (int) $row['id'];
$this->employee_code = $row['employee_code'];
$this->chat_user_id = $row['chat_user_id'];
$this->first_name = $row['first_name'];
$this->last_name = $row['last_name'];
$this->email = $row['email'];
$this->manager_id = $row['manager_id'] ? (int) $row['manager_id'] : null;
$this->is_manager = (bool) $row['is_manager'];
$this->is_hr = (bool) $row['is_hr'];
$this->created_at = $row['created_at'];
$this->updated_at = $row['updated_at'];
return $this;
}
return false;
}
/**
* Update an existing employee record in the database.
* Assumes $this->id is set.
* @return bool True on success, false on failure.
*/
public function update(): bool
{
if ($this->id === null) {
return false; // Cannot update without an ID
}
$query = "UPDATE {$this->table_name} SET
employee_code = :employee_code,
chat_user_id = :chat_user_id,
first_name = :first_name,
last_name = :last_name,
email = :email,
manager_id = :manager_id,
is_manager = :is_manager,
is_hr = :is_hr
WHERE id = :id";
$this->db->query($query);
$this->db->bind(':id', $this->id, PDO::PARAM_INT);
$this->db->bind(':employee_code', $this->employee_code);
$this->db->bind(':chat_user_id', $this->chat_user_id);
$this->db->bind(':first_name', $this->first_name);
$this->db->bind(':last_name', $this->last_name);
$this->db->bind(':email', $this->email);
$this->db->bind(':manager_id', $this->manager_id, $this->manager_id === null ? PDO::PARAM_NULL : PDO::PARAM_INT);
$this->db->bind(':is_manager', $this->is_manager, PDO::PARAM_BOOL);
$this->db->bind(':is_hr', $this->is_hr, PDO::PARAM_BOOL);
return $this->db->execute();
}
/**
* Delete an employee record from the database.
* Can delete by current object's ID or a specific ID.
* @param ?int $id If null, uses $this->id. Otherwise, uses the provided ID.
* @return bool True on success, false on failure.
*/
public function delete(?int $id = null): bool
{
$id_to_delete = $id ?? $this->id;
if ($id_to_delete === null) {
return false; // Cannot delete without an ID
}
$query = "DELETE FROM {$this->table_name} WHERE id = :id";
$this->db->query($query);
$this->db->bind(':id', $id_to_delete, PDO::PARAM_INT);
return $this->db->execute();
}
}