false, 'ERROR' => 'missing_params', 'MESSAGE' => 'BusinessID is required']); } try { $taskTypeName = trim($data['TaskTypeName'] ?? ''); if (empty($taskTypeName)) { apiAbort(['OK' => false, 'ERROR' => 'missing_params', 'MESSAGE' => 'TaskTypeName is required']); } if (strlen($taskTypeName) > 45) { apiAbort(['OK' => false, 'ERROR' => 'invalid_params', 'MESSAGE' => 'TaskTypeName must be 45 characters or less']); } $taskTypeDescription = trim($data['TaskTypeDescription'] ?? ''); if (strlen($taskTypeDescription) > 100) { apiAbort(['OK' => false, 'ERROR' => 'invalid_params', 'MESSAGE' => 'TaskTypeDescription must be 100 characters or less']); } $taskTypeIcon = trim($data['TaskTypeIcon'] ?? '') ?: 'notifications'; if (strlen($taskTypeIcon) > 30) { apiAbort(['OK' => false, 'ERROR' => 'invalid_params', 'MESSAGE' => 'TaskTypeIcon must be 30 characters or less']); } $taskTypeColor = trim($data['TaskTypeColor'] ?? '') ?: '#9C27B0'; if ($taskTypeColor[0] !== '#') { $taskTypeColor = '#' . $taskTypeColor; } if (strlen($taskTypeColor) > 7) { apiAbort(['OK' => false, 'ERROR' => 'invalid_params', 'MESSAGE' => 'TaskTypeColor must be a valid hex color']); } $requiresServicePoint = 1; if (isset($data['RequiresServicePoint'])) { $requiresServicePoint = $data['RequiresServicePoint'] ? 1 : 0; } $categoryID = null; if (isset($data['TaskTypeCategoryID']) && is_numeric($data['TaskTypeCategoryID']) && (int) $data['TaskTypeCategoryID'] > 0) { $categoryID = (int) $data['TaskTypeCategoryID']; } elseif (isset($data['CategoryID']) && is_numeric($data['CategoryID']) && (int) $data['CategoryID'] > 0) { $categoryID = (int) $data['CategoryID']; } $taskTypeID = (int) ($data['TaskTypeID'] ?? 0); if ($taskTypeID > 0) { // UPDATE $qCheck = queryOne(" SELECT ID FROM tt_TaskTypes WHERE ID = ? AND BusinessID = ? ", [$taskTypeID, $businessID]); if (!$qCheck) { apiAbort(['OK' => false, 'ERROR' => 'not_found', 'MESSAGE' => 'Task type not found or does not belong to this business']); } queryTimed(" UPDATE tt_TaskTypes SET Name = ?, Description = ?, Icon = ?, Color = ?, RequiresServicePoint = ?, TaskCategoryID = ? WHERE ID = ? ", [ $taskTypeName, !empty($taskTypeDescription) ? $taskTypeDescription : null, $taskTypeIcon, $taskTypeColor, $requiresServicePoint, $categoryID, $taskTypeID, ]); jsonResponse(['OK' => true, 'TASK_TYPE_ID' => $taskTypeID, 'MESSAGE' => 'Task type updated']); } else { // INSERT queryTimed(" INSERT INTO tt_TaskTypes (Name, Description, Icon, Color, RequiresServicePoint, BusinessID, TaskCategoryID) VALUES (?, ?, ?, ?, ?, ?, ?) ", [ $taskTypeName, !empty($taskTypeDescription) ? $taskTypeDescription : null, $taskTypeIcon, $taskTypeColor, $requiresServicePoint, $businessID, $categoryID, ]); $newID = (int) lastInsertId(); jsonResponse(['OK' => true, 'TASK_TYPE_ID' => $newID, 'MESSAGE' => 'Task type created']); } } catch (Exception $e) { jsonResponse(['OK' => false, 'ERROR' => 'server_error', 'MESSAGE' => $e->getMessage()]); }