Complete port of all 163 API endpoints from Lucee/CFML to PHP 8.3. Shared helpers in api/helpers.php (DB, auth, request/response, security). PDO prepared statements throughout. Same JSON response shapes as CFML.
103 lines
3.1 KiB
PHP
103 lines
3.1 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../helpers.php';
|
|
runAuth();
|
|
|
|
global $businessId;
|
|
|
|
$data = readJsonBody();
|
|
|
|
if ($businessId <= 0) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'no_business_selected']);
|
|
}
|
|
|
|
$qBiz = queryOne("
|
|
SELECT ID, Name, BeaconShardID, BeaconMajor FROM Businesses WHERE ID = ? LIMIT 1
|
|
", [$businessId]);
|
|
|
|
if (!$qBiz) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'invalid_business', 'MESSAGE' => 'Business not found']);
|
|
}
|
|
|
|
$shardID = (int) ($qBiz['BeaconShardID'] ?? 0);
|
|
$major = (int) ($qBiz['BeaconMajor'] ?? 0);
|
|
|
|
// Auto-allocate shard if needed
|
|
if ($shardID <= 0) {
|
|
$qFreeShard = queryOne("
|
|
SELECT bs.ID FROM BeaconShards bs
|
|
WHERE bs.IsActive = 1
|
|
AND bs.ID NOT IN (SELECT BeaconShardID FROM Businesses WHERE BeaconShardID IS NOT NULL)
|
|
ORDER BY bs.ID LIMIT 1
|
|
", []);
|
|
|
|
if (!$qFreeShard) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'no_shards_available', 'MESSAGE' => 'No beacon shards available']);
|
|
}
|
|
|
|
$shardID = (int) $qFreeShard['ID'];
|
|
|
|
$qMaxMajor = queryOne("
|
|
SELECT COALESCE(MAX(BeaconMajor), 0) AS MaxMajor FROM Businesses WHERE BeaconShardID = ?
|
|
", [$shardID]);
|
|
$major = (int) $qMaxMajor['MaxMajor'] + 1;
|
|
|
|
queryTimed("UPDATE Businesses SET BeaconShardID = ?, BeaconMajor = ? WHERE ID = ?",
|
|
[$shardID, $major, $businessId]);
|
|
}
|
|
|
|
$qShard = queryOne("SELECT UUID FROM BeaconShards WHERE ID = ?", [$shardID]);
|
|
$shardUUID = $qShard['UUID'];
|
|
|
|
// Service point handling
|
|
$spName = trim($data['Name'] ?? '');
|
|
if ($spName === '') {
|
|
apiAbort(['OK' => false, 'ERROR' => 'missing_name', 'MESSAGE' => 'Service point name is required']);
|
|
}
|
|
|
|
$servicePointID = (int) ($data['ServicePointID'] ?? 0);
|
|
|
|
if ($servicePointID > 0) {
|
|
$qSP = queryOne("
|
|
SELECT ID, BeaconMinor FROM ServicePoints WHERE ID = ? AND BusinessID = ? LIMIT 1
|
|
", [$servicePointID, $businessId]);
|
|
|
|
if (!$qSP) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'invalid_service_point', 'MESSAGE' => 'Service point not found']);
|
|
}
|
|
|
|
$minor = $qSP['BeaconMinor'];
|
|
if ($minor === null) {
|
|
$qMaxMinor = queryOne("
|
|
SELECT COALESCE(MAX(BeaconMinor), 0) AS MaxMinor FROM ServicePoints WHERE BusinessID = ?
|
|
", [$businessId]);
|
|
$minor = (int) $qMaxMinor['MaxMinor'] + 1;
|
|
}
|
|
|
|
queryTimed("UPDATE ServicePoints SET Name = ?, BeaconMinor = ?, IsActive = 1 WHERE ID = ?",
|
|
[$spName, $minor, $servicePointID]);
|
|
} else {
|
|
$qMaxMinor = queryOne("
|
|
SELECT COALESCE(MAX(BeaconMinor), 0) AS MaxMinor FROM ServicePoints WHERE BusinessID = ?
|
|
", [$businessId]);
|
|
$minor = (int) $qMaxMinor['MaxMinor'] + 1;
|
|
|
|
queryTimed("
|
|
INSERT INTO ServicePoints (BusinessID, Name, TypeID, IsActive, BeaconMinor, SortOrder)
|
|
VALUES (?, ?, 1, 1, ?, ?)
|
|
", [$businessId, $spName, $minor, $minor]);
|
|
|
|
$servicePointID = (int) lastInsertId();
|
|
}
|
|
|
|
jsonResponse([
|
|
'OK' => true,
|
|
'ERROR' => '',
|
|
'ServicePointID' => $servicePointID,
|
|
'ServicePointName' => $spName,
|
|
'BusinessID' => $businessId,
|
|
'BusinessName' => $qBiz['Name'],
|
|
'ShardID' => $shardID,
|
|
'UUID' => $shardUUID,
|
|
'Major' => $major,
|
|
'Minor' => (int) $minor,
|
|
]);
|