@fayz-ai/orders 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/README.md +38 -2
- package/dist/chunk-A4AGOZHO.js +168 -0
- package/dist/chunk-A4AGOZHO.js.map +1 -0
- package/dist/components/CommercialOrderCard.d.ts +7 -0
- package/dist/components/CommercialOrderCard.d.ts.map +1 -0
- package/dist/components/CommercialOrderCard.js +18 -0
- package/dist/components/CommercialOrderCard.js.map +1 -0
- package/dist/components/OrderBoardCard.d.ts +10 -0
- package/dist/components/OrderBoardCard.d.ts.map +1 -0
- package/dist/components/OrderBoardCard.js +35 -0
- package/dist/components/OrderBoardCard.js.map +1 -0
- package/dist/components/OrderStatusDot.d.ts +8 -0
- package/dist/components/OrderStatusDot.d.ts.map +1 -0
- package/dist/components/OrderStatusDot.js +22 -0
- package/dist/components/OrderStatusDot.js.map +1 -0
- package/dist/components/PaymentStateBadge.d.ts +6 -0
- package/dist/components/PaymentStateBadge.d.ts.map +1 -0
- package/dist/components/PaymentStateBadge.js +27 -0
- package/dist/components/PaymentStateBadge.js.map +1 -0
- package/dist/data/mock.d.ts +3 -0
- package/dist/data/mock.d.ts.map +1 -0
- package/dist/data/mock.js +208 -0
- package/dist/data/mock.js.map +1 -0
- package/dist/data/platform.d.ts +19 -0
- package/dist/data/platform.d.ts.map +1 -0
- package/dist/data/platform.js +362 -0
- package/dist/data/platform.js.map +1 -0
- package/dist/data/provider.d.ts +14 -0
- package/dist/data/provider.d.ts.map +1 -0
- package/dist/data/provider.js +3 -0
- package/dist/data/provider.js.map +1 -0
- package/dist/data/supabase.d.ts +19 -0
- package/dist/data/supabase.d.ts.map +1 -0
- package/dist/data/supabase.js +316 -0
- package/dist/data/supabase.js.map +1 -0
- package/dist/domain/order.d.ts +172 -0
- package/dist/domain/order.d.ts.map +1 -0
- package/dist/domain/order.js +3 -0
- package/dist/domain/order.js.map +1 -0
- package/dist/store.d.ts +30 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +146 -0
- package/dist/store.js.map +1 -0
- package/package.json +52 -3
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { summarizeOrders, lineTotal, withCancellationNote, canMoveTo, getNextStatus, orderTotals, matchesQuery, paginate } from '../chunk-A4AGOZHO.js';
|
|
2
|
+
|
|
3
|
+
// src/data/mock.ts
|
|
4
|
+
var uid = 100;
|
|
5
|
+
function nextId(prefix) {
|
|
6
|
+
return `${prefix}-${++uid}`;
|
|
7
|
+
}
|
|
8
|
+
function makeItem(orderId, input, sortOrder, createdAt) {
|
|
9
|
+
return {
|
|
10
|
+
id: nextId("item"),
|
|
11
|
+
orderId,
|
|
12
|
+
productId: input.productId,
|
|
13
|
+
name: input.name,
|
|
14
|
+
quantity: input.quantity,
|
|
15
|
+
unitPrice: input.unitPrice,
|
|
16
|
+
discount: input.discount ?? 0,
|
|
17
|
+
total: lineTotal(input),
|
|
18
|
+
sortOrder,
|
|
19
|
+
modifiers: input.modifiers,
|
|
20
|
+
kitchenNotes: input.kitchenNotes,
|
|
21
|
+
createdAt
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
var SEED = [
|
|
25
|
+
{
|
|
26
|
+
ref: "ORD-0001",
|
|
27
|
+
kind: "dine_in",
|
|
28
|
+
status: "preparing",
|
|
29
|
+
source: "pos",
|
|
30
|
+
table: ["table-3", "Table 3"],
|
|
31
|
+
items: [["Classic Burger", 1, 32, "prod-burger-classic"], ["Fries", 1, 15, "prod-fries"]]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
ref: "ORD-0002",
|
|
35
|
+
kind: "takeout",
|
|
36
|
+
status: "ready",
|
|
37
|
+
source: "pos",
|
|
38
|
+
items: [["Cheese Burger", 1, 36, "prod-burger-cheese"]]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
ref: "ORD-0003",
|
|
42
|
+
kind: "delivery",
|
|
43
|
+
status: "confirmed",
|
|
44
|
+
source: "ifood",
|
|
45
|
+
items: [
|
|
46
|
+
["Margherita Pizza", 1, 38, "prod-pizza-margherita"],
|
|
47
|
+
["Caesar Salad", 1, 22, "prod-salad-caesar"],
|
|
48
|
+
["Soda 350ml", 1, 12, "prod-soda"]
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
ref: "ORD-0004",
|
|
53
|
+
kind: "dine_in",
|
|
54
|
+
status: "new",
|
|
55
|
+
source: "pos",
|
|
56
|
+
table: ["table-7", "Table 7"],
|
|
57
|
+
items: [["BBQ Bacon Burger", 1, 42, "prod-burger-bbq"]]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
ref: "ORD-0005",
|
|
61
|
+
kind: "dine_in",
|
|
62
|
+
status: "completed",
|
|
63
|
+
source: "pos",
|
|
64
|
+
table: ["table-1", "Table 1"],
|
|
65
|
+
items: [
|
|
66
|
+
["Classic Burger", 2, 32, "prod-burger-classic"],
|
|
67
|
+
["Fries", 1, 15, "prod-fries"],
|
|
68
|
+
["Onion Rings", 1, 18, "prod-onion-rings"],
|
|
69
|
+
["Milkshake", 1, 23, "prod-milkshake"]
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
];
|
|
73
|
+
function seedOrders(now) {
|
|
74
|
+
return SEED.map((seed) => {
|
|
75
|
+
const id = nextId("order");
|
|
76
|
+
const items = seed.items.map(([name, quantity, unitPrice, productId], index) => makeItem(id, { name, quantity, unitPrice, productId }, index, now));
|
|
77
|
+
return {
|
|
78
|
+
id,
|
|
79
|
+
referenceNumber: seed.ref,
|
|
80
|
+
kind: seed.kind,
|
|
81
|
+
status: seed.status,
|
|
82
|
+
source: seed.source,
|
|
83
|
+
tableId: seed.table?.[0],
|
|
84
|
+
tableName: seed.table?.[1],
|
|
85
|
+
...orderTotals(items),
|
|
86
|
+
discount: 0,
|
|
87
|
+
tax: 0,
|
|
88
|
+
currency: "BRL",
|
|
89
|
+
tags: [],
|
|
90
|
+
items,
|
|
91
|
+
tenantId: "tenant-mock",
|
|
92
|
+
createdAt: now,
|
|
93
|
+
updatedAt: now,
|
|
94
|
+
...seed.status === "completed" ? { completedAt: now } : {}
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function createMockOrdersProvider() {
|
|
99
|
+
const orders = seedOrders((/* @__PURE__ */ new Date()).toISOString());
|
|
100
|
+
let refCounter = orders.length;
|
|
101
|
+
function findOrder(id) {
|
|
102
|
+
const order = orders.find((o) => o.id === id);
|
|
103
|
+
if (!order) throw new Error(`Order not found: ${id}`);
|
|
104
|
+
return order;
|
|
105
|
+
}
|
|
106
|
+
function findItem(itemId) {
|
|
107
|
+
for (const order of orders) {
|
|
108
|
+
const index = order.items.findIndex((i) => i.id === itemId);
|
|
109
|
+
if (index !== -1) return { order, index };
|
|
110
|
+
}
|
|
111
|
+
throw new Error(`Order item not found: ${itemId}`);
|
|
112
|
+
}
|
|
113
|
+
function touch(order) {
|
|
114
|
+
Object.assign(order, orderTotals(order.items, order));
|
|
115
|
+
order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
async getOrders(query) {
|
|
119
|
+
const matching = orders.filter((o) => matchesQuery(o, query)).sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
120
|
+
return paginate(matching, query.page, query.pageSize);
|
|
121
|
+
},
|
|
122
|
+
async getOrderById(id) {
|
|
123
|
+
return orders.find((o) => o.id === id) ?? null;
|
|
124
|
+
},
|
|
125
|
+
async createOrder(input) {
|
|
126
|
+
const id = nextId("order");
|
|
127
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
128
|
+
const items = input.items.map((item, index) => makeItem(id, item, index, now));
|
|
129
|
+
const order = {
|
|
130
|
+
id,
|
|
131
|
+
referenceNumber: `ORD-${String(++refCounter).padStart(4, "0")}`,
|
|
132
|
+
kind: input.kind,
|
|
133
|
+
status: "new",
|
|
134
|
+
source: input.source ?? "pos",
|
|
135
|
+
tableId: input.tableId,
|
|
136
|
+
partyId: input.partyId,
|
|
137
|
+
assigneeId: input.assigneeId,
|
|
138
|
+
notes: input.notes,
|
|
139
|
+
estimatedMinutes: input.estimatedMinutes,
|
|
140
|
+
...orderTotals(items),
|
|
141
|
+
discount: 0,
|
|
142
|
+
tax: 0,
|
|
143
|
+
currency: "BRL",
|
|
144
|
+
tags: [],
|
|
145
|
+
items,
|
|
146
|
+
tenantId: "tenant-mock",
|
|
147
|
+
createdAt: now,
|
|
148
|
+
updatedAt: now
|
|
149
|
+
};
|
|
150
|
+
orders.push(order);
|
|
151
|
+
return order;
|
|
152
|
+
},
|
|
153
|
+
async updateOrderStatus(input) {
|
|
154
|
+
const order = findOrder(input.orderId);
|
|
155
|
+
if (!canMoveTo(order.kind, order.status, input.status)) {
|
|
156
|
+
const next = getNextStatus(order.kind, order.status);
|
|
157
|
+
throw new Error(
|
|
158
|
+
`Invalid status transition: ${order.status} \u2192 ${input.status}. ` + (next ? `Expected next status: ${next}` : "Order is already in a terminal state.")
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
order.status = input.status;
|
|
162
|
+
order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
163
|
+
if (input.status === "completed") order.completedAt = order.updatedAt;
|
|
164
|
+
return order;
|
|
165
|
+
},
|
|
166
|
+
async updateOrder(id, data) {
|
|
167
|
+
const order = findOrder(id);
|
|
168
|
+
const { id: _id, items: _items, tenantId: _tenantId, createdAt: _createdAt, ...safe } = data;
|
|
169
|
+
Object.assign(order, safe);
|
|
170
|
+
order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
171
|
+
return order;
|
|
172
|
+
},
|
|
173
|
+
async cancelOrder(id, reason) {
|
|
174
|
+
const order = findOrder(id);
|
|
175
|
+
order.status = "cancelled";
|
|
176
|
+
order.notes = withCancellationNote(order.notes, reason);
|
|
177
|
+
order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
178
|
+
},
|
|
179
|
+
async addOrderItem(orderId, input) {
|
|
180
|
+
const order = findOrder(orderId);
|
|
181
|
+
const item = makeItem(orderId, input, order.items.length, (/* @__PURE__ */ new Date()).toISOString());
|
|
182
|
+
order.items.push(item);
|
|
183
|
+
touch(order);
|
|
184
|
+
return item;
|
|
185
|
+
},
|
|
186
|
+
async removeOrderItem(itemId) {
|
|
187
|
+
const { order, index } = findItem(itemId);
|
|
188
|
+
order.items.splice(index, 1);
|
|
189
|
+
touch(order);
|
|
190
|
+
},
|
|
191
|
+
async updateOrderItem(itemId, data) {
|
|
192
|
+
const { order, index } = findItem(itemId);
|
|
193
|
+
const item = order.items[index];
|
|
194
|
+
const { id: _id, orderId: _orderId, createdAt: _createdAt, ...safe } = data;
|
|
195
|
+
Object.assign(item, safe);
|
|
196
|
+
item.total = lineTotal(item);
|
|
197
|
+
touch(order);
|
|
198
|
+
return item;
|
|
199
|
+
},
|
|
200
|
+
async getSummary(dateRange) {
|
|
201
|
+
return summarizeOrders(orders, dateRange);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export { createMockOrdersProvider };
|
|
207
|
+
//# sourceMappingURL=mock.js.map
|
|
208
|
+
//# sourceMappingURL=mock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/data/mock.ts"],"names":[],"mappings":"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","file":"mock.js","sourcesContent":["import {\n canMoveTo, getNextStatus, lineTotal, matchesQuery, orderTotals, paginate, summarizeOrders, withCancellationNote,\n type CreateOrderItemInput, type OrderKind, type OrderStatus, type RestaurantOrder, type RestaurantOrderItem,\n} from '../domain/order'\nimport type { OrdersDataProvider } from './provider'\n\nlet uid = 100\nfunction nextId(prefix: string): string {\n return `${prefix}-${++uid}`\n}\n\nfunction makeItem(orderId: string, input: CreateOrderItemInput, sortOrder: number, createdAt: string): RestaurantOrderItem {\n return {\n id: nextId('item'),\n orderId,\n productId: input.productId,\n name: input.name,\n quantity: input.quantity,\n unitPrice: input.unitPrice,\n discount: input.discount ?? 0,\n total: lineTotal(input),\n sortOrder,\n modifiers: input.modifiers,\n kitchenNotes: input.kitchenNotes,\n createdAt,\n }\n}\n\ninterface SeedOrder {\n ref: string\n kind: OrderKind\n status: OrderStatus\n source: string\n table?: [id: string, name: string]\n items: Array<[name: string, quantity: number, unitPrice: number, productId: string]>\n}\n\nconst SEED: SeedOrder[] = [\n {\n ref: 'ORD-0001', kind: 'dine_in', status: 'preparing', source: 'pos', table: ['table-3', 'Table 3'],\n items: [['Classic Burger', 1, 32, 'prod-burger-classic'], ['Fries', 1, 15, 'prod-fries']],\n },\n {\n ref: 'ORD-0002', kind: 'takeout', status: 'ready', source: 'pos',\n items: [['Cheese Burger', 1, 36, 'prod-burger-cheese']],\n },\n {\n ref: 'ORD-0003', kind: 'delivery', status: 'confirmed', source: 'ifood',\n items: [\n ['Margherita Pizza', 1, 38, 'prod-pizza-margherita'],\n ['Caesar Salad', 1, 22, 'prod-salad-caesar'],\n ['Soda 350ml', 1, 12, 'prod-soda'],\n ],\n },\n {\n ref: 'ORD-0004', kind: 'dine_in', status: 'new', source: 'pos', table: ['table-7', 'Table 7'],\n items: [['BBQ Bacon Burger', 1, 42, 'prod-burger-bbq']],\n },\n {\n ref: 'ORD-0005', kind: 'dine_in', status: 'completed', source: 'pos', table: ['table-1', 'Table 1'],\n items: [\n ['Classic Burger', 2, 32, 'prod-burger-classic'],\n ['Fries', 1, 15, 'prod-fries'],\n ['Onion Rings', 1, 18, 'prod-onion-rings'],\n ['Milkshake', 1, 23, 'prod-milkshake'],\n ],\n },\n]\n\nfunction seedOrders(now: string): RestaurantOrder[] {\n return SEED.map((seed) => {\n const id = nextId('order')\n const items = seed.items.map(([name, quantity, unitPrice, productId], index) =>\n makeItem(id, { name, quantity, unitPrice, productId }, index, now))\n return {\n id,\n referenceNumber: seed.ref,\n kind: seed.kind,\n status: seed.status,\n source: seed.source,\n tableId: seed.table?.[0],\n tableName: seed.table?.[1],\n ...orderTotals(items),\n discount: 0,\n tax: 0,\n currency: 'BRL',\n tags: [],\n items,\n tenantId: 'tenant-mock',\n createdAt: now,\n updatedAt: now,\n ...(seed.status === 'completed' ? { completedAt: now } : {}),\n }\n })\n}\n\nexport function createMockOrdersProvider(): OrdersDataProvider {\n const orders = seedOrders(new Date().toISOString())\n let refCounter = orders.length\n\n function findOrder(id: string): RestaurantOrder {\n const order = orders.find((o) => o.id === id)\n if (!order) throw new Error(`Order not found: ${id}`)\n return order\n }\n\n function findItem(itemId: string): { order: RestaurantOrder; index: number } {\n for (const order of orders) {\n const index = order.items.findIndex((i) => i.id === itemId)\n if (index !== -1) return { order, index }\n }\n throw new Error(`Order item not found: ${itemId}`)\n }\n\n function touch(order: RestaurantOrder): void {\n Object.assign(order, orderTotals(order.items, order))\n order.updatedAt = new Date().toISOString()\n }\n\n return {\n async getOrders(query) {\n const matching = orders\n .filter((o) => matchesQuery(o, query))\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt))\n return paginate(matching, query.page, query.pageSize)\n },\n\n async getOrderById(id) {\n return orders.find((o) => o.id === id) ?? null\n },\n\n async createOrder(input) {\n const id = nextId('order')\n const now = new Date().toISOString()\n const items = input.items.map((item, index) => makeItem(id, item, index, now))\n const order: RestaurantOrder = {\n id,\n referenceNumber: `ORD-${String(++refCounter).padStart(4, '0')}`,\n kind: input.kind,\n status: 'new',\n source: input.source ?? 'pos',\n tableId: input.tableId,\n partyId: input.partyId,\n assigneeId: input.assigneeId,\n notes: input.notes,\n estimatedMinutes: input.estimatedMinutes,\n ...orderTotals(items),\n discount: 0,\n tax: 0,\n currency: 'BRL',\n tags: [],\n items,\n tenantId: 'tenant-mock',\n createdAt: now,\n updatedAt: now,\n }\n orders.push(order)\n return order\n },\n\n async updateOrderStatus(input) {\n const order = findOrder(input.orderId)\n if (!canMoveTo(order.kind, order.status, input.status)) {\n const next = getNextStatus(order.kind, order.status)\n throw new Error(\n `Invalid status transition: ${order.status} → ${input.status}. ` +\n (next ? `Expected next status: ${next}` : 'Order is already in a terminal state.'),\n )\n }\n order.status = input.status\n order.updatedAt = new Date().toISOString()\n if (input.status === 'completed') order.completedAt = order.updatedAt\n return order\n },\n\n async updateOrder(id, data) {\n const order = findOrder(id)\n const { id: _id, items: _items, tenantId: _tenantId, createdAt: _createdAt, ...safe } = data\n Object.assign(order, safe)\n order.updatedAt = new Date().toISOString()\n return order\n },\n\n async cancelOrder(id, reason) {\n const order = findOrder(id)\n order.status = 'cancelled'\n order.notes = withCancellationNote(order.notes, reason)\n order.updatedAt = new Date().toISOString()\n },\n\n async addOrderItem(orderId, input) {\n const order = findOrder(orderId)\n const item = makeItem(orderId, input, order.items.length, new Date().toISOString())\n order.items.push(item)\n touch(order)\n return item\n },\n\n async removeOrderItem(itemId) {\n const { order, index } = findItem(itemId)\n order.items.splice(index, 1)\n touch(order)\n },\n\n async updateOrderItem(itemId, data) {\n const { order, index } = findItem(itemId)\n const item = order.items[index]\n const { id: _id, orderId: _orderId, createdAt: _createdAt, ...safe } = data\n Object.assign(item, safe)\n item.total = lineTotal(item)\n touch(order)\n return item\n },\n\n async getSummary(dateRange) {\n return summarizeOrders(orders, dateRange)\n },\n }\n}\n"]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type FayzClientOptions } from '@fayz-ai/sdk';
|
|
2
|
+
import type { OrdersDataProvider } from './provider';
|
|
3
|
+
export interface FayzOrdersProviderOptions extends FayzClientOptions {
|
|
4
|
+
projectId?: string;
|
|
5
|
+
schema?: string;
|
|
6
|
+
runtime?: boolean;
|
|
7
|
+
ordersTable?: string;
|
|
8
|
+
orderItemsTable?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Active tenant id (or a getter) used to scope reads and stamp writes on the
|
|
11
|
+
* canonical orders and items tables. When omitted, scoping is left to
|
|
12
|
+
* the runtime/RLS context.
|
|
13
|
+
*/
|
|
14
|
+
tenantId?: string | (() => string | undefined | null);
|
|
15
|
+
/** Active unit id stamped on new orders and their items when available. */
|
|
16
|
+
unitId?: string | (() => string | undefined | null);
|
|
17
|
+
}
|
|
18
|
+
export declare function createFayzOrdersProvider(options?: FayzOrdersProviderOptions): OrdersDataProvider;
|
|
19
|
+
//# sourceMappingURL=platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/data/platform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,iBAAiB,EAAwB,MAAM,cAAc,CAAA;AAM7F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD,MAAM,WAAW,yBAA0B,SAAQ,iBAAiB;IAClE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;IACrD,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,CAAA;CACpD;AAiRD,wBAAgB,wBAAwB,CAAC,OAAO,GAAE,yBAA8B,GAAG,kBAAkB,CA2LpG"}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { summarizeOrders, orderTotals, withCancellationNote, paginate, matchesQuery, lineTotal } from '../chunk-A4AGOZHO.js';
|
|
2
|
+
import { createFayzClient } from '@fayz-ai/sdk';
|
|
3
|
+
|
|
4
|
+
var DEFAULT_ORDERS_TABLE = "orders";
|
|
5
|
+
var DEFAULT_ORDER_ITEMS_TABLE = "items";
|
|
6
|
+
var ORDERS_METADATA_KEY = "fayzOrders";
|
|
7
|
+
var RESTAURANT_STATUSES = /* @__PURE__ */ new Set([
|
|
8
|
+
"new",
|
|
9
|
+
"confirmed",
|
|
10
|
+
"preparing",
|
|
11
|
+
"ready",
|
|
12
|
+
"served",
|
|
13
|
+
"picked_up",
|
|
14
|
+
"dispatched",
|
|
15
|
+
"delivered",
|
|
16
|
+
"completed",
|
|
17
|
+
"cancelled"
|
|
18
|
+
]);
|
|
19
|
+
function nowIso() {
|
|
20
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
21
|
+
}
|
|
22
|
+
function numberValue(value) {
|
|
23
|
+
if (typeof value === "number") return value;
|
|
24
|
+
if (typeof value === "string") return Number(value) || 0;
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
function referenceNumber() {
|
|
28
|
+
return `ORD-${Date.now().toString().slice(-6)}`;
|
|
29
|
+
}
|
|
30
|
+
function objectValue(value) {
|
|
31
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
32
|
+
}
|
|
33
|
+
function canonicalStatus(status) {
|
|
34
|
+
if (status === "new") return "draft";
|
|
35
|
+
if (status === "completed" || status === "cancelled") return status;
|
|
36
|
+
return "confirmed";
|
|
37
|
+
}
|
|
38
|
+
function restaurantStatus(rowStatus, metadata) {
|
|
39
|
+
if (rowStatus === "completed" || rowStatus === "cancelled") return rowStatus;
|
|
40
|
+
const stored = metadata.restaurantStatus;
|
|
41
|
+
if (typeof stored === "string" && RESTAURANT_STATUSES.has(stored)) return stored;
|
|
42
|
+
if (rowStatus === "draft") return "new";
|
|
43
|
+
if (typeof rowStatus === "string" && RESTAURANT_STATUSES.has(rowStatus)) return rowStatus;
|
|
44
|
+
return "confirmed";
|
|
45
|
+
}
|
|
46
|
+
function ordersMetadata(metadata) {
|
|
47
|
+
return objectValue(metadata?.[ORDERS_METADATA_KEY]);
|
|
48
|
+
}
|
|
49
|
+
function mergeOrdersMetadata(metadata, patch) {
|
|
50
|
+
const base = { ...metadata ?? {} };
|
|
51
|
+
const current = ordersMetadata(base);
|
|
52
|
+
const definedPatch = Object.fromEntries(
|
|
53
|
+
Object.entries(patch).filter(([, value]) => value !== void 0)
|
|
54
|
+
);
|
|
55
|
+
const next = { ...current, ...definedPatch };
|
|
56
|
+
return { ...base, [ORDERS_METADATA_KEY]: next };
|
|
57
|
+
}
|
|
58
|
+
function itemToRow(item, orderId, sortOrder, tenantId, unitId) {
|
|
59
|
+
return {
|
|
60
|
+
order_id: orderId,
|
|
61
|
+
...tenantId ? { tenant_id: tenantId } : {},
|
|
62
|
+
...unitId ? { unit_id: unitId } : {},
|
|
63
|
+
product_id: item.productId ?? null,
|
|
64
|
+
name: item.name,
|
|
65
|
+
quantity: item.quantity,
|
|
66
|
+
unit_price: item.unitPrice,
|
|
67
|
+
discount: item.discount ?? 0,
|
|
68
|
+
total: lineTotal(item),
|
|
69
|
+
sort_order: sortOrder,
|
|
70
|
+
metadata: mergeOrdersMetadata(void 0, {
|
|
71
|
+
modifiers: item.modifiers ?? null,
|
|
72
|
+
kitchenNotes: item.kitchenNotes ?? null
|
|
73
|
+
})
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function rowToItem(row) {
|
|
77
|
+
const quantity = numberValue(row.quantity);
|
|
78
|
+
const unitPrice = numberValue(row.unit_price);
|
|
79
|
+
const discount = numberValue(row.discount);
|
|
80
|
+
const restaurant = ordersMetadata(row.metadata);
|
|
81
|
+
return {
|
|
82
|
+
id: row.id,
|
|
83
|
+
orderId: row.order_id ?? "",
|
|
84
|
+
productId: row.product_id ?? void 0,
|
|
85
|
+
name: row.name ?? "Item",
|
|
86
|
+
description: row.description ?? void 0,
|
|
87
|
+
quantity,
|
|
88
|
+
unitPrice,
|
|
89
|
+
discount,
|
|
90
|
+
total: numberValue(row.total) || quantity * unitPrice - discount,
|
|
91
|
+
sortOrder: row.sort_order ?? 0,
|
|
92
|
+
modifiers: row.modifiers ?? (typeof restaurant.modifiers === "string" ? restaurant.modifiers : void 0),
|
|
93
|
+
kitchenNotes: row.kitchen_notes ?? (typeof restaurant.kitchenNotes === "string" ? restaurant.kitchenNotes : void 0),
|
|
94
|
+
metadata: row.metadata ?? {},
|
|
95
|
+
createdAt: row.created_at ?? nowIso()
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function rowToOrder(row, items = []) {
|
|
99
|
+
const subtotal = numberValue(row.subtotal) || items.reduce((sum, item) => sum + item.total, 0);
|
|
100
|
+
const discount = numberValue(row.discount);
|
|
101
|
+
const tax = numberValue(row.tax);
|
|
102
|
+
const restaurant = ordersMetadata(row.metadata);
|
|
103
|
+
return {
|
|
104
|
+
id: row.id,
|
|
105
|
+
referenceNumber: row.reference_number ?? row.id,
|
|
106
|
+
kind: row.kind ?? "dine_in",
|
|
107
|
+
status: restaurantStatus(row.status, restaurant),
|
|
108
|
+
partyId: row.party_id ?? void 0,
|
|
109
|
+
partyName: row.party_name ?? (typeof restaurant.partyName === "string" ? restaurant.partyName : void 0),
|
|
110
|
+
assigneeId: row.assignee_id ?? void 0,
|
|
111
|
+
assigneeName: row.assignee_name ?? (typeof restaurant.assigneeName === "string" ? restaurant.assigneeName : void 0),
|
|
112
|
+
locationId: row.location_id ?? void 0,
|
|
113
|
+
subtotal,
|
|
114
|
+
discount,
|
|
115
|
+
tax,
|
|
116
|
+
total: numberValue(row.total) || subtotal - discount + tax,
|
|
117
|
+
currency: row.currency ?? "BRL",
|
|
118
|
+
notes: row.notes ?? void 0,
|
|
119
|
+
tags: row.tags ?? [],
|
|
120
|
+
source: row.source ?? (typeof restaurant.source === "string" ? restaurant.source : "pos"),
|
|
121
|
+
tableId: row.table_id ?? (typeof restaurant.tableId === "string" ? restaurant.tableId : void 0),
|
|
122
|
+
tableName: row.table_name ?? (typeof restaurant.tableName === "string" ? restaurant.tableName : void 0),
|
|
123
|
+
estimatedMinutes: row.estimated_minutes ?? (typeof restaurant.estimatedMinutes === "number" ? restaurant.estimatedMinutes : void 0),
|
|
124
|
+
items,
|
|
125
|
+
metadata: row.metadata ?? {},
|
|
126
|
+
tenantId: row.tenant_id ?? "runtime-tenant",
|
|
127
|
+
unitId: row.unit_id ?? void 0,
|
|
128
|
+
createdAt: row.created_at ?? nowIso(),
|
|
129
|
+
updatedAt: row.updated_at ?? row.created_at ?? nowIso(),
|
|
130
|
+
completedAt: row.completed_at ?? void 0
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function orderPayload(input) {
|
|
134
|
+
const subtotal = input.items.reduce((sum, item) => sum + lineTotal(item), 0);
|
|
135
|
+
return {
|
|
136
|
+
reference_number: referenceNumber(),
|
|
137
|
+
kind: input.kind,
|
|
138
|
+
status: "draft",
|
|
139
|
+
party_id: input.partyId ?? null,
|
|
140
|
+
assignee_id: input.assigneeId ?? null,
|
|
141
|
+
notes: input.notes ?? null,
|
|
142
|
+
subtotal,
|
|
143
|
+
discount: 0,
|
|
144
|
+
tax: 0,
|
|
145
|
+
total: subtotal,
|
|
146
|
+
currency: "BRL",
|
|
147
|
+
tags: [],
|
|
148
|
+
metadata: mergeOrdersMetadata(void 0, {
|
|
149
|
+
source: input.source ?? "pos",
|
|
150
|
+
tableId: input.tableId ?? null,
|
|
151
|
+
estimatedMinutes: input.estimatedMinutes ?? null,
|
|
152
|
+
restaurantStatus: "new"
|
|
153
|
+
})
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function updatePayload(data, existingMetadata) {
|
|
157
|
+
const payload = {};
|
|
158
|
+
if (data.referenceNumber !== void 0) payload.reference_number = data.referenceNumber;
|
|
159
|
+
if (data.kind !== void 0) payload.kind = data.kind;
|
|
160
|
+
if (data.status !== void 0) payload.status = canonicalStatus(data.status);
|
|
161
|
+
if (data.partyId !== void 0) payload.party_id = data.partyId;
|
|
162
|
+
if (data.assigneeId !== void 0) payload.assignee_id = data.assigneeId;
|
|
163
|
+
if (data.locationId !== void 0) payload.location_id = data.locationId;
|
|
164
|
+
if (data.subtotal !== void 0) payload.subtotal = data.subtotal;
|
|
165
|
+
if (data.discount !== void 0) payload.discount = data.discount;
|
|
166
|
+
if (data.tax !== void 0) payload.tax = data.tax;
|
|
167
|
+
if (data.total !== void 0) payload.total = data.total;
|
|
168
|
+
if (data.currency !== void 0) payload.currency = data.currency;
|
|
169
|
+
if (data.notes !== void 0) payload.notes = data.notes;
|
|
170
|
+
if (data.tags !== void 0) payload.tags = data.tags;
|
|
171
|
+
const metadataBase = data.metadata !== void 0 ? { ...existingMetadata ?? {}, ...data.metadata } : existingMetadata;
|
|
172
|
+
const metadataPatch = {
|
|
173
|
+
partyName: data.partyName,
|
|
174
|
+
assigneeName: data.assigneeName,
|
|
175
|
+
source: data.source,
|
|
176
|
+
tableId: data.tableId,
|
|
177
|
+
tableName: data.tableName,
|
|
178
|
+
estimatedMinutes: data.estimatedMinutes,
|
|
179
|
+
restaurantStatus: data.status
|
|
180
|
+
};
|
|
181
|
+
if (data.metadata !== void 0 || Object.values(metadataPatch).some((value) => value !== void 0)) {
|
|
182
|
+
payload.metadata = mergeOrdersMetadata(metadataBase, metadataPatch);
|
|
183
|
+
}
|
|
184
|
+
if (data.completedAt !== void 0) payload.completed_at = data.completedAt;
|
|
185
|
+
return payload;
|
|
186
|
+
}
|
|
187
|
+
function filtersFromQuery(query) {
|
|
188
|
+
const filters = [];
|
|
189
|
+
if (query.kind && !Array.isArray(query.kind)) filters.push({ column: "kind", operator: "eq", value: query.kind });
|
|
190
|
+
if (query.assigneeId) filters.push({ column: "assignee_id", operator: "eq", value: query.assigneeId });
|
|
191
|
+
return filters;
|
|
192
|
+
}
|
|
193
|
+
function createFayzOrdersProvider(options = {}) {
|
|
194
|
+
const client = createFayzClient(options);
|
|
195
|
+
const ordersTable = options.ordersTable ?? DEFAULT_ORDERS_TABLE;
|
|
196
|
+
const orderItemsTable = options.orderItemsTable ?? DEFAULT_ORDER_ITEMS_TABLE;
|
|
197
|
+
const tableOptions = { projectId: options.projectId, schema: options.schema, runtime: options.runtime };
|
|
198
|
+
function resolveTenant() {
|
|
199
|
+
const value = typeof options.tenantId === "function" ? options.tenantId() : options.tenantId;
|
|
200
|
+
return value ?? void 0;
|
|
201
|
+
}
|
|
202
|
+
function resolveUnit() {
|
|
203
|
+
const value = typeof options.unitId === "function" ? options.unitId() : options.unitId;
|
|
204
|
+
return value ?? void 0;
|
|
205
|
+
}
|
|
206
|
+
function withTenant(filters) {
|
|
207
|
+
const tenantId = resolveTenant();
|
|
208
|
+
return tenantId ? [{ column: "tenant_id", operator: "eq", value: tenantId }, ...filters] : filters;
|
|
209
|
+
}
|
|
210
|
+
async function listItemRows(orderIds) {
|
|
211
|
+
if (orderIds.length === 0) return [];
|
|
212
|
+
const rows = [];
|
|
213
|
+
await Promise.all(orderIds.map(async (orderId) => {
|
|
214
|
+
const response = await client.data.listRows({
|
|
215
|
+
...tableOptions,
|
|
216
|
+
table: orderItemsTable,
|
|
217
|
+
filters: [{ column: "order_id", operator: "eq", value: orderId }],
|
|
218
|
+
sortColumn: "sort_order",
|
|
219
|
+
sortDirection: "asc",
|
|
220
|
+
limit: 200
|
|
221
|
+
});
|
|
222
|
+
rows.push(...response.rows);
|
|
223
|
+
}));
|
|
224
|
+
return rows;
|
|
225
|
+
}
|
|
226
|
+
async function hydrate(rows) {
|
|
227
|
+
const itemRows = await listItemRows(rows.map((row) => row.id));
|
|
228
|
+
const byOrder = /* @__PURE__ */ new Map();
|
|
229
|
+
for (const itemRow of itemRows) {
|
|
230
|
+
const item = rowToItem(itemRow);
|
|
231
|
+
const list = byOrder.get(item.orderId) ?? [];
|
|
232
|
+
list.push(item);
|
|
233
|
+
byOrder.set(item.orderId, list);
|
|
234
|
+
}
|
|
235
|
+
return rows.map((row) => rowToOrder(row, byOrder.get(row.id) ?? []));
|
|
236
|
+
}
|
|
237
|
+
async function listOrders(query = {}) {
|
|
238
|
+
const response = await client.data.listRows({
|
|
239
|
+
...tableOptions,
|
|
240
|
+
table: ordersTable,
|
|
241
|
+
filters: withTenant(filtersFromQuery(query)),
|
|
242
|
+
sortColumn: "created_at",
|
|
243
|
+
sortDirection: "desc",
|
|
244
|
+
limit: 500
|
|
245
|
+
});
|
|
246
|
+
return (await hydrate(response.rows)).filter((order) => matchesQuery(order, query));
|
|
247
|
+
}
|
|
248
|
+
async function getById(id) {
|
|
249
|
+
const response = await client.data.listRows({
|
|
250
|
+
...tableOptions,
|
|
251
|
+
table: ordersTable,
|
|
252
|
+
filters: withTenant([{ column: "id", operator: "eq", value: id }]),
|
|
253
|
+
limit: 1
|
|
254
|
+
});
|
|
255
|
+
return (await hydrate(response.rows))[0] ?? null;
|
|
256
|
+
}
|
|
257
|
+
async function updateOrder(id, data) {
|
|
258
|
+
const existing = await getById(id);
|
|
259
|
+
const row = await client.data.updateRow({
|
|
260
|
+
...tableOptions,
|
|
261
|
+
table: ordersTable,
|
|
262
|
+
primaryKeys: { id },
|
|
263
|
+
row: updatePayload(data, existing?.metadata)
|
|
264
|
+
});
|
|
265
|
+
return await getById(row.id) ?? rowToOrder(row);
|
|
266
|
+
}
|
|
267
|
+
return {
|
|
268
|
+
async getOrders(query) {
|
|
269
|
+
return paginate(await listOrders(query), query.page, query.pageSize);
|
|
270
|
+
},
|
|
271
|
+
async getOrderById(id) {
|
|
272
|
+
return getById(id);
|
|
273
|
+
},
|
|
274
|
+
async createOrder(input) {
|
|
275
|
+
const tenantId = resolveTenant();
|
|
276
|
+
const unitId = resolveUnit();
|
|
277
|
+
const orderRow = await client.data.createRow({
|
|
278
|
+
...tableOptions,
|
|
279
|
+
table: ordersTable,
|
|
280
|
+
row: {
|
|
281
|
+
...orderPayload(input),
|
|
282
|
+
...tenantId ? { tenant_id: tenantId } : {},
|
|
283
|
+
...unitId ? { unit_id: unitId } : {}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
await Promise.all(input.items.map((item, index) => client.data.createRow({
|
|
287
|
+
...tableOptions,
|
|
288
|
+
table: orderItemsTable,
|
|
289
|
+
row: itemToRow(item, orderRow.id, index, tenantId, unitId)
|
|
290
|
+
})));
|
|
291
|
+
return await getById(orderRow.id) ?? rowToOrder(orderRow);
|
|
292
|
+
},
|
|
293
|
+
async updateOrderStatus(input) {
|
|
294
|
+
const completedAt = input.status === "completed" ? nowIso() : void 0;
|
|
295
|
+
return updateOrder(input.orderId, { status: input.status, completedAt });
|
|
296
|
+
},
|
|
297
|
+
updateOrder,
|
|
298
|
+
async cancelOrder(id, reason) {
|
|
299
|
+
const order = await getById(id);
|
|
300
|
+
await updateOrder(id, { status: "cancelled", notes: withCancellationNote(order?.notes, reason) });
|
|
301
|
+
},
|
|
302
|
+
async addOrderItem(orderId, item) {
|
|
303
|
+
const order = await getById(orderId);
|
|
304
|
+
const row = await client.data.createRow({
|
|
305
|
+
...tableOptions,
|
|
306
|
+
table: orderItemsTable,
|
|
307
|
+
row: itemToRow(item, orderId, order?.items.length ?? 0, order?.tenantId, order?.unitId ?? resolveUnit())
|
|
308
|
+
});
|
|
309
|
+
const created = rowToItem(row);
|
|
310
|
+
await updateOrder(orderId, orderTotals([...order?.items ?? [], created], order ?? {}));
|
|
311
|
+
return created;
|
|
312
|
+
},
|
|
313
|
+
async removeOrderItem(itemId) {
|
|
314
|
+
const orders = await listOrders();
|
|
315
|
+
const order = orders.find((candidate) => candidate.items.some((orderItem) => orderItem.id === itemId));
|
|
316
|
+
await client.data.deleteRows({ ...tableOptions, table: orderItemsTable, rows: [{ id: itemId }] });
|
|
317
|
+
if (order) {
|
|
318
|
+
await updateOrder(order.id, orderTotals(order.items.filter((item) => item.id !== itemId), order));
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
async updateOrderItem(itemId, data) {
|
|
322
|
+
const existingResult = await client.data.listRows({
|
|
323
|
+
...tableOptions,
|
|
324
|
+
table: orderItemsTable,
|
|
325
|
+
filters: [{ column: "id", operator: "eq", value: itemId }],
|
|
326
|
+
limit: 1
|
|
327
|
+
});
|
|
328
|
+
const existingMetadata = existingResult.rows[0]?.metadata ?? void 0;
|
|
329
|
+
const metadataPatch = {
|
|
330
|
+
modifiers: data.modifiers,
|
|
331
|
+
kitchenNotes: data.kitchenNotes
|
|
332
|
+
};
|
|
333
|
+
const row = await client.data.updateRow({
|
|
334
|
+
...tableOptions,
|
|
335
|
+
table: orderItemsTable,
|
|
336
|
+
primaryKeys: { id: itemId },
|
|
337
|
+
row: {
|
|
338
|
+
product_id: data.productId,
|
|
339
|
+
name: data.name,
|
|
340
|
+
description: data.description,
|
|
341
|
+
quantity: data.quantity,
|
|
342
|
+
unit_price: data.unitPrice,
|
|
343
|
+
discount: data.discount,
|
|
344
|
+
total: data.total,
|
|
345
|
+
sort_order: data.sortOrder,
|
|
346
|
+
metadata: data.metadata !== void 0 || Object.values(metadataPatch).some((value) => value !== void 0) ? mergeOrdersMetadata(
|
|
347
|
+
data.metadata !== void 0 ? { ...existingMetadata ?? {}, ...data.metadata } : existingMetadata,
|
|
348
|
+
metadataPatch
|
|
349
|
+
) : void 0
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
return rowToItem(row);
|
|
353
|
+
},
|
|
354
|
+
async getSummary(dateRange) {
|
|
355
|
+
return summarizeOrders(await listOrders({ dateRange }), dateRange);
|
|
356
|
+
}
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export { createFayzOrdersProvider };
|
|
361
|
+
//# sourceMappingURL=platform.js.map
|
|
362
|
+
//# sourceMappingURL=platform.js.map
|