Update product addon sales calculation logic and refine Slack notification handling for departments

- Replace `COUNT` with `SUM` for accurate addon quantity tracking in sales queries.
- Implement support for filtering applicable products when calculating max addons.
- Add logic to handle custom Slack webhooks for department notifications.
- Refactor percentage calculation methods and remove redundant return statements.
This commit is contained in:
Jeppe Bundgaard
2026-01-21 14:40:55 +01:00
parent 9b41f80ea5
commit 56d0ee03d3
2 changed files with 30 additions and 10 deletions
+13 -5
View File
@@ -470,9 +470,17 @@ class departments_o extends db
$wash_count = (new orders_o())->countWashesInDateRange($date_start, $date_end, $department_id);
$analytics = $this->analyzeAddonSalesData($product_ids, $date_start, $date_end, $department_id, $max_addons, $sold_addons, $percentages);
$tmp .= "Washes: $wash_count\n" . implode('', $analytics);
// Send test message to Slack
// Check if there's a custom webhook for the department
$slack = new slack();
$slack->send_department_booking_notification($this->id, $tmp);
if (empty($this->slack_webhook->value()) || true) {
// If no webhook is set for the department, use the default Slack notification
$slack->send_message($tmp, "Weekly results for {$department->name->value()}");
return;
}
// Send message to the department's Slack webhook
//$slack->send_department_booking_notification($this->id, $tmp);
}
/**
@@ -492,7 +500,7 @@ class departments_o extends db
// Combine percentages from multiple departments
$combined_percentages = [];
foreach ( $department_id as $dept_id ) {
list($product_id, $pid, $dept_percentages) = $this->getThePercentageOfAddonsSoldOutOfMax($product_ids, $date_start, $date_end, $dept_id, $max_addons, $sold_addons, $percentages);
$dept_percentages = $this->getThePercentageOfAddonsSoldOutOfMax($product_ids, $date_start, $date_end, $dept_id, $max_addons, $sold_addons, $percentages);
foreach ( $dept_percentages as $key => $value ) {
if (!isset($combined_percentages[$key])) {
$combined_percentages[$key] = 0;
@@ -503,7 +511,7 @@ class departments_o extends db
$percentages = $combined_percentages;
} else {
// Single department
list($product_id, $pid, $percentages) = $this->getThePercentageOfAddonsSoldOutOfMax($product_ids, $date_start, $date_end, $department_id, $max_addons, $sold_addons, $percentages);
$percentages = $this->getThePercentageOfAddonsSoldOutOfMax($product_ids, $date_start, $date_end, $department_id, $max_addons, $sold_addons, $percentages);
}
$tmp = [];
foreach ( $product_ids as $product_id ) {
@@ -573,6 +581,6 @@ class departments_o extends db
$sold_addons[is_array($product_id) ? implode('_', $product_id) : $product_id] = $addon_sold_count;
$percentages[is_array($product_id) ? implode('_', $product_id) : $product_id] = number_format($addon_percentage_sold, 2);
}
return array($product_id, $pid, $percentages);
return $percentages;
}
}
@@ -232,10 +232,9 @@ class product_options_o extends db
$date_end = date('Y-m-d H:i:s', strtotime($date_end));
$department_id = (int)$department_id;
$query = "
SELECT COUNT(oi.id) AS sold_addons_count
SELECT SUM(oi.quantity) AS sold_addons_count
FROM order_items oi
INNER JOIN orders o ON oi.order_id = o.id
WHERE oi.related_item_id IS NOT NULL
AND oi.product_id = {$product_id}
AND oi.deleted_at IS NULL
AND o.department_id = {$department_id}
@@ -249,7 +248,7 @@ class product_options_o extends db
{
/**
* Get the number of addons that could have been sold (maximum)
* Every order item that has the product_id as an option should be counted (number of orders with that order item)
* Every order item that has the product_id as an option should be counted (number of orders with that order item * the product_option max ?? 0)
* The order they were sold in must:
* - Be within the date range
* - Belong to the specified department
@@ -262,16 +261,29 @@ class product_options_o extends db
$date_start = date('Y-m-d H:i:s', strtotime($date_start));
$date_end = date('Y-m-d H:i:s', strtotime($date_end));
$department_id = (int)$department_id;
// Get all products that can have this addon
$applicable_products = $this->getOptionProducts($product_id);
if (empty($applicable_products)) {
return 0;
}
$applicable_product_ids = array_column($applicable_products, 'product_id');
$applicable_product_ids_str = implode(',', $applicable_product_ids);
// Build the query
$query = "
SELECT COUNT(oi.id) AS max_addons_count
SELECT SUM(oi.quantity / oi.quantity ) AS max_addons_count
FROM order_items oi
INNER JOIN orders o ON oi.order_id = o.id
WHERE oi.product_id = {$product_id}
INNER JOIN products_options po ON oi.product_id = po.product_id
WHERE oi.product_id IN ({$applicable_product_ids_str})
AND po.option_id = {$product_id}
AND oi.deleted_at IS NULL
AND o.department_id = {$department_id}
AND o.created_at BETWEEN '{$date_start}' AND '{$date_end}'
AND o.deleted_at IS NULL
";
return (int)$db->query($query)->fetch_object()->max_addons_count;
}
}