@stacksjs/commerce 0.70.53 → 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.
- package/package.json +3 -2
- package/src/carts/destroy.ts +54 -0
- package/src/carts/fetch.ts +20 -0
- package/src/carts/index.ts +13 -0
- package/src/carts/store.ts +75 -0
- package/src/carts/update.ts +78 -0
- package/src/coupons/destroy.ts +49 -0
- package/src/coupons/fetch.ts +510 -0
- package/src/coupons/index.ts +30 -0
- package/src/coupons/store.ts +46 -0
- package/src/coupons/update.ts +147 -0
- package/src/customers/destroy.ts +62 -0
- package/src/customers/fetch.ts +20 -0
- package/src/customers/index.ts +17 -0
- package/src/customers/store.ts +45 -0
- package/src/customers/update.ts +44 -0
- package/src/devices/destroy.ts +54 -0
- package/src/devices/export.ts +98 -0
- package/src/devices/fetch.ts +125 -0
- package/src/devices/index.ts +31 -0
- package/src/devices/store.ts +82 -0
- package/src/devices/update.ts +125 -0
- package/src/errors/destroy.ts +54 -0
- package/src/errors/fetch.ts +197 -0
- package/src/errors/index.ts +28 -0
- package/src/errors/update.ts +116 -0
- package/src/gift-cards/destroy.ts +87 -0
- package/src/gift-cards/fetch.ts +431 -0
- package/src/gift-cards/index.ts +26 -0
- package/src/gift-cards/store.ts +56 -0
- package/src/gift-cards/update.ts +102 -0
- package/src/index.ts +78 -0
- package/src/orders/destroy.ts +111 -0
- package/src/orders/events.ts +121 -0
- package/src/orders/export.ts +158 -0
- package/src/orders/fetch.ts +379 -0
- package/src/orders/guards.ts +261 -0
- package/src/orders/index.ts +91 -0
- package/src/orders/place-order.ts +274 -0
- package/src/orders/store.ts +51 -0
- package/src/orders/totals.ts +190 -0
- package/src/orders/update.ts +164 -0
- package/src/orders/webhook.ts +312 -0
- package/src/payments/destroy.ts +56 -0
- package/src/payments/fetch.ts +288 -0
- package/src/payments/index.ts +16 -0
- package/src/payments/store.ts +63 -0
- package/src/payments/update.ts +52 -0
- package/src/product.ts +0 -0
- package/src/products/categories/destroy.ts +103 -0
- package/src/products/categories/fetch.ts +285 -0
- package/src/products/categories/index.ts +36 -0
- package/src/products/categories/store.ts +87 -0
- package/src/products/categories/update.ts +251 -0
- package/src/products/index.ts +35 -0
- package/src/products/items/destroy.ts +54 -0
- package/src/products/items/fetch.ts +282 -0
- package/src/products/items/index.ts +26 -0
- package/src/products/items/store.ts +84 -0
- package/src/products/items/update.ts +324 -0
- package/src/products/manufacturers/destroy.ts +56 -0
- package/src/products/manufacturers/fetch.ts +117 -0
- package/src/products/manufacturers/index.ts +24 -0
- package/src/products/manufacturers/store.ts +82 -0
- package/src/products/manufacturers/update.ts +113 -0
- package/src/products/reviews/destroy.ts +56 -0
- package/src/products/reviews/fetch.ts +63 -0
- package/src/products/reviews/index.ts +25 -0
- package/src/products/reviews/store.ts +46 -0
- package/src/products/reviews/update.ts +82 -0
- package/src/products/units/destroy.ts +56 -0
- package/src/products/units/fetch.ts +20 -0
- package/src/products/units/index.ts +13 -0
- package/src/products/units/store.ts +162 -0
- package/src/products/units/update.ts +159 -0
- package/src/products/variants/destroy.ts +56 -0
- package/src/products/variants/fetch.ts +20 -0
- package/src/products/variants/index.ts +21 -0
- package/src/products/variants/store.ts +136 -0
- package/src/products/variants/update.ts +104 -0
- package/src/receipts/destroy.ts +54 -0
- package/src/receipts/export.ts +0 -0
- package/src/receipts/fetch.ts +222 -0
- package/src/receipts/index.ts +24 -0
- package/src/receipts/printer.ts +69 -0
- package/src/receipts/store.ts +69 -0
- package/src/receipts/update.ts +124 -0
- package/src/shippings/delivery-routes/destroy.ts +54 -0
- package/src/shippings/delivery-routes/fetch.ts +42 -0
- package/src/shippings/delivery-routes/index.ts +26 -0
- package/src/shippings/delivery-routes/store.ts +69 -0
- package/src/shippings/delivery-routes/update.ts +120 -0
- package/src/shippings/digital-deliveries/destroy.ts +111 -0
- package/src/shippings/digital-deliveries/fetch.ts +20 -0
- package/src/shippings/digital-deliveries/index.ts +26 -0
- package/src/shippings/digital-deliveries/store.ts +76 -0
- package/src/shippings/digital-deliveries/update.ts +129 -0
- package/src/shippings/drivers/destroy.ts +78 -0
- package/src/shippings/drivers/fetch.ts +20 -0
- package/src/shippings/drivers/index.ts +24 -0
- package/src/shippings/drivers/store.ts +69 -0
- package/src/shippings/drivers/update.ts +117 -0
- package/src/shippings/index.ts +39 -0
- package/src/shippings/license-keys/destroy.ts +111 -0
- package/src/shippings/license-keys/fetch.ts +20 -0
- package/src/shippings/license-keys/index.ts +26 -0
- package/src/shippings/license-keys/store.ts +77 -0
- package/src/shippings/license-keys/update.ts +117 -0
- package/src/shippings/shipping-methods/destroy.ts +111 -0
- package/src/shippings/shipping-methods/fetch.ts +62 -0
- package/src/shippings/shipping-methods/index.ts +28 -0
- package/src/shippings/shipping-methods/store.ts +123 -0
- package/src/shippings/shipping-methods/update.ts +120 -0
- package/src/shippings/shipping-rates/destroy.ts +102 -0
- package/src/shippings/shipping-rates/fetch.ts +320 -0
- package/src/shippings/shipping-rates/index.ts +36 -0
- package/src/shippings/shipping-rates/store.ts +102 -0
- package/src/shippings/shipping-rates/update.ts +139 -0
- package/src/shippings/shipping-zones/destroy.ts +111 -0
- package/src/shippings/shipping-zones/fetch.ts +96 -0
- package/src/shippings/shipping-zones/index.ts +26 -0
- package/src/shippings/shipping-zones/store.ts +74 -0
- package/src/shippings/shipping-zones/update.ts +156 -0
- package/src/tax/destroy.ts +54 -0
- package/src/tax/fetch.ts +20 -0
- package/src/tax/index.ts +24 -0
- package/src/tax/store.ts +69 -0
- package/src/tax/update.ts +119 -0
- package/src/tests/coupons.test.ts +90 -0
- package/src/tests/customers.test.ts +39 -0
- package/src/tests/device.test.ts +111 -0
- package/src/tests/digitals.test.ts +31 -0
- package/src/tests/drivers.test.ts +25 -0
- package/src/tests/gift-cards.test.ts +36 -0
- package/src/tests/license.test.ts +31 -0
- package/src/tests/manufacturers.test.ts +80 -0
- package/src/tests/orders.test.ts +25 -0
- package/src/tests/payments.test.ts +75 -0
- package/src/tests/rates.test.ts +367 -0
- package/src/tests/receipts.test.ts +287 -0
- package/src/tests/restaurant.test.ts +522 -0
- package/src/tests/reviews.test.ts +165 -0
- package/src/tests/routes.test.ts +51 -0
- package/src/tests/setup.ts +149 -0
- package/src/tests/shipping.test.ts +88 -0
- package/src/tests/tax.test.ts +25 -0
- package/src/tests/units.test.ts +110 -0
- package/src/tests/variants.test.ts +133 -0
- package/src/tests/waitlist.test.ts +303 -0
- package/src/tests/zones.test.ts +86 -0
- package/src/types.ts +312 -0
- package/src/utils/typed-stats.ts +67 -0
- package/src/waitlists/index.ts +19 -0
- package/src/waitlists/products/destroy.ts +65 -0
- package/src/waitlists/products/export.ts +113 -0
- package/src/waitlists/products/fetch.ts +362 -0
- package/src/waitlists/products/index.ts +33 -0
- package/src/waitlists/products/store.ts +112 -0
- package/src/waitlists/products/update.ts +125 -0
- package/src/waitlists/restaurant/destroy.ts +65 -0
- package/src/waitlists/restaurant/export.ts +107 -0
- package/src/waitlists/restaurant/fetch.ts +538 -0
- package/src/waitlists/restaurant/index.ts +43 -0
- package/src/waitlists/restaurant/store.ts +109 -0
- 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
|
+
}
|