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.
124 lines
4.4 KiB
PHP
124 lines
4.4 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../helpers.php';
|
|
runAuth();
|
|
|
|
require_once __DIR__ . '/_grantUtils.php';
|
|
|
|
global $userId;
|
|
|
|
$data = readJsonBody();
|
|
$ownerBusinessID = (int) ($data['OwnerBusinessID'] ?? 0);
|
|
$guestBusinessID = (int) ($data['GuestBusinessID'] ?? 0);
|
|
$servicePointID = (int) ($data['ServicePointID'] ?? 0);
|
|
$economicsType = trim($data['EconomicsType'] ?? 'none');
|
|
$economicsValue = (float) ($data['EconomicsValue'] ?? 0);
|
|
$eligibilityScope = trim($data['EligibilityScope'] ?? 'public');
|
|
$timePolicyType = trim($data['TimePolicyType'] ?? 'always');
|
|
$timePolicyData = $data['TimePolicyData'] ?? '';
|
|
|
|
if ($ownerBusinessID <= 0 || $guestBusinessID <= 0 || $servicePointID <= 0) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'missing_params', 'MESSAGE' => 'OwnerBusinessID, GuestBusinessID, and ServicePointID are required.']);
|
|
}
|
|
|
|
if ($ownerBusinessID === $guestBusinessID) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'self_grant', 'MESSAGE' => 'Cannot grant access to your own business.']);
|
|
}
|
|
|
|
if ($userId <= 0) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'not_authenticated', 'MESSAGE' => 'Authentication required.']);
|
|
}
|
|
|
|
// Validate caller is the owner of OwnerBusinessID
|
|
$qOwner = queryOne("SELECT UserID FROM Businesses WHERE ID = ? LIMIT 1", [$ownerBusinessID]);
|
|
if (!$qOwner || (int) $qOwner['UserID'] !== $userId) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'not_owner', 'MESSAGE' => 'You are not the owner of this business.']);
|
|
}
|
|
|
|
// Validate ServicePoint belongs to OwnerBusinessID
|
|
$qSP = queryOne(
|
|
"SELECT ID FROM ServicePoints WHERE ID = ? AND BusinessID = ? LIMIT 1",
|
|
[$servicePointID, $ownerBusinessID]
|
|
);
|
|
if (!$qSP) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'sp_not_owned', 'MESSAGE' => 'Service point does not belong to your business.']);
|
|
}
|
|
|
|
// Validate GuestBusiness exists
|
|
$qGuest = queryOne("SELECT ID FROM Businesses WHERE ID = ? LIMIT 1", [$guestBusinessID]);
|
|
if (!$qGuest) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'guest_not_found', 'MESSAGE' => 'Guest business not found.']);
|
|
}
|
|
|
|
// Check no active or pending grant exists for this combo
|
|
$qExisting = queryOne(
|
|
"SELECT ID FROM ServicePointGrants
|
|
WHERE OwnerBusinessID = ? AND GuestBusinessID = ? AND ServicePointID = ? AND StatusID IN (0, 1)
|
|
LIMIT 1",
|
|
[$ownerBusinessID, $guestBusinessID, $servicePointID]
|
|
);
|
|
if ($qExisting) {
|
|
apiAbort(['OK' => false, 'ERROR' => 'grant_exists', 'MESSAGE' => 'An active or pending grant already exists for this service point and guest business.']);
|
|
}
|
|
|
|
// Validate enum values
|
|
$validEconomics = ['none', 'flat_fee', 'percent_of_orders'];
|
|
$validEligibility = ['public', 'employees', 'guests', 'internal'];
|
|
$validTimePolicy = ['always', 'schedule', 'date_range', 'event'];
|
|
|
|
if (!in_array($economicsType, $validEconomics)) $economicsType = 'none';
|
|
if (!in_array($eligibilityScope, $validEligibility)) $eligibilityScope = 'public';
|
|
if (!in_array($timePolicyType, $validTimePolicy)) $timePolicyType = 'always';
|
|
|
|
// Generate UUID and InviteToken
|
|
$newUUID = generateUUID();
|
|
$inviteToken = generateSecureToken();
|
|
|
|
// Serialize TimePolicyData
|
|
$timePolicyJson = null;
|
|
if (is_array($timePolicyData) && !empty($timePolicyData)) {
|
|
$timePolicyJson = json_encode($timePolicyData);
|
|
} elseif (is_string($timePolicyData) && trim($timePolicyData) !== '') {
|
|
$timePolicyJson = $timePolicyData;
|
|
}
|
|
|
|
// Insert grant
|
|
queryTimed(
|
|
"INSERT INTO ServicePointGrants
|
|
(UUID, OwnerBusinessID, GuestBusinessID, ServicePointID, StatusID,
|
|
EconomicsType, EconomicsValue, EligibilityScope, TimePolicyType, TimePolicyData,
|
|
InviteToken, CreatedByUserID)
|
|
VALUES (?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?, ?)",
|
|
[
|
|
$newUUID, $ownerBusinessID, $guestBusinessID, $servicePointID,
|
|
$economicsType, $economicsValue, $eligibilityScope, $timePolicyType, $timePolicyJson,
|
|
$inviteToken, $userId,
|
|
]
|
|
);
|
|
|
|
$grantID = (int) lastInsertId();
|
|
|
|
recordGrantHistory(
|
|
$grantID,
|
|
'created',
|
|
$userId,
|
|
$ownerBusinessID,
|
|
[],
|
|
[
|
|
'OwnerBusinessID' => $ownerBusinessID,
|
|
'GuestBusinessID' => $guestBusinessID,
|
|
'ServicePointID' => $servicePointID,
|
|
'EconomicsType' => $economicsType,
|
|
'EconomicsValue' => $economicsValue,
|
|
'EligibilityScope' => $eligibilityScope,
|
|
'TimePolicyType' => $timePolicyType,
|
|
]
|
|
);
|
|
|
|
jsonResponse([
|
|
'OK' => true,
|
|
'GrantID' => $grantID,
|
|
'UUID' => $newUUID,
|
|
'InviteToken' => $inviteToken,
|
|
'StatusID' => 0,
|
|
'MESSAGE' => 'Grant created. Awaiting guest acceptance.',
|
|
]);
|