function apiAbort(obj) { writeOutput(serializeJSON(obj)); abort; } function readJsonBody() { raw = toString(getHttpRequestData().content); if (isNull(raw) || len(trim(raw)) EQ 0) return {}; try { parsed = deserializeJSON(raw); } catch(any e) { apiAbort({ OK=false, ERROR="bad_json", MESSAGE="Invalid JSON body" }); } if (!isStruct(parsed)) return {}; return parsed; } function normStr(v) { if (isNull(v)) return ""; return trim(toString(v)); } function resolveSingleServicePoint(uuid, major, minor) { // First find the business by UUID + Major var qBiz = queryExecute( "SELECT b.ID AS BusinessID, b.Name AS BusinessName FROM Businesses b JOIN BeaconShards bs ON b.BeaconShardID = bs.ID WHERE bs.UUID = ? AND b.BeaconMajor = ? LIMIT 1", [ { value=uuid, cfsqltype="cf_sql_varchar" }, { value=major, cfsqltype="cf_sql_smallint" } ], { datasource="payfrit" } ); if (qBiz.recordCount EQ 0) { return { Found=false, Error="business_not_found" }; } // Then find the service point by BusinessID + Minor var qSP = queryExecute( "SELECT ID, Name, Code, TypeID, Description FROM ServicePoints WHERE BusinessID = ? AND BeaconMinor = ? AND IsActive = 1 LIMIT 1", [ { value=qBiz.BusinessID, cfsqltype="cf_sql_integer" }, { value=minor, cfsqltype="cf_sql_smallint" } ], { datasource="payfrit" } ); if (qSP.recordCount EQ 0) { return { Found = false, Error = "servicepoint_not_found", BusinessID = qBiz.BusinessID, BusinessName = qBiz.BusinessName }; } return { Found = true, ServicePointID = qSP.ID, ServicePointName = qSP.Name, ServicePointCode = qSP.Code, ServicePointTypeID = qSP.TypeID, ServicePointDescription = qSP.Description, BusinessID = qBiz.BusinessID, BusinessName = qBiz.BusinessName }; } data = readJsonBody(); // Check for batch request if (structKeyExists(data, "Beacons") && isArray(data.Beacons)) { results = []; for (beacon in data.Beacons) { uuid = normStr(structKeyExists(beacon, "UUID") ? beacon.UUID : ""); major = structKeyExists(beacon, "Major") && isNumeric(beacon.Major) ? int(beacon.Major) : 0; minor = structKeyExists(beacon, "Minor") && isNumeric(beacon.Minor) ? int(beacon.Minor) : -1; if (len(uuid) EQ 0 || major LTE 0 || minor LT 0) { arrayAppend(results, { UUID=uuid, Major=major, Minor=minor, ServicePointID=javaCast("null",""), Error="invalid_params" }); continue; } resolved = resolveSingleServicePoint(uuid, major, minor); if (resolved.Found) { arrayAppend(results, { UUID = uuid, Major = major, Minor = minor, ServicePointID = resolved.ServicePointID, ServicePointName = resolved.ServicePointName, ServicePointCode = resolved.ServicePointCode, BusinessID = resolved.BusinessID, BusinessName = resolved.BusinessName }); } else { var errResult = { UUID=uuid, Major=major, Minor=minor, ServicePointID=javaCast("null",""), Error=resolved.Error }; if (structKeyExists(resolved, "BusinessID")) { errResult.BusinessID = resolved.BusinessID; errResult.BusinessName = resolved.BusinessName; } arrayAppend(results, errResult); } } writeOutput(serializeJSON({ OK=true, COUNT=arrayLen(results), Results=results })); abort; } // Single request uuid = normStr(structKeyExists(data, "UUID") ? data.UUID : ""); major = 0; minor = -1; if (structKeyExists(data, "Major") && isNumeric(data.Major)) { major = int(data.Major); } if (structKeyExists(data, "Minor") && isNumeric(data.Minor)) { minor = int(data.Minor); } // Also check URL params if (len(uuid) EQ 0 && structKeyExists(url, "UUID")) { uuid = normStr(url.UUID); } if (major LTE 0 && structKeyExists(url, "Major") && isNumeric(url.Major)) { major = int(url.Major); } if (minor LT 0 && structKeyExists(url, "Minor") && isNumeric(url.Minor)) { minor = int(url.Minor); } if (len(uuid) EQ 0) { apiAbort({ OK=false, ERROR="missing_uuid", MESSAGE="UUID is required" }); } if (major LTE 0) { apiAbort({ OK=false, ERROR="missing_major", MESSAGE="Major is required" }); } if (minor LT 0) { apiAbort({ OK=false, ERROR="missing_minor", MESSAGE="Minor is required" }); } resolved = resolveSingleServicePoint(uuid, major, minor); if (!resolved.Found) { errResponse = { OK=false, ERROR=resolved.Error }; if (structKeyExists(resolved, "BusinessID")) { errResponse.BusinessID = resolved.BusinessID; errResponse.BusinessName = resolved.BusinessName; errResponse.MESSAGE = "Service point not found for this business"; } else { errResponse.MESSAGE = "No business found for this beacon"; } apiAbort(errResponse); } #serializeJSON({ OK = true, ServicePointID = resolved.ServicePointID, ServicePointName = resolved.ServicePointName, ServicePointCode = resolved.ServicePointCode, ServicePointTypeID = resolved.ServicePointTypeID, ServicePointDescription = resolved.ServicePointDescription, BusinessID = resolved.BusinessID, BusinessName = resolved.BusinessName })# #serializeJSON({ OK=false, ERROR="server_error", MESSAGE=cfcatch.message, DETAIL=cfcatch.detail })#