Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/shopify-app/app/features/delivery/delivery-labels.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ export function inferDeliveryDateForOrder({
orderCreatedAt,
} = {}) {
return (
normalizeExplicitDeliveryDate(deliveryDate, orderCreatedAt) ??
inferDeliveryDateFromLineItems({
deliveryDay,
lineItems,
orderCreatedAt,
}) ??
normalizeExplicitDeliveryDate(deliveryDate, orderCreatedAt) ??
inferDeliveryDateFromOrderCycle({
deliveryCycle,
deliveryDay,
Expand Down Expand Up @@ -122,7 +122,7 @@ export function inferDeliveryDateFromOrderCycle({
);
const cutoffWeekdayIndex = WEEKDAY_INDEX_BY_CODE[cycle.cutoffWeekday];
let daysUntilCutoff = (cutoffWeekdayIndex - orderDate.getUTCDay() + 7) % 7;
if (daysUntilCutoff === 0 && getLocalMinutes(orderLocalDate) > parseCutoffMinutes(cycle.cutoffTime)) {
if (daysUntilCutoff === 0 && getLocalMinutes(orderLocalDate) >= parseCutoffMinutes(cycle.cutoffTime)) {
daysUntilCutoff = 7;
}

Expand Down
39 changes: 35 additions & 4 deletions apps/shopify-app/app/features/delivery/delivery-labels.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,36 @@ test("honors a configured delivery cycle cutoff time", () => {
);
});

test("keeps orders placed through 16:59 in the current K-food delivery cycle", () => {
assert.equal(
inferDeliveryDateFromOrderCycle({
deliveryCycle: {
cutoffTime: "17:00",
cutoffWeekday: "TUESDAY",
timeZone: "America/Toronto",
},
deliveryDay: "Friday",
orderCreatedAt: "2026-05-05T20:59:00.000Z",
}),
"2026-05-08",
);
});

test("starts the next K-food delivery cycle at exactly 17:00", () => {
assert.equal(
inferDeliveryDateFromOrderCycle({
deliveryCycle: {
cutoffTime: "17:00",
cutoffWeekday: "TUESDAY",
timeZone: "America/Toronto",
},
deliveryDay: "Friday",
orderCreatedAt: "2026-05-05T21:00:00.000Z",
}),
"2026-05-15",
);
});

test("normalizes invalid delivery cycle settings to the current default", () => {
assert.deepEqual(
normalizeDeliveryCycle({ cutoffTime: "99:99", cutoffWeekday: "NOPE" }),
Expand All @@ -108,15 +138,16 @@ test("uses the order cycle when Shopify line items do not include a date range",
);
});

test("uses an explicit delivery date before weekday/range inference", () => {
test("uses the product date range before an explicit delivery date", () => {
assert.equal(
inferDeliveryDateForOrder({
deliveryDate: "2026-05-18",
deliveryDay: "Friday",
lineItems: {
nodes: [{ title: "CLEVER 2026.05.18-05.31" }],
nodes: [{ title: "CLEVER 2026.05.21-05.23" }],
},
orderCreatedAt: null,
orderCreatedAt: "2026-05-01T15:30:00.000Z",
}),
"2026-05-18",
"2026-05-22",
);
});
1 change: 1 addition & 0 deletions apps/shopify-app/app/features/delivery/orders.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const DELIVERY_ORDERS_SYNC_REASON = "orders_page_open";
export async function syncDeliveryOrders(request, payload = {}, options = {}) {
const result = await deliveryApiRequest(request, "/admin/orders/sync", {
body: JSON.stringify({
...(payload.deliveryCycle ? { deliveryCycle: payload.deliveryCycle } : {}),
source: DELIVERY_ORDERS_SYNC_SOURCE,
reason: payload.reason ?? DELIVERY_ORDERS_SYNC_REASON,
orders: Array.isArray(payload.orders) ? payload.orders : [],
Expand Down
15 changes: 14 additions & 1 deletion apps/shopify-app/app/features/delivery/orders.server.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ test("syncs delivery orders through the delivery Admin API with an explicit clie

const result = await syncDeliveryOrders(
new Request("https://app.example/app/orders"),
{ reason: "manual_refresh", orders },
{
deliveryCycle: {
cutoffTime: "17:00",
cutoffWeekday: "TUESDAY",
timeZone: "America/Toronto",
},
reason: "manual_refresh",
orders,
},
{
fetch: async (url, options) => {
calls.push({ url, options });
Expand Down Expand Up @@ -48,6 +56,11 @@ test("syncs delivery orders through the delivery Admin API with an explicit clie
assert.equal(calls[0].options.headers["x-clever-app-id"], "clever-route-dev");
assert.equal(calls[0].options.headers["content-type"], "application/json");
assert.deepEqual(JSON.parse(calls[0].options.body), {
deliveryCycle: {
cutoffTime: "17:00",
cutoffWeekday: "TUESDAY",
timeZone: "America/Toronto",
},
source: "clever-app-orders",
reason: "manual_refresh",
orders,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,11 @@ export async function refreshRouteOrders({
const snapshots = getOrderSyncSnapshots(shopifyOrderData.orders);
const syncedOrderData = await syncDeliveryOrders(
request,
{ reason: "manual_refresh", orders: snapshots },
{
deliveryCycle: preferencesData.appPreferences.deliveryCycle,
reason: "manual_refresh",
orders: snapshots,
},
{ cacheKey: shopifyShopCacheKey, sessionToken },
);
errors.push(...(syncedOrderData.errors ?? []));
Expand Down
12 changes: 11 additions & 1 deletion apps/shopify-app/app/features/orders/orders-page.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,18 @@ async function handleOrdersAction(request) {
return { syncedOrders: [], sync: null, errors: [] };
}

const preferencesData = await fetchShopifyAppPreferences(admin);
if ((preferencesData.errors ?? []).length > 0) {
return { syncedOrders: [], sync: null, errors: preferencesData.errors };
}

const syncedOrderData = await syncDeliveryOrders(
request,
{ reason: "orders_page_open", orders: orderSnapshots },
{
deliveryCycle: preferencesData.appPreferences.deliveryCycle,
reason: "orders_page_open",
orders: orderSnapshots,
},
{
cacheKey: shopifyShopCacheKey,
primeOrdersCache: true,
Expand Down Expand Up @@ -471,6 +480,7 @@ async function resolvePlannedOrdersForAction({
? await syncDeliveryOrders(
request,
{
deliveryCycle: preferencesData.appPreferences.deliveryCycle,
reason,
orders: plannedShopifyOrderSnapshots,
},
Expand Down