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/inc/geocode.cfm
John Mizerek 4e0cc65ba2 Auto-geocode addresses on create/update
Extract geocoding functions into shared api/inc/geocode.cfm and call
geocodeAddressById() via cfthread after every address INSERT or UPDATE.
Uses OpenStreetMap Nominatim (free, no API key). Non-blocking — the
HTTP call runs in a background thread so responses aren't delayed.

Affected endpoints:
- setup/saveWizard.cfm (new business creation)
- businesses/update.cfm (business address update)
- portal/updateSettings.cfm (portal settings save)
- addresses/add.cfm (customer delivery address)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 01:00:07 -08:00

58 lines
2.2 KiB
Text

<cfscript>
function geocodeAddress(addressString) {
var result = { "success": false, "error": "" };
if (!len(trim(addressString))) { result.error = "Empty address"; return result; }
try {
var httpService = new http();
httpService.setMethod("GET");
httpService.setUrl("https://nominatim.openstreetmap.org/search?q=" & urlEncodedFormat(addressString) & "&format=json&limit=1");
httpService.addParam(type="header", name="User-Agent", value="Payfrit/1.0");
httpService.setTimeout(10);
var httpResult = httpService.send().getPrefix();
if (httpResult.statusCode CONTAINS "200") {
var data = deserializeJSON(httpResult.fileContent);
if (arrayLen(data) GT 0) {
result.success = true;
result.lat = data[1].lat;
result.lng = data[1].lon;
return result;
}
result.error = "No results found";
} else {
result.error = "HTTP " & httpResult.statusCode;
}
} catch (any e) { result.error = e.message; }
return result;
}
function buildAddressString(line1, line2, city, zipCode) {
var parts = [];
if (len(trim(line1))) arrayAppend(parts, trim(line1));
if (len(trim(line2))) arrayAppend(parts, trim(line2));
if (len(trim(city))) arrayAppend(parts, trim(city));
if (len(trim(zipCode))) arrayAppend(parts, trim(zipCode));
return arrayToList(parts, ", ");
}
function geocodeAddressById(addressId) {
var qAddr = queryExecute("
SELECT Line1, Line2, City, ZIPCode
FROM Addresses WHERE ID = :id
", { id: addressId }, { datasource: "payfrit" });
if (qAddr.recordCount == 0 || !len(trim(qAddr.Line1))) return;
var fullAddress = buildAddressString(qAddr.Line1, qAddr.Line2, qAddr.City, qAddr.ZIPCode);
var geo = geocodeAddress(fullAddress);
if (geo.success) {
queryExecute("
UPDATE Addresses SET Lat = :lat, Lng = :lng WHERE ID = :id
", {
lat: { value: geo.lat, cfsqltype: "cf_sql_decimal" },
lng: { value: geo.lng, cfsqltype: "cf_sql_decimal" },
id: addressId
}, { datasource: "payfrit" });
}
}
</cfscript>