This repository has been archived on 2026-03-21. You can view files and clone it, but cannot push or open issues or pull requests.
payfrit-biz/api/beacons/getBusinessFromBeacon.cfm
John Mizerek 8acf2f3249 Complete DB column normalization: strip redundant table-name prefixes from all SQL queries
Updated 70 files to match the payfrit_dev schema where columns like
BusinessName→Name, UserFirstName→FirstName, AddressCity→City, etc.
PKs renamed to ID, FKs keep referenced table name (e.g. BusinessID).
SQL aliases preserve original JSON response keys for API compatibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 20:03:40 -08:00

165 lines
5.3 KiB
Text

<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8" reset="true">
<cfheader name="Cache-Control" value="no-store">
<cfscript>
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;
}
data = readJsonBody();
if (!structKeyExists(data, "BeaconID") || !isNumeric(data.BeaconID) || int(data.BeaconID) LTE 0) {
apiAbort({ OK=false, ERROR="missing_beacon_id", MESSAGE="BeaconID is required" });
}
beaconId = int(data.BeaconID);
</cfscript>
<!--- Get beacon info first --->
<cfquery name="qBeacon" datasource="payfrit">
SELECT ID, Name, UUID, BusinessID
FROM Beacons
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#">
AND IsActive = 1
LIMIT 1
</cfquery>
<cfif qBeacon.recordCount EQ 0>
<cfoutput>#serializeJSON({ OK=false, ERROR="not_found", MESSAGE="Beacon not found or inactive" })#</cfoutput>
<cfabort>
</cfif>
<!--- Get all businesses that have assignments to this beacon (via service points or join table) --->
<cfquery name="qAssignments" datasource="payfrit">
SELECT
sp.BusinessID AS BusinessID,
sp.ID AS ServicePointID,
biz.Name AS BusinessName,
biz.ParentBusinessID AS BusinessParentBusinessID,
sp.Name AS ServicePointName
FROM ServicePoints sp
INNER JOIN Businesses biz ON biz.ID = sp.BusinessID
WHERE sp.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#">
AND sp.IsActive = 1
UNION
SELECT
lt.BusinessID,
0 AS ServicePointID,
biz.Name AS BusinessName,
biz.ParentBusinessID AS BusinessParentBusinessID,
'' AS ServicePointName
FROM lt_BeaconsID_BusinessesID lt
INNER JOIN Businesses biz ON biz.ID = lt.BusinessID
WHERE lt.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#">
AND lt.BusinessID NOT IN (
SELECT sp2.BusinessID FROM ServicePoints sp2
WHERE sp2.BeaconID = <cfqueryparam cfsqltype="cf_sql_integer" value="#beaconId#"> AND sp2.IsActive = 1
)
ORDER BY BusinessParentBusinessID IS NULL DESC, BusinessName ASC
</cfquery>
<!--- Check if any assigned business is a parent (has children) --->
<cfset parentBusinessID = 0>
<cfloop query="qAssignments">
<!--- Check if this business has children --->
<cfquery name="qChildren" datasource="payfrit">
SELECT COUNT(*) as cnt FROM Businesses
WHERE ParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#qAssignments.BusinessID#">
</cfquery>
<cfif qChildren.cnt GT 0>
<cfset parentBusinessID = qAssignments.BusinessID>
<cfbreak>
</cfif>
</cfloop>
<!--- Build response with array of businesses --->
<cfset businesses = []>
<!--- If beacon is assigned to a parent, return the child businesses instead --->
<cfif parentBusinessID GT 0>
<!--- Get parent business info for header image --->
<cfquery name="qParent" datasource="payfrit">
SELECT Name AS BusinessName, HeaderImageExtension AS BusinessHeaderImageExtension
FROM Businesses
WHERE ID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
</cfquery>
<cfquery name="qChildBusinesses" datasource="payfrit">
SELECT
ID,
Name AS BusinessName,
ParentBusinessID AS BusinessParentBusinessID,
HeaderImageExtension AS BusinessHeaderImageExtension
FROM Businesses
WHERE ParentBusinessID = <cfqueryparam cfsqltype="cf_sql_integer" value="#parentBusinessID#">
ORDER BY Name ASC
</cfquery>
<cfloop query="qChildBusinesses">
<cfset arrayAppend(businesses, {
"BusinessID" = qChildBusinesses.ID,
"Name" = qChildBusinesses.BusinessName,
"ServicePointID" = qAssignments.ServicePointID,
"ServicePointName" = qAssignments.ServicePointName,
"IsParent" = false,
"ParentBusinessID" = parentBusinessID
})>
</cfloop>
<cfelse>
<!--- Normal case: return directly assigned businesses --->
<cfloop query="qAssignments">
<cfset arrayAppend(businesses, {
"BusinessID" = qAssignments.BusinessID,
"Name" = qAssignments.BusinessName,
"ServicePointID" = qAssignments.ServicePointID,
"ServicePointName" = qAssignments.ServicePointName,
"IsParent" = isNull(qAssignments.ParentBusinessID) OR qAssignments.ParentBusinessID EQ 0
})>
</cfloop>
</cfif>
<cfset response = {
"OK" = true,
"ERROR" = "",
"BEACON" = {
"BeaconID" = qBeacon.ID,
"Name" = qBeacon.Name,
"UUID" = qBeacon.UUID
},
"BUSINESSES" = businesses,
"BUSINESS" = arrayLen(businesses) GT 0 ? businesses[1] : {},
"SERVICEPOINT" = arrayLen(businesses) GT 0 ? {
"ServicePointID" = businesses[1].ServicePointID,
"Name" = businesses[1].ServicePointName,
"IsActive" = true
} : {}
}>
<!--- Add parent info if this is a parent-child scenario --->
<cfif parentBusinessID GT 0>
<cfset response["PARENT"] = {
"BusinessID" = parentBusinessID,
"Name" = qParent.BusinessName,
"HeaderImageExtension" = len(trim(qParent.BusinessHeaderImageExtension)) ? qParent.BusinessHeaderImageExtension : ""
}>
</cfif>
<cfscript>try{logPerf(0);}catch(any e){}</cfscript>
<cfoutput>#serializeJSON(response)#</cfoutput>