167 lines
4.7 KiB
TypeScript
167 lines
4.7 KiB
TypeScript
import type { Weekday, TimeRange, LocationConfig, PeakDay, ProductRule, ShopSettings, CartItem } from "../types";
|
|
import { zonedToUtc } from "../time";
|
|
|
|
export const TZ = "America/Toronto";
|
|
/** Local Toronto wall time → epoch ms */
|
|
export const at = (date: string, time: string) => zonedToUtc(date, time, TZ);
|
|
|
|
const h = () => [{ start: "10:00", end: "18:00" }];
|
|
const monSat: Partial<Record<Weekday, TimeRange[]>> = { 1: h(), 2: h(), 3: h(), 4: h(), 5: h(), 6: h() };
|
|
const deliverySlots = [
|
|
{ start: "10:00", end: "13:00" },
|
|
{ start: "13:00", end: "16:00" },
|
|
{ start: "16:00", end: "19:00", surcharge: 300 },
|
|
];
|
|
|
|
export function kitchener(): LocationConfig {
|
|
return {
|
|
id: "kit",
|
|
name: "Kitchener",
|
|
address: "900 Guelph St, Kitchener, ON N2H 5Z6",
|
|
timezone: TZ,
|
|
lat: 43.4643,
|
|
lng: -80.4844,
|
|
enabled: true,
|
|
priority: 1,
|
|
exceptions: [],
|
|
zones: [
|
|
{ id: "z1", name: "Kitchener-Waterloo", postalPatterns: ["N2H*", "N2G*", "N2J..N2M"], fee: 799, freeOver: 7500, minOrder: 2500 },
|
|
{ id: "z2", name: "15 km radius", radiusKm: 15, fee: 1299 },
|
|
],
|
|
pickupInstructions: "Unit 7 — ring the bell",
|
|
methods: {
|
|
pickup: {
|
|
enabled: true,
|
|
weeklyHours: { ...monSat },
|
|
slotMode: "generated",
|
|
slotMinutes: 60,
|
|
prepMinutes: 60,
|
|
prepMode: "elapsed",
|
|
sameDayCutoff: "14:00",
|
|
horizonDays: 30,
|
|
slotCapacity: 4,
|
|
},
|
|
delivery: {
|
|
enabled: true,
|
|
weeklyHours: { 0: [{ start: "10:00", end: "19:00" }], 2: [{ start: "10:00", end: "19:00" }], 3: [{ start: "10:00", end: "19:00" }], 4: [{ start: "10:00", end: "19:00" }], 5: [{ start: "10:00", end: "19:00" }], 6: [{ start: "10:00", end: "19:00" }] },
|
|
slotMode: "explicit",
|
|
slots: { 0: deliverySlots, 2: deliverySlots, 3: deliverySlots, 4: deliverySlots, 5: deliverySlots, 6: deliverySlots },
|
|
prepMinutes: 120,
|
|
prepMode: "elapsed",
|
|
sameDayCutoff: "12:00",
|
|
horizonDays: 21,
|
|
slotCapacity: 5,
|
|
dailyCapacity: 12,
|
|
},
|
|
shipping: {
|
|
enabled: true,
|
|
weeklyHours: { ...monSat },
|
|
slotMode: "dateOnly",
|
|
prepMinutes: 0,
|
|
prepMode: "operating",
|
|
sameDayCutoff: "14:00",
|
|
horizonDays: 14,
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
export function waterloo(): LocationConfig {
|
|
const l = kitchener();
|
|
return {
|
|
...l,
|
|
id: "wat",
|
|
name: "Waterloo",
|
|
priority: 2,
|
|
lat: 43.4723,
|
|
lng: -80.5449,
|
|
zones: [{ id: "zw", name: "Waterloo", postalPatterns: ["N2L*", "N2J*"], fee: 599 }],
|
|
};
|
|
}
|
|
|
|
export const settings: ShopSettings = {
|
|
mixedPrepPolicy: "longest",
|
|
holdMinutes: 10,
|
|
weekStartsOn: 0,
|
|
reschedule: { enabled: true, minHoursBefore: 24, maxChanges: 2, allowMethodChange: false },
|
|
reminders: [
|
|
{ id: "r1", channel: "sms", minutesBefore: 24 * 60, template: "Hi {{name}}, your {{method}} is {{date}} {{time}}", enabled: true },
|
|
{ id: "r2", channel: "email", minutesBefore: 120, template: "Reminder {{order}}", enabled: true },
|
|
],
|
|
};
|
|
|
|
export const marigold: CartItem = {
|
|
productId: "p_marigold",
|
|
variantId: "v_marigold",
|
|
title: "Fresh Marigold Garland",
|
|
quantity: 2,
|
|
price: 1999,
|
|
collectionIds: ["c_flowers"],
|
|
vendor: "C2C Agricorp",
|
|
productType: "Fresh Flowers",
|
|
tags: ["perishable"],
|
|
};
|
|
|
|
export const pakku: CartItem = {
|
|
productId: "p_pakku",
|
|
variantId: "v_pakku",
|
|
title: "பாக்கு (Pākkŭ) 200g",
|
|
quantity: 1,
|
|
price: 699,
|
|
collectionIds: ["c_puja"],
|
|
vendor: "Clicks to Cart",
|
|
productType: "Puja",
|
|
};
|
|
|
|
export const saree: CartItem = {
|
|
productId: "p_saree",
|
|
variantId: "v_saree",
|
|
title: "Silk Saree",
|
|
quantity: 1,
|
|
price: 15999,
|
|
collectionIds: ["c_apparel"],
|
|
productType: "Apparel",
|
|
};
|
|
|
|
export const rules: ProductRule[] = [
|
|
{
|
|
id: "r_fresh_noship",
|
|
name: "Fresh flowers can't ship",
|
|
enabled: true,
|
|
priority: 1,
|
|
target: { type: "productType", values: ["Fresh Flowers"] },
|
|
action: { type: "prohibitMethods", methods: ["shipping"] },
|
|
message: "Fresh flowers are pickup or local delivery only",
|
|
},
|
|
{
|
|
id: "r_fresh_prep",
|
|
name: "Garland stringing time",
|
|
enabled: true,
|
|
priority: 2,
|
|
target: { type: "tag", values: ["perishable"] },
|
|
action: { type: "addPrep", minutes: 240 },
|
|
},
|
|
{
|
|
id: "r_saree_prep",
|
|
name: "Saree fall & pico",
|
|
enabled: true,
|
|
priority: 3,
|
|
target: { type: "collection", values: ["c_apparel"] },
|
|
action: { type: "addPrep", minutes: 60 * 24 },
|
|
},
|
|
];
|
|
|
|
export const diwali: PeakDay = {
|
|
id: "pk_diwali",
|
|
name: "Diwali",
|
|
dates: ["2026-11-08"],
|
|
methods: ["delivery", "pickup"],
|
|
dailyCapacity: 30,
|
|
slotCapacity: 10,
|
|
extraPrepMinutes: 60,
|
|
cutoff: { daysBefore: 2, time: "18:00" },
|
|
surcharge: 500,
|
|
waitlist: true,
|
|
message: "Diwali orders close Friday 6 PM",
|
|
};
|