@stacksjs/commerce 0.70.55 → 0.70.56
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +10 -7
- package/src/carts/destroy.ts +0 -54
- package/src/carts/fetch.ts +0 -20
- package/src/carts/index.ts +0 -13
- package/src/carts/store.ts +0 -75
- package/src/carts/update.ts +0 -78
- package/src/coupons/destroy.ts +0 -49
- package/src/coupons/fetch.ts +0 -510
- package/src/coupons/index.ts +0 -30
- package/src/coupons/store.ts +0 -46
- package/src/coupons/update.ts +0 -147
- package/src/customers/destroy.ts +0 -62
- package/src/customers/fetch.ts +0 -20
- package/src/customers/index.ts +0 -17
- package/src/customers/store.ts +0 -45
- package/src/customers/update.ts +0 -44
- package/src/devices/destroy.ts +0 -54
- package/src/devices/export.ts +0 -98
- package/src/devices/fetch.ts +0 -125
- package/src/devices/index.ts +0 -31
- package/src/devices/store.ts +0 -82
- package/src/devices/update.ts +0 -125
- package/src/errors/destroy.ts +0 -54
- package/src/errors/fetch.ts +0 -197
- package/src/errors/index.ts +0 -28
- package/src/errors/update.ts +0 -116
- package/src/gift-cards/destroy.ts +0 -87
- package/src/gift-cards/fetch.ts +0 -431
- package/src/gift-cards/index.ts +0 -26
- package/src/gift-cards/store.ts +0 -56
- package/src/gift-cards/update.ts +0 -102
- package/src/index.ts +0 -78
- package/src/orders/destroy.ts +0 -111
- package/src/orders/events.ts +0 -121
- package/src/orders/export.ts +0 -158
- package/src/orders/fetch.ts +0 -379
- package/src/orders/guards.ts +0 -261
- package/src/orders/index.ts +0 -91
- package/src/orders/place-order.ts +0 -274
- package/src/orders/store.ts +0 -51
- package/src/orders/totals.ts +0 -190
- package/src/orders/update.ts +0 -164
- package/src/orders/webhook.ts +0 -312
- package/src/payments/destroy.ts +0 -56
- package/src/payments/fetch.ts +0 -288
- package/src/payments/index.ts +0 -16
- package/src/payments/store.ts +0 -63
- package/src/payments/update.ts +0 -52
- package/src/product.ts +0 -0
- package/src/products/categories/destroy.ts +0 -103
- package/src/products/categories/fetch.ts +0 -285
- package/src/products/categories/index.ts +0 -36
- package/src/products/categories/store.ts +0 -87
- package/src/products/categories/update.ts +0 -251
- package/src/products/index.ts +0 -35
- package/src/products/items/destroy.ts +0 -54
- package/src/products/items/fetch.ts +0 -282
- package/src/products/items/index.ts +0 -26
- package/src/products/items/store.ts +0 -84
- package/src/products/items/update.ts +0 -324
- package/src/products/manufacturers/destroy.ts +0 -56
- package/src/products/manufacturers/fetch.ts +0 -117
- package/src/products/manufacturers/index.ts +0 -24
- package/src/products/manufacturers/store.ts +0 -82
- package/src/products/manufacturers/update.ts +0 -113
- package/src/products/reviews/destroy.ts +0 -56
- package/src/products/reviews/fetch.ts +0 -63
- package/src/products/reviews/index.ts +0 -25
- package/src/products/reviews/store.ts +0 -46
- package/src/products/reviews/update.ts +0 -82
- package/src/products/units/destroy.ts +0 -56
- package/src/products/units/fetch.ts +0 -20
- package/src/products/units/index.ts +0 -13
- package/src/products/units/store.ts +0 -162
- package/src/products/units/update.ts +0 -159
- package/src/products/variants/destroy.ts +0 -56
- package/src/products/variants/fetch.ts +0 -20
- package/src/products/variants/index.ts +0 -21
- package/src/products/variants/store.ts +0 -136
- package/src/products/variants/update.ts +0 -104
- package/src/receipts/destroy.ts +0 -54
- package/src/receipts/export.ts +0 -0
- package/src/receipts/fetch.ts +0 -222
- package/src/receipts/index.ts +0 -24
- package/src/receipts/printer.ts +0 -69
- package/src/receipts/store.ts +0 -69
- package/src/receipts/update.ts +0 -124
- package/src/shippings/delivery-routes/destroy.ts +0 -54
- package/src/shippings/delivery-routes/fetch.ts +0 -42
- package/src/shippings/delivery-routes/index.ts +0 -26
- package/src/shippings/delivery-routes/store.ts +0 -69
- package/src/shippings/delivery-routes/update.ts +0 -120
- package/src/shippings/digital-deliveries/destroy.ts +0 -111
- package/src/shippings/digital-deliveries/fetch.ts +0 -20
- package/src/shippings/digital-deliveries/index.ts +0 -26
- package/src/shippings/digital-deliveries/store.ts +0 -76
- package/src/shippings/digital-deliveries/update.ts +0 -129
- package/src/shippings/drivers/destroy.ts +0 -78
- package/src/shippings/drivers/fetch.ts +0 -20
- package/src/shippings/drivers/index.ts +0 -24
- package/src/shippings/drivers/store.ts +0 -69
- package/src/shippings/drivers/update.ts +0 -117
- package/src/shippings/index.ts +0 -39
- package/src/shippings/license-keys/destroy.ts +0 -111
- package/src/shippings/license-keys/fetch.ts +0 -20
- package/src/shippings/license-keys/index.ts +0 -26
- package/src/shippings/license-keys/store.ts +0 -77
- package/src/shippings/license-keys/update.ts +0 -117
- package/src/shippings/shipping-methods/destroy.ts +0 -111
- package/src/shippings/shipping-methods/fetch.ts +0 -62
- package/src/shippings/shipping-methods/index.ts +0 -28
- package/src/shippings/shipping-methods/store.ts +0 -123
- package/src/shippings/shipping-methods/update.ts +0 -120
- package/src/shippings/shipping-rates/destroy.ts +0 -102
- package/src/shippings/shipping-rates/fetch.ts +0 -320
- package/src/shippings/shipping-rates/index.ts +0 -36
- package/src/shippings/shipping-rates/store.ts +0 -102
- package/src/shippings/shipping-rates/update.ts +0 -139
- package/src/shippings/shipping-zones/destroy.ts +0 -111
- package/src/shippings/shipping-zones/fetch.ts +0 -96
- package/src/shippings/shipping-zones/index.ts +0 -26
- package/src/shippings/shipping-zones/store.ts +0 -74
- package/src/shippings/shipping-zones/update.ts +0 -156
- package/src/tax/destroy.ts +0 -54
- package/src/tax/fetch.ts +0 -20
- package/src/tax/index.ts +0 -24
- package/src/tax/store.ts +0 -69
- package/src/tax/update.ts +0 -119
- package/src/tests/coupons.test.ts +0 -90
- package/src/tests/customers.test.ts +0 -39
- package/src/tests/device.test.ts +0 -111
- package/src/tests/digitals.test.ts +0 -31
- package/src/tests/drivers.test.ts +0 -25
- package/src/tests/gift-cards.test.ts +0 -36
- package/src/tests/license.test.ts +0 -31
- package/src/tests/manufacturers.test.ts +0 -80
- package/src/tests/orders.test.ts +0 -25
- package/src/tests/payments.test.ts +0 -75
- package/src/tests/rates.test.ts +0 -367
- package/src/tests/receipts.test.ts +0 -287
- package/src/tests/restaurant.test.ts +0 -522
- package/src/tests/reviews.test.ts +0 -165
- package/src/tests/routes.test.ts +0 -51
- package/src/tests/setup.ts +0 -149
- package/src/tests/shipping.test.ts +0 -88
- package/src/tests/tax.test.ts +0 -25
- package/src/tests/units.test.ts +0 -110
- package/src/tests/variants.test.ts +0 -133
- package/src/tests/waitlist.test.ts +0 -303
- package/src/tests/zones.test.ts +0 -86
- package/src/types.ts +0 -312
- package/src/utils/typed-stats.ts +0 -67
- package/src/waitlists/index.ts +0 -19
- package/src/waitlists/products/destroy.ts +0 -65
- package/src/waitlists/products/export.ts +0 -113
- package/src/waitlists/products/fetch.ts +0 -362
- package/src/waitlists/products/index.ts +0 -33
- package/src/waitlists/products/store.ts +0 -112
- package/src/waitlists/products/update.ts +0 -125
- package/src/waitlists/restaurant/destroy.ts +0 -65
- package/src/waitlists/restaurant/export.ts +0 -107
- package/src/waitlists/restaurant/fetch.ts +0 -538
- package/src/waitlists/restaurant/index.ts +0 -43
- package/src/waitlists/restaurant/store.ts +0 -109
- package/src/waitlists/restaurant/update.ts +0 -198
- /package/dist/{src/coupons → coupons}/destroy.d.ts +0 -0
- /package/dist/{src/coupons → coupons}/fetch.d.ts +0 -0
- /package/dist/{src/coupons → coupons}/index.d.ts +0 -0
- /package/dist/{src/coupons → coupons}/store.d.ts +0 -0
- /package/dist/{src/coupons → coupons}/update.d.ts +0 -0
- /package/dist/{src/customers → customers}/destroy.d.ts +0 -0
- /package/dist/{src/customers → customers}/fetch.d.ts +0 -0
- /package/dist/{src/customers → customers}/index.d.ts +0 -0
- /package/dist/{src/customers → customers}/store.d.ts +0 -0
- /package/dist/{src/customers → customers}/update.d.ts +0 -0
- /package/dist/{src/devices → devices}/destroy.d.ts +0 -0
- /package/dist/{src/devices → devices}/export.d.ts +0 -0
- /package/dist/{src/devices → devices}/fetch.d.ts +0 -0
- /package/dist/{src/devices → devices}/index.d.ts +0 -0
- /package/dist/{src/devices → devices}/store.d.ts +0 -0
- /package/dist/{src/devices → devices}/update.d.ts +0 -0
- /package/dist/{src/errors → errors}/destroy.d.ts +0 -0
- /package/dist/{src/errors → errors}/fetch.d.ts +0 -0
- /package/dist/{src/errors → errors}/index.d.ts +0 -0
- /package/dist/{src/errors → errors}/update.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/destroy.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/fetch.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/index.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/store.d.ts +0 -0
- /package/dist/{src/gift-cards → gift-cards}/update.d.ts +0 -0
- /package/dist/{src/index.d.ts → index.d.ts} +0 -0
- /package/dist/{src/orders → orders}/destroy.d.ts +0 -0
- /package/dist/{src/orders → orders}/events.d.ts +0 -0
- /package/dist/{src/orders → orders}/export.d.ts +0 -0
- /package/dist/{src/orders → orders}/fetch.d.ts +0 -0
- /package/dist/{src/orders → orders}/guards.d.ts +0 -0
- /package/dist/{src/orders → orders}/index.d.ts +0 -0
- /package/dist/{src/orders → orders}/place-order.d.ts +0 -0
- /package/dist/{src/orders → orders}/store.d.ts +0 -0
- /package/dist/{src/orders → orders}/totals.d.ts +0 -0
- /package/dist/{src/orders → orders}/update.d.ts +0 -0
- /package/dist/{src/orders → orders}/webhook.d.ts +0 -0
- /package/dist/{src/payments → payments}/destroy.d.ts +0 -0
- /package/dist/{src/payments → payments}/fetch.d.ts +0 -0
- /package/dist/{src/payments → payments}/index.d.ts +0 -0
- /package/dist/{src/payments → payments}/store.d.ts +0 -0
- /package/dist/{src/payments → payments}/update.d.ts +0 -0
- /package/dist/{src/products → products}/categories/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/categories/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/categories/index.d.ts +0 -0
- /package/dist/{src/products → products}/categories/store.d.ts +0 -0
- /package/dist/{src/products → products}/categories/update.d.ts +0 -0
- /package/dist/{src/products → products}/index.d.ts +0 -0
- /package/dist/{src/products → products}/items/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/items/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/items/index.d.ts +0 -0
- /package/dist/{src/products → products}/items/store.d.ts +0 -0
- /package/dist/{src/products → products}/items/update.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/index.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/store.d.ts +0 -0
- /package/dist/{src/products → products}/manufacturers/update.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/index.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/store.d.ts +0 -0
- /package/dist/{src/products → products}/reviews/update.d.ts +0 -0
- /package/dist/{src/products → products}/units/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/units/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/units/index.d.ts +0 -0
- /package/dist/{src/products → products}/units/store.d.ts +0 -0
- /package/dist/{src/products → products}/units/update.d.ts +0 -0
- /package/dist/{src/products → products}/variants/destroy.d.ts +0 -0
- /package/dist/{src/products → products}/variants/fetch.d.ts +0 -0
- /package/dist/{src/products → products}/variants/index.d.ts +0 -0
- /package/dist/{src/products → products}/variants/store.d.ts +0 -0
- /package/dist/{src/products → products}/variants/update.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/destroy.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/fetch.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/index.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/store.d.ts +0 -0
- /package/dist/{src/receipts → receipts}/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/delivery-routes/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/digital-deliveries/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/drivers/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/license-keys/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-methods/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-rates/update.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/destroy.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/fetch.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/index.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/store.d.ts +0 -0
- /package/dist/{src/shippings → shippings}/shipping-zones/update.d.ts +0 -0
- /package/dist/{src/tax → tax}/destroy.d.ts +0 -0
- /package/dist/{src/tax → tax}/fetch.d.ts +0 -0
- /package/dist/{src/tax → tax}/index.d.ts +0 -0
- /package/dist/{src/tax → tax}/store.d.ts +0 -0
- /package/dist/{src/tax → tax}/update.d.ts +0 -0
- /package/dist/{src/types.d.ts → types.d.ts} +0 -0
- /package/dist/{src/utils → utils}/typed-stats.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/index.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/destroy.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/fetch.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/index.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/store.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/products/update.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/destroy.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/fetch.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/index.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/store.d.ts +0 -0
- /package/dist/{src/waitlists → waitlists}/restaurant/update.d.ts +0 -0
|
@@ -1,538 +0,0 @@
|
|
|
1
|
-
import type { StacksExpressionBuilder } from '@stacksjs/database'
|
|
2
|
-
import { db } from '@stacksjs/database'
|
|
3
|
-
import { formatDate } from '@stacksjs/orm'
|
|
4
|
-
type WaitlistRestaurantJsonResponse = ModelRow<typeof WaitlistRestaurant>
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Fetch a restaurant waitlist entry by ID
|
|
8
|
-
*/
|
|
9
|
-
export async function fetchById(id: number): Promise<WaitlistRestaurantJsonResponse | undefined> {
|
|
10
|
-
return await db
|
|
11
|
-
.selectFrom('waitlist_restaurants')
|
|
12
|
-
.where('id', '=', id)
|
|
13
|
-
.selectAll()
|
|
14
|
-
.executeTakeFirst() as WaitlistRestaurantJsonResponse | undefined
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Fetch all restaurant waitlist entries
|
|
19
|
-
*/
|
|
20
|
-
export async function fetchAll(): Promise<WaitlistRestaurantJsonResponse[]> {
|
|
21
|
-
return await db.selectFrom('waitlist_restaurants').selectAll().execute() as WaitlistRestaurantJsonResponse[]
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Fetch the count of restaurant waitlist entries grouped by table preference
|
|
26
|
-
* @returns An object containing the count for each table preference
|
|
27
|
-
*/
|
|
28
|
-
export async function fetchCountByTablePreference(): Promise<Record<string, number>> {
|
|
29
|
-
const results = await db
|
|
30
|
-
.selectFrom('waitlist_restaurants')
|
|
31
|
-
.select(['table_preference', (eb: StacksExpressionBuilder) => eb.fn.count('id').as('count')] as any)
|
|
32
|
-
.groupBy('table_preference')
|
|
33
|
-
.execute() as { table_preference: string, count: number }[]
|
|
34
|
-
|
|
35
|
-
return results.reduce((acc: Record<string, number>, { table_preference, count }) => {
|
|
36
|
-
acc[table_preference as string] = count
|
|
37
|
-
return acc
|
|
38
|
-
}, {} as Record<string, number>)
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Fetch the count of restaurant waitlist entries for a specific date
|
|
43
|
-
* @param date The date to count entries for (defaults to today)
|
|
44
|
-
* @returns The count of entries for the specified date
|
|
45
|
-
*/
|
|
46
|
-
export async function fetchCountByDate(date: Date = new Date()): Promise<number> {
|
|
47
|
-
const startOfDay = new Date(date)
|
|
48
|
-
startOfDay.setHours(0, 0, 0, 0)
|
|
49
|
-
|
|
50
|
-
const endOfDay = new Date(date)
|
|
51
|
-
endOfDay.setHours(23, 59, 59, 999)
|
|
52
|
-
|
|
53
|
-
const startDateStr = formatDate(startOfDay)
|
|
54
|
-
const endDateStr = formatDate(endOfDay)
|
|
55
|
-
|
|
56
|
-
const result = await db
|
|
57
|
-
.selectFrom('waitlist_restaurants')
|
|
58
|
-
.select(((eb: StacksExpressionBuilder) => eb.fn.count('id').as('count')) as any)
|
|
59
|
-
.where('created_at', '>=', startDateStr)
|
|
60
|
-
.where('created_at', '<=', endDateStr)
|
|
61
|
-
.executeTakeFirst() as { count: number } | undefined
|
|
62
|
-
|
|
63
|
-
return result?.count ?? 0
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Fetch the count of restaurant waitlist entries with a specific party size
|
|
68
|
-
* @param partySize The party size to count entries for
|
|
69
|
-
* @returns The count of entries with the specified party size
|
|
70
|
-
*/
|
|
71
|
-
export async function fetchCountByPartySize(partySize: number): Promise<number> {
|
|
72
|
-
const result = await db
|
|
73
|
-
.selectFrom('waitlist_restaurants')
|
|
74
|
-
.select(((eb: StacksExpressionBuilder) => eb.fn.count('id').as('count')) as any)
|
|
75
|
-
.where('party_size', '=', partySize)
|
|
76
|
-
.executeTakeFirst() as { count: number } | undefined
|
|
77
|
-
|
|
78
|
-
return result?.count ?? 0
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Fetch the count of restaurant waitlist entries grouped by party size
|
|
83
|
-
* @returns An object containing the count for each party size
|
|
84
|
-
*/
|
|
85
|
-
export async function fetchCountByAllPartySizes(): Promise<Record<number, number>> {
|
|
86
|
-
const results = await db
|
|
87
|
-
.selectFrom('waitlist_restaurants')
|
|
88
|
-
.select(['party_size', (eb: StacksExpressionBuilder) => eb.fn.count('id').as('count')] as any)
|
|
89
|
-
.groupBy('party_size')
|
|
90
|
-
.execute() as { party_size: number, count: number }[]
|
|
91
|
-
|
|
92
|
-
return results.reduce((acc: Record<number, number>, { party_size, count }) => {
|
|
93
|
-
acc[party_size] = count
|
|
94
|
-
return acc
|
|
95
|
-
}, {} as Record<number, number>)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Fetch restaurant waitlist entries between two dates
|
|
100
|
-
* @param startDate The start date of the range
|
|
101
|
-
* @param endDate The end date of the range
|
|
102
|
-
* @returns Array of waitlist entries within the date range
|
|
103
|
-
*/
|
|
104
|
-
export async function fetchBetweenDates(
|
|
105
|
-
startDate: Date,
|
|
106
|
-
_endDate: Date,
|
|
107
|
-
): Promise<WaitlistRestaurantJsonResponse[]> {
|
|
108
|
-
const startDateStr = formatDate(startDate)
|
|
109
|
-
const endDateStr = formatDate(_endDate)
|
|
110
|
-
|
|
111
|
-
return await db
|
|
112
|
-
.selectFrom('waitlist_restaurants')
|
|
113
|
-
.selectAll()
|
|
114
|
-
.where('created_at', '>=', startDateStr)
|
|
115
|
-
.where('created_at', '<=', endDateStr)
|
|
116
|
-
.execute() as WaitlistRestaurantJsonResponse[]
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Fetch restaurant waitlist entries that were seated between two dates
|
|
121
|
-
* @param startDate The start date of the range
|
|
122
|
-
* @param endDate The end date of the range
|
|
123
|
-
* @returns Array of waitlist entries that were seated within the date range
|
|
124
|
-
*/
|
|
125
|
-
export async function fetchSeatedBetweenDates(
|
|
126
|
-
startDate: Date,
|
|
127
|
-
_endDate: Date,
|
|
128
|
-
): Promise<WaitlistRestaurantJsonResponse[]> {
|
|
129
|
-
const startDateStr = formatDate(startDate)
|
|
130
|
-
const endDateStr = formatDate(_endDate)
|
|
131
|
-
|
|
132
|
-
return await db
|
|
133
|
-
.selectFrom('waitlist_restaurants')
|
|
134
|
-
.selectAll()
|
|
135
|
-
.where('check_in_time', '>=', startDateStr)
|
|
136
|
-
.where('check_in_time', '<=', endDateStr)
|
|
137
|
-
.where('status', '=', 'seated')
|
|
138
|
-
.execute() as WaitlistRestaurantJsonResponse[]
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Fetch all restaurant waitlist entries with waiting status
|
|
143
|
-
* @returns Array of waitlist entries with waiting status
|
|
144
|
-
*/
|
|
145
|
-
export async function fetchWaiting(): Promise<WaitlistRestaurantJsonResponse[]> {
|
|
146
|
-
return await db
|
|
147
|
-
.selectFrom('waitlist_restaurants')
|
|
148
|
-
.selectAll()
|
|
149
|
-
.where('status', '=', 'waiting')
|
|
150
|
-
.execute() as WaitlistRestaurantJsonResponse[]
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* Fetch conversion rates for restaurant waitlist entries
|
|
155
|
-
* @returns Object containing total conversion rate and breakdown by status
|
|
156
|
-
*/
|
|
157
|
-
export async function fetchConversionRates(): Promise<{
|
|
158
|
-
totalConversionRate: number
|
|
159
|
-
statusBreakdown: Record<string, { count: number, percentage: number }>
|
|
160
|
-
}> {
|
|
161
|
-
const results = await db
|
|
162
|
-
.selectFrom('waitlist_restaurants')
|
|
163
|
-
.select(['status', (eb: StacksExpressionBuilder) => eb.fn.count('id').as('count')] as any)
|
|
164
|
-
.groupBy('status')
|
|
165
|
-
.execute() as { status: string, count: number }[]
|
|
166
|
-
|
|
167
|
-
const totalCount = results.reduce((sum: number, { count }) => sum + count, 0)
|
|
168
|
-
const seatedCount = results.find((r) => r.status === 'seated')?.count ?? 0
|
|
169
|
-
|
|
170
|
-
const totalConversionRate = totalCount > 0 ? (Number(seatedCount) / totalCount) * 100 : 0
|
|
171
|
-
|
|
172
|
-
const statusBreakdown = results.reduce((acc: Record<string, { count: number, percentage: number }>, { status, count }) => {
|
|
173
|
-
acc[status as string] = {
|
|
174
|
-
count,
|
|
175
|
-
percentage: totalCount > 0 ? (count / totalCount) * 100 : 0,
|
|
176
|
-
}
|
|
177
|
-
return acc
|
|
178
|
-
}, {} as Record<string, { count: number, percentage: number }>)
|
|
179
|
-
|
|
180
|
-
return {
|
|
181
|
-
totalConversionRate,
|
|
182
|
-
statusBreakdown,
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Fetch average wait times for restaurant waitlist entries
|
|
188
|
-
* @returns Object containing average quoted and actual wait times
|
|
189
|
-
*/
|
|
190
|
-
export async function fetchAverageWaitTimes(): Promise<{
|
|
191
|
-
averageQuotedWaitTime: number
|
|
192
|
-
averageActualWaitTime: number
|
|
193
|
-
}> {
|
|
194
|
-
const result = await db
|
|
195
|
-
.selectFrom('waitlist_restaurants')
|
|
196
|
-
.select([(eb: StacksExpressionBuilder) => eb.fn.avg('quoted_wait_time').as('avg_quoted_wait_time'), (eb: StacksExpressionBuilder) => eb.fn.avg('actual_wait_time').as('avg_actual_wait_time')] as any)
|
|
197
|
-
.executeTakeFirst() as { avg_quoted_wait_time: number, avg_actual_wait_time: number } | undefined
|
|
198
|
-
|
|
199
|
-
return {
|
|
200
|
-
averageQuotedWaitTime: result?.avg_quoted_wait_time ?? 0,
|
|
201
|
-
averageActualWaitTime: result?.avg_actual_wait_time ?? 0,
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Fetch all waiting entries with their quoted wait times
|
|
207
|
-
* @returns Array of waiting entries with their quoted wait times
|
|
208
|
-
*/
|
|
209
|
-
export async function fetchWaitingWithQuotedTimes(): Promise<{
|
|
210
|
-
entries: WaitlistRestaurantJsonResponse[]
|
|
211
|
-
totalQuotedWaitTime: number
|
|
212
|
-
averageQuotedWaitTime: number
|
|
213
|
-
}> {
|
|
214
|
-
const waitingEntries = await db
|
|
215
|
-
.selectFrom('waitlist_restaurants')
|
|
216
|
-
.selectAll()
|
|
217
|
-
.where('status', '=', 'waiting')
|
|
218
|
-
.execute() as WaitlistRestaurantJsonResponse[]
|
|
219
|
-
|
|
220
|
-
const totalQuotedWaitTime = waitingEntries.reduce((sum: any, entry: any) => sum + (entry.quoted_wait_time ?? 0), 0)
|
|
221
|
-
const averageQuotedWaitTime = waitingEntries.length > 0 ? totalQuotedWaitTime / waitingEntries.length : 0
|
|
222
|
-
|
|
223
|
-
return {
|
|
224
|
-
entries: waitingEntries,
|
|
225
|
-
totalQuotedWaitTime,
|
|
226
|
-
averageQuotedWaitTime,
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/**
|
|
231
|
-
* Fetch all waiting entries with party size calculations
|
|
232
|
-
* @returns Object containing waiting entries and party size statistics
|
|
233
|
-
*/
|
|
234
|
-
export async function fetchWaitingWithPartySizes(): Promise<{
|
|
235
|
-
entries: WaitlistRestaurantJsonResponse[]
|
|
236
|
-
totalPartySize: number
|
|
237
|
-
averagePartySize: number
|
|
238
|
-
partySizeBreakdown: Record<number, number>
|
|
239
|
-
}> {
|
|
240
|
-
const waitingEntries = await db
|
|
241
|
-
.selectFrom('waitlist_restaurants')
|
|
242
|
-
.selectAll()
|
|
243
|
-
.where('status', '=', 'waiting')
|
|
244
|
-
.execute() as WaitlistRestaurantJsonResponse[]
|
|
245
|
-
|
|
246
|
-
const totalPartySize = waitingEntries.reduce((sum: any, entry: any) => sum + entry.party_size, 0)
|
|
247
|
-
const averagePartySize = waitingEntries.length > 0 ? totalPartySize / waitingEntries.length : 0
|
|
248
|
-
|
|
249
|
-
// Calculate breakdown of party sizes
|
|
250
|
-
const partySizeBreakdown = waitingEntries.reduce((acc: any, entry: any) => {
|
|
251
|
-
acc[entry.party_size] = (acc[entry.party_size] || 0) + 1
|
|
252
|
-
return acc
|
|
253
|
-
}, {} as Record<number, number>)
|
|
254
|
-
|
|
255
|
-
return {
|
|
256
|
-
entries: waitingEntries as WaitlistRestaurantJsonResponse[],
|
|
257
|
-
totalPartySize,
|
|
258
|
-
averagePartySize,
|
|
259
|
-
partySizeBreakdown,
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Fetch tables turned statistics for today
|
|
265
|
-
* @returns Object containing tables turned statistics
|
|
266
|
-
*/
|
|
267
|
-
export async function fetchTablesTurnedToday(): Promise<{
|
|
268
|
-
totalTablesTurned: number
|
|
269
|
-
averagePartySize: number
|
|
270
|
-
totalCustomersSeated: number
|
|
271
|
-
breakdownByTablePreference: Record<string, number>
|
|
272
|
-
breakdownByPartySize: Record<number, number>
|
|
273
|
-
}> {
|
|
274
|
-
const today = new Date()
|
|
275
|
-
const startOfDay = new Date(today)
|
|
276
|
-
startOfDay.setHours(0, 0, 0, 0)
|
|
277
|
-
const endOfDay = new Date(today)
|
|
278
|
-
endOfDay.setHours(23, 59, 59, 999)
|
|
279
|
-
|
|
280
|
-
const startDateStr = formatDate(startOfDay)
|
|
281
|
-
const endDateStr = formatDate(endOfDay)
|
|
282
|
-
|
|
283
|
-
// Fetch all seated entries for today
|
|
284
|
-
const seatedEntries = await db
|
|
285
|
-
.selectFrom('waitlist_restaurants')
|
|
286
|
-
.selectAll()
|
|
287
|
-
.where('status', '=', 'seated')
|
|
288
|
-
.where('check_in_time', '>=', startDateStr)
|
|
289
|
-
.where('check_in_time', '<=', endDateStr)
|
|
290
|
-
.execute()
|
|
291
|
-
|
|
292
|
-
// Calculate total tables turned
|
|
293
|
-
const totalTablesTurned = seatedEntries.length
|
|
294
|
-
|
|
295
|
-
// Calculate total customers seated
|
|
296
|
-
const totalCustomersSeated = seatedEntries.reduce((sum: any, entry: any) => sum + entry.party_size, 0)
|
|
297
|
-
|
|
298
|
-
// Calculate average party size
|
|
299
|
-
const averagePartySize = totalTablesTurned > 0 ? totalCustomersSeated / totalTablesTurned : 0
|
|
300
|
-
|
|
301
|
-
// Calculate breakdown by table preference
|
|
302
|
-
const breakdownByTablePreference = seatedEntries.reduce((acc: any, entry: any) => {
|
|
303
|
-
acc[entry.table_preference as string] = (acc[entry.table_preference as string] || 0) + 1
|
|
304
|
-
return acc
|
|
305
|
-
}, {} as Record<string, number>)
|
|
306
|
-
|
|
307
|
-
// Calculate breakdown by party size
|
|
308
|
-
const breakdownByPartySize = seatedEntries.reduce((acc: any, entry: any) => {
|
|
309
|
-
acc[entry.party_size] = (acc[entry.party_size] || 0) + 1
|
|
310
|
-
return acc
|
|
311
|
-
}, {} as Record<number, number>)
|
|
312
|
-
|
|
313
|
-
return {
|
|
314
|
-
totalTablesTurned,
|
|
315
|
-
averagePartySize,
|
|
316
|
-
totalCustomersSeated,
|
|
317
|
-
breakdownByTablePreference,
|
|
318
|
-
breakdownByPartySize,
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Fetch seating rate statistics
|
|
324
|
-
* @param startDate Start date for filtering entries
|
|
325
|
-
* @param endDate End date for filtering entries
|
|
326
|
-
* @returns Object containing seating rate and status breakdown
|
|
327
|
-
*/
|
|
328
|
-
export async function fetchSeatingRate(
|
|
329
|
-
_startDate: Date,
|
|
330
|
-
_endDate: Date,
|
|
331
|
-
): Promise<{
|
|
332
|
-
totalEntries: number
|
|
333
|
-
seatedEntries: number
|
|
334
|
-
seatingRate: number
|
|
335
|
-
statusBreakdown: Record<string, { count: number, percentage: number }>
|
|
336
|
-
}> {
|
|
337
|
-
const startDateStr = formatDate(_startDate)
|
|
338
|
-
const endDateStr = formatDate(_endDate)
|
|
339
|
-
|
|
340
|
-
const results = await db
|
|
341
|
-
.selectFrom('waitlist_restaurants')
|
|
342
|
-
.select(['status', (eb: StacksExpressionBuilder) => eb.fn.count('id').as('count')] as any)
|
|
343
|
-
.where('check_in_time', '>=', startDateStr)
|
|
344
|
-
.where('check_in_time', '<=', endDateStr)
|
|
345
|
-
.groupBy('status')
|
|
346
|
-
.execute() as { status: string, count: number }[]
|
|
347
|
-
|
|
348
|
-
const totalEntries = results.reduce((sum: number, { count }) => sum + count, 0)
|
|
349
|
-
const seatedCount = results.find((r) => r.status === 'seated')?.count ?? 0
|
|
350
|
-
|
|
351
|
-
const seatingRate = totalEntries > 0 ? (Number(seatedCount) / totalEntries) * 100 : 0
|
|
352
|
-
|
|
353
|
-
const statusBreakdown = results.reduce((acc: Record<string, { count: number, percentage: number }>, { status, count }) => {
|
|
354
|
-
acc[status as string] = {
|
|
355
|
-
count,
|
|
356
|
-
percentage: totalEntries > 0 ? (count / totalEntries) * 100 : 0,
|
|
357
|
-
}
|
|
358
|
-
return acc
|
|
359
|
-
}, {} as Record<string, { count: number, percentage: number }>)
|
|
360
|
-
|
|
361
|
-
return {
|
|
362
|
-
totalEntries,
|
|
363
|
-
seatedEntries: seatedCount,
|
|
364
|
-
seatingRate,
|
|
365
|
-
statusBreakdown,
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Fetch no-show statistics
|
|
371
|
-
* @param startDate Start date for filtering entries
|
|
372
|
-
* @param endDate End date for filtering entries
|
|
373
|
-
* @returns Object containing no-show statistics and related information
|
|
374
|
-
*/
|
|
375
|
-
export async function fetchNoShowStats(
|
|
376
|
-
_startDate: Date,
|
|
377
|
-
_endDate: Date,
|
|
378
|
-
): Promise<{
|
|
379
|
-
totalNoShows: number
|
|
380
|
-
noShowRate: number
|
|
381
|
-
averageQuotedWaitTime: number
|
|
382
|
-
averagePartySize: number
|
|
383
|
-
breakdownByTablePreference: Record<string, number>
|
|
384
|
-
breakdownByPartySize: Record<number, number>
|
|
385
|
-
}> {
|
|
386
|
-
const startDateStr = formatDate(_startDate)
|
|
387
|
-
const endDateStr = formatDate(_endDate)
|
|
388
|
-
|
|
389
|
-
// Build base query for no-show entries
|
|
390
|
-
const noShowQuery = db
|
|
391
|
-
.selectFrom('waitlist_restaurants')
|
|
392
|
-
.selectAll()
|
|
393
|
-
.where('status', '=', 'no_show')
|
|
394
|
-
.where('check_in_time', '>=', startDateStr)
|
|
395
|
-
.where('check_in_time', '<=', endDateStr)
|
|
396
|
-
|
|
397
|
-
// Build base query for total entries - use expression builder for count
|
|
398
|
-
const totalResult = await db
|
|
399
|
-
.selectFrom('waitlist_restaurants')
|
|
400
|
-
.select(((eb: StacksExpressionBuilder) => eb.fn.count('id').as('count')) as any)
|
|
401
|
-
.where('check_in_time', '>=', startDateStr)
|
|
402
|
-
.where('check_in_time', '<=', endDateStr)
|
|
403
|
-
.executeTakeFirst() as { count: number } | undefined
|
|
404
|
-
|
|
405
|
-
// Execute queries
|
|
406
|
-
const noShowEntries = await noShowQuery.execute()
|
|
407
|
-
|
|
408
|
-
const totalNoShows = noShowEntries.length
|
|
409
|
-
|
|
410
|
-
const noShowRate = totalResult?.count && totalResult.count > 0
|
|
411
|
-
? (totalNoShows / totalResult.count) * 100
|
|
412
|
-
: 0
|
|
413
|
-
|
|
414
|
-
// Calculate average quoted wait time for no-shows
|
|
415
|
-
const totalQuotedWaitTime = noShowEntries.reduce((sum: any, entry: any) => sum + (entry.quoted_wait_time ?? 0), 0)
|
|
416
|
-
const averageQuotedWaitTime = totalNoShows > 0 ? totalQuotedWaitTime / totalNoShows : 0
|
|
417
|
-
|
|
418
|
-
// Calculate average party size for no-shows
|
|
419
|
-
const totalPartySize = noShowEntries.reduce((sum: any, entry: any) => sum + entry.party_size, 0)
|
|
420
|
-
const averagePartySize = totalNoShows > 0 ? totalPartySize / totalNoShows : 0
|
|
421
|
-
|
|
422
|
-
// Calculate breakdown by table preference
|
|
423
|
-
const breakdownByTablePreference = noShowEntries.reduce((acc: any, entry: any) => {
|
|
424
|
-
acc[entry.table_preference as string] = (acc[entry.table_preference as string] || 0) + 1
|
|
425
|
-
return acc
|
|
426
|
-
}, {} as Record<string, number>)
|
|
427
|
-
|
|
428
|
-
// Calculate breakdown by party size
|
|
429
|
-
const breakdownByPartySize = noShowEntries.reduce((acc: any, entry: any) => {
|
|
430
|
-
acc[entry.party_size] = (acc[entry.party_size] || 0) + 1
|
|
431
|
-
return acc
|
|
432
|
-
}, {} as Record<number, number>)
|
|
433
|
-
|
|
434
|
-
return {
|
|
435
|
-
totalNoShows,
|
|
436
|
-
noShowRate,
|
|
437
|
-
averageQuotedWaitTime,
|
|
438
|
-
averagePartySize,
|
|
439
|
-
breakdownByTablePreference,
|
|
440
|
-
breakdownByPartySize,
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
/**
|
|
445
|
-
* Fetch current wait time statistics
|
|
446
|
-
* @returns Object containing average quoted and actual wait times
|
|
447
|
-
*/
|
|
448
|
-
export async function fetchCurrentWaitTimes(): Promise<{
|
|
449
|
-
averageQuoted: number
|
|
450
|
-
averageActual: number
|
|
451
|
-
}> {
|
|
452
|
-
const waitingEntries = await db
|
|
453
|
-
.selectFrom('waitlist_restaurants')
|
|
454
|
-
.select(['quoted_wait_time', 'actual_wait_time'])
|
|
455
|
-
.where('status', '=', 'waiting')
|
|
456
|
-
.execute()
|
|
457
|
-
|
|
458
|
-
const totalQuoted = waitingEntries.reduce((sum: any, entry: any) => sum + (entry.quoted_wait_time || 0), 0)
|
|
459
|
-
const totalActual = waitingEntries.reduce((sum: any, entry: any) => sum + (entry.actual_wait_time || 0), 0)
|
|
460
|
-
const count = waitingEntries.length
|
|
461
|
-
|
|
462
|
-
return {
|
|
463
|
-
averageQuoted: count > 0 ? totalQuoted / count : 0,
|
|
464
|
-
averageActual: count > 0 ? totalActual / count : 0,
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
/**
|
|
469
|
-
* Fetch seated statistics for the last 24 hours
|
|
470
|
-
* @returns Object containing total seated count and hourly breakdown
|
|
471
|
-
*/
|
|
472
|
-
export async function fetchSeatedStats(): Promise<{
|
|
473
|
-
total: number
|
|
474
|
-
byHour: Array<{ hour: number, count: number }>
|
|
475
|
-
}> {
|
|
476
|
-
const twentyFourHoursAgo = Date.now() - 24 * 60 * 60 * 1000
|
|
477
|
-
const seatedEntries = await db
|
|
478
|
-
.selectFrom('waitlist_restaurants')
|
|
479
|
-
.select(['seated_at'])
|
|
480
|
-
.where('status', '=', 'seated')
|
|
481
|
-
.where('seated_at', '>=', twentyFourHoursAgo)
|
|
482
|
-
.execute()
|
|
483
|
-
|
|
484
|
-
const byHour = Array.from({ length: 24 }, (_, hour) => ({
|
|
485
|
-
hour,
|
|
486
|
-
count: seatedEntries.filter((entry: any) => {
|
|
487
|
-
const entryHour = entry.seated_at
|
|
488
|
-
|
|
489
|
-
return entryHour === hour
|
|
490
|
-
}).length,
|
|
491
|
-
}))
|
|
492
|
-
|
|
493
|
-
return {
|
|
494
|
-
total: seatedEntries.length,
|
|
495
|
-
byHour,
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
/**
|
|
500
|
-
* Fetch time series statistics for all statuses
|
|
501
|
-
* @returns Object containing daily counts for each status
|
|
502
|
-
*/
|
|
503
|
-
export async function fetchTimeSeriesStats(): Promise<Record<string, {
|
|
504
|
-
total: number
|
|
505
|
-
waiting: number
|
|
506
|
-
seated: number
|
|
507
|
-
cancelled: number
|
|
508
|
-
no_show: number
|
|
509
|
-
}>> {
|
|
510
|
-
const entries = await db
|
|
511
|
-
.selectFrom('waitlist_restaurants')
|
|
512
|
-
.select(['created_at', 'status'])
|
|
513
|
-
.execute()
|
|
514
|
-
|
|
515
|
-
return entries.reduce((acc: any, curr: any) => {
|
|
516
|
-
const date = curr.created_at
|
|
517
|
-
|
|
518
|
-
if (!acc[date!]) {
|
|
519
|
-
acc[date!] = {
|
|
520
|
-
total: 0,
|
|
521
|
-
waiting: 0,
|
|
522
|
-
seated: 0,
|
|
523
|
-
cancelled: 0,
|
|
524
|
-
no_show: 0,
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
acc[date!].total++
|
|
528
|
-
acc[date!][curr.status]++
|
|
529
|
-
|
|
530
|
-
return acc
|
|
531
|
-
}, {} as Record<string, {
|
|
532
|
-
total: number
|
|
533
|
-
waiting: number
|
|
534
|
-
seated: number
|
|
535
|
-
cancelled: number
|
|
536
|
-
no_show: number
|
|
537
|
-
}>)
|
|
538
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
// Functions from destroy.ts
|
|
2
|
-
export {
|
|
3
|
-
bulkDestroy,
|
|
4
|
-
destroy,
|
|
5
|
-
} from './destroy'
|
|
6
|
-
|
|
7
|
-
// Functions from fetch.ts
|
|
8
|
-
export {
|
|
9
|
-
fetchAll,
|
|
10
|
-
fetchAverageWaitTimes,
|
|
11
|
-
fetchBetweenDates,
|
|
12
|
-
fetchById,
|
|
13
|
-
fetchConversionRates,
|
|
14
|
-
fetchCountByAllPartySizes,
|
|
15
|
-
fetchCountByDate,
|
|
16
|
-
fetchCountByPartySize,
|
|
17
|
-
fetchCountByTablePreference,
|
|
18
|
-
fetchCurrentWaitTimes,
|
|
19
|
-
fetchNoShowStats,
|
|
20
|
-
fetchSeatedBetweenDates,
|
|
21
|
-
fetchSeatedStats,
|
|
22
|
-
fetchSeatingRate,
|
|
23
|
-
fetchTablesTurnedToday,
|
|
24
|
-
fetchTimeSeriesStats,
|
|
25
|
-
fetchWaiting,
|
|
26
|
-
fetchWaitingWithPartySizes,
|
|
27
|
-
fetchWaitingWithQuotedTimes,
|
|
28
|
-
} from './fetch'
|
|
29
|
-
|
|
30
|
-
// Functions from store.ts
|
|
31
|
-
export {
|
|
32
|
-
bulkStore,
|
|
33
|
-
store,
|
|
34
|
-
} from './store'
|
|
35
|
-
|
|
36
|
-
// Functions from update.ts
|
|
37
|
-
export {
|
|
38
|
-
update,
|
|
39
|
-
updatePartySize,
|
|
40
|
-
updateQueuePosition,
|
|
41
|
-
updateStatus,
|
|
42
|
-
updateWaitTimes,
|
|
43
|
-
} from './update'
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
type WaitlistRestaurantJsonResponse = ModelRow<typeof WaitlistRestaurant>
|
|
2
|
-
type NewWaitlistRestaurant = NewModelData<typeof WaitlistRestaurant>
|
|
3
|
-
import { randomUUIDv7 } from 'bun'
|
|
4
|
-
import { db } from '@stacksjs/database'
|
|
5
|
-
import { formatDate } from '@stacksjs/orm'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Create a new restaurant waitlist entry
|
|
9
|
-
*
|
|
10
|
-
* @param data Restaurant waitlist data to store
|
|
11
|
-
* @returns The newly created restaurant waitlist record
|
|
12
|
-
*/
|
|
13
|
-
export async function store(data: NewWaitlistRestaurant): Promise<WaitlistRestaurantJsonResponse> {
|
|
14
|
-
try {
|
|
15
|
-
const d = data as Record<string, unknown>
|
|
16
|
-
const waitlistData = {
|
|
17
|
-
name: data.name,
|
|
18
|
-
email: data.email,
|
|
19
|
-
phone: data.phone,
|
|
20
|
-
party_size: d.party_size,
|
|
21
|
-
check_in_time: typeof d.check_in_time === 'number' ? formatDate(d.check_in_time) : d.check_in_time,
|
|
22
|
-
table_preference: d.table_preference,
|
|
23
|
-
status: data.status || 'waiting',
|
|
24
|
-
quoted_wait_time: data.quoted_wait_time,
|
|
25
|
-
actual_wait_time: data.actual_wait_time,
|
|
26
|
-
queue_position: data.queue_position,
|
|
27
|
-
customer_id: data.customer_id,
|
|
28
|
-
uuid: randomUUIDv7(),
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Filter out undefined values to avoid storing explicit nulls
|
|
32
|
-
const filteredData: Record<string, any> = {}
|
|
33
|
-
for (const [key, value] of Object.entries(waitlistData)) {
|
|
34
|
-
if (value !== undefined) {
|
|
35
|
-
filteredData[key] = value
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const result = await db
|
|
40
|
-
.insertInto('waitlist_restaurants')
|
|
41
|
-
.values(filteredData)
|
|
42
|
-
.returningAll()
|
|
43
|
-
.executeTakeFirst()
|
|
44
|
-
|
|
45
|
-
if (!result)
|
|
46
|
-
throw new Error('Failed to create restaurant waitlist entry')
|
|
47
|
-
|
|
48
|
-
// Convert null values to undefined for nullable fields
|
|
49
|
-
const cleaned: any = { ...result }
|
|
50
|
-
for (const key of Object.keys(cleaned)) {
|
|
51
|
-
if (cleaned[key] === null)
|
|
52
|
-
cleaned[key] = undefined
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return cleaned as WaitlistRestaurantJsonResponse
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
if (error instanceof Error) {
|
|
59
|
-
throw new TypeError(`Failed to create restaurant waitlist entry: ${error.message}`)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
throw error
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Create multiple restaurant waitlist entries at once
|
|
68
|
-
*
|
|
69
|
-
* @param data Array of restaurant waitlist data to store
|
|
70
|
-
* @returns Number of restaurant waitlist entries created
|
|
71
|
-
*/
|
|
72
|
-
export async function bulkStore(data: NewWaitlistRestaurant[]): Promise<number> {
|
|
73
|
-
if (!data.length)
|
|
74
|
-
return 0
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const waitlistDataArray = data.map((item) => {
|
|
78
|
-
const i = item as Record<string, unknown>
|
|
79
|
-
return {
|
|
80
|
-
name: item.name,
|
|
81
|
-
email: item.email,
|
|
82
|
-
phone: item.phone,
|
|
83
|
-
party_size: i.party_size,
|
|
84
|
-
check_in_time: typeof i.check_in_time === 'number' ? formatDate(i.check_in_time as number) : i.check_in_time,
|
|
85
|
-
table_preference: i.table_preference,
|
|
86
|
-
status: item.status || 'waiting',
|
|
87
|
-
quoted_wait_time: item.quoted_wait_time,
|
|
88
|
-
actual_wait_time: item.actual_wait_time,
|
|
89
|
-
queue_position: item.queue_position,
|
|
90
|
-
customer_id: item.customer_id,
|
|
91
|
-
uuid: randomUUIDv7(),
|
|
92
|
-
}
|
|
93
|
-
})
|
|
94
|
-
|
|
95
|
-
const result = await db
|
|
96
|
-
.insertInto('waitlist_restaurants')
|
|
97
|
-
.values(waitlistDataArray)
|
|
98
|
-
.executeTakeFirst()
|
|
99
|
-
|
|
100
|
-
return Number(result.numInsertedOrUpdatedRows)
|
|
101
|
-
}
|
|
102
|
-
catch (error) {
|
|
103
|
-
if (error instanceof Error) {
|
|
104
|
-
throw new TypeError(`Failed to create restaurant waitlist entries in bulk: ${error.message}`)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
throw error
|
|
108
|
-
}
|
|
109
|
-
}
|