Refactored notification methods to handle Slack, SMS, and email delivery logic more effectively. Introduced `sendBookingNotification` email functionality and a new template for booking notifications. Improved handling of booking data for emails and centralized logic for retrieving booking details.
584 lines
26 KiB
PHP
584 lines
26 KiB
PHP
<?php
|
|
|
|
namespace objects;
|
|
|
|
use classes\db;
|
|
use classes\email;
|
|
use classes\gatewayapi;
|
|
use classes\object_property;
|
|
use classes\pdf_generator;
|
|
use classes\response;
|
|
use classes\slack;
|
|
use classes\wash_certificate_store;
|
|
use classes\wordpress_bookings_remote;
|
|
use Exception;
|
|
use Psr\Http\Client\ClientExceptionInterface;
|
|
use traits\db_object_t;
|
|
|
|
class bookings_o extends db
|
|
{
|
|
use db_object_t;
|
|
|
|
public object_property $customer_number;
|
|
public object_property $wash_type;
|
|
public object_property $contact_email;
|
|
public object_property $reference_number;
|
|
public object_property $regNrTraekker;
|
|
public object_property $regNrTrailer;
|
|
public object_property $washCertificateEmail;
|
|
public object_property $date;
|
|
public object_property $department;
|
|
public object_property $pickup_bool;
|
|
public object_property $notes;
|
|
public object_property $washCertificateStatus;
|
|
public object_property $washCertificateUrl;
|
|
public object_property $wash_certificate_pdf;
|
|
public object_property $status;
|
|
public object_property $data;
|
|
|
|
public function structure(): void
|
|
{
|
|
$this->setTable('bookings');
|
|
}
|
|
|
|
public function objectChanged(): void
|
|
{
|
|
// Clear the cache
|
|
redis->clear_department_booking_count($this->department->value());
|
|
}
|
|
|
|
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 */
|
|
$db, $response;
|
|
// Add the customer number to the filters
|
|
$filters['customer_number'] = $customer_number;
|
|
// List the objects with pagination
|
|
$array = $this->listObjectsWithPagination($page, $limit, $search, $filters, $order);
|
|
// Get the total number of objects
|
|
$total = $this->getTotalObjects($search, $filters);
|
|
$response->paginate($page, $limit, $total);
|
|
return $array;
|
|
}
|
|
|
|
public function getDepartmentBookingsUnfulfilledCount(int $department_id): int
|
|
{
|
|
global /** @var response $response */
|
|
$db, $response;
|
|
// Check if the count is cached
|
|
if (redis->get_department_booking_count($department_id)) {
|
|
$response->add_meta('cached', true);
|
|
return redis->get_department_booking_count($department_id);
|
|
}
|
|
$sql = "SELECT COUNT(*) as count FROM $this->table WHERE department = $department_id AND status = 'pending'";
|
|
$result = $db->query($sql);
|
|
$row = $db->fetch_assoc($result);
|
|
// Cache the count
|
|
redis->cache_department_booking_count($department_id, $row['count']);
|
|
return $row['count'];
|
|
}
|
|
|
|
public function delete(int $id): void
|
|
{
|
|
$this->id = $id;
|
|
$this->getObjectProperties();
|
|
// Set the status to cancelled
|
|
$this->status->set('cancelled');
|
|
// Remove the cache
|
|
redis->clear_department_booking_count($this->department->value());
|
|
}
|
|
|
|
public function getObjectProperties(): void
|
|
{
|
|
$this->customer_number = new object_property($this->table, $this->id, 'customer_number', 'int', true);
|
|
$this->wash_type = new object_property($this->table, $this->id, 'wash_type', 'string', true);
|
|
$this->contact_email = new object_property($this->table, $this->id, 'contact_email', 'string', true);
|
|
$this->reference_number = new object_property($this->table, $this->id, 'reference_number', 'string', true);
|
|
$this->regNrTraekker = new object_property($this->table, $this->id, 'regNrTraekker', 'string', true);
|
|
$this->regNrTrailer = new object_property($this->table, $this->id, 'regNrTrailer', 'string', true);
|
|
$this->washCertificateEmail = new object_property($this->table, $this->id, 'washCertificateEmail', 'string', true);
|
|
$this->date = new object_property($this->table, $this->id, 'date', 'string', true);
|
|
$this->department = new object_property($this->table, $this->id, 'department', 'int', true);
|
|
$this->pickup_bool = new object_property($this->table, $this->id, 'pickup_bool', 'int', true);
|
|
$this->notes = new object_property($this->table, $this->id, 'notes', 'string', true);
|
|
$this->washCertificateStatus = new object_property($this->table, $this->id, 'washCertificateStatus', 'string', true);
|
|
$this->washCertificateUrl = new object_property($this->table, $this->id, 'washCertificateUrl', 'string', true);
|
|
$this->wash_certificate_pdf = new object_property($this->table, $this->id, 'wash_certificate_pdf', 'string', true);
|
|
$this->status = new object_property($this->table, $this->id, 'status', 'string', true);
|
|
$this->data = new object_property($this->table, $this->id, 'data', 'string', true);
|
|
}
|
|
|
|
public function parseBookings(array $listObjectsWithPaginationIfSet): array
|
|
{
|
|
// Parse the customer numbers
|
|
$bookings = $this->parseCustomerNumbers($listObjectsWithPaginationIfSet);
|
|
return $bookings;
|
|
}
|
|
|
|
public function parseCustomerNumbers(array $listObjectsWithPaginationIfSet): array
|
|
{
|
|
// Parse the customer numbers
|
|
foreach ( $listObjectsWithPaginationIfSet as $key => $value ) {
|
|
$listObjectsWithPaginationIfSet[$key]['customer_name'] = (new users_o())->getCustomerName($value['customer_number']);
|
|
}
|
|
return $listObjectsWithPaginationIfSet;
|
|
|
|
}
|
|
|
|
public function syncBookings(): array
|
|
{
|
|
global /** @var response $response */
|
|
$db, $response;
|
|
$wordpress_bookings_remote = new wordpress_bookings_remote();
|
|
// Get all the bookings from the remote API
|
|
$bookings = $wordpress_bookings_remote->get_all_bookings()['data']['all_wash_bookings'];
|
|
// Parse the bookings
|
|
$parsed_bookings = $wordpress_bookings_remote->parse_bookings($bookings);
|
|
// Remove the cancelled bookings from the $parsed_bookings array
|
|
$cancelled_bookings = $this->getAllCancelledOrCompletedBookings();
|
|
foreach ( $cancelled_bookings as $cancelled_booking ) {
|
|
// Remove the cancelled booking from the parsed bookings
|
|
foreach ( $parsed_bookings as $key => $parsed_booking ) {
|
|
if ((int)$parsed_booking['id'] === (int)$cancelled_booking['id']) {
|
|
unset($parsed_bookings[$key]);
|
|
}
|
|
}
|
|
}
|
|
// Sync the bookings
|
|
foreach ( $parsed_bookings as $booking ) {
|
|
// Add or update the booking
|
|
$this->addOrUpdate(
|
|
$booking['id'],
|
|
$booking['customer_number'],
|
|
$booking['wash_type'],
|
|
$booking['contact_email'],
|
|
$booking['reference_number'],
|
|
$booking['regNrTraekker'],
|
|
$booking['regNrTrailer'],
|
|
$booking['washCertificateEmail'],
|
|
$booking['date'],
|
|
$booking['department'],
|
|
$booking['pickup_bool'] ? 1 : 0,
|
|
$booking['notes'],
|
|
$booking['washCertificateStatus'],
|
|
$booking['washCertificateUrl'],
|
|
$booking['status']
|
|
);
|
|
}
|
|
return [
|
|
"bookings" => count($bookings),
|
|
"cancelled" => count($cancelled_bookings),
|
|
"parsed" => count($parsed_bookings),
|
|
];
|
|
}
|
|
|
|
public function getAllCancelledOrCompletedBookings(): array
|
|
{
|
|
global $db;
|
|
// Get all the cancelled bookings
|
|
$sql = "SELECT * FROM $this->table WHERE status = 'cancelled' OR status = 'completed'";
|
|
$result = $db->query($sql);
|
|
return $db->fetch_all($result);
|
|
}
|
|
|
|
public function addOrUpdate(int $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,
|
|
'taulov' => 7,
|
|
];
|
|
return $departmentLegacyNames[strtolower($departmentName)] ?? 0;
|
|
}
|
|
|
|
/**
|
|
* Add a new booking
|
|
* @throws Exception If the object could not be created
|
|
*/
|
|
public function add(int $customer_number, string $wash_type, string $contact_email, string $reference_number, string $regNrTraekker, string $regNrTrailer, string $washCertificateEmail, string $date, int $department, int $pickup_bool, string $notes, string $washCertificateStatus, string $washCertificateUrl, string $status, array $data = []): void
|
|
{
|
|
global $db;
|
|
$tmp_id = self::add_object([
|
|
'customer_number' => (int)$db->escape_string($customer_number),
|
|
'wash_type' => (string)$db->escape_string($wash_type),
|
|
'contact_email' => (string)$db->escape_string($contact_email),
|
|
'reference_number' => (string)$db->escape_string($reference_number),
|
|
'regNrTraekker' => (string)$db->escape_string($regNrTraekker),
|
|
'regNrTrailer' => (string)$db->escape_string($regNrTrailer),
|
|
'washCertificateEmail' => (string)$washCertificateEmail ? $db->escape_string($washCertificateEmail) : '',
|
|
'date' => (string)$db->escape_string($date),
|
|
'department' => (int)$db->escape_string($department),
|
|
'pickup_bool' => (int)$db->escape_string($pickup_bool),
|
|
'notes' => (string)$db->escape_string($notes),
|
|
'washCertificateStatus' => (string)$db->escape_string($washCertificateStatus),
|
|
'washCertificateUrl' => (string)$db->escape_string($washCertificateUrl),
|
|
'status' => (string)$db->escape_string($status),
|
|
'data' => json_encode($data),
|
|
]);
|
|
// Check if the booking was created successfully
|
|
self::select((int)$tmp_id);
|
|
self::requireSelected();
|
|
self::notifyNewBooking();
|
|
}
|
|
|
|
/**
|
|
* 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 = !empty($department->slack_webhook->value());
|
|
$deliverSMS = (
|
|
!empty($branding->phone_country_code->value()) &&
|
|
!empty($branding->phone->value()) &&
|
|
!$deliverSlack // Only send SMS if slack is not available
|
|
);
|
|
$deliverEmail = (
|
|
!empty($this->contact_email->value()) &&
|
|
!$deliverSlack // Only send email if slack is not available
|
|
);
|
|
// Check if the department has a slack webhook
|
|
if ($deliverSlack) {
|
|
// Send a notification to the department
|
|
$slack = new slack();
|
|
$slack->send_department_booking_notification($department->id, $slack->format_new_booking(
|
|
$this->id,
|
|
$customer_array['customer_number'],
|
|
self::formatWashTypeFromServices(json_decode($this->data->value(), true)),
|
|
$this->contact_email->value(),
|
|
$this->reference_number->value() ?: '-',
|
|
$this->regNrTraekker->value(),
|
|
$this->regNrTrailer->value(),
|
|
$this->washCertificateEmail->value(),
|
|
$this->date->value(),
|
|
$department->id,
|
|
(bool)$this->pickup_bool->value(),
|
|
$this->notes->value(),
|
|
$this->washCertificateStatus->value(),
|
|
$this->washCertificateUrl->value(),
|
|
$this->status->value()
|
|
));
|
|
}
|
|
|
|
if (!$deliverSMS) {
|
|
// Send an SMS notification to the department
|
|
$gatewayapi = new gatewayapi();
|
|
$gatewayapi->send(
|
|
[$branding->phone_country_code->value() . $branding->phone->value()],
|
|
'New booking from ' . $customer->getCustomerName($customer_array['customer_number']) . ' (' . $this->id . ')',
|
|
);
|
|
}
|
|
|
|
if ($deliverEmail) {
|
|
// Send an email notification to the department
|
|
$email = new email();
|
|
$email->sendBookingNotification($this->id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws Exception If the object is not selected
|
|
*/
|
|
public function asArray(): array
|
|
{
|
|
self::requireSelected();
|
|
return [
|
|
'id' => (int)$this->id,
|
|
'customer_number' => (int)$this->customer_number->value(),
|
|
'wash_type' => $this->wash_type->value(),
|
|
'contact_email' => $this->contact_email->value(),
|
|
'reference_number' => $this->reference_number->value(),
|
|
'regNrTraekker' => $this->regNrTraekker->value(),
|
|
'regNrTrailer' => $this->regNrTrailer->value(),
|
|
'washCertificateEmail' => $this->washCertificateEmail->value(),
|
|
'date' => $this->date->value(),
|
|
'department' => (int)$this->department->value(),
|
|
'pickup_bool' => $this->pickup_bool->value() ? true : false,
|
|
'notes' => $this->notes->value(),
|
|
'washCertificateStatus' => $this->washCertificateStatus->value(),
|
|
'washCertificateUrl' => $this->washCertificateUrl->value(),
|
|
'wash_certificate_pdf' => $this->wash_certificate_pdf->value(),
|
|
'status' => $this->status->value(),
|
|
'data' => $this->data->value() ? json_decode($this->data->value(), true) : null,
|
|
];
|
|
}
|
|
|
|
private function formatWashTypeFromServices(array $services): string
|
|
{
|
|
// Format the wash type from the services array
|
|
$wash_services = [
|
|
1 => 'Udvendig sættevognstræk ( Trækker / trailer )',
|
|
2 => 'Udvendigt trailer vask',
|
|
3 => 'Indvendig trailer vask',
|
|
];
|
|
$string = '';
|
|
foreach ( $services as $service ) {
|
|
if (isset($wash_services[$service])) {
|
|
$string .= $wash_services[$service] . ', ';
|
|
}
|
|
}
|
|
// Remove the last comma and space
|
|
return rtrim($string, ', ');
|
|
}
|
|
|
|
public function checkUnfulfilledBookings(): void
|
|
{
|
|
$unfulfilled_bookings = [];
|
|
function addUnfulfilledBooking(int $department, array $arr): array
|
|
{
|
|
// Check if the department has a count in the unfulfilled bookings array
|
|
if (!isset($arr[$department])) {
|
|
$arr[$department] = 0;
|
|
}
|
|
// Add the unfulfilled booking to the department count
|
|
$arr[$department]++;
|
|
return $arr;
|
|
}
|
|
|
|
global $db;
|
|
// Get all the unfulfilled bookings
|
|
$bookings = $this->listObjectsWithPagination(1, 100000, null, ['status' => 'pending']);
|
|
// Check if the booking has been fulfilled
|
|
foreach ( $bookings as $booking ) {
|
|
if ($this->isCancelled($booking['id'])) {
|
|
echo "Booking with ID $booking[id] has been cancelled\n";
|
|
continue;
|
|
}
|
|
// Check if the booking is scheduled for the future
|
|
if (strtotime($booking['date']) > time()) {
|
|
continue;
|
|
}
|
|
// Check if the booking has been fulfilled
|
|
$fulfilled = $this->checkBookingFulfilled($booking['id']);
|
|
if (!$fulfilled) {
|
|
$unfulfilled_bookings = addUnfulfilledBooking($booking['department'], $unfulfilled_bookings);
|
|
echo "Booking with ID $booking[id] has not been fulfilled\n";
|
|
}
|
|
}
|
|
// Send a department webhook if the booking has not been fulfilled
|
|
foreach ( $unfulfilled_bookings as $department => $count ) {
|
|
$slack = new slack();
|
|
try {
|
|
$slack->send_department_booking_notification($department, 'There are ' . $count . ' unfulfilled bookings');
|
|
} catch (Exception $e) {
|
|
// Log the error
|
|
$logs = new logs_o();
|
|
$logs->add('slack', 0, 3, 0, 'SEND_DEPARTMENT_UNFULFILLED_BOOKINGS_NOTIFICATION', $e->getMessage());
|
|
}
|
|
}
|
|
}
|
|
|
|
private static function isCancelled(int $id): bool
|
|
{
|
|
global $db;
|
|
// Check if the booking has been cancelled
|
|
$sql = "SELECT status FROM bookings WHERE id = $id";
|
|
$result = $db->query($sql);
|
|
$row = $db->fetch_assoc($result);
|
|
return $row['status'] === 'cancelled';
|
|
}
|
|
|
|
public function checkBookingFulfilled(int $booking_id): bool
|
|
{
|
|
// Check if the booking has a wash certificate
|
|
$wash_certificate_store = new wash_certificate_store();
|
|
return $wash_certificate_store->washCertificateExists($booking_id);
|
|
}
|
|
|
|
public function completeWashWithoutWashCertificate(int $id): void
|
|
{
|
|
global $db;
|
|
// Set the status to completed
|
|
$sql = "UPDATE $this->table SET status = 'completed', washCertificateStatus = 'cancelled' WHERE id = $id";
|
|
$db->query($sql);
|
|
}
|
|
|
|
/**
|
|
* Generate a wash certificate
|
|
* @param int|null $safety_seal The safety seal number
|
|
* @param string|null $operator The operator name
|
|
* @throws Exception If the object is not selected
|
|
* @throws Exception If the booking already has a wash certificate
|
|
*/
|
|
public function generateWashCertificate(int|null $safety_seal = null, string|null $operator = null): void
|
|
{
|
|
self::requireSelected();
|
|
// Check if the booking already has a wash certificate
|
|
if ($this->hasWashCertificate()) {
|
|
throw new Exception('Booking already has a wash certificate');
|
|
}
|
|
// Generate the wash certificate
|
|
// 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();
|
|
$booking_array = self::asArray();
|
|
$department_array['branding'] = $branding->asArray();
|
|
//print_r($department_array);
|
|
//print_r($customer_array);
|
|
//print_r($booking_array);
|
|
$pdf_generator = new pdf_generator();
|
|
$pdf_generator->add_html($pdf_generator->templates->getTemplate('wash_certificate')
|
|
->setCompany([
|
|
'name' => 'Truck Wash',
|
|
'address' => 'Letland Allé 2',
|
|
'zip' => 2630,
|
|
'city' => 'Taastrup',
|
|
'phone_prefix' => 45,
|
|
'phone' => 43717886,
|
|
'email' => 'cph@truckwash.dk',
|
|
'website' => 'www.truckwash.dk',
|
|
'images' => [
|
|
'logo' => '/truckwash-banner-png.png',
|
|
'banner' => '/truckwash-banner-png.png',
|
|
'signature' => '/truckwash-underskrift.png',
|
|
],
|
|
])
|
|
->addData([
|
|
'booking_number' => $this->id,
|
|
'seal_number' => ($safety_seal ?? null),
|
|
'reg_1' => $booking_array['regNrTraekker'],
|
|
'reg_2' => $booking_array['regNrTrailer'],
|
|
'date' => date('d-m-Y'),
|
|
'time' => date('H:i'),
|
|
'carried_out_by' => ($operator ?? null),
|
|
'department_id' => $department->id,
|
|
'department_name' => $department_array['branding']['name'] ?: $department_array['name'],
|
|
'department_address' => $department_array['branding']['address'] ?: $department_array['description'],
|
|
'customer_name' => $customer->getCustomerName($customer_array['customer_number']),
|
|
'customer_address' => $customer->getCustomerEcocomicData($customer_array['customer_number'])->economic_customer->address ?: '-',
|
|
'type' => $booking_array['wash_type'],
|
|
])
|
|
->getHtml()
|
|
);
|
|
$pdf_path = $pdf_generator->generate_pdf();
|
|
// Set the PDF in the booking
|
|
$this->wash_certificate_pdf->set($pdf_path);
|
|
}
|
|
|
|
/**
|
|
* Check if the booking has a wash certificate
|
|
* @throws Exception If the object is not selected
|
|
*/
|
|
public function hasWashCertificate(): bool
|
|
{
|
|
self::requireSelected();
|
|
// Check if the booking has a wash certificate
|
|
if ($this->wash_certificate_pdf->value() !== null) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Send the wash certificate to the customer
|
|
* @throws Exception If the object is not selected
|
|
* @throws ClientExceptionInterface
|
|
*/
|
|
public function sendWashCertificateToCustomer(): void
|
|
{
|
|
self::requireSelected();
|
|
// Check if the booking has a wash certificate
|
|
if (!$this->hasWashCertificate()) {
|
|
throw new Exception('Booking does not have a wash certificate');
|
|
}
|
|
// Send the wash certificate to the customer
|
|
$email = new email();
|
|
$email->sendWashCertificateEmail(
|
|
$this->id,
|
|
(new users_o())->getCustomerName((int)$this->customer_number->value()),
|
|
$this->contact_email->value(),
|
|
$this->reference_number->value() ?: '-',
|
|
$this->wash_certificate_pdf->value(),
|
|
$this->washCertificateEmail->value(),
|
|
);
|
|
|
|
}
|
|
|
|
} |