From 97c448b5b60f28c81cbff8f9eb8d257b1ac6fd79 Mon Sep 17 00:00:00 2001 From: Jeppe Bundgaard Date: Wed, 3 Sep 2025 14:03:02 +0200 Subject: [PATCH] Add `is_wash` field to products and support wash statistics in reports - Introduced `is_wash` field to `products_o` for marking wash-related products. - Updated `productsRoute` to handle `is_wash` in product creation and editing. - Added `getTransactionsOnDateWashesCount` method in `department_daily_reports_o` for calculating wash-related transactions in reports. - Adjusted department daily reports routes to include wash statistics output. --- .../objects/department_daily_reports_o.php | 46 +++++++++++++++++++ services/nginx/app/objects/products_o.php | 7 +++ .../routes/departmentDailyReportsRoute.php | 7 +++ services/nginx/app/routes/productsRoute.php | 6 ++- 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/services/nginx/app/objects/department_daily_reports_o.php b/services/nginx/app/objects/department_daily_reports_o.php index 3a3256ca..88dea33b 100644 --- a/services/nginx/app/objects/department_daily_reports_o.php +++ b/services/nginx/app/objects/department_daily_reports_o.php @@ -514,4 +514,50 @@ class department_daily_reports_o extends db } return (int)$amount; } + + /** + * This function calculates how many of the transactions on a given date included a wash + * That is defined as any product that has the "is_wash" field set to true in the products table + * @note This does not count products from removed orders, only products from orders that are still active + * @param string $date The date to get the report for (YYYY-MM-DD) + * @param int $department_id The id of the department + * @param string|null $date_to (Optional) The end date to get the report for (YYYY-MM-DD). If provided, the report will be for the date range between $date and $date_to + * @return void + */ + public function getTransactionsOnDateWashesCount(string $date, int $department_id, string $date_to = null): int + { + global /** @var db $db */ + $db; + // If the date_to is null, set it to the date + if ($date_to === null) { + $date_to = $date; // Making the report for an entire day + } + $conn = $db->conn(); + // Get all the product prices, in all the orders (Not counting removed orders), for the given date and department, and sum them + $stmt = $conn->prepare( + 'SELECT COUNT(DISTINCT o.id) as amount FROM orders o + JOIN order_items oi ON o.id = oi.order_id + JOIN products p ON oi.product_id = p.id + WHERE o.department_id = ? AND DATE(o.created_at) BETWEEN ? AND ? AND o.deleted_at IS NULL AND p.is_wash = 1' + ); + if ($stmt) { + $stmt->bind_param('iss', $department_id, $date, $date_to); // Bind parameters (i = integer, s = string) + $stmt->execute(); + $result = $stmt->get_result(); // Get the result set from the statement + $data = $result->fetch_assoc(); // Fetch the result as an associative array + + // Access the "amount" field + if (!$data) { + // If there are no orders, set the amount to 0 + $amount = 0; + } else { + $amount = $data['amount']; + } + $stmt->close(); // Close the statement + } else { + // Handle query preparation error + die('Query preparation failed: ' . $conn->error); + } + return (int)$amount; + } } \ No newline at end of file diff --git a/services/nginx/app/objects/products_o.php b/services/nginx/app/objects/products_o.php index 6e1f6e7d..5c69a73b 100644 --- a/services/nginx/app/objects/products_o.php +++ b/services/nginx/app/objects/products_o.php @@ -55,6 +55,11 @@ class products_o extends db * @var object_property */ public object_property $requires_note; + /** + * Whether the product is a wash, and should be included in wash statistics + * @var object_property $is_wash + */ + public object_property $is_wash; /** * The timestamp of when the object was created * @var object_property @@ -100,6 +105,7 @@ class products_o extends db $this->economic_product_id = new object_property($this->table, $this->id, 'economic_product_id', 'int', false); $this->apply_category_discount = new object_property($this->table, $this->id, 'apply_category_discount', 'bool', false); $this->requires_note = new object_property($this->table, $this->id, 'requires_note', 'bool', false); + $this->is_wash = new object_property($this->table, $this->id, 'is_wash', 'bool', false); $this->created_at = new object_property($this->table, $this->id, 'created_at', 'string', false); $this->updated_at = new object_property($this->table, $this->id, 'updated_at', 'string', false); } @@ -189,6 +195,7 @@ class products_o extends db 'economic_product_id' => $this->economic_product_id->value(), 'apply_category_discount' => (bool)$this->apply_category_discount->value(), 'requires_note' => (bool)$this->requires_note->value(), + 'is_wash' => (bool)$this->is_wash->value(), 'created_at' => (string)$this->created_at->value(), 'updated_at' => (string)$this->updated_at->value(), ]; diff --git a/services/nginx/app/routes/departmentDailyReportsRoute.php b/services/nginx/app/routes/departmentDailyReportsRoute.php index 58d0580d..c327961a 100644 --- a/services/nginx/app/routes/departmentDailyReportsRoute.php +++ b/services/nginx/app/routes/departmentDailyReportsRoute.php @@ -499,6 +499,13 @@ class departmentDailyReportsRoute (int)self::getParameter('department_id'), $date_to ), + 'washes' => + (new department_daily_reports_o()) + ->getTransactionsOnDateWashesCount( + (string)self::getParameter('date'), + (int)self::getParameter('department_id'), + $date_to + ), 'date' => (string)self::getParameter('date'), 'department_id' => (int)self::getParameter('department_id'), 'date_to' => $date_to, diff --git a/services/nginx/app/routes/productsRoute.php b/services/nginx/app/routes/productsRoute.php index 60902545..f475c7f4 100644 --- a/services/nginx/app/routes/productsRoute.php +++ b/services/nginx/app/routes/productsRoute.php @@ -30,7 +30,8 @@ class productsRoute 'requires_note' => (boolean)$product['requires_note'], 'created_at' => (string)$product['created_at'], 'updated_at' => (string)$product['updated_at'], - 'addons' => (new product_options_o())->getProductOptions($product['id']) + 'addons' => (new product_options_o())->getProductOptions($product['id']), + 'is_wash' => (bool)$product['is_wash'], ]; } @@ -193,6 +194,9 @@ class productsRoute if (self::isParametersSet(['requires_note'])) { $product->requires_note->set($response->getRequestParameter('requires_note') ? 1 : 0); } + if (self::isParametersSet(['is_wash'])) { + $product->is_wash->set($response->getRequestParameter('is_wash') ? 1 : 0); + } (new logs_o())->add('products', 'global', 1, $user->id, 'EDIT_PRODUCT', 'Product id: ' . $id); // Return a success message $response->success(['message' => 'Product edited successfully']);