Filter out demo and hidden businesses from restaurant list

Businesses with BusinessIsDemo=1 or BusinessIsHidden=1 will not appear
in the nearby restaurants list. Hidden businesses will be searchable
in a future update.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John Mizerek 2026-01-23 12:14:45 -08:00
parent 3b7225e57f
commit 72f5b7eb12

View file

@ -10,33 +10,97 @@ function apiAbort(payload) {
abort; abort;
} }
// Read JSON body for user location
function readJsonBody() {
var raw = getHttpRequestData().content;
if (isNull(raw) OR len(trim(raw)) EQ 0) return {};
try {
var data = deserializeJSON(raw);
if (isStruct(data)) return data;
return {};
} catch (any e) {
return {};
}
}
// Haversine formula to calculate distance in miles
function haversineDistance(lat1, lng1, lat2, lng2) {
var R = 3959; // Earth radius in miles
var dLat = (lat2 - lat1) * 3.14159265359 / 180;
var dLng = (lng2 - lng1) * 3.14159265359 / 180;
var a = sin(dLat/2) * sin(dLat/2) +
cos(lat1 * 3.14159265359 / 180) * cos(lat2 * 3.14159265359 / 180) *
sin(dLng/2) * sin(dLng/2);
var c = 2 * atn(sqr(a) / sqr(1-a));
return R * c;
}
try { try {
data = readJsonBody();
userLat = structKeyExists(data, "lat") ? val(data.lat) : 0;
userLng = structKeyExists(data, "lng") ? val(data.lng) : 0;
hasUserLocation = (userLat != 0 AND userLng != 0);
// Get businesses with their address coordinates (exclude demo and hidden)
q = queryExecute( q = queryExecute(
" "
SELECT SELECT
BusinessID, b.BusinessID,
BusinessName b.BusinessName,
FROM Businesses a.AddressLat,
ORDER BY BusinessName a.AddressLng,
a.AddressCity,
a.AddressLine1
FROM Businesses b
LEFT JOIN Addresses a ON b.BusinessAddressID = a.AddressID
WHERE (b.BusinessIsDemo = 0 OR b.BusinessIsDemo IS NULL)
AND (b.BusinessIsHidden = 0 OR b.BusinessIsHidden IS NULL)
ORDER BY b.BusinessName
", ",
[], [],
{ datasource = "payfrit" } { datasource = "payfrit" }
); );
// Convert query -> array of structs (JSON-native) // Convert query -> array of structs with distance
rows = []; rows = [];
for (i = 1; i <= q.recordCount; i++) { for (i = 1; i <= q.recordCount; i++) {
arrayAppend(rows, { row = {
"BusinessID": q.BusinessID[i], "BusinessID": q.BusinessID[i],
"BusinessName": q.BusinessName[i] "BusinessName": q.BusinessName[i],
"AddressCity": isNull(q.AddressCity[i]) ? "" : q.AddressCity[i],
"AddressLine1": isNull(q.AddressLine1[i]) ? "" : q.AddressLine1[i]
};
// Calculate distance if we have both user location and business location
bizLat = isNull(q.AddressLat[i]) ? 0 : val(q.AddressLat[i]);
bizLng = isNull(q.AddressLng[i]) ? 0 : val(q.AddressLng[i]);
if (hasUserLocation AND bizLat != 0 AND bizLng != 0) {
row["DistanceMiles"] = haversineDistance(userLat, userLng, bizLat, bizLng);
} else {
row["DistanceMiles"] = 99999; // No location = sort to end
}
arrayAppend(rows, row);
}
// Sort by distance if user location provided
if (hasUserLocation) {
arraySort(rows, function(a, b) {
return compare(a.DistanceMiles, b.DistanceMiles);
}); });
} }
// Limit to 20 nearest restaurants
if (arrayLen(rows) > 20) {
rows = arraySlice(rows, 1, 20);
}
// Provide BOTH keys to satisfy any Flutter casing expectation // Provide BOTH keys to satisfy any Flutter casing expectation
writeOutput(serializeJSON({ writeOutput(serializeJSON({
"OK": true, "OK": true,
"ERROR": "", "ERROR": "",
"VERSION": "businesses_list_v3", "VERSION": "businesses_list_v5",
"BUSINESSES": rows, "BUSINESSES": rows,
"Businesses": rows "Businesses": rows
})); }));