From 16198f49e632f15b1a29383e0b59005e8ca88dab Mon Sep 17 00:00:00 2001 From: Jeppe Bundgaard Date: Mon, 21 Jul 2025 16:47:05 +0200 Subject: [PATCH] Refactor XL Vask module for better null handling and primary item validation - Improved null safety by updating product ID retrieval logic in parsers and usage logs. - Enhanced primary wash item selection with stricter checks for valid product types. - Adjusted import date modifier in `importUsageLogs` for extended range (`-7 day`). - Streamlined product and user association in order creation with additional validations. - Removed redundant checks and refined permission handling in import tasks. --- .../helpers/xlvask_parser_skylning_med_ro.php | 5 ++--- .../helpers/xlvask_parser_undervognskylning.php | 5 ++--- .../modules/xlvask/helpers/xlvask_usage_log.php | 17 +++++++++++++++-- services/nginx/app/objects/orders_o.php | 17 ++++++++++------- services/nginx/app/objects/users_o.php | 1 + .../nginx/app/objects/xlvask_usage_logs_o.php | 2 +- services/nginx/app/routes/moduleXLVaskRoute.php | 2 +- 7 files changed, 32 insertions(+), 17 deletions(-) diff --git a/services/nginx/app/modules/xlvask/helpers/xlvask_parser_skylning_med_ro.php b/services/nginx/app/modules/xlvask/helpers/xlvask_parser_skylning_med_ro.php index c81966b6..6a418cc6 100644 --- a/services/nginx/app/modules/xlvask/helpers/xlvask_parser_skylning_med_ro.php +++ b/services/nginx/app/modules/xlvask/helpers/xlvask_parser_skylning_med_ro.php @@ -27,11 +27,10 @@ class xlvask_parser_skylning_med_ro extends xlvask_product_parser // Spot Free- Varevogn (23) // Spot Free- Lastbil (24) // This means that we need to check the vehicle type and return the appropriate product. - $primary_product = $xlvask_usage_log->getPrimaryItem()->getProduct($xlvask_usage_log); - $primary_product_id = $primary_product->id; + $primary_product_id = $xlvask_usage_log->getPrimaryItem()?->getProduct($xlvask_usage_log)?->id ?? null; // Get the available addons for the primary product $product_options = new product_options_o(); - if ($product_options->isOptionAllowedOnType(23, $primary_product_id)) { + if (empty($primary_product_id) || $product_options->isOptionAllowedOnType(23, $primary_product_id)) { // If the primary product is a varevogn (van), return the Spot Free- Varevogn product return (new products_o())->select(23); // Spot Free- Varevogn product ID } elseif ($product_options->isOptionAllowedOnType(24, $primary_product_id)) { diff --git a/services/nginx/app/modules/xlvask/helpers/xlvask_parser_undervognskylning.php b/services/nginx/app/modules/xlvask/helpers/xlvask_parser_undervognskylning.php index 86bc461f..5300145c 100644 --- a/services/nginx/app/modules/xlvask/helpers/xlvask_parser_undervognskylning.php +++ b/services/nginx/app/modules/xlvask/helpers/xlvask_parser_undervognskylning.php @@ -23,11 +23,10 @@ class xlvask_parser_undervognskylning extends xlvask_product_parser protected function parse(xlvask_wash_item $wash_item, xlvask_usage_log $xlvask_usage_log): products_o { // This means that we need to check the vehicle type and return the appropriate product. - $primary_product = $xlvask_usage_log->getPrimaryItem()->getProduct($xlvask_usage_log); - $primary_product_id = $primary_product->id; + $primary_product_id = $xlvask_usage_log->getPrimaryItem()?->getProduct($xlvask_usage_log)?->id ?? null; // Get the available addons for the primary product $product_options = new product_options_o(); - if ($product_options->isOptionAllowedOnType(21, $primary_product_id)) { + if (empty($primary_product_id) || $product_options->isOptionAllowedOnType(21, $primary_product_id)) { return (new products_o())->select(21); // Undervognskylning product ID } // Throw an exception if the vehicle type is not supported diff --git a/services/nginx/app/modules/xlvask/helpers/xlvask_usage_log.php b/services/nginx/app/modules/xlvask/helpers/xlvask_usage_log.php index 156ff1b3..8f06f093 100644 --- a/services/nginx/app/modules/xlvask/helpers/xlvask_usage_log.php +++ b/services/nginx/app/modules/xlvask/helpers/xlvask_usage_log.php @@ -425,11 +425,24 @@ class xlvask_usage_log extends xlvask_helper * This method returns the first wash item in the WashItems array as the primary item. * @throws Exception */ - public function getPrimaryItem(): xlvask_wash_item + public function getPrimaryItem(): ?xlvask_wash_item { // Return the first wash item as the primary item if (isset($this->WashItems[0]) && $this->WashItems[0] instanceof xlvask_wash_item) { - return $this->WashItems[0]; + $allowed_primary_items = [ + 'Stor bil', + 'Lille bil', + 'Vask udført', + 'Hænger', + ]; + // Check if the first item is an allowed primary item + if (in_array($this->WashItems[0]->OriginalProductName, $allowed_primary_items, true)) { + // If it is, return it + return $this->WashItems[0]; + } + //echo "Returning primary wash item: " . $this->WashItems[0]->OriginalProductName . PHP_EOL; + //echo "Available items: " . implode(', ', array_map(fn($item) => $item->OriginalProductName, $this->WashItems)) . PHP_EOL; + return null; // There's no actual primary wash item in the usage log } throw new Exception("No primary wash item found in the usage log."); } diff --git a/services/nginx/app/objects/orders_o.php b/services/nginx/app/objects/orders_o.php index 4d7df581..c373bd06 100644 --- a/services/nginx/app/objects/orders_o.php +++ b/services/nginx/app/objects/orders_o.php @@ -1138,10 +1138,10 @@ class orders_o extends db foreach ( $xlvask_usage_log->WashItems as $washItem ) { // Check if the item should be included in the order // Check if the product is with id 64 (irrelevant product, a bi product of the wash) - if ($washItem->getProduct($xlvask_usage_log)->id === 64) { - continue; // Skip items that should not be included in the order - } - if (!$washItem->shouldIncludeInOrder() || $washItem->getProduct($xlvask_usage_log)->id === 64) { + $product = $washItem->getProduct($xlvask_usage_log); + + if (!$washItem->shouldIncludeInOrder() || $product->id === 64) { + unset($washItem); continue; // Skip items that should not be included in the order } $order_item = new order_items_o(); @@ -1152,13 +1152,16 @@ class orders_o extends db } $order_item->getObjectProperties(); $order_item->order_id->set($this->id); // Set the order ID to the simulated order ID - $order_item->product_id->set($washItem->getProduct($xlvask_usage_log)->id); // Set the product ID from the wash item + $order_item->product_id->set($product->id); // Set the product ID to the product ID from the wash item $order_item->reference->set(''); - $product = $washItem->getProduct($xlvask_usage_log); // Get the product price based on the department $product_price = (int)$product->getDepartmentPrice((int)$this->department_id->value()); // Get the department price for the product // Get the customers custom price discount percentage - $product_price_discount_percentage = (int)$xlvask_usage_log->getUser()->getCustomPrice($product->id, false); // Get the custom price discount percentage for the product + $user = $xlvask_usage_log->getUser(); // Get the user from the usage log + if (!$user->exists()) { + throw new Exception('No user found matching the customer number in the usage log'); + } + $product_price_discount_percentage = (int)$user->getCustomPrice($product->id, false); // Get the custom price discount percentage for the product // Apply the discount percentage to the product price $product_price = (int)($product_price * (1 - ($product_price_discount_percentage / 100))); // Apply the discount percentage to the product price $order_item->notes->set(null); // Set notes for the simulated order item diff --git a/services/nginx/app/objects/users_o.php b/services/nginx/app/objects/users_o.php index c5232f82..2f77c4c1 100644 --- a/services/nginx/app/objects/users_o.php +++ b/services/nginx/app/objects/users_o.php @@ -682,6 +682,7 @@ class users_o extends db */ public function getCustomPrice(int $object_id, bool $is_category = false): int|null { + self::requireSelected(); // Get the custom price for the product $discount = $this->price_overrides->setUser($this->id)->getPrice($is_category, $object_id); // If the is_category is false, check if there is a custom price for the category that the product belongs to diff --git a/services/nginx/app/objects/xlvask_usage_logs_o.php b/services/nginx/app/objects/xlvask_usage_logs_o.php index 596b8b3b..3713e720 100644 --- a/services/nginx/app/objects/xlvask_usage_logs_o.php +++ b/services/nginx/app/objects/xlvask_usage_logs_o.php @@ -90,7 +90,7 @@ class xlvask_usage_logs_o extends db * @throws Exception If the objects were not successfully added. * @returns void */ - public function importUsageLogs(string $dateTimeModifier = '-1 day'): void + public function importUsageLogs(string $dateTimeModifier = '-7 day'): void { if (!empty($this->id)) { throw new Exception('To prevent issues, having a selected object is not allowed.'); diff --git a/services/nginx/app/routes/moduleXLVaskRoute.php b/services/nginx/app/routes/moduleXLVaskRoute.php index 9d4a14d8..d8b52a6d 100644 --- a/services/nginx/app/routes/moduleXLVaskRoute.php +++ b/services/nginx/app/routes/moduleXLVaskRoute.php @@ -251,7 +251,7 @@ class moduleXLVaskRoute $this->get('/modules/xlvask/tasks/import-usage', function () { global $response; - //self::requirePermission('modules_xlvask_import_usage'); + self::requirePermission('modules_xlvask_import_usage'); // Create the xlvask_usage_logs_o object $xlvask_usage_logs_o = new \objects\xlvask_usage_logs_o(); // Import usage logs