Add departmentGoalsRoute for CRUD operations on department goals

- Implement route for listing department goals with optional pagination and single-goal retrieval.
- Add logic to create, update, and delete department goals with validation for input and permissions.
- Support department and criteria management via JSON parsing and object transformation.
This commit is contained in:
Jeppe Bundgaard
2026-01-26 17:18:01 +01:00
parent d1963b5299
commit 4a0e86164c
@@ -0,0 +1,161 @@
<?php
namespace routes;
use classes\authentication;
use classes\response;
use goals\classes\goals_criteria;
use objects\departments_o;
use objects\department_goals_o;
use traits\route_t;
class departmentGoalsRoute
{
use route_t;
public function run(): void
{
// List or get single department goal(s)
$this->get('/goals/department', function () {
global /** @var response $response */ $response;
$this->requirePermission('goals_department_list');
$goals = new department_goals_o();
// Single by id
if (self::isParametersSet(['id'])) {
$id = self::getParameter('id');
if (!is_numeric($id)) {
$response->error('id must be numeric', 400);
}
$goal = (new department_goals_o())->select((int)$id);
if (!$goal->exists()) {
$response->error('Goal not found', 404);
}
$response->success($goal->asArray());
}
// List with pagination if set (page, limit, search, filters, order supported by db_object_t)
$response->success(
$goals->listObjectsWithPaginationIfSet(
function ($row) {
return (new department_goals_o())->select((int)$row['id'])->asArray();
}
)
);
}, [
'goals_department_list' => 'List department goals or retrieve a single goal when id is provided'
]);
// Create a new department goal
$this->post('/goals/department', function () {
global /** @var response $response */ $response;
$this->requirePermission('goals_department_create');
// Authenticated user (creator)
$user = (new authentication())->get_user();
if (!$user) {
$response->error('Unauthorized', 401);
}
// Validate input
$this->requireParameters(['departments', 'criteria']);
$departmentsInput = self::getParameter('departments');
$criteriaInput = self::getParameter('criteria');
$this->requireType($departmentsInput, 'array');
$this->requireTypeIn($criteriaInput, ['array', 'object']);
// Build departments objects array
$departments = [];
foreach ($departmentsInput as $deptId) {
if (!is_numeric($deptId)) {
$response->error('All department ids must be numeric', 400);
}
$dept = (new departments_o())->select((int)$deptId);
if (!$dept->exists()) {
$response->error('Department not found: ' . $deptId, 404);
}
$departments[] = $dept;
}
// Parse criteria
$criteria = goals_criteria::fromJson(json_encode($criteriaInput));
// Create
$goal = (new department_goals_o())->add($user, $departments, $criteria);
$response->success($goal->asArray(), 201);
}, [
'goals_department_create' => 'Create a new department goal'
]);
// Update an existing department goal
$this->put('/goals/department', function () {
global /** @var response $response */ $response;
$this->requirePermission('goals_department_update');
$this->requireParameters(['id']);
$id = self::getParameter('id');
if (!is_numeric($id)) {
$response->error('id must be numeric', 400);
}
$goal = (new department_goals_o())->select((int)$id);
if (!$goal->exists()) {
$response->error('Goal not found', 404);
}
$dataToUpdate = [];
// Optional: departments
if ($response->isRequestParameterSet('departments')) {
$departmentsInput = self::getParameter('departments');
$this->requireType($departmentsInput, 'array');
foreach ($departmentsInput as $deptId) {
if (!is_numeric($deptId)) {
$response->error('All department ids must be numeric', 400);
}
}
// store as ids array in column
$dataToUpdate['departments'] = array_map('intval', $departmentsInput);
}
// Optional: criteria
if ($response->isRequestParameterSet('criteria')) {
$criteriaInput = self::getParameter('criteria');
$this->requireTypeIn($criteriaInput, ['array', 'object']);
$criteria = goals_criteria::fromJson(json_encode($criteriaInput));
$dataToUpdate['criteria'] = $criteria->toArray();
}
if (empty($dataToUpdate)) {
$response->error('No updatable fields provided. Allowed: departments, criteria', 400);
}
$goal->update($dataToUpdate);
$response->success($goal->asArray());
}, [
'goals_department_update' => 'Update an existing department goal'
]);
// Delete a department goal (soft delete if supported)
$this->delete('/goals/department', function () {
global /** @var response $response */ $response;
$this->requirePermission('goals_department_delete');
$this->requireParameters(['id']);
$id = self::getParameter('id');
if (!is_numeric($id)) {
$response->error('id must be numeric', 400);
}
$goal = (new department_goals_o())->select((int)$id);
if (!$goal->exists()) {
$response->error('Goal not found', 404);
}
$goal->delete();
$response->success(['message' => 'Deleted']);
}, [
'goals_department_delete' => 'Delete a department goal (soft delete when supported)'
]);
}
}