Add notification functionality for new order bookings

- Implemented `onAfterNewBooking` and `notifyNewBooking` methods to handle post-booking notifications.
- Added Slack and SMS notifications for departments upon creating new bookings.
- Enhanced error handling and logging for failed encoding and notification delivery.
- Updated `db_object_t` to JSON encode objects and arrays before database operations.
This commit is contained in:
Jeppe Bundgaard
2025-11-10 11:46:22 +01:00
parent 76483313ec
commit b76c4deaa9
3 changed files with 77 additions and 0 deletions
@@ -3,7 +3,10 @@
namespace objects;
use classes\db;
use classes\email;
use classes\gatewayapi;
use classes\object_property;
use classes\slack;
use Exception;
use traits\db_object_t;
@@ -48,8 +51,74 @@ class order_bookings_o extends db
// Add the object to the database
$new_id = self::add_object($data);
self::select($new_id);
$this->onAfterNewBooking();
}
/**
* @throws Exception
*/
public function onAfterNewBooking(): void
{
self::requireSelected();
// TODO: Send department notification (Slack, SMS)
}
/**
* Notify the department about a new booking
* @throws Exception If the object is not selected
* @throws ClientExceptionInterface If the request to the API fails
*/
public function notifyNewBooking(): void
{
self::requireSelected();
// Get the department from the booking
$department = (new departments_o())->select((int)$this->department->value());
if (!$department->exists()) {
throw new Exception('Department not found');
}
// Get the branding from the department
$branding = (new branding_o())->select((int)$department->branding->value());
if (!$branding->exists()) {
throw new Exception('Branding not found');
}
// Get the customer from the booking
$customer = (new users_o())->getUserByCustomerNumber((int)$this->customer_number->value());
$department_array = $department->asArray();
$customer_array = $customer->asArray();
// Define delivery methods
$deliverSlack = (boolean)!empty($department->slack_webhook->value());
$deliverSMS = true;
// Check if the department has a slack webhook
if ($deliverSlack) {
// Construct email
$message = "*" . $branding->name->value() . "*\n";
$message .= "_New Booking Created_\n\n";
$message .= "*Customer:* " . $customer->getCustomerName($customer_array['customer_number']) . " (`" . $customer_array['customer_number'] . "`)\n";
// Send a notification to the department
$slack = new slack();
$slack->send_department_booking_notification($department->id, $message);
}
if ($deliverSMS) {
// Send an SMS notification to the department
$gatewayapi = new gatewayapi();
try {
$gatewayapi->send(
[
// Add all the phone numbers from the department
...$department->notificationSmsPhoneNumbers()
],
'New booking from ' . $customer->getCustomerName($customer_array['customer_number']) . ' (' . $this->id . ')',
);
} catch (Exception $e) {
// Log the error
$logs = new logs_o();
$logs->add('gatewayapi', 0, 3, 0, 'SEND_DEPARTMENT_BOOKING_NOTIFICATION', $e->getMessage());
}
}
}
public function getObjectProperties(): void
{
$this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'int', false);
@@ -248,6 +248,7 @@ class orderBookingRoute
'delete_bookings' => 'Permission to delete order bookings. Only applies to bookings already permitted.'
]
);
}
/**
@@ -1024,6 +1024,13 @@ trait db_object_t
global $db;
$set = [];
foreach ( $data as $key => $value ) {
// JSON encode objects and arrays
if (is_object($value) || is_array($value)) {
$value = json_encode($value);
if ($value === false) {
throw new Exception('Failed to encode value for key: ' . $key . ' - ' . json_last_error_msg());
}
}
// If the value is null, set it to null
if ($value === null || (is_string($value) && strtolower($value) === 'null')) {
$set[] = "$key = NULL";