Enhance booking handling with service options and transactions
Added support for including customer name, department name, and parsed services in `asArray()` method. Introduced functionality for creating transactions, linking bookings to orders, and properly handling related services. Improved department daily report handling and removed unnecessary fields.
This commit is contained in:
@@ -356,12 +356,23 @@ class bookings_o extends db
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to an array
|
||||
* @options include_customer_name Include the customer name
|
||||
* @options include_department_name Include the department name
|
||||
* @options include_parsed_services Include the parsed services
|
||||
* @param array $options [@options] The options to include in the array
|
||||
* @return array The object as an array
|
||||
* @throws Exception If the object is not selected
|
||||
*/
|
||||
public function asArray(): array
|
||||
public function asArray(array $options = []): array
|
||||
{
|
||||
self::requireSelected();
|
||||
return [
|
||||
$options = array_merge([
|
||||
'include_customer_name' => false,
|
||||
'include_department_name' => false,
|
||||
'include_parsed_services' => false,
|
||||
], $options);
|
||||
$tmp_array = [
|
||||
'id' => (int)$this->id,
|
||||
'customer_number' => (int)$this->customer_number->value(),
|
||||
'wash_type' => $this->wash_type->value(),
|
||||
@@ -380,16 +391,39 @@ class bookings_o extends db
|
||||
'status' => $this->status->value(),
|
||||
'data' => $this->data->value() ? json_decode($this->data->value(), true) : null,
|
||||
];
|
||||
// Include the customer name
|
||||
if ($options['include_customer_name']) {
|
||||
$customer = (new users_o())->getUserByCustomerNumber((int)$this->customer_number->value());
|
||||
$tmp_array['customer_name'] = $customer->getCustomerName($this->customer_number->value());
|
||||
}
|
||||
// Include the department name
|
||||
if ($options['include_department_name']) {
|
||||
$department = (new departments_o())->select((int)$this->department->value());
|
||||
if ($department->exists()) {
|
||||
$tmp_array['department_name'] = $department->name->value();
|
||||
}
|
||||
}
|
||||
// Include the parsed services
|
||||
if ($options['include_parsed_services']) {
|
||||
// Format the wash type from the services array as followed:
|
||||
// 1 => 'Udvendig sættevognstræk ( Trækker / trailer )',
|
||||
$tmp_array['parsed_services']['string'] = $this->formatWashTypeFromServices(
|
||||
$this->data->value() ? json_decode($this->data->value(), true) : []
|
||||
);
|
||||
$tmp_array['parsed_services']['array'] = $this->data->value() ? json_decode($this->data->value(), true) : [];
|
||||
}
|
||||
return $tmp_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the wash type from the services array
|
||||
* @param array $services The services array
|
||||
* @return string The formatted wash type
|
||||
*/
|
||||
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',
|
||||
];
|
||||
$wash_services = self::getWashServicesString(self::getWashServices());
|
||||
$string = '';
|
||||
foreach ( $services as $service ) {
|
||||
if (isset($wash_services[$service])) {
|
||||
@@ -400,6 +434,89 @@ class bookings_o extends db
|
||||
return rtrim($string, ', ');
|
||||
}
|
||||
|
||||
private static function getWashServicesString(array $services): array
|
||||
{
|
||||
// Format the wash services as a string (product1, product2, product3)
|
||||
$string = [];
|
||||
foreach ( $services as $key => $service ) {
|
||||
if (isset($service['overrides']['name'])) {
|
||||
$string[$key] = $service['overrides']['name'];
|
||||
} else {
|
||||
$string[$key] = $service['name'];
|
||||
}
|
||||
}
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getWashServices(): array
|
||||
{
|
||||
// Define the product function
|
||||
|
||||
|
||||
// Get the wash services from the database
|
||||
return [
|
||||
// Exterior wash "Sættevognstræk"
|
||||
1 => self::defineProduct(1, 3, [
|
||||
'name' => 'Udvendig sættevognstræk ( Trækker / trailer )',
|
||||
'description' => 'Udvendig vask af sættevognstræk',
|
||||
]),
|
||||
// Exterior trailer wash "Udvendig trailer vask"
|
||||
2 => self::defineProduct(2, 2, [
|
||||
'name' => 'Udvendig trailer vask',
|
||||
'description' => 'Udvendig vask af trailer',
|
||||
]),
|
||||
3 => self::defineProduct(3, 10, [
|
||||
'name' => 'Indvendig trailer vask',
|
||||
'description' => 'Indvendig vask af trailer',
|
||||
]),
|
||||
4 => self::defineProduct(41, 41),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a product for the booking
|
||||
* @param int $id
|
||||
* @param int $product_id
|
||||
* @param array $overrides
|
||||
* @param array $options
|
||||
* @param array $addons
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* @see getWashServices()
|
||||
* @see getWashServicesString()
|
||||
*/
|
||||
private function defineProduct(int $id, int $product_id, array $overrides = [], array $options = [], array $addons = []): array
|
||||
{
|
||||
|
||||
// Check if the product exists
|
||||
if (!empty($product_id)) {
|
||||
$product_obj = (new products_o())->select((int)$product_id);
|
||||
if ($product_obj->exists()) {
|
||||
$default_options = $product_obj->asArray();
|
||||
}
|
||||
}
|
||||
|
||||
// Return the product
|
||||
return [
|
||||
'id' => (int)$id,
|
||||
'product_id' => (int)$product_id,
|
||||
'addons' => [...$addons],
|
||||
...($default_options ?? []),
|
||||
'overrides' => [
|
||||
'name' => null,
|
||||
'quantity' => null,
|
||||
'description' => null,
|
||||
'notes' => null,
|
||||
'reference' => null,
|
||||
...$overrides,
|
||||
],
|
||||
...$options,
|
||||
];
|
||||
}
|
||||
|
||||
public function checkUnfulfilledBookings(): void
|
||||
{
|
||||
$unfulfilled_bookings = [];
|
||||
@@ -543,6 +660,10 @@ class bookings_o extends db
|
||||
$pdf_path = $pdf_generator->generate_pdf();
|
||||
// Set the PDF in the booking
|
||||
$this->wash_certificate_pdf->set($pdf_path);
|
||||
// Add the wash certificate to the bookings data (If it does not exist)
|
||||
if (!self::hasServiceInBookingData(4)) {
|
||||
self::addServiceToBookingData(4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -559,6 +680,37 @@ class bookings_o extends db
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the booking data has a service
|
||||
* @param int $service_id The service id
|
||||
* @return bool True if the service exists, false otherwise
|
||||
* @throws Exception If the object is not selected
|
||||
*/
|
||||
public function hasServiceInBookingData(int $service_id): bool
|
||||
{
|
||||
self::requireSelected();
|
||||
// Get the current data
|
||||
$data = $this->data->value() ? json_decode($this->data->value(), true) : [];
|
||||
// Check if the service exists
|
||||
return in_array($service_id, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a service to the booking data
|
||||
* @param int $service_id The service id
|
||||
* @throws Exception If the object is not selected
|
||||
*/
|
||||
public function addServiceToBookingData(int $service_id): void
|
||||
{
|
||||
self::requireSelected();
|
||||
// Get the current data
|
||||
$data = $this->data->value() ? json_decode($this->data->value(), true) : [];
|
||||
// Add the service to the data
|
||||
$data[] = (int)$service_id;
|
||||
// Set the data
|
||||
$this->data->set(json_encode($data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the wash certificate to the customer
|
||||
* @throws Exception If the object is not selected
|
||||
@@ -584,4 +736,97 @@ class bookings_o extends db
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function createTransaction(): orders_o
|
||||
{
|
||||
global $response;
|
||||
self::requireSelected();
|
||||
// Get the services from the booking
|
||||
$services = $this->data->value() ? json_decode($this->data->value(), true) : [];
|
||||
// Get the department from the booking
|
||||
$department = (new departments_o())->select((int)$this->department->value());
|
||||
if (!$department->exists()) {
|
||||
throw new Exception('Department not found');
|
||||
}
|
||||
// Create a new order
|
||||
$order = new orders_o();
|
||||
$order->add(
|
||||
(int)$this->customer_number->value(),
|
||||
(int)$this->id,
|
||||
(string)$this->reference_number->value(),
|
||||
(string)$this->notes->value(),
|
||||
(int)$this->department->value(),
|
||||
(string)$this->regNrTraekker->value(),
|
||||
(string)$this->regNrTrailer->value(),
|
||||
);
|
||||
// Set the orders booking id
|
||||
$order->booking_id->set((int)$this->id);
|
||||
// Define the relation order item ids, when applicable.
|
||||
$relations = [
|
||||
// This is the order item id for the primary product, the wash certificate applies to.
|
||||
// This can be left null, if the product does not exist.
|
||||
4 => null,
|
||||
];
|
||||
// Sort the services, so the primary product is first, and the services with relations are last.
|
||||
$services_sorted = [];
|
||||
$services_not_relation = [];
|
||||
$services_relation = [];
|
||||
foreach ( $services as $service ) {
|
||||
// Get the service id
|
||||
$service_id = (int)$service;
|
||||
// Check if the service has the posibility to have a relation (null values are allowed)
|
||||
if (in_array($service_id, array_keys($relations))) {
|
||||
$services_relation[] = $service_id;
|
||||
} else {
|
||||
$services_not_relation[] = $service_id;
|
||||
}
|
||||
}
|
||||
// Sort the services, so the primary product is first, and the services with (potential) relations are last.
|
||||
$services_sorted = [
|
||||
...$services_not_relation,
|
||||
...$services_relation,
|
||||
];
|
||||
// Add the services to the order
|
||||
foreach ( $services_sorted as $service_id ) {
|
||||
$service = self::getWashServiceProduct((int)$service_id);
|
||||
// Add the service to the order
|
||||
$tmp_order_item = new order_items_o();
|
||||
$tmp_order_item->addItemToOrder(
|
||||
$order->id,
|
||||
(int)$service->id,
|
||||
(int)$response->get_user()->id,
|
||||
(int)1,
|
||||
$relations[(int)$service_id] ?? null,
|
||||
);
|
||||
// Check if the service allows for a wash certificate
|
||||
if ((int)$service_id === 3) {
|
||||
// Set the relation id for the wash certificate
|
||||
$relations[4] = (int)$tmp_order_item->id;
|
||||
}
|
||||
}
|
||||
// Return the order
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getWashServiceProduct(int $service_id): products_o
|
||||
{
|
||||
// Get the product id from the service id
|
||||
$services = self::getWashServices();
|
||||
if (!isset($services[$service_id])) {
|
||||
throw new Exception('Service not found');
|
||||
}
|
||||
$product_id = $services[$service_id]['product_id'];
|
||||
// Get the wash service product from the database
|
||||
$product = (new products_o())->select($product_id);
|
||||
if (!$product->exists()) {
|
||||
throw new Exception('Product not found');
|
||||
}
|
||||
return $product;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user