Files
api/services/nginx/app/objects/order_bookings_o.php
T
Jeppe Bundgaard b76c4deaa9 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.
2025-11-10 11:46:22 +01:00

169 lines
6.4 KiB
PHP

<?php
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;
class order_bookings_o extends db
{
use db_object_t;
public object_property $customer_number;
public object_property $department;
public object_property $reg_1;
public object_property $reg_2;
public object_property $reg_3;
public object_property $datetime;
public object_property $note;
public object_property $reference;
public object_property $po;
public object_property $pickup;
public object_property $items;
public object_property $order_id;
public object_property $created_at;
public object_property $updated_at;
public object_property $deleted_at;
public function structure(): void
{
$this->setTable('order_bookings');
}
/**
* Add an object
* @param array $data The additional data of the object (e.g. ["key" => "value"])
* @return void
* @throws Exception If the object was not created successfully
*/
public function add(
array $data,
): void
{
global /** @var db $db */
$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);
$this->department = new object_property($this->table, $this->id, 'department', 'int', false);
$this->reg_1 = new object_property($this->table, $this->id, 'reg_1', 'string', false);
$this->reg_2 = new object_property($this->table, $this->id, 'reg_2', 'string', false);
$this->reg_3 = new object_property($this->table, $this->id, 'reg_3', 'string', false);
$this->datetime = new object_property($this->table, $this->id, 'datetime', 'timestamp', false);
$this->note = new object_property($this->table, $this->id, 'note', 'string', false);
$this->reference = new object_property($this->table, $this->id, 'reference', 'string', false);
$this->po = new object_property($this->table, $this->id, 'po', 'string', false);
$this->pickup = new object_property($this->table, $this->id, 'pickup', 'bool', false);
$this->items = new object_property($this->table, $this->id, 'items', 'json', false);
$this->order_id = new object_property($this->table, $this->id, 'order_id', 'int', false);
$this->created_at = new object_property($this->table, $this->id, 'created_at', 'timestamp', false);
$this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'timestamp', false);
$this->deleted_at = new object_property($this->table, $this->id, 'deleted_at', 'timestamp', false);
}
public function objectChanged(): void
{
//TODO: Add cache invalidation
}
public function asArray(): array
{
$order_id = $this->order_id->value();
return [
'id' => (int)$this->id,
'customer_number' => (int)$this->customer_number->value(),
'department' => (int)$this->department->value(),
'reg_1' => $this->reg_1->value(),
'reg_2' => $this->reg_2->value(),
'reg_3' => $this->reg_3->value(),
'datetime' => $this->datetime->value(),
'note' => $this->note->value(),
'reference' => $this->reference->value(),
'po' => $this->po->value(),
'pickup' => (bool)$this->pickup->value(),
'items' => $this->items->value(),
'order_id' => $order_id === null ? null : (int)$order_id,
'created_at' => $this->created_at->value(),
'updated_at' => $this->updated_at->value(),
];
}
}