Clarify self-serve entity relationships and naming intent
This commit is contained in:
@@ -11,10 +11,18 @@ class department_selfserve_conditions_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
|
||||
/**
|
||||
* Canonical relationship model:
|
||||
* - A condition is a reusable logical node.
|
||||
* - `condition_id` on this entity is a parent condition id, enabling nested condition trees.
|
||||
* - Questions may reference a condition as their gate.
|
||||
* - Tasks may reference a question as their gate (legacy stored in tasks.condition_id).
|
||||
*/
|
||||
|
||||
public object_property $department; // The department id
|
||||
public object_property $lane; // The lane id
|
||||
public object_property $product; // The product id
|
||||
public object_property $condition_id; // The condition id (optional)
|
||||
public object_property $condition_id; // Parent condition id for nesting/grouping (nullable)
|
||||
public object_property $name; // The condition name
|
||||
public object_property $description; // The task description
|
||||
public object_property $created_at;
|
||||
@@ -34,7 +42,7 @@ class department_selfserve_conditions_o extends db
|
||||
* @param int $product The product id
|
||||
* @param string $name The condition name
|
||||
* @param string $description The condition description
|
||||
* @param int|null $condition_id The condition id (optional)
|
||||
* @param int|null $condition_id Optional parent condition id for nesting/grouping.
|
||||
* @return department_selfserve_conditions_o
|
||||
* @throws Exception If the object was not created successfully
|
||||
*/
|
||||
@@ -102,4 +110,4 @@ class department_selfserve_conditions_o extends db
|
||||
'updated_at' => (string)$this->updated_at->value(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,14 @@ class department_selfserve_questions_o extends db
|
||||
public object_property $department; // The department id
|
||||
public object_property $lane; // The lane id
|
||||
public object_property $product; // The product id
|
||||
public object_property $condition_id; // The question condition object id (if applicable)
|
||||
/**
|
||||
* Canonical relationship model:
|
||||
* - Question `condition_id` references `department_selfserve_conditions.id` and means
|
||||
* "show/ask this question only when this parent condition is met".
|
||||
* - Tasks are linked to questions (not conditions); tasks use adapter methods in tasks object
|
||||
* while persisting to legacy `department_selfserve_tasks.condition_id`.
|
||||
*/
|
||||
public object_property $condition_id; // Parent condition id that gates this question (nullable)
|
||||
public object_property $question; // The question text
|
||||
public object_property $description; // The question description
|
||||
public object_property $order_priority; // The order priority of the question (lower numbers are shown first)
|
||||
@@ -37,7 +44,7 @@ class department_selfserve_questions_o extends db
|
||||
* @param int $product The product id
|
||||
* @param string $question The question text
|
||||
* @param string $description The question description
|
||||
* @param int|null $condition_id The question condition_id (if applicable)
|
||||
* @param int|null $condition_id Optional parent condition id that gates this question.
|
||||
* @param int $order_priority The order priority of the question (lower numbers are shown first)
|
||||
* @return department_selfserve_questions_o
|
||||
* @throws Exception If the object was not created successfully
|
||||
@@ -96,6 +103,8 @@ class department_selfserve_questions_o extends db
|
||||
self::requireSelected();
|
||||
global $db;
|
||||
$id = (int)$this->id;
|
||||
// Deleting a question detaches dependent tasks by clearing the legacy
|
||||
// `department_selfserve_tasks.condition_id` link (which semantically stores question id).
|
||||
$sql = "UPDATE department_selfserve_tasks SET condition_id = NULL WHERE condition_id = $id";
|
||||
$db->query($sql);
|
||||
$this->trait_delete();
|
||||
@@ -117,4 +126,4 @@ class department_selfserve_questions_o extends db
|
||||
'updated_at' => (string)$this->updated_at->value(),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,18 @@ class department_selfserve_tasks_o extends db
|
||||
{
|
||||
use db_object_t;
|
||||
|
||||
/**
|
||||
* Canonical relationship model for self-serve entities:
|
||||
* - Conditions can be nested via `department_selfserve_conditions.condition_id` (parent condition id).
|
||||
* - Questions can optionally be gated by a condition via `department_selfserve_questions.condition_id` (parent condition id).
|
||||
* - Tasks can optionally be gated by a question. For backward compatibility this is stored in
|
||||
* `department_selfserve_tasks.condition_id`, but semantically this is a question reference.
|
||||
*/
|
||||
|
||||
public object_property $department; // The department id
|
||||
public object_property $lane; // The lane id
|
||||
public object_property $product; // The product id
|
||||
public object_property $condition_id; // The question id (if conditional task)
|
||||
public object_property $condition_id; // Legacy column name: stores question id that gates this task (nullable)
|
||||
public object_property $task; // The task
|
||||
public object_property $description; // The task description
|
||||
public object_property $order_priority; // The order priority of the task (lower numbers are shown first)
|
||||
@@ -54,7 +62,7 @@ class department_selfserve_tasks_o extends db
|
||||
* @param int $department The department id
|
||||
* @param int $lane The lane id
|
||||
* @param int $product The product id
|
||||
* @param int|null $condition_id The question id (if conditional task)
|
||||
* @param int|null $question_id Optional question id that gates this task. Persisted in legacy `condition_id` column.
|
||||
* @param string $task The task text
|
||||
* @param string $description The task description
|
||||
* @param int $order_priority The order priority of the task (lower numbers are shown first)
|
||||
@@ -64,7 +72,7 @@ class department_selfserve_tasks_o extends db
|
||||
* @return department_selfserve_tasks_o
|
||||
* @throws Exception If the object was not created successfully
|
||||
*/
|
||||
public function add(int $department, int $lane, int $product, int|null $condition_id, string $task, string $description, int $order_priority = 0, ?array $services = null, array|string|null $buttons = null, int|null $dynamic_images_vehicle_type = null): self
|
||||
public function add(int $department, int $lane, int $product, int|null $question_id, string $task, string $description, int $order_priority = 0, ?array $services = null, array|string|null $buttons = null, int|null $dynamic_images_vehicle_type = null): self
|
||||
{
|
||||
global /** @var db $db */
|
||||
$db;
|
||||
@@ -72,8 +80,8 @@ class department_selfserve_tasks_o extends db
|
||||
$department = (int)$department;
|
||||
$lane = (int)$lane;
|
||||
$product = (int)$product;
|
||||
if (!is_null($condition_id)) {
|
||||
$condition_id = (int)$condition_id;
|
||||
if (!is_null($question_id)) {
|
||||
$question_id = (int)$question_id;
|
||||
}
|
||||
$task = $db->escape_string($task);
|
||||
$description = $db->escape_string($description);
|
||||
@@ -124,7 +132,7 @@ class department_selfserve_tasks_o extends db
|
||||
'department' => $department,
|
||||
'lane' => $lane,
|
||||
'product' => $product,
|
||||
...(!is_null($condition_id) ? ['condition_id' => $condition_id] : []), // If the question is null, it will be set to null in the database
|
||||
...(!is_null($question_id) ? ['condition_id' => $question_id] : []), // Legacy column name; contains the gating question id
|
||||
'task' => $task,
|
||||
'description' => $description,
|
||||
'order_priority' => $order_priority,
|
||||
@@ -181,6 +189,26 @@ class department_selfserve_tasks_o extends db
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter for canonical naming.
|
||||
* @return int|null Question id that gates this task.
|
||||
*/
|
||||
public function getQuestionId(): ?int
|
||||
{
|
||||
$value = $this->condition_id->value();
|
||||
return is_null($value) ? null : (int)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adapter for canonical naming while persisting to legacy `condition_id` column.
|
||||
* @param int|null $question_id
|
||||
* @return void
|
||||
*/
|
||||
public function setQuestionId(?int $question_id): void
|
||||
{
|
||||
$this->condition_id->set(is_null($question_id) ? null : (int)$question_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize input for dynamic_images_vehicle_type into a nullable non-negative integer.
|
||||
* Accepts int, string (numeric), null, or empty string (treated as null).
|
||||
@@ -259,4 +287,4 @@ class department_selfserve_tasks_o extends db
|
||||
$ids = array_values(array_unique($ids));
|
||||
return $ids;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,13 +98,13 @@ class departmentSelfserveConditionsRoute
|
||||
$department = (int)$response->getRequestParameter('department');
|
||||
$lane = (int)$response->getRequestParameter('lane');
|
||||
$product = (int)$response->getRequestParameter('product');
|
||||
$condition_id = $response->getRequestParameter('condition_id');
|
||||
$condition_id = $response->getRequestParameter('condition_id'); // parent condition id for nested condition trees
|
||||
$condition_id = is_null($condition_id) || $condition_id === 'null' ? null : (int)$condition_id;
|
||||
$name = (string)$response->getRequestParameter('name');
|
||||
$description = (string)$response->getRequestParameter('description');
|
||||
|
||||
if (!$department || !$lane || !$product || !$name || !$description) {
|
||||
$response->error('Missing required fields', 400);
|
||||
$response->error('Missing required fields: department, lane, product, name, and description', 400);
|
||||
}
|
||||
|
||||
$authorized_department_ids = $user->getGroup()->getDepartments();
|
||||
@@ -143,7 +143,7 @@ class departmentSelfserveConditionsRoute
|
||||
if ($user) {
|
||||
$id = (int)$response->getRequestParameter('id');
|
||||
if (!$id) {
|
||||
$response->error('Missing required fields', 400);
|
||||
$response->error('Missing required fields: id', 400);
|
||||
}
|
||||
|
||||
$condition_o = new department_selfserve_conditions_o();
|
||||
@@ -171,7 +171,7 @@ class departmentSelfserveConditionsRoute
|
||||
$condition_o->product->update((int)$response->getRequestParameter('product'));
|
||||
}
|
||||
if ($response->isRequestParameterSet('condition_id')) {
|
||||
$condition_id = $response->getRequestParameter('condition_id');
|
||||
$condition_id = $response->getRequestParameter('condition_id'); // parent condition id for nested condition trees
|
||||
$condition_o->condition_id->update(is_null($condition_id) || $condition_id === 'null' ? null : (int)$condition_id);
|
||||
}
|
||||
if ($response->isRequestParameterSet('name')) {
|
||||
@@ -200,7 +200,7 @@ class departmentSelfserveConditionsRoute
|
||||
if ($user) {
|
||||
$id = (int)$response->getRequestParameter('id');
|
||||
if (!$id) {
|
||||
$response->error('Missing required fields', 400);
|
||||
$response->error('Missing required fields: id', 400);
|
||||
}
|
||||
|
||||
$condition_o = new department_selfserve_conditions_o();
|
||||
|
||||
@@ -100,11 +100,11 @@ class departmentSelfserveQuestionsRoute
|
||||
$product = (int)$response->getRequestParameter('product');
|
||||
$question = (string)$response->getRequestParameter('question');
|
||||
$description = (string)$response->getRequestParameter('description');
|
||||
$condition_id = $response->isRequestParameterSet('condition_id') ? (int)$response->getRequestParameter('condition_id') : null;
|
||||
$condition_id = $response->isRequestParameterSet('condition_id') ? (int)$response->getRequestParameter('condition_id') : null; // parent condition id that gates this question
|
||||
$order_priority = (int)($response->getRequestParameter('order_priority') ?? 0);
|
||||
|
||||
if (!$department || !$lane || !$product || !$question || !$description) {
|
||||
$response->error('Missing required fields', 400);
|
||||
$response->error('Missing required fields: department, lane, product, question, and description', 400);
|
||||
}
|
||||
|
||||
$authorized_department_ids = $user->getGroup()->getDepartments();
|
||||
|
||||
@@ -106,7 +106,7 @@ class departmentSelfserveTasksRoute
|
||||
$department = (int)$response->getRequestParameter('department');
|
||||
$lane = (int)$response->getRequestParameter('lane');
|
||||
$product = (int)$response->getRequestParameter('product');
|
||||
$condition_id = $response->isRequestParameterSet('condition_id') ? (int)$response->getRequestParameter('condition_id') : null;
|
||||
$question_id = $response->isRequestParameterSet('condition_id') ? (int)$response->getRequestParameter('condition_id') : null; // legacy request field: condition_id
|
||||
$task = (string)$response->getRequestParameter('task');
|
||||
$description = (string)$response->getRequestParameter('description');
|
||||
$order_priority = (int)($response->getRequestParameter('order_priority') ?? 0);
|
||||
@@ -168,7 +168,7 @@ class departmentSelfserveTasksRoute
|
||||
}
|
||||
|
||||
if (!$department || !$lane || !$product || !$task || !$description) {
|
||||
$response->error('Missing required fields', 400);
|
||||
$response->error('Missing required fields: department, lane, product, task, and description', 400);
|
||||
}
|
||||
|
||||
$authorized_department_ids = $user->getGroup()->getDepartments();
|
||||
@@ -181,7 +181,7 @@ class departmentSelfserveTasksRoute
|
||||
$department,
|
||||
$lane,
|
||||
$product,
|
||||
$condition_id,
|
||||
$question_id,
|
||||
$task,
|
||||
$description,
|
||||
$order_priority,
|
||||
@@ -237,7 +237,7 @@ class departmentSelfserveTasksRoute
|
||||
$task_o->product->set((int)self::getParameter('product'));
|
||||
}
|
||||
if (self::isParametersSet(['condition_id'])) {
|
||||
$task_o->condition_id->set(self::getParameter('condition_id') === null ? null : (int)self::getParameter('condition_id'));
|
||||
$task_o->setQuestionId(self::getParameter('condition_id') === null ? null : (int)self::getParameter('condition_id'));
|
||||
}
|
||||
if (self::isParametersSet(['task'])) {
|
||||
$task_o->task->set((string)self::getParameter('task'));
|
||||
|
||||
Reference in New Issue
Block a user