@stacksjs/commerce 0.70.54 → 0.70.55

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.
Files changed (165) hide show
  1. package/package.json +3 -2
  2. package/src/carts/destroy.ts +54 -0
  3. package/src/carts/fetch.ts +20 -0
  4. package/src/carts/index.ts +13 -0
  5. package/src/carts/store.ts +75 -0
  6. package/src/carts/update.ts +78 -0
  7. package/src/coupons/destroy.ts +49 -0
  8. package/src/coupons/fetch.ts +510 -0
  9. package/src/coupons/index.ts +30 -0
  10. package/src/coupons/store.ts +46 -0
  11. package/src/coupons/update.ts +147 -0
  12. package/src/customers/destroy.ts +62 -0
  13. package/src/customers/fetch.ts +20 -0
  14. package/src/customers/index.ts +17 -0
  15. package/src/customers/store.ts +45 -0
  16. package/src/customers/update.ts +44 -0
  17. package/src/devices/destroy.ts +54 -0
  18. package/src/devices/export.ts +98 -0
  19. package/src/devices/fetch.ts +125 -0
  20. package/src/devices/index.ts +31 -0
  21. package/src/devices/store.ts +82 -0
  22. package/src/devices/update.ts +125 -0
  23. package/src/errors/destroy.ts +54 -0
  24. package/src/errors/fetch.ts +197 -0
  25. package/src/errors/index.ts +28 -0
  26. package/src/errors/update.ts +116 -0
  27. package/src/gift-cards/destroy.ts +87 -0
  28. package/src/gift-cards/fetch.ts +431 -0
  29. package/src/gift-cards/index.ts +26 -0
  30. package/src/gift-cards/store.ts +56 -0
  31. package/src/gift-cards/update.ts +102 -0
  32. package/src/index.ts +78 -0
  33. package/src/orders/destroy.ts +111 -0
  34. package/src/orders/events.ts +121 -0
  35. package/src/orders/export.ts +158 -0
  36. package/src/orders/fetch.ts +379 -0
  37. package/src/orders/guards.ts +261 -0
  38. package/src/orders/index.ts +91 -0
  39. package/src/orders/place-order.ts +274 -0
  40. package/src/orders/store.ts +51 -0
  41. package/src/orders/totals.ts +190 -0
  42. package/src/orders/update.ts +164 -0
  43. package/src/orders/webhook.ts +312 -0
  44. package/src/payments/destroy.ts +56 -0
  45. package/src/payments/fetch.ts +288 -0
  46. package/src/payments/index.ts +16 -0
  47. package/src/payments/store.ts +63 -0
  48. package/src/payments/update.ts +52 -0
  49. package/src/product.ts +0 -0
  50. package/src/products/categories/destroy.ts +103 -0
  51. package/src/products/categories/fetch.ts +285 -0
  52. package/src/products/categories/index.ts +36 -0
  53. package/src/products/categories/store.ts +87 -0
  54. package/src/products/categories/update.ts +251 -0
  55. package/src/products/index.ts +35 -0
  56. package/src/products/items/destroy.ts +54 -0
  57. package/src/products/items/fetch.ts +282 -0
  58. package/src/products/items/index.ts +26 -0
  59. package/src/products/items/store.ts +84 -0
  60. package/src/products/items/update.ts +324 -0
  61. package/src/products/manufacturers/destroy.ts +56 -0
  62. package/src/products/manufacturers/fetch.ts +117 -0
  63. package/src/products/manufacturers/index.ts +24 -0
  64. package/src/products/manufacturers/store.ts +82 -0
  65. package/src/products/manufacturers/update.ts +113 -0
  66. package/src/products/reviews/destroy.ts +56 -0
  67. package/src/products/reviews/fetch.ts +63 -0
  68. package/src/products/reviews/index.ts +25 -0
  69. package/src/products/reviews/store.ts +46 -0
  70. package/src/products/reviews/update.ts +82 -0
  71. package/src/products/units/destroy.ts +56 -0
  72. package/src/products/units/fetch.ts +20 -0
  73. package/src/products/units/index.ts +13 -0
  74. package/src/products/units/store.ts +162 -0
  75. package/src/products/units/update.ts +159 -0
  76. package/src/products/variants/destroy.ts +56 -0
  77. package/src/products/variants/fetch.ts +20 -0
  78. package/src/products/variants/index.ts +21 -0
  79. package/src/products/variants/store.ts +136 -0
  80. package/src/products/variants/update.ts +104 -0
  81. package/src/receipts/destroy.ts +54 -0
  82. package/src/receipts/export.ts +0 -0
  83. package/src/receipts/fetch.ts +222 -0
  84. package/src/receipts/index.ts +24 -0
  85. package/src/receipts/printer.ts +69 -0
  86. package/src/receipts/store.ts +69 -0
  87. package/src/receipts/update.ts +124 -0
  88. package/src/shippings/delivery-routes/destroy.ts +54 -0
  89. package/src/shippings/delivery-routes/fetch.ts +42 -0
  90. package/src/shippings/delivery-routes/index.ts +26 -0
  91. package/src/shippings/delivery-routes/store.ts +69 -0
  92. package/src/shippings/delivery-routes/update.ts +120 -0
  93. package/src/shippings/digital-deliveries/destroy.ts +111 -0
  94. package/src/shippings/digital-deliveries/fetch.ts +20 -0
  95. package/src/shippings/digital-deliveries/index.ts +26 -0
  96. package/src/shippings/digital-deliveries/store.ts +76 -0
  97. package/src/shippings/digital-deliveries/update.ts +129 -0
  98. package/src/shippings/drivers/destroy.ts +78 -0
  99. package/src/shippings/drivers/fetch.ts +20 -0
  100. package/src/shippings/drivers/index.ts +24 -0
  101. package/src/shippings/drivers/store.ts +69 -0
  102. package/src/shippings/drivers/update.ts +117 -0
  103. package/src/shippings/index.ts +39 -0
  104. package/src/shippings/license-keys/destroy.ts +111 -0
  105. package/src/shippings/license-keys/fetch.ts +20 -0
  106. package/src/shippings/license-keys/index.ts +26 -0
  107. package/src/shippings/license-keys/store.ts +77 -0
  108. package/src/shippings/license-keys/update.ts +117 -0
  109. package/src/shippings/shipping-methods/destroy.ts +111 -0
  110. package/src/shippings/shipping-methods/fetch.ts +62 -0
  111. package/src/shippings/shipping-methods/index.ts +28 -0
  112. package/src/shippings/shipping-methods/store.ts +123 -0
  113. package/src/shippings/shipping-methods/update.ts +120 -0
  114. package/src/shippings/shipping-rates/destroy.ts +102 -0
  115. package/src/shippings/shipping-rates/fetch.ts +320 -0
  116. package/src/shippings/shipping-rates/index.ts +36 -0
  117. package/src/shippings/shipping-rates/store.ts +102 -0
  118. package/src/shippings/shipping-rates/update.ts +139 -0
  119. package/src/shippings/shipping-zones/destroy.ts +111 -0
  120. package/src/shippings/shipping-zones/fetch.ts +96 -0
  121. package/src/shippings/shipping-zones/index.ts +26 -0
  122. package/src/shippings/shipping-zones/store.ts +74 -0
  123. package/src/shippings/shipping-zones/update.ts +156 -0
  124. package/src/tax/destroy.ts +54 -0
  125. package/src/tax/fetch.ts +20 -0
  126. package/src/tax/index.ts +24 -0
  127. package/src/tax/store.ts +69 -0
  128. package/src/tax/update.ts +119 -0
  129. package/src/tests/coupons.test.ts +90 -0
  130. package/src/tests/customers.test.ts +39 -0
  131. package/src/tests/device.test.ts +111 -0
  132. package/src/tests/digitals.test.ts +31 -0
  133. package/src/tests/drivers.test.ts +25 -0
  134. package/src/tests/gift-cards.test.ts +36 -0
  135. package/src/tests/license.test.ts +31 -0
  136. package/src/tests/manufacturers.test.ts +80 -0
  137. package/src/tests/orders.test.ts +25 -0
  138. package/src/tests/payments.test.ts +75 -0
  139. package/src/tests/rates.test.ts +367 -0
  140. package/src/tests/receipts.test.ts +287 -0
  141. package/src/tests/restaurant.test.ts +522 -0
  142. package/src/tests/reviews.test.ts +165 -0
  143. package/src/tests/routes.test.ts +51 -0
  144. package/src/tests/setup.ts +149 -0
  145. package/src/tests/shipping.test.ts +88 -0
  146. package/src/tests/tax.test.ts +25 -0
  147. package/src/tests/units.test.ts +110 -0
  148. package/src/tests/variants.test.ts +133 -0
  149. package/src/tests/waitlist.test.ts +303 -0
  150. package/src/tests/zones.test.ts +86 -0
  151. package/src/types.ts +312 -0
  152. package/src/utils/typed-stats.ts +67 -0
  153. package/src/waitlists/index.ts +19 -0
  154. package/src/waitlists/products/destroy.ts +65 -0
  155. package/src/waitlists/products/export.ts +113 -0
  156. package/src/waitlists/products/fetch.ts +362 -0
  157. package/src/waitlists/products/index.ts +33 -0
  158. package/src/waitlists/products/store.ts +112 -0
  159. package/src/waitlists/products/update.ts +125 -0
  160. package/src/waitlists/restaurant/destroy.ts +65 -0
  161. package/src/waitlists/restaurant/export.ts +107 -0
  162. package/src/waitlists/restaurant/fetch.ts +538 -0
  163. package/src/waitlists/restaurant/index.ts +43 -0
  164. package/src/waitlists/restaurant/store.ts +109 -0
  165. package/src/waitlists/restaurant/update.ts +198 -0
@@ -0,0 +1,222 @@
1
+ import { db } from '@stacksjs/database'
2
+ import { aggregateStats } from '../utils/typed-stats'
3
+ type ReceiptJsonResponse = ModelRow<typeof Receipt>
4
+
5
+ /**
6
+ * Fetch a print log by ID
7
+ */
8
+ export async function fetchById(id: number): Promise<ReceiptJsonResponse | undefined> {
9
+ // Single `as` at the kysely → typed-result boundary — schema-wide
10
+ // typing for `selectAll()` would force every consumer to import the
11
+ // generated row types, which we want to keep optional in user code.
12
+ return await db
13
+ .selectFrom('receipts')
14
+ .where('id', '=', id)
15
+ .selectAll()
16
+ .executeTakeFirst() as ReceiptJsonResponse | undefined
17
+ }
18
+
19
+ /**
20
+ * Fetch all print logs
21
+ */
22
+ export async function fetchAll(): Promise<ReceiptJsonResponse[]> {
23
+ return await db.selectFrom('receipts').selectAll().execute() as ReceiptJsonResponse[]
24
+ }
25
+
26
+ /**
27
+ * Fetch print job statistics by status within a date range
28
+ *
29
+ * @param startDate Start date for the range
30
+ * @param endDate End date for the range
31
+ * @returns Object containing counts for each status and total
32
+ */
33
+ export async function fetchPrintJobStats(
34
+ _startDate: Date | number,
35
+ _endDate: Date | number,
36
+ ): Promise<{
37
+ total: number
38
+ success: number
39
+ failed: number
40
+ warning: number
41
+ averageSize: number
42
+ averagePages: number
43
+ averageDuration: number
44
+ }> {
45
+ const start = typeof _startDate === 'number' ? _startDate : _startDate.getTime()
46
+ const end = typeof _endDate === 'number' ? _endDate : _endDate.getTime()
47
+
48
+ const stats = await aggregateStats('receipts', {
49
+ total: { kind: 'count' },
50
+ success: { kind: 'count', filter: { column: 'status', op: '=', value: 'success' } },
51
+ failed: { kind: 'count', filter: { column: 'status', op: '=', value: 'failed' } },
52
+ warning: { kind: 'count', filter: { column: 'status', op: '=', value: 'warning' } },
53
+ averageSize: { kind: 'avg', column: 'size' },
54
+ averagePages: { kind: 'avg', column: 'pages' },
55
+ averageDuration: { kind: 'avg', column: 'duration' },
56
+ }, qb => qb.where('timestamp', '>=', start).where('timestamp', '<=', end))
57
+
58
+ return {
59
+ total: stats.total,
60
+ success: stats.success,
61
+ failed: stats.failed,
62
+ warning: stats.warning,
63
+ averageSize: Math.round(stats.averageSize),
64
+ averagePages: Math.round(stats.averagePages),
65
+ averageDuration: Math.round(stats.averageDuration),
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Calculate the success rate percentage for print jobs within a date range
71
+ *
72
+ * @param startDate Start date for the range
73
+ * @param endDate End date for the range
74
+ * @returns Object containing success rate percentage and detailed counts
75
+ */
76
+ export async function fetchSuccessRate(
77
+ _startDate: Date | number,
78
+ _endDate: Date | number,
79
+ ): Promise<{
80
+ successRate: number
81
+ total: number
82
+ success: number
83
+ failed: number
84
+ warning: number
85
+ }> {
86
+ const start = typeof _startDate === 'number' ? _startDate : _startDate.getTime()
87
+ const end = typeof _endDate === 'number' ? _endDate : _endDate.getTime()
88
+
89
+ const stats = await aggregateStats('receipts', {
90
+ total: { kind: 'count' },
91
+ success: { kind: 'count', filter: { column: 'status', op: '=', value: 'success' } },
92
+ failed: { kind: 'count', filter: { column: 'status', op: '=', value: 'failed' } },
93
+ warning: { kind: 'count', filter: { column: 'status', op: '=', value: 'warning' } },
94
+ }, qb => qb.where('timestamp', '>=', start).where('timestamp', '<=', end))
95
+
96
+ const successRate = stats.total > 0 ? Math.round((stats.success / stats.total) * 100) : 0
97
+
98
+ return {
99
+ successRate,
100
+ total: stats.total,
101
+ success: stats.success,
102
+ failed: stats.failed,
103
+ warning: stats.warning,
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Calculate total pages and average pages per receipt within a date range
109
+ *
110
+ * @param startDate Start date for the range
111
+ * @param endDate End date for the range
112
+ * @returns Object containing total pages and average pages per receipt
113
+ */
114
+ export async function fetchPageStats(
115
+ _startDate: Date | number,
116
+ _endDate: Date | number,
117
+ ): Promise<{
118
+ totalPages: number
119
+ averagePagesPerReceipt: number
120
+ totalReceipts: number
121
+ }> {
122
+ const start = typeof _startDate === 'number' ? _startDate : _startDate.getTime()
123
+ const end = typeof _endDate === 'number' ? _endDate : _endDate.getTime()
124
+
125
+ const stats = await aggregateStats('receipts', {
126
+ totalReceipts: { kind: 'count' },
127
+ totalPages: { kind: 'sum', column: 'pages' },
128
+ averagePagesPerReceipt: { kind: 'avg', column: 'pages' },
129
+ }, qb => qb.where('timestamp', '>=', start).where('timestamp', '<=', end))
130
+
131
+ return {
132
+ totalPages: stats.totalPages,
133
+ averagePagesPerReceipt: Math.round(stats.averagePagesPerReceipt),
134
+ totalReceipts: stats.totalReceipts,
135
+ }
136
+ }
137
+
138
+ /**
139
+ * Calculate average print time statistics within a date range
140
+ *
141
+ * @param startDate Start date for the range
142
+ * @param endDate End date for the range
143
+ * @returns Object containing average print time and related statistics
144
+ */
145
+ export async function fetchPrintTimeStats(
146
+ _startDate: Date | number,
147
+ _endDate: Date | number,
148
+ ): Promise<{
149
+ averageDuration: number
150
+ minDuration: number
151
+ maxDuration: number
152
+ totalJobs: number
153
+ }> {
154
+ const start = typeof _startDate === 'number' ? _startDate : _startDate.getTime()
155
+ const end = typeof _endDate === 'number' ? _endDate : _endDate.getTime()
156
+
157
+ const stats = await aggregateStats('receipts', {
158
+ totalJobs: { kind: 'count' },
159
+ averageDuration: { kind: 'avg', column: 'duration' },
160
+ minDuration: { kind: 'min', column: 'duration' },
161
+ maxDuration: { kind: 'max', column: 'duration' },
162
+ }, qb => qb.where('timestamp', '>=', start).where('timestamp', '<=', end))
163
+
164
+ return {
165
+ averageDuration: Math.round(stats.averageDuration),
166
+ minDuration: stats.minDuration,
167
+ maxDuration: stats.maxDuration,
168
+ totalJobs: stats.totalJobs,
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Calculate prints per hour statistics within a date range
174
+ *
175
+ * @param startDate Start date for the range
176
+ * @param endDate End date for the range
177
+ * @returns Object containing prints per hour statistics
178
+ */
179
+ export async function fetchPrintsPerHour(
180
+ _startDate: Date | number,
181
+ _endDate: Date | number,
182
+ ): Promise<{
183
+ totalPrints: number
184
+ totalHours: number
185
+ printsPerHour: number
186
+ hourlyBreakdown: Array<{
187
+ hour: number
188
+ count: number
189
+ }>
190
+ }> {
191
+ const start = typeof _startDate === 'number' ? _startDate : _startDate.getTime()
192
+ const end = typeof _endDate === 'number' ? _endDate : _endDate.getTime()
193
+
194
+ const receipts = await db
195
+ .selectFrom('receipts')
196
+ .where('timestamp', '>=', start)
197
+ .where('timestamp', '<=', end)
198
+ .selectAll()
199
+ .execute()
200
+
201
+ const totalPrints = receipts.length
202
+ const totalHours = Math.ceil((end - start) / (1000 * 60 * 60))
203
+ const printsPerHour = totalHours > 0 ? Math.round(totalPrints / totalHours) : 0
204
+
205
+ const hourlyBreakdown = Array.from({ length: 24 }, (_, i) => ({
206
+ hour: i,
207
+ count: 0,
208
+ }))
209
+
210
+ receipts.forEach((receipt: any) => {
211
+ const date = new Date(Number(receipt.timestamp))
212
+ const hour = date.getHours()
213
+ hourlyBreakdown[hour].count++
214
+ })
215
+
216
+ return {
217
+ totalPrints,
218
+ totalHours,
219
+ printsPerHour,
220
+ hourlyBreakdown,
221
+ }
222
+ }
@@ -0,0 +1,24 @@
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
+ fetchById,
11
+ } from './fetch'
12
+
13
+ // Functions from store.ts
14
+ export {
15
+ bulkStore,
16
+ store,
17
+ } from './store'
18
+
19
+ // Functions from update.ts
20
+ export {
21
+ update,
22
+ updatePrintJob,
23
+ updateStatus,
24
+ } from './update'
@@ -0,0 +1,69 @@
1
+ // wip
2
+ import { log } from '@stacksjs/logging'
3
+
4
+ interface Printer {
5
+ id: string | number
6
+ name: string
7
+ status: string
8
+ }
9
+
10
+ interface PrintJob {
11
+ printer: Printer
12
+ receipt: Receipt
13
+ }
14
+
15
+ interface PrinterDriver {
16
+ print: (printJob: PrintJob) => Promise<void>
17
+ cleanUp: (printer: Printer) => Promise<void>
18
+ checkStatus: (printer: Printer) => Promise<boolean>
19
+ findPrinters: () => Promise<Printer[]>
20
+ setup: (printer: Printer) => Promise<void>
21
+ restart: () => Promise<void>
22
+ canInteractWithPrinter: (printer: Printer) => Promise<boolean>
23
+ }
24
+
25
+ type Path = string
26
+
27
+ interface Receipt {
28
+ id: string | number
29
+ name: string
30
+ price: number
31
+ quantity: number
32
+ template: Path
33
+ }
34
+
35
+ class TSPIVPrinter implements PrinterDriver {
36
+ async print(printJob: PrintJob): Promise<void> {
37
+ log.debug('TSP IV Printer: Printing receipt', printJob.receipt)
38
+ }
39
+
40
+ async cleanUp(_printer: Printer): Promise<void> {
41
+ log.debug('TSP IV Printer: Cleaning up print job...')
42
+ }
43
+
44
+ async checkStatus(_printer: Printer): Promise<boolean> {
45
+ log.debug('TSP IV Printer: Checking online status...')
46
+ return true
47
+ }
48
+
49
+ async findPrinters(): Promise<Printer[]> {
50
+ log.debug('TSP IV Printer: Finding printers...')
51
+ return []
52
+ }
53
+
54
+ async setup(_printer: Printer): Promise<void> {
55
+ log.debug('TSP IV Printer: Setting up printer...')
56
+ }
57
+
58
+ async restart(): Promise<void> {
59
+ log.debug('TSP IV Printer: Restarting...')
60
+ }
61
+
62
+ async canInteractWithPrinter(_printer: Printer): Promise<boolean> {
63
+ log.debug('TSP IV Printer: Checking if can interact with printer...')
64
+ return true
65
+ }
66
+ }
67
+
68
+ // Export the TSP IV printer instance
69
+ export const tspIVPrinter: PrinterDriver = new TSPIVPrinter()
@@ -0,0 +1,69 @@
1
+ type ReceiptJsonResponse = ModelRow<typeof Receipt>
2
+ type NewReceipt = NewModelData<typeof Receipt>
3
+ import { randomUUIDv7 } from 'bun'
4
+ import { db } from '@stacksjs/database'
5
+
6
+ /**
7
+ * Create a new receipt
8
+ *
9
+ * @param data The receipt data to store
10
+ * @returns The newly created receipt record
11
+ */
12
+ export async function store(data: NewReceipt): Promise<ReceiptJsonResponse> {
13
+ try {
14
+ const receiptData = {
15
+ ...data,
16
+ uuid: randomUUIDv7(),
17
+ }
18
+
19
+ const result = await db
20
+ .insertInto('receipts')
21
+ .values(receiptData)
22
+ .returningAll()
23
+ .executeTakeFirst()
24
+
25
+ if (!result)
26
+ throw new Error('Failed to create receipt')
27
+
28
+ return result as ReceiptJsonResponse
29
+ }
30
+ catch (error) {
31
+ if (error instanceof Error) {
32
+ throw new TypeError(`Failed to create receipt: ${error.message}`)
33
+ }
34
+
35
+ throw error
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Create multiple receipts at once
41
+ *
42
+ * @param data Array of receipt data to store
43
+ * @returns Number of receipts created
44
+ */
45
+ export async function bulkStore(data: NewReceipt[]): Promise<number> {
46
+ if (!data.length)
47
+ return 0
48
+
49
+ try {
50
+ const receiptDataArray = data.map(item => ({
51
+ ...item,
52
+ uuid: randomUUIDv7(),
53
+ }))
54
+
55
+ const result = await db
56
+ .insertInto('receipts')
57
+ .values(receiptDataArray)
58
+ .executeTakeFirst()
59
+
60
+ return Number(result.numInsertedOrUpdatedRows)
61
+ }
62
+ catch (error) {
63
+ if (error instanceof Error) {
64
+ throw new TypeError(`Failed to create receipts in bulk: ${error.message}`)
65
+ }
66
+
67
+ throw error
68
+ }
69
+ }
@@ -0,0 +1,124 @@
1
+ import { db } from '@stacksjs/database'
2
+ import { formatDate } from '@stacksjs/orm'
3
+ type ReceiptJsonResponse = ModelRow<typeof Receipt>
4
+ type ReceiptUpdate = UpdateModelData<typeof Receipt>
5
+
6
+ /**
7
+ * Update a receipt
8
+ *
9
+ * @param id The id of the receipt to update
10
+ * @param data The receipt data to update
11
+ * @returns The updated receipt record
12
+ */
13
+ export async function update(id: number, data: ReceiptUpdate): Promise<ReceiptJsonResponse> {
14
+ try {
15
+ if (!id)
16
+ throw new Error('Receipt ID is required for update')
17
+
18
+ const result = await db
19
+ .updateTable('receipts')
20
+ .set({
21
+ ...data,
22
+ updated_at: formatDate(new Date()),
23
+ })
24
+ .where('id', '=', id)
25
+ .returningAll()
26
+ .executeTakeFirst()
27
+
28
+ if (!result)
29
+ throw new Error('Failed to update receipt')
30
+
31
+ return result as ReceiptJsonResponse
32
+ }
33
+ catch (error) {
34
+ if (error instanceof Error) {
35
+ throw new TypeError(`Failed to update receipt: ${error.message}`)
36
+ }
37
+
38
+ throw error
39
+ }
40
+ }
41
+
42
+ /**
43
+ * Update a receipt's status
44
+ *
45
+ * @param id The ID of the receipt
46
+ * @param status The new status
47
+ * @returns The updated receipt with the new status
48
+ */
49
+ export async function updateStatus(
50
+ id: number,
51
+ status: 'success' | 'failed' | 'warning',
52
+ ): Promise<ReceiptJsonResponse> {
53
+ try {
54
+ const result = await db
55
+ .updateTable('receipts')
56
+ .set({
57
+ status,
58
+ updated_at: formatDate(new Date()),
59
+ })
60
+ .where('id', '=', id)
61
+ .returningAll()
62
+ .executeTakeFirst()
63
+
64
+ if (!result)
65
+ throw new Error('Failed to update receipt status')
66
+
67
+ return result as ReceiptJsonResponse
68
+ }
69
+ catch (error) {
70
+ if (error instanceof Error) {
71
+ throw new TypeError(`Failed to update receipt status: ${error.message}`)
72
+ }
73
+
74
+ throw error
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Update print job information
80
+ *
81
+ * @param id The ID of the receipt
82
+ * @param size Optional new size value
83
+ * @param pages Optional new pages value
84
+ * @param duration Optional new duration value
85
+ * @returns The updated receipt
86
+ */
87
+ export async function updatePrintJob(
88
+ id: number,
89
+ size?: number,
90
+ pages?: number,
91
+ duration?: number,
92
+ ): Promise<ReceiptJsonResponse> {
93
+ try {
94
+ const updateData: Record<string, any> = {
95
+ updated_at: formatDate(new Date()),
96
+ }
97
+
98
+ if (size !== undefined)
99
+ updateData.size = size
100
+ if (pages !== undefined)
101
+ updateData.pages = pages
102
+ if (duration !== undefined)
103
+ updateData.duration = duration
104
+
105
+ const result = await db
106
+ .updateTable('receipts')
107
+ .set(updateData)
108
+ .where('id', '=', id)
109
+ .returningAll()
110
+ .executeTakeFirst()
111
+
112
+ if (!result)
113
+ throw new Error('Failed to update receipt job information')
114
+
115
+ return result as ReceiptJsonResponse
116
+ }
117
+ catch (error) {
118
+ if (error instanceof Error) {
119
+ throw new TypeError(`Failed to update receipt job information: ${error.message}`)
120
+ }
121
+
122
+ throw error
123
+ }
124
+ }
@@ -0,0 +1,54 @@
1
+ import { db } from '@stacksjs/database'
2
+
3
+ /**
4
+ * Delete a delivery route by ID
5
+ *
6
+ * @param id The ID of the delivery route to delete
7
+ * @returns True if the delivery route was deleted, false otherwise
8
+ */
9
+ export async function destroy(id: number): Promise<boolean> {
10
+ try {
11
+ const result = await db
12
+ .deleteFrom('delivery_routes')
13
+ .where('id', '=', id)
14
+ .executeTakeFirst()
15
+
16
+ return Number(result.numDeletedRows) > 0
17
+ }
18
+ catch (error) {
19
+ if (error instanceof Error) {
20
+ throw new TypeError(`Failed to delete delivery route: ${error.message}`)
21
+ }
22
+
23
+ throw error
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Delete multiple delivery routes by ID
29
+ *
30
+ * @param ids Array of delivery route IDs to delete
31
+ * @returns Number of delivery routes deleted
32
+ */
33
+ export async function bulkDestroy(ids: number[]): Promise<number> {
34
+ if (!ids.length)
35
+ return 0
36
+
37
+ try {
38
+ // Perform the delete operation
39
+ const result = await db
40
+ .deleteFrom('delivery_routes')
41
+ .where('id', 'in', ids)
42
+ .executeTakeFirst()
43
+
44
+ // Return the number of deleted rows
45
+ return Number(result.numDeletedRows)
46
+ }
47
+ catch (error) {
48
+ if (error instanceof Error) {
49
+ throw new TypeError(`Failed to delete delivery routes: ${error.message}`)
50
+ }
51
+
52
+ throw error
53
+ }
54
+ }
@@ -0,0 +1,42 @@
1
+ type DeliveryRouteJsonResponse = ModelRow<typeof DeliveryRoute>
2
+ import { db } from '@stacksjs/database'
3
+
4
+ /**
5
+ * Fetch a delivery route by ID
6
+ */
7
+ export async function fetchById(id: number): Promise<DeliveryRouteJsonResponse | undefined> {
8
+ return await db
9
+ .selectFrom('delivery_routes')
10
+ .where('id', '=', id)
11
+ .selectAll()
12
+ .executeTakeFirst() as DeliveryRouteJsonResponse | undefined
13
+ }
14
+
15
+ /**
16
+ * Fetch all delivery routes
17
+ */
18
+ export async function fetchAll(): Promise<DeliveryRouteJsonResponse[]> {
19
+ return await db.selectFrom('delivery_routes').selectAll().execute() as DeliveryRouteJsonResponse[]
20
+ }
21
+
22
+ /**
23
+ * Fetch active delivery routes
24
+ */
25
+ export async function fetchActive(): Promise<DeliveryRouteJsonResponse[]> {
26
+ return await db
27
+ .selectFrom('delivery_routes')
28
+ .where('last_active', '<=', new Date(Date.now() - 24 * 60 * 60 * 1000)) // Last 24 hours
29
+ .selectAll()
30
+ .execute() as DeliveryRouteJsonResponse[]
31
+ }
32
+
33
+ /**
34
+ * Fetch delivery routes by driver
35
+ */
36
+ export async function fetchByDriver(driver: string): Promise<DeliveryRouteJsonResponse[]> {
37
+ return await db
38
+ .selectFrom('delivery_routes')
39
+ .where('driver', '=', driver)
40
+ .selectAll()
41
+ .execute() as DeliveryRouteJsonResponse[]
42
+ }
@@ -0,0 +1,26 @@
1
+ // Functions from destroy.ts
2
+ export {
3
+ bulkDestroy,
4
+ destroy,
5
+ } from './destroy'
6
+
7
+ // Functions from fetch.ts
8
+ export {
9
+ fetchActive,
10
+ fetchAll,
11
+ fetchByDriver,
12
+ fetchById,
13
+ } from './fetch'
14
+
15
+ // Functions from store.ts
16
+ export {
17
+ store,
18
+ updateLastActive,
19
+ } from './store'
20
+
21
+ // Functions from update.ts
22
+ export {
23
+ update,
24
+ updateMetrics,
25
+ updateStops,
26
+ } from './update'
@@ -0,0 +1,69 @@
1
+ type DeliveryRouteJsonResponse = ModelRow<typeof DeliveryRoute>
2
+ type NewDeliveryRoute = NewModelData<typeof DeliveryRoute>
3
+ import { randomUUIDv7 } from 'bun'
4
+ import { db } from '@stacksjs/database'
5
+
6
+ /**
7
+ * Create a new delivery route
8
+ *
9
+ * @param data The delivery route data to store
10
+ * @returns The newly created delivery route record
11
+ */
12
+ export async function store(data: NewDeliveryRoute): Promise<DeliveryRouteJsonResponse> {
13
+ try {
14
+ const routeData = {
15
+ ...data,
16
+ uuid: randomUUIDv7(),
17
+ }
18
+
19
+ const result = await db
20
+ .insertInto('delivery_routes')
21
+ .values(routeData)
22
+ .returningAll()
23
+ .executeTakeFirst()
24
+
25
+ if (!result)
26
+ throw new Error('Failed to create delivery route')
27
+
28
+ return result as DeliveryRouteJsonResponse
29
+ }
30
+ catch (error) {
31
+ if (error instanceof Error) {
32
+ throw new TypeError(`Failed to create delivery route: ${error.message}`)
33
+ }
34
+
35
+ throw error
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Update a delivery route's last active timestamp
41
+ *
42
+ * @param id The ID of the delivery route to update
43
+ * @returns The updated delivery route record
44
+ */
45
+ export async function updateLastActive(id: number): Promise<DeliveryRouteJsonResponse> {
46
+ try {
47
+ const result = await db
48
+ .updateTable('delivery_routes')
49
+ .set({
50
+ last_active: new Date().toISOString(),
51
+ updated_at: new Date().toISOString(),
52
+ })
53
+ .where('id', '=', id)
54
+ .returningAll()
55
+ .executeTakeFirst()
56
+
57
+ if (!result)
58
+ throw new Error('Failed to update delivery route last active')
59
+
60
+ return result as DeliveryRouteJsonResponse
61
+ }
62
+ catch (error) {
63
+ if (error instanceof Error) {
64
+ throw new TypeError(`Failed to update delivery route last active: ${error.message}`)
65
+ }
66
+
67
+ throw error
68
+ }
69
+ }