From 7ec64ec84d88c5b8b5f433132abe48b8a97125a1 Mon Sep 17 00:00:00 2001 From: Truck Wash Agent Date: Mon, 10 Aug 2026 20:04:57 +0200 Subject: [PATCH] fix(api): order order_items so primary precedes addons in getOrderItems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SELECT in orders_o::getOrderItems had no explicit ORDER BY clause, so MySQL returned rows in undefined order. On the POS Fuldfør click and the superuser invoice tree, addons (related_item_id != NULL) were sometimes returned before their primary item, which broke the FE tree-builder and the OrderContentTable render. Add a stable ordering: primary items first (related_item_id IS NULL DESC), addons grouped by their parent (related_item_id ASC), and insertion order as the final tiebreaker (id ASC). --- services/nginx/app/objects/orders_o.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/nginx/app/objects/orders_o.php b/services/nginx/app/objects/orders_o.php index f37b49c8..a039d3dd 100644 --- a/services/nginx/app/objects/orders_o.php +++ b/services/nginx/app/objects/orders_o.php @@ -615,7 +615,12 @@ class orders_o extends db public function getOrderItems(int $order_id): array { global $db; - $sql = "SELECT * FROM order_items WHERE order_id = $order_id"; + // Order primary items first (related_item_id IS NULL), then addons grouped by + // their parent (related_item_id ASC), and finally fall back to insertion order + // (id ASC). Without an explicit ORDER BY, MySQL is free to return rows in any + // order, which causes the FE tree-builder to render addons before their + // primary on the invoice and POS displays. + $sql = "SELECT * FROM order_items WHERE order_id = $order_id ORDER BY (related_item_id IS NULL) DESC, related_item_id ASC, id ASC"; $result = $db->query($sql); $order_items = []; if ($result->num_rows > 0 && $result) {