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/grants/update.cfm
John 16a3b7c9a3 Replace queryExecute with queryTimed across all endpoints for perf tracking
Converts 200+ endpoint files to use queryTimed() wrapper which tracks
DB query count and execution time. Restores perf dashboard files that
were accidentally moved to _scripts/. Includes portal UI updates.
2026-02-02 00:28:37 -08:00

153 lines
5.4 KiB
Text

<cfsetting showdebugoutput="false">
<cfsetting enablecfoutputonly="true">
<cfcontent type="application/json; charset=utf-8" reset="true">
<cfheader name="Cache-Control" value="no-store">
<cfinclude template="_grantUtils.cfm">
<cfscript>
data = {};
try {
raw = toString(getHttpRequestData().content);
if (len(trim(raw))) {
data = deserializeJSON(raw);
if (!isStruct(data)) data = {};
}
} catch (any e) { data = {}; }
grantID = val(data.GrantID ?: 0);
if (grantID LTE 0) {
apiAbort({ "OK": false, "ERROR": "missing_grantid", "MESSAGE": "GrantID is required." });
}
callerUserID = val(structKeyExists(request, "UserID") ? request.UserID : 0);
if (callerUserID LTE 0) {
apiAbort({ "OK": false, "ERROR": "not_authenticated" });
}
// Load current grant
qGrant = queryTimed(
"SELECT g.*, b.UserID AS OwnerUserID
FROM ServicePointGrants g
JOIN Businesses b ON b.ID = g.OwnerBusinessID
WHERE g.ID = ?
LIMIT 1",
[{ value = grantID, cfsqltype = "cf_sql_integer" }],
{ datasource = "payfrit" }
);
if (qGrant.recordCount == 0) {
apiAbort({ "OK": false, "ERROR": "not_found", "MESSAGE": "Grant not found." });
}
if (qGrant.OwnerUserID != callerUserID) {
apiAbort({ "OK": false, "ERROR": "not_owner", "MESSAGE": "Only the owner business can update grant terms." });
}
if (qGrant.StatusID != 0 && qGrant.StatusID != 1) {
apiAbort({ "OK": false, "ERROR": "bad_state", "MESSAGE": "Only pending or active grants can be updated." });
}
// Collect updates
setClauses = [];
setParams = [];
previousData = {};
newData = {};
validEconomics = ["none", "flat_fee", "percent_of_orders"];
validEligibility = ["public", "employees", "guests", "internal"];
validTimePolicy = ["always", "schedule", "date_range", "event"];
// Economics
if (structKeyExists(data, "EconomicsType") || structKeyExists(data, "EconomicsValue")) {
eType = trim(data.EconomicsType ?: qGrant.EconomicsType);
eValue = val(structKeyExists(data, "EconomicsValue") ? data.EconomicsValue : qGrant.EconomicsValue);
if (!arrayFind(validEconomics, eType)) eType = qGrant.EconomicsType;
if (eType != qGrant.EconomicsType || eValue != qGrant.EconomicsValue) {
previousData["EconomicsType"] = qGrant.EconomicsType;
previousData["EconomicsValue"] = qGrant.EconomicsValue;
newData["EconomicsType"] = eType;
newData["EconomicsValue"] = eValue;
arrayAppend(setClauses, "EconomicsType = ?");
arrayAppend(setParams, { value = eType, cfsqltype = "cf_sql_varchar" });
arrayAppend(setClauses, "EconomicsValue = ?");
arrayAppend(setParams, { value = eValue, cfsqltype = "cf_sql_decimal" });
}
}
// Eligibility
if (structKeyExists(data, "EligibilityScope")) {
eScope = trim(data.EligibilityScope);
if (!arrayFind(validEligibility, eScope)) eScope = qGrant.EligibilityScope;
if (eScope != qGrant.EligibilityScope) {
previousData["EligibilityScope"] = qGrant.EligibilityScope;
newData["EligibilityScope"] = eScope;
arrayAppend(setClauses, "EligibilityScope = ?");
arrayAppend(setParams, { value = eScope, cfsqltype = "cf_sql_varchar" });
}
}
// Time policy
if (structKeyExists(data, "TimePolicyType") || structKeyExists(data, "TimePolicyData")) {
tType = trim(data.TimePolicyType ?: qGrant.TimePolicyType);
if (!arrayFind(validTimePolicy, tType)) tType = qGrant.TimePolicyType;
tData = structKeyExists(data, "TimePolicyData") ? data.TimePolicyData : qGrant.TimePolicyData;
changed = (tType != qGrant.TimePolicyType);
if (!changed && isStruct(tData)) {
changed = (serializeJSON(tData) != (qGrant.TimePolicyData ?: ""));
}
if (changed) {
previousData["TimePolicyType"] = qGrant.TimePolicyType;
previousData["TimePolicyData"] = qGrant.TimePolicyData ?: "";
newData["TimePolicyType"] = tType;
newData["TimePolicyData"] = tData;
arrayAppend(setClauses, "TimePolicyType = ?");
arrayAppend(setParams, { value = tType, cfsqltype = "cf_sql_varchar" });
tDataJson = javaCast("null", "");
if (isStruct(tData) && !structIsEmpty(tData)) {
tDataJson = serializeJSON(tData);
} else if (isSimpleValue(tData) && len(trim(tData))) {
tDataJson = tData;
}
arrayAppend(setClauses, "TimePolicyData = ?");
arrayAppend(setParams, { value = tDataJson, cfsqltype = "cf_sql_varchar", null = isNull(tDataJson) });
}
}
if (arrayLen(setClauses) == 0) {
apiAbort({ "OK": true, "MESSAGE": "No changes detected.", "GrantID": grantID });
}
// Execute update
arrayAppend(setParams, { value = grantID, cfsqltype = "cf_sql_integer" });
queryTimed(
"UPDATE ServicePointGrants SET #arrayToList(setClauses, ', ')# WHERE ID = ?",
setParams,
{ datasource = "payfrit" }
);
// Determine action name for history
action = "updated";
if (structKeyExists(newData, "EconomicsType") || structKeyExists(newData, "EconomicsValue")) action = "updated_economics";
if (structKeyExists(newData, "EligibilityScope")) action = "updated_eligibility";
if (structKeyExists(newData, "TimePolicyType")) action = "updated_time_policy";
recordGrantHistory(
grantID = grantID,
action = action,
actorUserID = callerUserID,
actorBusinessID = qGrant.OwnerBusinessID,
previousData = previousData,
newData = newData
);
writeOutput(serializeJSON({
"OK": true,
"GrantID": grantID,
"MESSAGE": "Grant updated."
}));
</cfscript>