get('/modules/xlvask/services/usage/orders', function () { // Define the permissions: $permission_list_own = 'list_xlvask_usage_orders_own'; // Permission to list own orders (Without department filter) $permission_list_all = 'list_xlvask_usage_orders_all'; // Permission to list all orders (With department filter) $response_includes_items = false; // Whether to include items in the response (This would increase the memory usage significantly) $response_includes_items_link = true; // Whether to include a cached direct link to fetch the order with items (This is used to avoid memory issues when the items are not needed) // Require the user to be logged in global $response; self::requirePermission($permission_list_own); // Check if the user has permission to list all entries if (self::hasPermission($permission_list_all)) { $this->requirePermission($permission_list_all); } else { $this->requirePermission($permission_list_own); } // Get the user object $user = (new authentication())->get_user(); // Check if the request was successful if ($user) { // Log the incident (new logs_o())->add('xlvask_usage_orders', 'global', 1, $user->id, 'LIST_XLVASK_USAGE_ORDERS', 'User accessed the list of xlvask usage orders'); $xlvask_usage_logs = new xlvask_usage_logs_o(); $xlvask = new xlvask(); $xlvask->new($xlvask->helpers->xlvask_usage_log)->getDepartment(); $orders_o = new orders_o(); $xlvask_usage_log = $xlvask->new($xlvask->helpers->xlvask_usage_log); // Increase the memory limit to 512MB (Provided it's currently less than that) if (ini_get('memory_limit') < '5120M') { ini_set('memory_limit', '5120M'); } // Set debug php error_reporting(E_ALL); ini_set('display_errors', '1'); // Return the list of usage logs $result = $xlvask_usage_logs // Make sure the Customer is not in the default customers list ->setAdditionalWhereClause("`Customer` NOT IN ('" . implode("', '", $xlvask_usage_log::$default_customers) . "')") ->listObjectsWithPaginationIfSet( function ($log) use ($response_includes_items_link, $response_includes_items, $xlvask_usage_logs, $user, $xlvask) { // Remove the 'id' field from the log $id = (int)$log['id']; unset($log['id']); // Convert the 'WashItems' field from JSON to an array $log['WashItems'] = json_decode($log['WashItems'], true); // Create a new xlvask usage log object $tmp = $xlvask->new($xlvask->helpers->xlvask_usage_log); // Set the properties of the temporary object $tmp->setProperties($log); // Define the result structure $isEligibleForAutomaticContinuance = $tmp->isEligibleForAutomaticContinuance(true); // Generate a fast link key for the order, used to retrieve the order with items later. if ($response_includes_items_link && $isEligibleForAutomaticContinuance) { // Add a link to the order with items $fast_link_key = redis->generateTemporaryCacheKey(); redis->set( $fast_link_key, json_encode($tmp->toArray(), JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), ); redis->expire($fast_link_key, 3600); // Set the link to expire in 1 hour } // Return the result $tmp_res = ($isEligibleForAutomaticContinuance ? (new orders_o())->simulateOrderFromXLVask($tmp, $response_includes_items) : []); $tmp_res['order']['customer_name'] = $tmp->Customer; // Add the customer name to the order // Clear memory unset($tmp); unset($log); // Return the result return [ 'id' => $id, // Return the ID of the log 'fast_link_key' => $fast_link_key ?? null, // Return the fast link key if it was generated ...$tmp_res['order'], // Return the simulated order from XLVask (with or without items) ]; }, $xlvask_usage_logs->forceRestrictFilters( [ // This makes sure that the user can only see department logs that belong to their departments 'HallId' => $user->getGroup()->getDepartmentsScannersHallIds(), 'FinishStatus' => ['1'], // Only show finished logs ] ) ); // Return the response $response->success($result); } else { // Log the incident (new logs_o())->add('xlvask_usage_orders', 'global', 1, 0, 'LIST_XLVASK_USAGE_ORDERS', 'No user found, or invalid session'); // Return an error $response->error('Invalid session', 400); } }, [ 'list_xlvask_usage_orders_own' => 'List own xlvask usage orders (Without department filter)', 'list_xlvask_usage_orders_all' => 'List all xlvask usage orders (With department filter)', ] ); $this->get('/modules/xlvask/services/usage/orders/fast-link', function () { global $response; self::requireParameters([ 'fast_link_key', // Example: 'temporary_cache_6878cf0603d77' ]); // Get the fast link key from the request $fast_link_key = (string)self::getParameter('fast_link_key'); self::requireType($fast_link_key, self::type_string()); self::requireMinLength('fast_link_key', 20); // Minimum length of the fast link key self::requireMaxLength('fast_link_key', 50); // Maximum length of the fast link key // Check if the fast link key is valid // First, check if the key has the correct format if (preg_match('/^temporary_cache_[a-z0-9]{12,32}$/', $fast_link_key)) { // Get the cached data from Redis $cached_data = redis->get($fast_link_key); // Check if the cached data is valid if ($cached_data) { // Decode the cached data $data = json_decode($cached_data, true); // Check if the data is valid if (is_array($data)) { // Delete the cached data from Redis redis->delete($fast_link_key); // Return the data $xlvask = new xlvask(); $order_arr = (new orders_o())->simulateOrderFromXLVask($xlvask->new($xlvask->helpers->xlvask_usage_log)->setProperties($data), true); // ['order' => $order_arr, 'order_items' => $items_arr] $tmp_order_obj = (object)[]; $tmp_order_arr = $order_arr['order'] ?? []; /** * "id": -1, * "customer_id": 39159000, * "cashier_id": 2285, * "reference": "Simulated Order from XL Vask", * "notes": "This is a simulated order generated from an XL Vask usage log", * "department_id": 1, * "reg_1": "DE55248", * "reg_2": "", * "reg_3": "", * "completed_at": null, * "created_at": "2025-07-16 13:04:54", * "deleted_at": null, * "total_net_amount": 683, * "invoice_collection_id": 0, * "booking_id": 0, * "wash_id": "b24728ea-e22b-4dce-8cd3-a0998f7fdc5e", * "lane": 1, * "closed_at": null */ $tmp_order_obj->customer_id = $tmp_order_arr['customer_id'] ?? 0; $tmp_order_obj->department_id = $tmp_order_arr['department_id'] ?? 0; $tmp_order_obj->reg_1 = $tmp_order_arr['reg_1'] ?? ''; $tmp_order_obj->reg_2 = $tmp_order_arr['reg_2'] ?? ''; $tmp_order_obj->reg_3 = $tmp_order_arr['reg_3'] ?? ''; $tmp_order_obj->created_at = $tmp_order_arr['created_at'] ?? ''; $tmp_order_obj->wash_id = $tmp_order_arr['wash_id'] ?? ''; $tmp_order_obj->lane = $tmp_order_arr['lane'] ?? 0; $response->success([ ...$order_arr, 'potential_duplicates' => (new orders_o())->getOrderPotentialDuplicatesIfFound( $tmp_order_obj->reg_1, $tmp_order_obj->reg_2, $tmp_order_obj->reg_3, $tmp_order_obj->department_id, $tmp_order_obj->created_at, ), ]); } else { // Return an error if the data is not valid $response->error('Invalid cached data', 400); } } else { // Return an error if the fast link key does not exist in Redis $response->error('Fast link key not found', 404); } } else { // Return an error if the fast link key is invalid $response->error('Invalid fast link key format', 400); } }, [ 'fast_link_key' => 'string', // Example: 'temporary_cache_6878cf0603d77' ] ); } }