Introduced support for a `data` property in bookings, extended form handling with additional validation and input fields, and added functionality for retrieving booking counts by date and status. Improved safety seal labeling and enhanced PDF generation comments.
492 lines
19 KiB
PHP
492 lines
19 KiB
PHP
<?php
|
|
|
|
namespace objects;
|
|
|
|
use classes\db;
|
|
use classes\object_property;
|
|
use Exception;
|
|
use traits\db_object_t;
|
|
|
|
class department_daily_reports_o extends db
|
|
{
|
|
use db_object_t;
|
|
|
|
/**
|
|
* The id of the department
|
|
* @var object_property $department_id
|
|
*/
|
|
public object_property $department_id;
|
|
/**
|
|
* The cm3 of water used in the department today
|
|
* @var object_property $water_usage
|
|
*/
|
|
public object_property $water_usage;
|
|
/**
|
|
* The cm3 of water used in the department today
|
|
* @var object_property $water_usage_morning
|
|
*/
|
|
public object_property $water_usage_morning;
|
|
|
|
/**
|
|
* Any notes for the report
|
|
* @var object_property $notes
|
|
*/
|
|
public object_property $notes;
|
|
|
|
/**
|
|
* The user (id) that filled the report
|
|
* @var object_property $filled_by
|
|
*/
|
|
public object_property $filled_by;
|
|
/**
|
|
* The timestamp of when the object was created
|
|
* @var object_property $created_at
|
|
*/
|
|
public object_property $created_at;
|
|
|
|
|
|
public function structure(): void
|
|
{
|
|
$this->setTable('department_daily_reports');
|
|
}
|
|
|
|
public function asArray(): array
|
|
{
|
|
return [
|
|
'id' => (int)$this->id,
|
|
'department_id' => (int)$this->department_id->value(),
|
|
'water_usage' => (int)$this->water_usage->value(),
|
|
'water_usage_morning' => (int)$this->water_usage_morning->value(),
|
|
'notes' => (string)$this->notes->value(),
|
|
'filled_by' => (int)$this->filled_by->value(),
|
|
'created_at' => (string)$this->created_at->value(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Add a department daily report
|
|
* @param int $department_id The id of the department
|
|
* @param int $water_usage The cm3 of water used in the department today
|
|
* @param int $water_usage_morning The cm3 of water used in the department (Checked in the morning)
|
|
* @param string $notes Any notes for the report
|
|
* @param int $filled_by The user (id) that filled the report
|
|
* @return department_daily_reports_o
|
|
* @throws Exception If the object was not created successfully
|
|
*/
|
|
public function add(
|
|
int $department_id,
|
|
int $water_usage,
|
|
int $water_usage_morning,
|
|
string $notes,
|
|
int $filled_by,
|
|
string $created_at = null
|
|
): department_daily_reports_o
|
|
{
|
|
// Validate the created_at date, if provided
|
|
if ($created_at !== null) {
|
|
$dateTime = \DateTime::createFromFormat('Y-m-d', $created_at);
|
|
if (!$dateTime || $dateTime->format('Y-m-d') !== $created_at) {
|
|
throw new Exception('Invalid date format for created_at. Expected format: YYYY-MM-DD');
|
|
}
|
|
}
|
|
$tmp_id = $this->add_object([
|
|
'department_id' => (int)$department_id,
|
|
'water_usage' => (int)$water_usage,
|
|
'water_usage_morning' => (int)$water_usage_morning,
|
|
'notes' => (string)$notes,
|
|
'filled_by' => (int)$filled_by,
|
|
'created_at' => $created_at ? $created_at : date('Y-m-d H:i:s'),
|
|
]);
|
|
$this->id = $tmp_id;
|
|
$this->getObjectProperties();
|
|
$this->objectChanged();
|
|
return $this;
|
|
}
|
|
|
|
public function getObjectProperties(): void
|
|
{
|
|
$this->department_id = new object_property($this->table, $this->id, 'department_id', 'int', false);
|
|
$this->water_usage = new object_property($this->table, $this->id, 'water_usage', 'int', false);
|
|
$this->water_usage_morning = new object_property($this->table, $this->id, 'water_usage_morning', 'int', false);
|
|
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', false);
|
|
$this->filled_by = new object_property($this->table, $this->id, 'filled_by', 'int', false);
|
|
$this->created_at = new object_property($this->table, $this->id, 'created_at', 'string', false);
|
|
}
|
|
|
|
public function objectChanged(): void
|
|
{
|
|
//TODO: Add cache invalidation
|
|
}
|
|
|
|
/**
|
|
* Get the amount of products sold on a given date
|
|
* @note This does not count products from removed orders, only products from orders that are still active
|
|
* @param string $date The date to get the report for (YYYY-MM-DD)
|
|
* @param int $department_id The id of the department
|
|
* @param int $product_id The id of the product
|
|
* @return int The amount of products sold on the given date (Not counting products from removed orders)
|
|
*/
|
|
public function getProductsSoldOnDate(string $date, int $department_id, int $product_id): int
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT SUM(oi.quantity) as amount FROM orders o
|
|
JOIN order_items oi ON o.id = oi.order_id
|
|
WHERE o.department_id = ? AND oi.product_id = ? AND DATE(o.created_at) = ? AND o.deleted_at IS NULL'
|
|
);
|
|
|
|
if ($stmt) {
|
|
$stmt->bind_param('iis', $department_id, $product_id, $date); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
$amount = $data['amount'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
return (int)$amount;
|
|
}
|
|
|
|
/**
|
|
* Get the amount of products sold, where the product would be applicable as an addon
|
|
* E.g. if the product is "Cheese" this would return the amount of "Pizza" sold
|
|
* @note This does not count products from removed orders, only products from orders that are still active
|
|
* @param string $date The date to get the report for (YYYY-MM-DD)
|
|
* @param int $department_id The id of the department
|
|
* @param int $product_id The id of the product (the addon)
|
|
* @return int The amount of products sold on the given date (Not counting products from removed orders)
|
|
*/
|
|
public function getProductsSoldWithAddonApplicable(string $date, int $department_id, int $product_id): int
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
// Get all the addons for the product
|
|
$addons = (new product_options_o())->getOptionProducts($product_id);
|
|
$addons = array_map(function ($addon) {
|
|
return $addon['product_id'];
|
|
}, $addons);
|
|
$addons = implode(',', $addons);
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT SUM(oi.quantity) as amount FROM orders o
|
|
JOIN order_items oi ON o.id = oi.order_id
|
|
WHERE o.department_id = ? AND oi.product_id IN (' . $addons . ') AND DATE(o.created_at) = ? AND o.deleted_at IS NULL'
|
|
);
|
|
|
|
if ($stmt) {
|
|
$stmt->bind_param('is', $department_id, $date); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
$amount = $data['amount'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
return (int)$amount;
|
|
|
|
}
|
|
|
|
/**
|
|
* Get the amount of products sold on a given date
|
|
* @note This does not count products from removed orders, only products from orders that are still active
|
|
* @param string $date The date to get the report for (YYYY-MM-DD)
|
|
* @param int $department_id The id of the department
|
|
* @return int The amount of products sold on the given date (Not counting products from removed orders)
|
|
*/
|
|
public function getTransactionProductsOnDateCount(string $date, int $department_id): int
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT SUM(oi.quantity) as amount FROM orders o
|
|
JOIN order_items oi ON o.id = oi.order_id
|
|
WHERE o.department_id = ? AND DATE(o.created_at) = ? AND o.deleted_at IS NULL'
|
|
);
|
|
|
|
if ($stmt) {
|
|
$stmt->bind_param('is', $department_id, $date); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
$amount = $data['amount'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
return (int)$amount;
|
|
}
|
|
|
|
/**
|
|
* Get the amount of transactions on a given date
|
|
* @note This does not count products from removed orders, only products from orders that are still active
|
|
* @param string $date The date to get the report for (YYYY-MM-DD)
|
|
* @param int $department_id The id of the department
|
|
* @return int The amount of transactions on the given date (Not counting products from removed orders)
|
|
*/
|
|
public function getTransactionsOnDateCount(string $date, int $department_id): int
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT COUNT(*) as amount FROM orders o
|
|
WHERE o.department_id = ? AND DATE(o.created_at) = ? AND o.deleted_at IS NULL'
|
|
);
|
|
|
|
if ($stmt) {
|
|
$stmt->bind_param('is', $department_id, $date); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
$amount = $data['amount'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
return (int)$amount;
|
|
}
|
|
|
|
/**
|
|
* Select the department daily report for today
|
|
* @param int $department_id The id of the department
|
|
* @return department_daily_reports_o The department daily report
|
|
* @throws Exception If a department daily report does not exist for today
|
|
* @throws Exception If the object was not selected
|
|
*/
|
|
public function selectDepartmentDailyReport(int $department_id): department_daily_reports_o
|
|
{
|
|
global $db;
|
|
if (!$this->doesDepartmentDailyReportExist($department_id)) {
|
|
throw new Exception('Department daily report does not exist');
|
|
}
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT id FROM department_daily_reports o
|
|
WHERE o.department_id = ? AND DATE(o.created_at) = CURDATE()'
|
|
);
|
|
// Check if the statement was prepared successfully
|
|
if ($stmt) {
|
|
$stmt->bind_param('i', $department_id); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
$id = $data['id'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
$this->select($id);
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Check if a department daily report exists for today
|
|
* @param int $department_id The id of the department
|
|
* @param string $date The date to check for (YYYY-MM-DD)
|
|
* @return bool True if the report exists, false otherwise
|
|
*/
|
|
public function doesDepartmentDailyReportExist(int $department_id, string $date = 'today'): bool
|
|
{
|
|
global $db;
|
|
if ($date === 'today') {
|
|
$date = date('Y-m-d');
|
|
}
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT COUNT(*) as amount FROM department_daily_reports o
|
|
WHERE o.department_id = ? AND DATE(o.created_at) = ?'
|
|
);
|
|
|
|
if ($stmt) {
|
|
$stmt->bind_param('is', $department_id, $date); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
$amount = $data['amount'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
return (int)$amount > 0;
|
|
}
|
|
|
|
/**
|
|
* Select the last department daily report for a department
|
|
* @param int $department_id The id of the department
|
|
* @return department_daily_reports_o The department daily report
|
|
* @throws Exception If the object was not selected
|
|
*/
|
|
public function selectLastDepartmentDailyReport(int $department_id): department_daily_reports_o
|
|
{
|
|
global $db;
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT id FROM department_daily_reports o
|
|
WHERE o.department_id = ? ORDER BY o.created_at DESC LIMIT 1'
|
|
);
|
|
// Check if the statement was prepared successfully
|
|
if ($stmt) {
|
|
$stmt->bind_param('i', $department_id); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "id" field
|
|
if (!$data) {
|
|
throw new Exception('Department daily report does not exist');
|
|
}
|
|
$id = $data['id'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
$this->select($id);
|
|
return $this;
|
|
}
|
|
|
|
public function getTransactionsOnDateEarnings(string $date, int $department_id): int
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
$conn = $db->conn();
|
|
// Get all the product prices, in all the orders (Not counting removed orders), for the given date and department, and sum them
|
|
$stmt = $conn->prepare(
|
|
'SELECT SUM(oi.price * oi.quantity) as amount FROM orders o
|
|
JOIN order_items oi ON o.id = oi.order_id
|
|
WHERE o.department_id = ? AND DATE(o.created_at) = ? AND o.deleted_at IS NULL'
|
|
);
|
|
if ($stmt) {
|
|
$stmt->bind_param('is', $department_id, $date); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
if (!$data) {
|
|
// If there are no orders, set the amount to 0
|
|
$amount = 0;
|
|
} else {
|
|
$amount = $data['amount'];
|
|
}
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
return (int)$amount;
|
|
}
|
|
|
|
/**
|
|
* Check if a department daily report exists for today
|
|
* @param int $department_id The id of the department
|
|
* @return bool True if the report exists, false otherwise
|
|
*/
|
|
public function hasReportForToday(int $department_id): bool
|
|
{
|
|
return $this->doesDepartmentDailyReportExist($department_id);
|
|
}
|
|
|
|
/**
|
|
* Select the department daily report for a given date
|
|
* @param int $department_id The id of the department
|
|
* @param string $date The date to get the report for (YYYY-MM-DD)
|
|
* @return department_daily_reports_o The department daily report
|
|
* @throws Exception If a department daily report does not exist for today
|
|
* @throws Exception If the object was not selected
|
|
*/
|
|
public function selectDepartmentReportByDate(int $department_id, string $date): department_daily_reports_o
|
|
{
|
|
global $db;
|
|
if (!$this->doesDepartmentDailyReportExist($department_id, $date)) {
|
|
throw new Exception('Department daily report does not exist');
|
|
}
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT id FROM department_daily_reports o
|
|
WHERE o.department_id = ? AND DATE(o.created_at) = ?'
|
|
);
|
|
// Check if the statement was prepared successfully
|
|
if ($stmt) {
|
|
$stmt->bind_param('is', $department_id, $date); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
if (!$data) {
|
|
throw new Exception('Department daily report does not exist');
|
|
}
|
|
$id = $data['id'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
$this->select($id);
|
|
return $this;
|
|
}
|
|
|
|
public function hasReport(int $department_id, string $date): bool
|
|
{
|
|
return $this->doesDepartmentDailyReportExist($department_id, $date);
|
|
}
|
|
|
|
public function getBookingsOnDateCount(string $date, int $department_id, string $status): int
|
|
{
|
|
global /** @var db $db */
|
|
$db;
|
|
$conn = $db->conn();
|
|
$stmt = $conn->prepare(
|
|
'SELECT COUNT(*) as amount FROM bookings_new o
|
|
WHERE o.department = ? AND DATE(o.created_at) = ? AND o.status = ?'
|
|
);
|
|
|
|
if ($stmt) {
|
|
$stmt->bind_param('iss', $department_id, $date, $status); // Bind parameters (i = integer, s = string)
|
|
$stmt->execute();
|
|
$result = $stmt->get_result(); // Get the result set from the statement
|
|
$data = $result->fetch_assoc(); // Fetch the result as an associative array
|
|
|
|
// Access the "amount" field
|
|
$amount = $data['amount'];
|
|
|
|
$stmt->close(); // Close the statement
|
|
} else {
|
|
// Handle query preparation error
|
|
die('Query preparation failed: ' . $conn->error);
|
|
}
|
|
return (int)$amount;
|
|
}
|
|
} |