From 88f4f34c34bf983a7975870c262d351bf6de1ec5 Mon Sep 17 00:00:00 2001 From: Jeppe Bundgaard Date: Wed, 25 Feb 2026 14:40:26 +0100 Subject: [PATCH] Update department daily targets to support floats - Refactored `department_daily_targets` logic to accept and process float values instead of integers. - Adjusted relevant type declarations, validations, and calculations in `GoalsCriteria`. - Updated OpenAPI schema to align with new data type for per-department daily targets. --- openapi.yaml | 37 +++++++++++++++---- .../modules/goals/classes/goals_criteria.php | 16 ++++---- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/openapi.yaml b/openapi.yaml index d1b36a7b..8ee5059e 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -8390,11 +8390,12 @@ components: department_daily_targets: type: object description: | - Optional per-department custom daily targets. Keys are department IDs and values are non-negative integers representing the target per operating day for that department. + Optional per-department custom daily targets. Keys are department IDs and values are non-negative numbers representing the target per operating day for that department. If omitted, the daily target is split evenly across selected departments. The canonical field name is snake_case `department_daily_targets`. For backward-compatibility the API also accepts camelCase `departmentDailyTargets` on input. + x-additionalPropertiesName: department_id additionalProperties: - type: integer + type: number minimum: 0 example: "12": 3 @@ -8410,6 +8411,20 @@ components: type: number description: Target value for the period + DepartmentGoalProgress: + type: object + title: Department progress details + description: Goal progress details for a single department across multiple timeframes + properties: + all: + $ref: '#/components/schemas/GoalProgressDetails' + today: + $ref: '#/components/schemas/GoalProgressDetails' + week: + $ref: '#/components/schemas/GoalProgressDetails' + month: + $ref: '#/components/schemas/GoalProgressDetails' + DepartmentGoal: type: object properties: @@ -8438,17 +8453,23 @@ components: departmental_distribution: type: object description: Progress details broken down by department. Keys are department IDs. + x-additionalPropertiesName: department_id additionalProperties: - type: object - properties: + $ref: '#/components/schemas/DepartmentGoalProgress' + example: + "12": all: - $ref: '#/components/schemas/GoalProgressDetails' + count: 15 + target: 100 today: - $ref: '#/components/schemas/GoalProgressDetails' + count: 2 + target: 5 week: - $ref: '#/components/schemas/GoalProgressDetails' + count: 10 + target: 35 month: - $ref: '#/components/schemas/GoalProgressDetails' + count: 15 + target: 100 created_at: type: string description: Creation timestamp diff --git a/services/nginx/app/modules/goals/classes/goals_criteria.php b/services/nginx/app/modules/goals/classes/goals_criteria.php index 5ba46b1e..6bfdfde0 100644 --- a/services/nginx/app/modules/goals/classes/goals_criteria.php +++ b/services/nginx/app/modules/goals/classes/goals_criteria.php @@ -79,7 +79,7 @@ class goals_criteria implements goals_criteria_i public ?string $progress_alert_time_of_day = null; /** * Optional per-department custom daily targets (department_id => daily_target) - * @var array + * @var array */ public array $department_daily_targets; /** @@ -265,7 +265,7 @@ class goals_criteria implements goals_criteria_i foreach ($data['department_daily_targets'] as $deptId => $target) { if (is_numeric($deptId) && is_numeric($target)) { $id = (int)$deptId; - $t = max(0, (int)$target); + $t = max(0.0, (float)$target); $targets[$id] = $t; } } @@ -552,7 +552,7 @@ class goals_criteria implements goals_criteria_i $deptIds = $this->departments?->listIDs() ?? []; foreach ($this->department_daily_targets as $k => $v) { if (!is_numeric($k) || !is_numeric($v)) { continue; } - $dk = (int)$k; $dv = (int)$v; + $dk = (int)$k; $dv = (float)$v; if ($dk > 0 && $dv >= 0 && in_array($dk, $deptIds)) { $normalized[$dk] = $dv; } @@ -707,23 +707,23 @@ class goals_criteria implements goals_criteria_i $this->setTimeframeByName($timeframe); } - $target = 0; + $target = 0.0; $active_dept_ids = $this->departments->listIDs(); if ($timeframe === 'today') { foreach ($active_dept_ids as $id) { - $target += $this->department_daily_targets[$id] ?? 0; + $target += (float)($this->department_daily_targets[$id] ?? 0); } } elseif ($timeframe === 'week') { foreach ($active_dept_ids as $id) { - $target += ($this->department_daily_targets[$id] ?? 0) * 7; + $target += (float)($this->department_daily_targets[$id] ?? 0) * 7; } } elseif ($timeframe === 'month') { foreach ($active_dept_ids as $id) { - $target += ($this->department_daily_targets[$id] ?? 0) * 30; + $target += (float)($this->department_daily_targets[$id] ?? 0) * 30; } } else { - $target = (int)$this->target; + $target = (float)$this->target; } return [