/** * Update Business Settings * Updates settings for the currently selected business * * POST: { * TaxRatePercent: 8.25 (percentage, will be converted to decimal) * -- OR -- * TaxRate: 0.0825 (decimal, stored directly) * } * * Requires: request.BusinessID (set by auth middleware) */ function apiAbort(obj) { writeOutput(serializeJSON(obj)); abort; } function readJsonBody() { raw = toString(getHttpRequestData().content); if (isNull(raw) || len(trim(raw)) EQ 0) { apiAbort({ OK: false, ERROR: "missing_body" }); } try { parsed = deserializeJSON(raw); } catch (any e) { apiAbort({ OK: false, ERROR: "bad_json", MESSAGE: "Invalid JSON body" }); } if (!isStruct(parsed)) { apiAbort({ OK: false, ERROR: "bad_json", MESSAGE: "JSON must be an object" }); } return parsed; } if (!structKeyExists(request, "BusinessID") || !isNumeric(request.BusinessID) || request.BusinessID LTE 0) { apiAbort({ OK: false, ERROR: "no_business_selected" }); } try { data = readJsonBody(); updates = []; params = { businessId: request.BusinessID }; // Handle tax rate (accept either percent or decimal) if (structKeyExists(data, "TaxRatePercent") && isNumeric(data.TaxRatePercent)) { taxRate = data.TaxRatePercent / 100; if (taxRate < 0 || taxRate > 0.5) { apiAbort({ OK: false, ERROR: "invalid_tax_rate", MESSAGE: "Tax rate must be between 0% and 50%" }); } arrayAppend(updates, "BusinessTaxRate = :taxRate"); params.taxRate = { value: taxRate, cfsqltype: "cf_sql_decimal" }; } else if (structKeyExists(data, "TaxRate") && isNumeric(data.TaxRate)) { taxRate = data.TaxRate; if (taxRate < 0 || taxRate > 0.5) { apiAbort({ OK: false, ERROR: "invalid_tax_rate", MESSAGE: "Tax rate must be between 0 and 0.5" }); } arrayAppend(updates, "BusinessTaxRate = :taxRate"); params.taxRate = { value: taxRate, cfsqltype: "cf_sql_decimal" }; } // Add more updatable fields as needed if (structKeyExists(data, "BusinessName") && len(trim(data.BusinessName))) { arrayAppend(updates, "BusinessName = :businessName"); params.businessName = { value: left(trim(data.BusinessName), 100), cfsqltype: "cf_sql_varchar" }; } if (structKeyExists(data, "Address") && len(trim(data.Address))) { arrayAppend(updates, "BusinessAddress = :address"); params.address = { value: left(trim(data.Address), 255), cfsqltype: "cf_sql_varchar" }; } if (structKeyExists(data, "City")) { arrayAppend(updates, "BusinessCity = :city"); params.city = { value: left(trim(data.City), 100), cfsqltype: "cf_sql_varchar" }; } if (structKeyExists(data, "State")) { arrayAppend(updates, "BusinessState = :state"); params.state = { value: left(trim(data.State), 2), cfsqltype: "cf_sql_varchar" }; } if (structKeyExists(data, "Zip")) { arrayAppend(updates, "BusinessZip = :zip"); params.zip = { value: left(trim(data.Zip), 10), cfsqltype: "cf_sql_varchar" }; } if (structKeyExists(data, "Phone")) { arrayAppend(updates, "BusinessContactNumber = :phone"); params.phone = { value: left(trim(data.Phone), 20), cfsqltype: "cf_sql_varchar" }; } if (structKeyExists(data, "Email")) { arrayAppend(updates, "BusinessEmailAddress = :email"); params.email = { value: left(trim(data.Email), 100), cfsqltype: "cf_sql_varchar" }; } if (arrayLen(updates) == 0) { apiAbort({ OK: false, ERROR: "no_fields", MESSAGE: "No valid fields to update" }); } // Build and execute update sql = "UPDATE Businesses SET " & arrayToList(updates, ", ") & " WHERE BusinessID = :businessId"; queryExecute(sql, params, { datasource: "payfrit" }); // Return updated settings q = queryExecute(" SELECT BusinessID, BusinessName, BusinessTaxRate, BusinessAddress, BusinessCity, BusinessState, BusinessZip, BusinessContactNumber, BusinessEmailAddress FROM Businesses WHERE BusinessID = :businessId LIMIT 1 ", { businessId: request.BusinessID }, { datasource: "payfrit" }); taxRateRaw = isNumeric(q.BusinessTaxRate) ? q.BusinessTaxRate : 0; taxRatePercent = taxRateRaw * 100; writeOutput(serializeJSON({ "OK": true, "MESSAGE": "Settings updated", "SETTINGS": { "BusinessID": q.BusinessID, "BusinessName": q.BusinessName, "TaxRate": taxRateRaw, "TaxRatePercent": taxRatePercent, "Address": q.BusinessAddress ?: "", "City": q.BusinessCity ?: "", "State": q.BusinessState ?: "", "Zip": q.BusinessZip ?: "", "Phone": q.BusinessContactNumber ?: "", "Email": q.BusinessEmailAddress ?: "" } })); } catch (any e) { apiAbort({ OK: false, ERROR: "server_error", MESSAGE: e.message }); }