Add time-based progress tracking and department-specific target calculations
- Added support for `today`, `week`, and `month` progress tracking in `GoalsCriteria`. - Introduced `setTimeframeByName` method to manage time-based progress criteria. - Enhanced `calculateProgressFromArray` and `calculateProgressDetailsFromArray` to include customizable timeframes. - Updated departmental progress calculations with detailed breakdowns for multiple time periods. - Replaced obsolete single-value progress tracking with comprehensive progress details.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user