diff --git a/classes/db.php b/classes/db.php index 42f2f9fe..9d9940cd 100644 --- a/classes/db.php +++ b/classes/db.php @@ -108,4 +108,9 @@ class db { return $this->conn->prepare($sql); } + + public function num_rows(\mysqli_result|bool $result): int|string + { + return $result->num_rows; + } } \ No newline at end of file diff --git a/classes/redis.php b/classes/redis.php index 1fc48b6b..8fc2fb03 100644 --- a/classes/redis.php +++ b/classes/redis.php @@ -108,4 +108,33 @@ class redis implements redis_i $this->delete('department_webhook_' . $department_id); return $this; } + + /** + * @inheritDoc + */ + public function cache_department_name(int $department_id, string $department_name): self + { + // Cache the department name + $this->set('department_name_' . $department_id, $department_name); + return $this; + } + + /** + * @inheritDoc + */ + public function get_department_name(int $department_id): string|null + { + // Get the department name + return $this->get('department_name_' . $department_id); + } + + /** + * @inheritDoc + */ + public function clear_department_name(int $department_id): self + { + // Clear the department name + $this->delete('department_name_' . $department_id); + return $this; + } } \ No newline at end of file diff --git a/classes/slack.php b/classes/slack.php index 1fe9b39a..adc5a59d 100644 --- a/classes/slack.php +++ b/classes/slack.php @@ -5,6 +5,7 @@ namespace classes; use GuzzleHttp\Client; use interfaces\notification_i; use objects\departments_o; +use objects\users_o; use traits\notification_t; @@ -78,4 +79,28 @@ class slack implements notification_i return 'Failed to send message: ' . $e->getMessage(); } } + + public function format_new_booking($id, $customer_number, string $wash_type, string $contact_email, string $reference_number, string $regNrTraekker, string $regNrTrailer, string $washCertificateEmail, string $date, int $department, $pickup_bool, string $notes, string $washCertificateStatus, string $washCertificateUrl, string $status): string + { + // Get the department name + $department_name = (new departments_o())->getDepartmentName($department); + // Get the customer name + $customer_name = (new users_o())->getCustomerName($customer_number); + // Format the message + return "New booking created\n" + . "ID: $id\n" + . "Customer: $customer_name\n" + . "Customer number: $customer_number\n" + . "Wash type: $wash_type\n" + . "Contact email: $contact_email\n" + . "Reference number: $reference_number\n" + . "RegNr Traekker: $regNrTraekker\n" + . "RegNr Trailer: $regNrTrailer\n" + . "Wash certificate email: $washCertificateEmail\n" + . "Date: $date\n" + . "Department: $department_name\n" + . "Pickup: $pickup_bool\n" + . "Notes: $notes\n" + . "Status: $status"; + } } \ No newline at end of file diff --git a/index.php b/index.php index 85879f70..d4c41558 100644 --- a/index.php +++ b/index.php @@ -1,4 +1,5 @@ -setTable('bookings'); } + public function addOrUpdate($id, $customer_number, $wash_type, $contact_email, $reference_number, $regNrTraekker, $regNrTrailer, $washCertificateEmail, $date, $department, $pickup_bool, $notes, $washCertificateStatus, $washCertificateUrl, $status): void + { + global $db; + // Avoid SQL injection + $wash_type = $db->escape_string($wash_type); + $contact_email = $db->escape_string($contact_email); + $reference_number = $db->escape_string($reference_number); + $regNrTraekker = $db->escape_string($regNrTraekker); + $regNrTrailer = $db->escape_string($regNrTrailer); + $washCertificateEmail = $db->escape_string($washCertificateEmail); + $date = $db->escape_string($date); + // Parse the department name to id + $department = $this->getDepartmentIdByLegacyName($department); + $notes = $db->escape_string($notes); + $washCertificateStatus = $db->escape_string($washCertificateStatus); + $washCertificateUrl = $db->escape_string($washCertificateUrl); + $status = $db->escape_string($status); + // Check if the entry already exists + $sql = "SELECT * FROM $this->table WHERE id = $id"; + $result = $db->query($sql); + if ($db->num_rows($result) === 0) { + // Send a department webhook if the booking is new + $slack = new slack(); + try { + $slack->send_department_booking_notification($department, $slack->format_new_booking( + $id, + $customer_number, + $wash_type, + $contact_email, + $reference_number, + $regNrTraekker, + $regNrTrailer, + $washCertificateEmail, + $date, + $department, + $pickup_bool, + $notes, + $washCertificateStatus, + $washCertificateUrl, + $status + )); + } catch (\Exception $e) { + // Log the error + $logs = new logs_o(); + $logs->add('slack', 0, 3, 0, 'SEND_DEPARTMENT_BOOKING_NOTIFICATION', $e->getMessage()); + } + } + // Create a new record in the database ( Replace the code, if an entry already exists ) + $sql = "INSERT INTO $this->table (id, customer_number, wash_type, contact_email, reference_number, regNrTraekker, regNrTrailer, washCertificateEmail, date, department, pickup_bool, notes, washCertificateStatus, washCertificateUrl, status) VALUES ($id, $customer_number, '$wash_type', '$contact_email', '$reference_number', '$regNrTraekker', '$regNrTrailer', '$washCertificateEmail', '$date', '$department', $pickup_bool, '$notes', '$washCertificateStatus', '$washCertificateUrl', '$status') ON DUPLICATE KEY UPDATE customer_number = $customer_number, wash_type = '$wash_type', contact_email = '$contact_email', reference_number = '$reference_number', regNrTraekker = '$regNrTraekker', regNrTrailer = '$regNrTrailer', washCertificateEmail = '$washCertificateEmail', date = '$date', department = '$department', pickup_bool = $pickup_bool, notes = '$notes', washCertificateStatus = '$washCertificateStatus', washCertificateUrl = '$washCertificateUrl', status = '$status'"; + $db->query($sql); + // Clear the cache + redis->clear_department_booking_count($department); + } + + public function getDepartmentIdByLegacyName(string $departmentName): int + { + // Get the department id by the legacy name + $departmentLegacyNames = [ + 'køge' => 4, + 'taastrup' => 2, + 'aarhusc' => 5, + 'roskilde' => 6, + 'hvidovre' => 1, + 'glostrup' => 3, + ]; + return $departmentLegacyNames[strtolower($departmentName)] ?? 0; + } + public function add(int $customer_number, string $wash_type, string $contact_email, string $reference_number, string $regNrTraekker, string $regNrTrailer, string $washCertificateEmail, string $date, string $department, int $pickup_bool, string $notes, string $washCertificateStatus, string $washCertificateUrl, string $status): void { global $db; @@ -58,44 +127,6 @@ class bookings_o extends db $this->id = $db->insert_id(); } - public function getDepartmentIdByLegacyName(string $departmentName): int - { - // Get the department id by the legacy name - $departmentLegacyNames = [ - 'køge' => 4, - 'taastrup' => 2, - 'aarhusc' => 5, - 'roskilde' => 6, - 'hvidovre' => 1, - 'glostrup' => 3, - ]; - return $departmentLegacyNames[strtolower($departmentName)] ?? 0; - } - - public function addOrUpdate($id, $customer_number, $wash_type, $contact_email, $reference_number, $regNrTraekker, $regNrTrailer, $washCertificateEmail, $date, $department, $pickup_bool, $notes, $washCertificateStatus, $washCertificateUrl, $status): void - { - global $db; - // Avoid SQL injection - $wash_type = $db->escape_string($wash_type); - $contact_email = $db->escape_string($contact_email); - $reference_number = $db->escape_string($reference_number); - $regNrTraekker = $db->escape_string($regNrTraekker); - $regNrTrailer = $db->escape_string($regNrTrailer); - $washCertificateEmail = $db->escape_string($washCertificateEmail); - $date = $db->escape_string($date); - // Parse the department name to id - $department = $this->getDepartmentIdByLegacyName($department); - $notes = $db->escape_string($notes); - $washCertificateStatus = $db->escape_string($washCertificateStatus); - $washCertificateUrl = $db->escape_string($washCertificateUrl); - $status = $db->escape_string($status); - // Create a new record in the database ( Replace the code, if an entry already exists ) - $sql = "INSERT INTO $this->table (id, customer_number, wash_type, contact_email, reference_number, regNrTraekker, regNrTrailer, washCertificateEmail, date, department, pickup_bool, notes, washCertificateStatus, washCertificateUrl, status) VALUES ($id, $customer_number, '$wash_type', '$contact_email', '$reference_number', '$regNrTraekker', '$regNrTrailer', '$washCertificateEmail', '$date', '$department', $pickup_bool, '$notes', '$washCertificateStatus', '$washCertificateUrl', '$status') ON DUPLICATE KEY UPDATE customer_number = $customer_number, wash_type = '$wash_type', contact_email = '$contact_email', reference_number = '$reference_number', regNrTraekker = '$regNrTraekker', regNrTrailer = '$regNrTrailer', washCertificateEmail = '$washCertificateEmail', date = '$date', department = '$department', pickup_bool = $pickup_bool, notes = '$notes', washCertificateStatus = '$washCertificateStatus', washCertificateUrl = '$washCertificateUrl', status = '$status'"; - $db->query($sql); - // Clear the cache - redis->clear_department_booking_count($department); - } - public function getCustomerBookingsPaginated(int $customer_number, int $page = 1, int $limit = 10, array $order = ['id' => 'DESC'], string $search = null, array $filters = null): array { global /** @var response $response */ diff --git a/objects/departments_o.php b/objects/departments_o.php index 93ded757..4589ca5a 100644 --- a/objects/departments_o.php +++ b/objects/departments_o.php @@ -147,4 +147,21 @@ class departments_o extends db $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) { + $sql = "SELECT name FROM $this->table WHERE id = $department"; + $result = $db->query($sql); + $result = $db->fetch_assoc($result); + $name = $result['name']; + // Cache the department name + redis->cache_department_name($department, $name); + } + return redis->get_department_name($department); + } } \ No newline at end of file diff --git a/objects/users_o.php b/objects/users_o.php index 21487260..cc8688ce 100644 --- a/objects/users_o.php +++ b/objects/users_o.php @@ -642,6 +642,19 @@ class users_o extends db return false; } + public function parseUsers(array $listObjectsWithPaginationIfSet): array + { + return self::parseCustomerNumbers($listObjectsWithPaginationIfSet); + } + + public function parseCustomerNumbers(array $listObjectsWithPaginationIfSet): array + { + foreach ( $listObjectsWithPaginationIfSet as $key => $value ) { + $listObjectsWithPaginationIfSet[$key]['customer_name'] = $this->getCustomerName($value['customer_number']); + } + return $listObjectsWithPaginationIfSet; + } + public function getCustomerName(int $customer_number): string|null { // Check if the customer name is cached @@ -652,7 +665,7 @@ class users_o extends db $economic = new economicCustomers(); $customer_name = $economic->getCustomerName($customer_number); // Cache the customer name - redis->cache_economic_customer_name($customer_number, $customer_name); + redis->cache_economic_customer_name($customer_number, $customer_name ?? ''); return $customer_name; } } \ No newline at end of file diff --git a/routes/usersRoute.php b/routes/usersRoute.php index 871764e4..fc24909a 100644 --- a/routes/usersRoute.php +++ b/routes/usersRoute.php @@ -3,6 +3,7 @@ namespace routes; use classes\authentication; +use classes\response; use objects\logs_o; use objects\users_o; use traits\route_t; @@ -15,7 +16,8 @@ class usersRoute { $this->get('/users', function () { // Require the user to be logged in - global $response; + global /** @var response $response */ + $response; $this->requirePermission('list_users'); // Get the user object $user = (new authentication())->get_user(); @@ -24,8 +26,9 @@ class usersRoute // Log the incident (new logs_o())->add('users', 'global', 1, $user->id, 'LIST_USERS', 'Successfully listed users'); // Return the list of users + $users_o = new users_o(); $response->success( - (new users_o())->listObjects() + $users_o->parseUsers($users_o->listObjectsWithPaginationIfSet()) ); } else { // Log the incident