function apiAbort(required struct payload) { writeOutput(serializeJSON(payload)); abort; } function getHeader(name) { try { req = getPageContext().getRequest(); val = req.getHeader(arguments.name); if (!isNull(val)) return trim(val); } catch (any e) { k = "HTTP_" & ucase(reReplace(arguments.name, "[^A-Za-z0-9]", "_", "all")); if (structKeyExists(cgi, k)) return trim(cgi[k]); } return ""; } function readJsonBody() { var raw = getHttpRequestData().content; if (isNull(raw) || len(trim(toString(raw))) == 0) return {}; try { var data = deserializeJSON(toString(raw)); return isStruct(data) ? data : {}; } catch (any e) { return {}; } } // Get authenticated user userId = 0; if (structKeyExists(request, "UserID") && isNumeric(request.UserID) && request.UserID > 0) { userId = request.UserID; } else { userToken = getHeader("X-User-Token"); if (len(userToken)) { try { qTok = queryExecute( "SELECT UserID FROM UserTokens WHERE Token = ? LIMIT 1", [{ value = userToken, cfsqltype = "cf_sql_varchar" }], { datasource = "payfrit" } ); if (qTok.recordCount EQ 1) { userId = qTok.UserID; } } catch (any e) {} } } if (userId <= 0) { apiAbort({ "OK": false, "ERROR": "not_logged_in", "MESSAGE": "Authentication required" }); } // Get address ID from URL, form, or JSON body addressId = 0; if (structKeyExists(url, "id") && isNumeric(url.id)) { addressId = val(url.id); } else if (structKeyExists(form, "addressId") && isNumeric(form.addressId)) { addressId = val(form.addressId); } else { data = readJsonBody(); if (structKeyExists(data, "AddressID") && isNumeric(data.AddressID)) { addressId = val(data.AddressID); } } if (addressId <= 0) { apiAbort({ "OK": false, "ERROR": "invalid_id", "MESSAGE": "Address ID required" }); } try { // First, get the address details so we can find all matching duplicates qAddr = queryExecute(" SELECT AddressLine1, AddressLine2, AddressCity, AddressStateID, AddressZIPCode FROM Addresses WHERE AddressID = :addressId AND AddressUserID = :userId AND AddressIsDeleted = 0 ", { addressId: { value = addressId, cfsqltype = "cf_sql_integer" }, userId: { value = userId, cfsqltype = "cf_sql_integer" } }); if (qAddr.recordCount EQ 0) { apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Address not found" }); } // Soft-delete ALL addresses that match the same Line1, Line2, City, StateID, ZIPCode qDelete = queryExecute(" UPDATE Addresses SET AddressIsDeleted = 1 WHERE AddressUserID = :userId AND AddressLine1 = :line1 AND AddressLine2 = :line2 AND AddressCity = :city AND AddressStateID = :stateId AND AddressZIPCode = :zip AND AddressIsDeleted = 0 ", { userId: { value = userId, cfsqltype = "cf_sql_integer" }, line1: { value = qAddr.AddressLine1, cfsqltype = "cf_sql_varchar", null = !len(qAddr.AddressLine1) }, line2: { value = qAddr.AddressLine2, cfsqltype = "cf_sql_varchar", null = !len(qAddr.AddressLine2) }, city: { value = qAddr.AddressCity, cfsqltype = "cf_sql_varchar", null = !len(qAddr.AddressCity) }, stateId: { value = qAddr.AddressStateID, cfsqltype = "cf_sql_integer" }, zip: { value = qAddr.AddressZIPCode, cfsqltype = "cf_sql_varchar", null = !len(qAddr.AddressZIPCode) } }); writeOutput(serializeJSON({ "OK": true, "MESSAGE": "Address deleted" })); } catch (any e) { apiAbort({ "OK": false, "ERROR": "server_error", "MESSAGE": e.message, "LINE": e.tagContext[1].line ?: 0 }); }