Add business timezone support for menu scheduling
- Add getTimeInZone() and getDayInZone() helpers in Application.cfm - Update items.cfm and getForBuilder.cfm to use business timezone - Menu availability now correctly respects each business's timezone Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
9e5770f131
commit
2c655a5963
3 changed files with 56 additions and 11 deletions
|
|
@ -84,6 +84,35 @@ function toISO8601(d) {
|
||||||
return dateTimeFormat(utc, "yyyy-MM-dd'T'HH:nn:ss") & "Z";
|
return dateTimeFormat(utc, "yyyy-MM-dd'T'HH:nn:ss") & "Z";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get current time in a specific timezone (returns "HH:mm:ss" string)
|
||||||
|
// Used for schedule filtering (menu availability, business hours)
|
||||||
|
function getTimeInZone(tz) {
|
||||||
|
if (isNull(tz) || !len(trim(tz))) tz = "America/Los_Angeles";
|
||||||
|
try {
|
||||||
|
var zoneId = createObject("java", "java.time.ZoneId").of(tz);
|
||||||
|
var zonedNow = createObject("java", "java.time.ZonedDateTime").now(zoneId);
|
||||||
|
var formatter = createObject("java", "java.time.format.DateTimeFormatter").ofPattern("HH:mm:ss");
|
||||||
|
return zonedNow.format(formatter);
|
||||||
|
} catch (any e) {
|
||||||
|
// Fallback to server time if timezone is invalid
|
||||||
|
return timeFormat(now(), "HH:mm:ss");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current day of week in a specific timezone (returns 1-7, Sunday=1)
|
||||||
|
function getDayInZone(tz) {
|
||||||
|
if (isNull(tz) || !len(trim(tz))) tz = "America/Los_Angeles";
|
||||||
|
try {
|
||||||
|
var zoneId = createObject("java", "java.time.ZoneId").of(tz);
|
||||||
|
var zonedNow = createObject("java", "java.time.ZonedDateTime").now(zoneId);
|
||||||
|
// Java DayOfWeek: Monday=1, Sunday=7. Convert to CFML: Sunday=1, Monday=2...
|
||||||
|
var javaDow = zonedNow.getDayOfWeek().getValue();
|
||||||
|
return (javaDow mod 7) + 1; // Convert: Mon=2, Tue=3, ..., Sat=7, Sun=1
|
||||||
|
} catch (any e) {
|
||||||
|
return dayOfWeek(now());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine request path
|
// Determine request path
|
||||||
request._api_scriptName = "";
|
request._api_scriptName = "";
|
||||||
if (structKeyExists(cgi, "SCRIPT_NAME")) {
|
if (structKeyExists(cgi, "SCRIPT_NAME")) {
|
||||||
|
|
|
||||||
|
|
@ -60,13 +60,15 @@ try {
|
||||||
// Check for MenuID filter (optional - if provided, only return categories for that menu)
|
// Check for MenuID filter (optional - if provided, only return categories for that menu)
|
||||||
menuID = structKeyExists(requestData, "MenuID") ? val(requestData.MenuID) : 0;
|
menuID = structKeyExists(requestData, "MenuID") ? val(requestData.MenuID) : 0;
|
||||||
|
|
||||||
// Get business's default menu setting
|
// Get business's default menu setting and timezone
|
||||||
defaultMenuID = 0;
|
defaultMenuID = 0;
|
||||||
|
businessTimezone = "America/Los_Angeles";
|
||||||
try {
|
try {
|
||||||
qBiz = queryTimed("SELECT DefaultMenuID FROM Businesses WHERE ID = :businessID",
|
qBiz = queryTimed("SELECT DefaultMenuID, Timezone FROM Businesses WHERE ID = :businessID",
|
||||||
{ businessID: businessID }, { datasource: "payfrit" });
|
{ businessID: businessID }, { datasource: "payfrit" });
|
||||||
if (qBiz.recordCount > 0 && !isNull(qBiz.DefaultMenuID)) {
|
if (qBiz.recordCount > 0) {
|
||||||
defaultMenuID = val(qBiz.DefaultMenuID);
|
if (!isNull(qBiz.DefaultMenuID)) defaultMenuID = val(qBiz.DefaultMenuID);
|
||||||
|
if (!isNull(qBiz.Timezone) && len(trim(qBiz.Timezone))) businessTimezone = qBiz.Timezone;
|
||||||
}
|
}
|
||||||
} catch (any e) {}
|
} catch (any e) {}
|
||||||
|
|
||||||
|
|
@ -95,9 +97,9 @@ try {
|
||||||
|
|
||||||
// Auto-select menu based on current time when no specific menu requested
|
// Auto-select menu based on current time when no specific menu requested
|
||||||
if (menuID == 0 && qMenus.recordCount > 1) {
|
if (menuID == 0 && qMenus.recordCount > 1) {
|
||||||
now = timeFormat(now(), "HH:mm");
|
currentTime = left(getTimeInZone(businessTimezone), 5); // "HH:mm"
|
||||||
dayOfWeek = dayOfWeek(now()); // 1=Sun, 2=Mon, ... 7=Sat
|
currentDay = getDayInZone(businessTimezone); // 1=Sun, 2=Mon, ... 7=Sat
|
||||||
dayBit = 2 ^ (dayOfWeek - 1); // bitmask: 1=Sun, 2=Mon, 4=Tue, etc.
|
dayBit = 2 ^ (currentDay - 1); // bitmask: 1=Sun, 2=Mon, 4=Tue, etc.
|
||||||
activeMenuIds = [];
|
activeMenuIds = [];
|
||||||
|
|
||||||
for (m = 1; m <= qMenus.recordCount; m++) {
|
for (m = 1; m <= qMenus.recordCount; m++) {
|
||||||
|
|
@ -111,7 +113,7 @@ try {
|
||||||
if (hasStart && hasEnd) {
|
if (hasStart && hasEnd) {
|
||||||
startT = timeFormat(qMenus.StartTime[m], "HH:mm");
|
startT = timeFormat(qMenus.StartTime[m], "HH:mm");
|
||||||
endT = timeFormat(qMenus.EndTime[m], "HH:mm");
|
endT = timeFormat(qMenus.EndTime[m], "HH:mm");
|
||||||
if (now >= startT && now <= endT) {
|
if (currentTime >= startT && currentTime <= endT) {
|
||||||
arrayAppend(activeMenuIds, qMenus.ID[m]);
|
arrayAppend(activeMenuIds, qMenus.ID[m]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,23 @@
|
||||||
<cfset apiAbort({ "OK": false, "ERROR": "missing_businessid", "MESSAGE": "BusinessID is required.", "DETAIL": "" })>
|
<cfset apiAbort({ "OK": false, "ERROR": "missing_businessid", "MESSAGE": "BusinessID is required.", "DETAIL": "" })>
|
||||||
</cfif>
|
</cfif>
|
||||||
|
|
||||||
<!--- Get current time and day for schedule filtering --->
|
<!--- Get business timezone for schedule filtering --->
|
||||||
<cfset currentTime = timeFormat(now(), "HH:mm:ss")>
|
<cfset businessTimezone = "America/Los_Angeles">
|
||||||
<cfset currentDayID = dayOfWeek(now())>
|
<cftry>
|
||||||
|
<cfset qTz = queryExecute(
|
||||||
|
"SELECT Timezone FROM Businesses WHERE ID = ?",
|
||||||
|
[ { value = BusinessID, cfsqltype = "cf_sql_integer" } ],
|
||||||
|
{ datasource = "payfrit" }
|
||||||
|
)>
|
||||||
|
<cfif qTz.recordCount GT 0 AND len(trim(qTz.Timezone))>
|
||||||
|
<cfset businessTimezone = qTz.Timezone>
|
||||||
|
</cfif>
|
||||||
|
<cfcatch><!--- Column might not exist yet, use default ---></cfcatch>
|
||||||
|
</cftry>
|
||||||
|
|
||||||
|
<!--- Get current time and day in business timezone for schedule filtering --->
|
||||||
|
<cfset currentTime = getTimeInZone(businessTimezone)>
|
||||||
|
<cfset currentDayID = getDayInZone(businessTimezone)>
|
||||||
|
|
||||||
<cfset menuList = []>
|
<cfset menuList = []>
|
||||||
<cftry>
|
<cftry>
|
||||||
|
|
|
||||||
Reference in a new issue