diff --git a/services/nginx/app/modules/goals/classes/goals_criteria.php b/services/nginx/app/modules/goals/classes/goals_criteria.php index 1cc8df6f..5ba46b1e 100644 --- a/services/nginx/app/modules/goals/classes/goals_criteria.php +++ b/services/nginx/app/modules/goals/classes/goals_criteria.php @@ -379,9 +379,12 @@ class goals_criteria implements goals_criteria_i /** * @throws \Exception */ - public static function calculateProgressFromArray(array $criteria_array): float + public static function calculateProgressFromArray(array $criteria_array, ?string $timeframe = null): float { $criteria = self::fromJson(json_encode($criteria_array)); + if ($timeframe) { + $criteria->setTimeframeByName($timeframe); + } return $criteria->getProgress(); } @@ -459,6 +462,25 @@ class goals_criteria implements goals_criteria_i }; } + public function setTimeframeByName(string $timeframe): void + { + $now = new \DateTime(); + switch ($timeframe) { + case 'today': + $this->start = (clone $now)->setTime(0, 0, 0); + $this->end = (clone $now)->setTime(23, 59, 59); + break; + case 'week': + $this->start = (clone $now)->modify('monday this week')->setTime(0, 0, 0); + $this->end = (clone $now)->setTime(23, 59, 59); + break; + case 'month': + $this->start = (clone $now)->modify('first day of this month')->setTime(0, 0, 0); + $this->end = (clone $now)->setTime(23, 59, 59); + break; + } + } + /** * Calculate revenue within the criteria filters. * Revenue is computed as sum(price * quantity) for matching order items. @@ -658,13 +680,58 @@ class goals_criteria implements goals_criteria_i foreach ($department_ids as $dept_id) { $dept_criteria = clone $this; $dept_criteria->departments->set([(new \objects\departments_o())->select($dept_id)]); - $results[$dept_id] = $dept_criteria->getProgress(); + $results[$dept_id] = [ + 'all' => $dept_criteria->getProgressDetails(null), + 'today' => $dept_criteria->getProgressDetails('today'), + 'week' => $dept_criteria->getProgressDetails('week'), + 'month' => $dept_criteria->getProgressDetails('month'), + ]; } // reset the departments to original $this->departments->set(array_map(fn($id) => (new \objects\departments_o())->select($id), $department_ids)); return $results; } + /** + * @throws \Exception + */ + public static function calculateProgressDetailsFromArray(array $criteria_array, ?string $timeframe = null): array + { + $criteria = self::fromJson(json_encode($criteria_array)); + return $criteria->getProgressDetails($timeframe); + } + + public function getProgressDetails(?string $timeframe = null): array + { + if ($timeframe) { + $this->setTimeframeByName($timeframe); + } + + $target = 0; + $active_dept_ids = $this->departments->listIDs(); + + if ($timeframe === 'today') { + foreach ($active_dept_ids as $id) { + $target += $this->department_daily_targets[$id] ?? 0; + } + } elseif ($timeframe === 'week') { + foreach ($active_dept_ids as $id) { + $target += ($this->department_daily_targets[$id] ?? 0) * 7; + } + } elseif ($timeframe === 'month') { + foreach ($active_dept_ids as $id) { + $target += ($this->department_daily_targets[$id] ?? 0) * 30; + } + } else { + $target = (int)$this->target; + } + + return [ + 'count' => $this->getProgress(), + 'target' => $target + ]; + } + public function withDepartmentFilter(int $department_id): goals_criteria { // Clone the criteria and create a fresh departments collection to avoid mutating the original diff --git a/services/nginx/app/objects/department_goals_o.php b/services/nginx/app/objects/department_goals_o.php index 71084519..40218561 100644 --- a/services/nginx/app/objects/department_goals_o.php +++ b/services/nginx/app/objects/department_goals_o.php @@ -85,13 +85,13 @@ class department_goals_o extends db 'departments' => (array)$this->departments->value(), 'criteria' => (array)$this->criteria->value(), 'progress' => [ - 'value' => $include_progress ? goals_criteria::calculateProgressFromArray((array)$this->criteria->value()) : null, + 'all' => $include_progress ? goals_criteria::calculateProgressDetailsFromArray((array)$this->criteria->value()) : null, 'departmental_distribution' => $include_progress ? goals_criteria::calculateDepartmentalProgressFromArray((array)$this->criteria->value()) : null, // array of department_id => [ 'all' => [ 'count' => int, 'target' => int ], 'today' => [ 'count' => int, 'target' => int ], 'week' => [ 'count' => int, 'target' => int ], 'month' => [ 'count' => int, 'target' => int ] ] // Showing progress for different time periods - 'today' => $include_progress ? goals_criteria::calculateProgressFromArray((array)$this->criteria->value(), 'today') : null, - 'week' => $include_progress ? goals_criteria::calculateProgressFromArray((array)$this->criteria->value(), 'week') : null, - 'month' => $include_progress ? goals_criteria::calculateProgressFromArray((array)$this->criteria->value(), 'month') : null, + 'today' => $include_progress ? goals_criteria::calculateProgressDetailsFromArray((array)$this->criteria->value(), 'today') : null, + 'week' => $include_progress ? goals_criteria::calculateProgressDetailsFromArray((array)$this->criteria->value(), 'week') : null, + 'month' => $include_progress ? goals_criteria::calculateProgressDetailsFromArray((array)$this->criteria->value(), 'month') : null, ], 'created_at' => (string)$this->created_at->value(), 'updated_at' => (string)$this->updated_at->value(),