Added a `visible` property to manage department visibility. Updated routes, traits, and objects to filter out non-visible departments and restrict access to internal system departments for end-users. This improves data security and enhances control over information exposure.
349 lines
13 KiB
PHP
349 lines
13 KiB
PHP
<?php
|
|
|
|
namespace objects;
|
|
|
|
use classes\db;
|
|
use classes\object_property;
|
|
use classes\stripe;
|
|
use Exception;
|
|
use traits\db_object_t;
|
|
|
|
class departments_o extends db
|
|
{
|
|
use db_object_t;
|
|
|
|
public object_property $name;
|
|
public object_property $description;
|
|
public object_property $economic_department_id; // The id of the department in the economic system (Can be null)
|
|
public object_property $slack_webhook; // The slack webhook for the department
|
|
public department_variables_o $variables; // The department variables object
|
|
public object_property $dimension; // The dimension of the department
|
|
public object_property $visible; // The visibility of the department
|
|
public object_property $branding; // The branding of the department
|
|
public object_property $created_at;
|
|
public object_property $updated_at;
|
|
|
|
public function structure(): void
|
|
{
|
|
$this->setTable('departments');
|
|
}
|
|
|
|
public function objectChanged(): void
|
|
{
|
|
// Clear the cache
|
|
redis->clear_departments();
|
|
}
|
|
|
|
/**
|
|
* Add a department
|
|
* @param string $name
|
|
* @param string $description
|
|
* @throws Exception If the object was not created successfully
|
|
*/
|
|
public function create(string $name, string $description): void
|
|
{
|
|
global $db;
|
|
// Avoid SQL injection
|
|
$name = $db->escape_string($name);
|
|
$description = $db->escape_string($description);
|
|
// Create a new record in the database
|
|
$sql = "INSERT INTO $this->table (name, description) VALUES ('$name', '$description')";
|
|
$db->query($sql);
|
|
|
|
// Get the id of the new record
|
|
$this->id = $db->insert_id();
|
|
|
|
// Set the values of the object properties
|
|
$this->getObjectProperties();
|
|
|
|
// Clear the cache
|
|
redis->clear_departments();
|
|
}
|
|
|
|
/**
|
|
* Get the object properties of the department
|
|
* @throws Exception If the object is not selected
|
|
*/
|
|
public function getObjectProperties(): void
|
|
{
|
|
self::requireSelected();
|
|
$this->name = new object_property($this->table, $this->id, 'name', 'string', true);
|
|
$this->description = new object_property($this->table, $this->id, 'description', 'string', false);
|
|
$this->economic_department_id = new object_property($this->table, $this->id, 'economic_department_id', 'int', false);
|
|
$this->slack_webhook = new object_property($this->table, $this->id, 'slack_webhook', 'string', false);
|
|
$this->variables = (new department_variables_o())->selectDepartment($this->id);
|
|
$this->dimension = new object_property($this->table, $this->id, 'dimension', 'int', false);
|
|
$this->branding = new object_property($this->table, $this->id, 'branding', 'int', false);
|
|
$this->visible = new object_property($this->table, $this->id, 'visible', 'int', false);
|
|
$this->created_at = new object_property($this->table, $this->id, 'created_at', 'string', false);
|
|
$this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'string', false);
|
|
}
|
|
|
|
public function edit(int $id, string $name, string $description, int $economic_department_id): void
|
|
{
|
|
global $db;
|
|
$this->id = $id;
|
|
// Avoid SQL injection
|
|
$name = $db->escape_string($name);
|
|
$description = $db->escape_string($description);
|
|
// If the economic_department_id is 0, set it to null
|
|
if ($economic_department_id === 0) {
|
|
$economic_department_id = null;
|
|
}
|
|
// Update the record in the database
|
|
$sql = "UPDATE $this->table SET name = '$name', description = '$description', economic_department_id = " . ($economic_department_id ?? 'NULL') . " WHERE id = $this->id";
|
|
$db->query($sql);
|
|
|
|
// Set the values of the object properties
|
|
$this->getObjectProperties();
|
|
|
|
// Clear the cache
|
|
redis->clear_department($id);
|
|
}
|
|
|
|
public function list($superUser = false): array
|
|
{
|
|
global $db;
|
|
// Check if the departments are cached
|
|
$departments = redis->get_departments();
|
|
// If the departments are not cached, get them from the database
|
|
if ($departments === null) {
|
|
$sql = "SELECT * FROM $this->table";
|
|
$result = $db->query($sql);
|
|
$departments = $db->fetch_all($result);
|
|
// Cache the departments (If it is not empty or null)
|
|
if (!empty($departments)) {
|
|
redis->cache_departments($departments);
|
|
}
|
|
}
|
|
// Only show the name, description and id if the user isn't a super user
|
|
if (!$superUser) {
|
|
// Map the departments to only show the name, description and id
|
|
$departments = array_map(function ($department) {
|
|
return [
|
|
'name' => $department['name'],
|
|
'description' => $department['description'],
|
|
'id' => $department['id'],
|
|
'visible' => $department['visible'],
|
|
];
|
|
}, $departments);
|
|
}
|
|
return $departments;
|
|
}
|
|
|
|
public function getDepartmentById(int $id, bool $force_all = false): array
|
|
{
|
|
global $db;
|
|
// Check if the department is cached
|
|
$department = redis->get_department($id);
|
|
// If the department is not cached, get it from the database
|
|
if ($department === null || $force_all) {
|
|
$sql = "SELECT * FROM $this->table WHERE id = $id";
|
|
$result = $db->query($sql);
|
|
$department = $db->fetch_assoc($result);
|
|
// Cache the department (If it is not empty or null)
|
|
if (!empty($department)) {
|
|
redis->cache_department($id, $department);
|
|
}
|
|
}
|
|
return $department;
|
|
}
|
|
|
|
/**
|
|
* Get the price of a product in a department
|
|
* @param int $department_id
|
|
* @param int $product_id
|
|
* @param int $price
|
|
* @return void
|
|
*/
|
|
public function setDepartmentProductPrice(int $department_id, int $product_id, int $price): void
|
|
{
|
|
global $db;
|
|
// Check if the record already exists
|
|
$this->removeDepartmentProductPriceIfExist($department_id, $product_id);
|
|
// If the price is 0, return
|
|
if ($price === 0) {
|
|
return;
|
|
}
|
|
// Create a new record in the database
|
|
$sql = "INSERT INTO product_department_prices (department_id, product_id, price) VALUES ($department_id, $product_id, $price)";
|
|
$db->query($sql);
|
|
}
|
|
|
|
/**
|
|
* Remove the price of a product in a department
|
|
* @param int $department_id
|
|
* @param int $product_id
|
|
* @return void
|
|
*/
|
|
private function removeDepartmentProductPriceIfExist(int $department_id, int $product_id): void
|
|
{
|
|
global $db;
|
|
// Get the price from the database
|
|
$sql = "SELECT * FROM product_department_prices WHERE department_id = $department_id AND product_id = $product_id";
|
|
$result = $db->query($sql);
|
|
|
|
if ($result->num_rows > 0) {
|
|
// Remove the record from the database
|
|
$sql = "DELETE FROM product_department_prices WHERE department_id = $department_id AND product_id = $product_id";
|
|
$db->query($sql);
|
|
}
|
|
}
|
|
|
|
public function getDepartmentProductPrices(int $department_id): array
|
|
{
|
|
global $db;
|
|
$sql = "SELECT * FROM product_department_prices WHERE department_id = $department_id";
|
|
$result = $db->query($sql);
|
|
return $db->fetch_all($result);
|
|
}
|
|
|
|
public function selectId(int $department_id): self
|
|
{
|
|
$this->id = $department_id;
|
|
$this->getObjectProperties();
|
|
return $this;
|
|
}
|
|
|
|
public function getDepartmentName(int $department): string
|
|
{
|
|
global $db;
|
|
// Check if the department name is cached
|
|
$name = redis->get_department_name($department);
|
|
// If the department name is not cached, get it from the database
|
|
if ($name === null) {
|
|
try {
|
|
$this->id = $department;
|
|
$this->getObjectProperties();
|
|
$name = $this->name->value();
|
|
// Cache the department name (If it is not empty or null)
|
|
if (!empty($name)) {
|
|
redis->cache_department_name($department, $name);
|
|
}
|
|
} catch (Exception $e) {
|
|
$name = 'Unable to get department name: ' . $department;
|
|
}
|
|
return $name;
|
|
}
|
|
return redis->get_department_name($department) ?? 'Unable to get department name: ' . $department;
|
|
}
|
|
|
|
/**
|
|
* Get the Stripe terminal location department variable
|
|
* @note This is a link to the department_variables_o::getVariable(stripe_terminal_location) method
|
|
* @return string The Stripe terminal location id
|
|
* @throws Exception If the department variable is not set
|
|
* @throws Exception If the department is not selected
|
|
*/
|
|
public function getStripeTerminalLocation(): string
|
|
{
|
|
self::requireSelected();
|
|
if (!$this->variables->isSet('stripe_terminal_location')) {
|
|
throw new Exception('The Stripe terminal location is not set for the department.');
|
|
}
|
|
return $this->variables->getVariable('stripe_terminal_location');
|
|
}
|
|
|
|
/**
|
|
* Check if the Stripe terminal location variable is set
|
|
* @note This is a link to the department_variables_o::isSet(stripe_terminal_location) method
|
|
* @return bool true If the Stripe terminal location is set
|
|
* @throws Exception If the department is not selected
|
|
*/
|
|
public function isStripeTerminalLocationSet(): bool
|
|
{
|
|
self::requireSelected();
|
|
return $this->variables->isSet('stripe_terminal_location');
|
|
}
|
|
|
|
/**
|
|
* Set the Stripe terminal location department variable
|
|
* @note This is a link to the department_variables_o::set(stripe_terminal_location) method
|
|
* @param string $location The Stripe terminal location id
|
|
* @throws Exception If the department is not selected
|
|
* @throws Exception If the department variable is not updated successfully
|
|
*/
|
|
public function setStripeTerminalLocation(string $location): void
|
|
{
|
|
self::requireSelected();
|
|
$this->variables->set('stripe_terminal_location', $location);
|
|
}
|
|
|
|
/**
|
|
* Get the Stripe terminal readers
|
|
* @note This is a link to the stripe_endpoint_readers::listLocation method
|
|
* @throws Exception If the department is not selected
|
|
* @throws Exception If the Stripe terminal location is not set for the department
|
|
*/
|
|
public function getStripeTerminalReaders(): \Stripe\Collection
|
|
{
|
|
self::requireSelected();
|
|
if (!$this->variables->isSet('stripe_terminal_location')) {
|
|
throw new Exception('The Stripe terminal location is not set for the department.');
|
|
}
|
|
return (new stripe())->readers->listLocation($this->variables->getVariable('stripe_terminal_location'));
|
|
}
|
|
|
|
/**
|
|
* Convert the object to an array
|
|
* @param array|null $options The options for the conversion (e.g. ['slack_webhook' => true])
|
|
* @return array The object as an array
|
|
* @throws Exception If the object is not selected
|
|
*/
|
|
public function asArray(array $options = null): array
|
|
{
|
|
self::requireSelected();
|
|
$tmp = [
|
|
'id' => (int)$this->id,
|
|
'name' => (string)$this->name->value(),
|
|
'description' => (string)$this->description->value(),
|
|
'economic_department_id' => (int)$this->economic_department_id->value(),
|
|
'dimension' => (int)$this->dimension->value(),
|
|
'branding' => (int)$this->branding->value(),
|
|
'created_at' => (string)$this->created_at->value(),
|
|
'updated_at' => (string)$this->updated_at->value(),
|
|
];
|
|
// Check if the webhook should be included
|
|
if ($options && $options['slack_webhook']) {
|
|
$tmp['slack_webhook'] = (string)$this->slack_webhook->value();
|
|
}
|
|
return $tmp;
|
|
}
|
|
|
|
/**
|
|
* Check if the Stripe is configured for the department
|
|
* @note This is a link to the department_variables_o::isSet(stripe_terminal_location) method
|
|
* @return bool true If the Stripe is configured
|
|
* @throws Exception If the department is not selected
|
|
*/
|
|
public function isStripeConfigured(): bool
|
|
{
|
|
self::requireSelected();
|
|
if ($this->variables->isSet('stripe_terminal_location')) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @throws Exception If the department is not selected
|
|
* @throws Exception If the branding is not set
|
|
* @throws Exception If the branding is not found
|
|
*/
|
|
public function getBranding(): branding_o
|
|
{
|
|
self::requireSelected();
|
|
return (new branding_o())->select($this->branding->value());
|
|
}
|
|
|
|
/**
|
|
* Get the phone numbers for the SMS notification
|
|
* @note This is a link to the department_notification_sms_o::getDepartmentActivePhoneNumbers method
|
|
* @throws Exception If the department is not selected
|
|
*/
|
|
public function notificationSmsPhoneNumbers(): array
|
|
{
|
|
self::requireSelected();
|
|
return (new department_notification_sms_o())->getDepartmentActivePhoneNumbers($this->id);
|
|
}
|
|
} |