From 4cc270e258aa5b2e334d1d635b8efd04b72b455d Mon Sep 17 00:00:00 2001 From: Jeppe Bundgaard Date: Mon, 21 Jul 2025 13:10:15 +0200 Subject: [PATCH] Refactor order creation to use `addArray` method and sanitize inputs - Introduced `addArray` method in `orders_o` for streamlined order creation using an associative array. - Updated `ordersRoute` to utilize `addArray`, replacing older implementation for better manageability. - Improved input handling by trimming whitespaces from registration numbers. - Enhanced product pricing by incorporating department-specific prices and discount percentages. --- services/nginx/app/objects/orders_o.php | 38 +++++++++++++++++++++-- services/nginx/app/routes/ordersRoute.php | 23 ++++++++++++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/services/nginx/app/objects/orders_o.php b/services/nginx/app/objects/orders_o.php index c62d8e01..4d7df581 100644 --- a/services/nginx/app/objects/orders_o.php +++ b/services/nginx/app/objects/orders_o.php @@ -290,6 +290,31 @@ class orders_o extends db self::objectChanged(); } + public function addArray(array $order_array): orders_o + { + global $db, $response; + + try { + // Avoid SQL injection + $order_array = array_map(function ($value) use ($db) { + if (is_string($value)) { + // Escape string values + return $db->escape_string($value); + } + // Return other types as is + return $value; + }, $order_array); + // Create a new record in the database + $this->id = self::add_object([...$order_array]); + $this->getObjectProperties(); + self::requireSelected(); + self::assignToInvoiceCollection(); + return $this; + } catch (Exception $e) { + $response->error($e->getMessage()); + } + } + public function add(int $customer_id, int $cashier_id, string $reference, string $notes, int $department_id, string $reg_1 = '', string $reg_2 = '', string $reg_3 = ''): orders_o { global $db, $response; @@ -879,8 +904,8 @@ class orders_o extends db $this->getObjectProperties(); $this->customer_id->set(($xlvask_usage_log->hasBillableCustomer() ? (int)$xlvask_usage_log->CustomerId : 12345679)); // Set the customer ID from the usage log, or 0 if not billable $this->cashier_id->set(2285); // Set the cashier ID to a default value for simulation - $this->reference->set('Simulated Order from XL Vask'); - $this->notes->set('This is a simulated order generated from an XL Vask usage log'); + $this->reference->set((new customer_vehicles_o())->getPlateReferenceIfExists((string)$xlvask_usage_log->RegistrationNumber)); // Set the reference to the vehicle plate reference (If it exists) + $this->notes->set(''); // Set notes to an empty string for simulation $this->department_id->set($xlvask_usage_log->getDepartment()->id); // Set a default department ID for simulation $this->reg_1->set((string)$xlvask_usage_log->RegistrationNumber); // Set the registration number from the usage log $this->reg_2->set(''); @@ -1129,8 +1154,15 @@ class orders_o extends db $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->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 + // 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 - $order_item->price->set((int)$washItem->getUnitPriceExVat() * (int)$washItem->Count); // Set the price based on the wash item + $order_item->price->set((int)$product_price); // Set the price based on the product price and discount percentage $order_item->quantity->set((int)$washItem->Count); // Set the quantity based on the wash item $order_item->related_item_id->set($firstItemId === null ? null : $firstItemId); // Set the related item ID to the first item ID (if applicable) $order_item->include_in_invoice->set(true); // Set include_in_invoice to true for the simulated order item diff --git a/services/nginx/app/routes/ordersRoute.php b/services/nginx/app/routes/ordersRoute.php index f9a97d01..e5298bd6 100644 --- a/services/nginx/app/routes/ordersRoute.php +++ b/services/nginx/app/routes/ordersRoute.php @@ -147,13 +147,32 @@ class ordersRoute // Get the registration numbers (If they are set, they 2-3 are optional) $reg_2 = $data['reg_2'] ?? ''; $reg_3 = $data['reg_3'] ?? ''; + // Strip the registration numbers of any whitespace + $reg_1 = preg_replace('/\s+/', '', $reg_1); + $reg_2 = preg_replace('/\s+/', '', $reg_2); + $reg_3 = preg_replace('/\s+/', '', $reg_3); + $new_data = [ + 'customer_id' => (int)$data['customer_id'], + 'department_id' => (int)$data['department_id'], + 'reference' => (string)$data['reference'] ?? '', + 'cashier_id' => (int)$user->id, // The user who created the order + 'notes' => (string)$data['notes'] ?? '', + 'reg_1' => (string)$reg_1, + 'reg_2' => (string)$reg_2, + 'reg_3' => (string)$reg_3, + ...(!empty($data['lane']) ? ['lane' => (int)$data['lane']] : []), // Optional lane + ...(!empty($data['wash_id']) ? ['wash_id' => (string)$data['wash_id']] : []), // Optional wash ID + ...(!empty($data['booking_id']) ? ['booking_id' => (int)$data['booking_id']] : []), // Optional booking ID + 'created_at' => (string)($data['created_at'] ?? date('Y-m-d H:i:s')), // Default to current time if not set + ]; // Create the order - $order = (new orders_o())->add((int)$data['customer_id'], $user->id, $data['reference'], $data['notes'], (int)$data['department_id'], (string)$reg_1, (string)$reg_2, (string)$reg_3); + //$order = (new orders_o())->add((int)$data['customer_id'], $user->id, $data['reference'], $data['notes'], (int)$data['department_id'], (string)$reg_1, (string)$reg_2, (string)$reg_3); + $order = (new orders_o())->addArray($new_data); // Log the incident (new logs_o())->add('orders', $data['department_id'], 1, $user->id, 'ADD_ORDER', 'Successfully added an order (ID: ' . $data['department_id'] . ')'); // Return a success message, containing the orders array $response->success($order->asArray()); - } else { + } else { // Log the incident (new logs_o())->add('orders', 'global', 1, 0, 'ADD_ORDER', 'No user found, or invalid session'); // Return an error