Enhance department goal criteria handling
- Refactored department daily targets logic for optimization and better maintainability. - Ensured department-specific targets are validated, sanitized, and consistently applied in updates. - Improved database interaction safety by preventing unnecessary updates for unchanged object properties. - Adjusted route and API behavior for criteria and department updates to handle validations comprehensively.
This commit is contained in:
@@ -81,7 +81,7 @@ class goals_criteria implements goals_criteria_i
|
||||
* Optional per-department custom daily targets (department_id => daily_target)
|
||||
* @var array<int,int>
|
||||
*/
|
||||
public array $department_daily_targets = [];
|
||||
public array $department_daily_targets;
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@@ -96,7 +96,6 @@ class goals_criteria implements goals_criteria_i
|
||||
$this->progress_alert_destination = goals_criteria_progress_alert_destination::NONE;
|
||||
$this->progress_alert_progress_type = goals_criteria_progress_alert_progress_type::NONE;
|
||||
$this->progress_alert_style = goals_criteria_progress_alert_style::NONE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -255,72 +254,23 @@ class goals_criteria implements goals_criteria_i
|
||||
|
||||
// Parse progress alert time of day (string with timezone)
|
||||
if (isset($data['progress_alert_time_of_day']) && is_string($data['progress_alert_time_of_day'])) {
|
||||
$criteria->progress_alert_time_of_day = trim((string)$data['progress_alert_time_of_day']);
|
||||
$criteria->progress_alert_time_of_day = trim($data['progress_alert_time_of_day']);
|
||||
} elseif (isset($data['progressAlertTimeOfDay']) && is_string($data['progressAlertTimeOfDay'])) {
|
||||
$criteria->progress_alert_time_of_day = trim((string)$data['progressAlertTimeOfDay']);
|
||||
$criteria->progress_alert_time_of_day = trim($data['progressAlertTimeOfDay']);
|
||||
}
|
||||
|
||||
// Parse department_daily_targets (assoc map or array of objects)
|
||||
if (isset($data['department_daily_targets'])) {
|
||||
$map = [];
|
||||
if (is_array($data['department_daily_targets'])) {
|
||||
$src = $data['department_daily_targets'];
|
||||
// Case A: assoc map { "12": 3, "15": 5 }
|
||||
$assocLike = array_keys($src) !== range(0, count($src) - 1);
|
||||
if ($assocLike) {
|
||||
foreach ($src as $k => $v) {
|
||||
if (is_numeric($k) && is_numeric($v)) {
|
||||
$dk = (int)$k; $dv = (int)$v;
|
||||
if ($dk > 0 && $dv >= 0) { $map[$dk] = $dv; }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Case B: list of objects [{id:12, daily_target:3}] or [{department_id:12, daily_target:3}]
|
||||
foreach ($src as $item) {
|
||||
if (!is_array($item) && !is_object($item)) { continue; }
|
||||
$arr = (array)$item;
|
||||
$dk = null;
|
||||
if (isset($arr['id']) && is_numeric($arr['id'])) { $dk = (int)$arr['id']; }
|
||||
elseif (isset($arr['department_id']) && is_numeric($arr['department_id'])) { $dk = (int)$arr['department_id']; }
|
||||
$dv = null;
|
||||
if (isset($arr['daily_target']) && is_numeric($arr['daily_target'])) { $dv = (int)$arr['daily_target']; }
|
||||
elseif (isset($arr['dailyTarget']) && is_numeric($arr['dailyTarget'])) { $dv = (int)$arr['dailyTarget']; }
|
||||
if ($dk !== null && $dk > 0 && $dv !== null && $dv >= 0) {
|
||||
$map[$dk] = $dv;
|
||||
}
|
||||
}
|
||||
// Parse department daily targets (expects object with department_id => target)
|
||||
if (isset($data['department_daily_targets']) && is_array($data['department_daily_targets'])) {
|
||||
$targets = [];
|
||||
foreach ($data['department_daily_targets'] as $deptId => $target) {
|
||||
if (is_numeric($deptId) && is_numeric($target)) {
|
||||
$id = (int)$deptId;
|
||||
$t = max(0, (int)$target);
|
||||
$targets[$id] = $t;
|
||||
}
|
||||
}
|
||||
$criteria->department_daily_targets = $map;
|
||||
} elseif (isset($data['departmentDailyTargets']) && is_array($data['departmentDailyTargets'])) {
|
||||
$map = [];
|
||||
$src = $data['departmentDailyTargets'];
|
||||
$assocLike = array_keys($src) !== range(0, count($src) - 1);
|
||||
if ($assocLike) {
|
||||
foreach ($src as $k => $v) {
|
||||
if (is_numeric($k) && is_numeric($v)) {
|
||||
$dk = (int)$k; $dv = (int)$v;
|
||||
if ($dk > 0 && $dv >= 0) { $map[$dk] = $dv; }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
foreach ($src as $item) {
|
||||
if (!is_array($item) && !is_object($item)) { continue; }
|
||||
$arr = (array)$item;
|
||||
$dk = null;
|
||||
if (isset($arr['id']) && is_numeric($arr['id'])) { $dk = (int)$arr['id']; }
|
||||
elseif (isset($arr['department_id']) && is_numeric($arr['department_id'])) { $dk = (int)$arr['department_id']; }
|
||||
$dv = null;
|
||||
if (isset($arr['daily_target']) && is_numeric($arr['daily_target'])) { $dv = (int)$arr['daily_target']; }
|
||||
elseif (isset($arr['dailyTarget']) && is_numeric($arr['dailyTarget'])) { $dv = (int)$arr['dailyTarget']; }
|
||||
if ($dk !== null && $dk > 0 && $dv !== null && $dv >= 0) {
|
||||
$map[$dk] = $dv;
|
||||
}
|
||||
}
|
||||
}
|
||||
$criteria->department_daily_targets = $map;
|
||||
$criteria->department_daily_targets = $targets;
|
||||
}
|
||||
|
||||
// Parse timeframe with validation
|
||||
if (isset($data['start']) && is_string($data['start'])) {
|
||||
try {
|
||||
@@ -478,20 +428,7 @@ class goals_criteria implements goals_criteria_i
|
||||
'progress_alert_format' => $this->progress_alert_format,
|
||||
'progress_alert_weekdays' => array_map(fn($e) => ($e instanceof goals_criteria_progress_alert_weekday) ? $e->name : (string)$e, $this->progress_alert_weekdays ?? []),
|
||||
'progress_alert_time_of_day' => $this->progress_alert_time_of_day,
|
||||
'department_daily_targets' => (function(){
|
||||
$map = [];
|
||||
if (is_array($this->department_daily_targets)) {
|
||||
// Only include targets for departments present in criteria
|
||||
$deptIds = $this->departments?->listIDs() ?? [];
|
||||
foreach ($this->department_daily_targets as $k => $v) {
|
||||
$dk = (int)$k; $dv = (int)$v;
|
||||
if (in_array($dk, $deptIds, true) && $dk > 0 && $dv >= 0) {
|
||||
$map[$dk] = $dv;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $map;
|
||||
})(),
|
||||
'department_daily_targets' => $this->department_daily_targets
|
||||
];
|
||||
}
|
||||
|
||||
@@ -589,13 +526,12 @@ class goals_criteria implements goals_criteria_i
|
||||
public function validateAndSanitize(): void
|
||||
{
|
||||
// Normalize custom daily targets map: ints and non-negative; filter to selected departments
|
||||
if (!is_array($this->department_daily_targets)) { $this->department_daily_targets = []; }
|
||||
$normalized = [];
|
||||
$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;
|
||||
if ($dk > 0 && $dv >= 0 && in_array($dk, $deptIds, true)) {
|
||||
if ($dk > 0 && $dv >= 0 && in_array($dk, $deptIds)) {
|
||||
$normalized[$dk] = $dv;
|
||||
}
|
||||
}
|
||||
@@ -708,6 +644,8 @@ class goals_criteria implements goals_criteria_i
|
||||
$this->progress_alert_time_of_day = null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->department_daily_targets = array_filter($this->department_daily_targets, fn($v) => is_numeric($v) && $v >= 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user