@fayz-ai/plugin-orders 0.14.4 → 0.15.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.
Files changed (36) hide show
  1. package/README.md +1 -0
  2. package/dist/{OrderDetailRoute-LTPDQXQU.js → OrderDetailRoute-QGZIMEQ3.js} +9 -7
  3. package/dist/OrderDetailRoute-QGZIMEQ3.js.map +1 -0
  4. package/dist/{OrdersPage-5326V62H.js → OrdersPage-3KNCFC7K.js} +3 -3
  5. package/dist/OrdersPage-3KNCFC7K.js.map +1 -0
  6. package/dist/context.d.ts +9 -6
  7. package/dist/context.d.ts.map +1 -1
  8. package/dist/index.d.ts +20 -45
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +61 -1425
  11. package/dist/index.js.map +1 -1
  12. package/dist/lib/list-query.d.ts +1 -1
  13. package/dist/lib/list-query.d.ts.map +1 -1
  14. package/dist/settings/DeliverySettings.d.ts.map +1 -1
  15. package/dist/settings/v1-settings.d.ts +2 -0
  16. package/dist/settings/v1-settings.d.ts.map +1 -0
  17. package/dist/views/OrderReceivableActions.d.ts.map +1 -1
  18. package/dist/views/OrdersPage.d.ts +2 -2
  19. package/dist/views/OrdersPage.d.ts.map +1 -1
  20. package/package.json +8 -9
  21. package/dist/OrderDetailRoute-LTPDQXQU.js.map +0 -1
  22. package/dist/OrdersPage-5326V62H.js.map +0 -1
  23. package/dist/data/core-supabase.d.ts +0 -26
  24. package/dist/data/core-supabase.d.ts.map +0 -1
  25. package/dist/data/mock.d.ts +0 -3
  26. package/dist/data/mock.d.ts.map +0 -1
  27. package/dist/data/platform.d.ts +0 -19
  28. package/dist/data/platform.d.ts.map +0 -1
  29. package/dist/data/types.d.ts +0 -17
  30. package/dist/data/types.d.ts.map +0 -1
  31. package/dist/integrations/index.d.ts +0 -8
  32. package/dist/integrations/index.d.ts.map +0 -1
  33. package/dist/store.d.ts +0 -33
  34. package/dist/store.d.ts.map +0 -1
  35. package/dist/types.d.ts +0 -145
  36. package/dist/types.d.ts.map +0 -1
package/dist/index.js CHANGED
@@ -1,573 +1,16 @@
1
1
  export { ORDER_DETAIL_COMPONENT_ID } from './chunk-YVC7R552.js';
2
2
  import React from 'react';
3
- import { createConnectionStore, connectionRuns, connectionSettings, connectionStatus, settingsStatus, getSupabaseClientOptional, emitDomainEvent, errorMessage } from '@fayz-ai/core';
4
- import { createStore } from 'zustand/vanilla';
5
- import { fayzConnectorOAuth, PluginSettingsPanel, dedup, useConnectors, useConnectorsPanelAvailable, openConnectorsPanel, SettingsGroup, ToggleRow, AddConnectorButton, ConnectorRow, AddConnectorPanel, ConnectorDetail, TextRow } from '@fayz-ai/admin';
6
- import { toast } from 'sonner';
3
+ import { createConnectionStore, connectionRuns, connectionSettings, connectionStatus, settingsStatus, tl, getSupabaseClientOptional } from '@fayz-ai/core';
4
+ import { createSupabaseOrdersProvider } from '@fayz-ai/orders/data/supabase';
5
+ export { createSupabaseOrdersProvider as createCoreOrdersProvider } from '@fayz-ai/orders/data/supabase';
6
+ import { createOrdersStore } from '@fayz-ai/orders/store';
7
+ import { fayzConnectorOAuth, defineSettingsTab, PluginSettingsPanel, useConnectors, useConnectorsPanelAvailable, openConnectorsPanel, SettingsGroup, ToggleRow, AddConnectorButton, ConnectorRow, AddConnectorPanel, ConnectorDetail, TextRow } from '@fayz-ai/admin';
7
8
  import { Skeleton } from '@fayz-ai/ui';
8
9
  import { AlertTriangle, Loader2, Check } from 'lucide-react';
9
10
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
10
- import { createFayzClient } from '@fayz-ai/sdk';
11
-
12
- var READ_ONLY = "This provider reads the core order archetype; pass `writes` to let the app that owns the flow create and edit them.";
13
- var DEFAULT_CHANNELS = {
14
- dine_in: "dine_in",
15
- delivery: "delivery",
16
- takeout: "balcao"
17
- };
18
- function searchTerm(raw) {
19
- return (raw ?? "").replace(/[,()%*\\"]/g, " ").trim();
20
- }
21
- function createCoreOrdersProvider(options) {
22
- const db = () => {
23
- const client = getSupabaseClientOptional();
24
- if (!client) throw new Error("Supabase client is not configured");
25
- return client;
26
- };
27
- const writes = options?.writes;
28
- function requireWrites() {
29
- if (!writes) throw new Error(READ_ONLY);
30
- return writes;
31
- }
32
- async function load(query, only) {
33
- const client = db();
34
- let q = client.from("v_orders").select("id, tenant_id, unit_id, kind, channel, status, reference_number, party_id, assignee_id, subtotal, discount, tax, total, currency, notes, created_at, updated_at, completed_at, fulfillment_status, metadata", { count: "exact" }).order("created_at", { ascending: false });
35
- if (only?.id) q = q.eq("id", only.id);
36
- if (options?.kinds?.length) q = q.in("kind", options.kinds);
37
- if (options?.channel) q = q.eq("channel", options.channel);
38
- if (query?.kind) {
39
- q = Array.isArray(query.kind) ? q.in("kind", query.kind) : q.eq("kind", query.kind);
40
- }
41
- if (query?.status) {
42
- q = Array.isArray(query.status) ? q.in("status", query.status) : q.eq("status", query.status);
43
- }
44
- if (query?.channel) q = q.eq("channel", query.channel);
45
- if (query?.excludeKinds?.length) q = q.not("kind", "in", `(${query.excludeKinds.join(",")})`);
46
- if (query?.fulfillmentStatus) q = q.eq("fulfillment_status", query.fulfillmentStatus);
47
- if (query?.tableId) q = q.eq("metadata->>tableId", query.tableId);
48
- if (query?.assigneeId) q = q.eq("assignee_id", query.assigneeId);
49
- if (query?.dateRange) {
50
- q = q.gte("created_at", query.dateRange.from).lte("created_at", query.dateRange.to);
51
- }
52
- const term = searchTerm(query?.search);
53
- if (term) {
54
- const { data: named } = await client.from("people").select("id").ilike("name", `%${term}%`).limit(50);
55
- const ids2 = (named ?? []).map((p) => p.id);
56
- q = q.or([
57
- `reference_number.ilike.%${term}%`,
58
- ...ids2.length ? [`party_id.in.(${ids2.join(",")})`] : []
59
- ].join(","));
60
- }
61
- const pageSize = query?.pageSize ?? 100;
62
- const from = ((query?.page ?? 1) - 1) * pageSize;
63
- q = q.range(from, from + pageSize - 1);
64
- const { data, error, count } = await q;
65
- if (error) throw new Error(error.message);
66
- const rows = data ?? [];
67
- const ids = rows.map((r) => r.id);
68
- const withItems = query?.withItems !== false;
69
- const [{ data: people }, { data: payments }, { data: items }, { data: shipments }] = await Promise.all([
70
- ids.length ? client.from("people").select("id, name").in("id", [...new Set(rows.flatMap((r) => [r.party_id, r.assignee_id]).filter(Boolean))]) : Promise.resolve({ data: [] }),
71
- ids.length ? client.from("v_order_payment_status").select("order_id, status, total_amount, paid_amount").in("order_id", ids) : Promise.resolve({ data: [] }),
72
- ids.length && withItems ? client.from("items").select("id, order_id, product_id, name, description, quantity, unit_price, discount, total, sort_order, metadata, created_at").in("order_id", ids).order("sort_order") : Promise.resolve({ data: [] }),
73
- ids.length ? client.from("fulfillments").select("order_id, status").in("order_id", ids).in("kind", ["shipment", "pickup"]) : Promise.resolve({ data: [] })
74
- ]);
75
- const shipmentsByOrder = /* @__PURE__ */ new Map();
76
- for (const s of shipments ?? []) {
77
- shipmentsByOrder.set(s.order_id, [...shipmentsByOrder.get(s.order_id) ?? [], s.status]);
78
- }
79
- const nameById = new Map((people ?? []).map((p) => [p.id, p.name]));
80
- const payById = new Map((payments ?? []).map((p) => [p.order_id, p]));
81
- const itemsByOrder = /* @__PURE__ */ new Map();
82
- for (const item of items ?? []) {
83
- const list = itemsByOrder.get(item.order_id) ?? [];
84
- list.push(toItem(item));
85
- itemsByOrder.set(item.order_id, list);
86
- }
87
- return {
88
- data: rows.map((r) => {
89
- const pay = payById.get(r.id);
90
- const meta = r.metadata ?? {};
91
- return {
92
- id: r.id,
93
- referenceNumber: r.reference_number ?? String(r.id).slice(0, 8),
94
- kind: r.kind,
95
- status: r.status,
96
- partyId: r.party_id ?? void 0,
97
- partyName: r.party_id ? nameById.get(r.party_id) : void 0,
98
- assigneeId: r.assignee_id ?? void 0,
99
- assigneeName: r.assignee_id ? nameById.get(r.assignee_id) : void 0,
100
- subtotal: Number(r.subtotal) || 0,
101
- discount: Number(r.discount) || 0,
102
- tax: Number(r.tax) || 0,
103
- total: Number(r.total) || 0,
104
- currency: r.currency ?? "BRL",
105
- notes: r.notes ?? void 0,
106
- tags: [],
107
- // `source` is the archetype's channel where it has one; the salon's
108
- // counter sale has none, and 'balcao' is what that means.
109
- source: r.channel ?? "balcao",
110
- // NOT location_id: that column is a FK to `app.units`, i.e. the
111
- // BRANCH this order belongs to. A mesa has no table of its own yet,
112
- // so its id rides in metadata until the floor plan gets one.
113
- tableId: typeof meta.tableId === "string" ? meta.tableId : void 0,
114
- estimatedMinutes: typeof meta.estimatedMinutes === "number" ? meta.estimatedMinutes : void 0,
115
- items: itemsByOrder.get(r.id) ?? [],
116
- metadata: {
117
- ...meta,
118
- channel: r.channel ?? null,
119
- fulfillmentStatus: r.fulfillment_status ?? null,
120
- paymentStatus: pay?.status ?? "none",
121
- invoicedAmount: Number(pay?.total_amount) || 0,
122
- paidAmount: Number(pay?.paid_amount) || 0,
123
- shipmentStatuses: shipmentsByOrder.get(r.id) ?? []
124
- },
125
- tenantId: r.tenant_id,
126
- unitId: r.unit_id ?? void 0,
127
- createdAt: r.created_at,
128
- updatedAt: r.updated_at,
129
- completedAt: r.completed_at ?? void 0
130
- };
131
- }),
132
- total: count ?? rows.length
133
- };
134
- }
135
- function toItem(row) {
136
- const meta = row.metadata ?? {};
137
- return {
138
- id: row.id,
139
- orderId: row.order_id,
140
- productId: row.product_id ?? void 0,
141
- name: row.name ?? "",
142
- description: row.description ?? void 0,
143
- quantity: Number(row.quantity) || 0,
144
- unitPrice: Number(row.unit_price) || 0,
145
- discount: Number(row.discount) || 0,
146
- total: Number(row.total) || 0,
147
- sortOrder: row.sort_order ?? 0,
148
- modifiers: typeof meta.modifiers === "string" ? meta.modifiers : void 0,
149
- kitchenNotes: typeof meta.kitchenNotes === "string" ? meta.kitchenNotes : void 0,
150
- metadata: meta,
151
- createdAt: row.created_at
152
- };
153
- }
154
- function lineTotal(item) {
155
- return item.quantity * item.unitPrice - (item.discount ?? 0);
156
- }
157
- async function loadOne(id) {
158
- const page = await load(void 0, { id });
159
- return page.data[0] ?? null;
160
- }
161
- async function recalc(orderId) {
162
- const client = db();
163
- const { data, error } = await client.from("items").select("total").eq("order_id", orderId);
164
- if (error) throw new Error(error.message);
165
- const subtotal = (data ?? []).reduce((sum, r) => sum + (Number(r.total) || 0), 0);
166
- const { error: upErr } = await client.from("orders").update({ subtotal, total: subtotal }).eq("id", orderId);
167
- if (upErr) throw new Error(upErr.message);
168
- }
169
- async function orderIdOfItem(itemId) {
170
- const client = db();
171
- const { data, error } = await client.from("items").select("order_id").eq("id", itemId).single();
172
- if (error) throw new Error(error.message);
173
- return data.order_id;
174
- }
175
- return {
176
- getOrders: (query) => load(query),
177
- getOrderById: loadOne,
178
- async createOrder(input) {
179
- const w = requireWrites();
180
- const client = db();
181
- const tenantId = w.tenantId();
182
- if (!tenantId) throw new Error("No active organization: an order cannot be opened without one");
183
- const channel = (w.channelFor ?? ((k) => DEFAULT_CHANNELS[k]))(input.kind);
184
- const subtotal = input.items.reduce(
185
- (sum, i) => sum + lineTotal({ quantity: i.quantity, unitPrice: i.unitPrice, discount: i.discount }),
186
- 0
187
- );
188
- const { data: order, error } = await client.from("orders").insert({
189
- tenant_id: tenantId,
190
- unit_id: w.unitId?.() ?? null,
191
- kind: input.kind,
192
- status: "new",
193
- ...channel ? { channel } : {},
194
- // party_id is left out on purpose: `trg_orders_require_party` fills it
195
- // with `public.walkin_party(tenant_id)`, which is exactly what a table
196
- // with no named customer is.
197
- ...input.partyId ? { party_id: input.partyId } : {},
198
- ...input.assigneeId ? { assignee_id: input.assigneeId } : {},
199
- ...input.notes ? { notes: input.notes } : {},
200
- subtotal,
201
- total: subtotal,
202
- currency: "BRL",
203
- metadata: {
204
- ...input.tableId ? { tableId: input.tableId } : {},
205
- ...input.estimatedMinutes ? { estimatedMinutes: input.estimatedMinutes } : {}
206
- }
207
- }).select("id").single();
208
- if (error) throw new Error(error.message);
209
- if (input.items.length) {
210
- const { error: itemsErr } = await client.from("items").insert(
211
- input.items.map((item, index) => ({
212
- order_id: order.id,
213
- // tenant_id and parent_kind are inherited from the parent by
214
- // `trg_items_inherit`; setting them here would only duplicate it.
215
- product_id: item.productId ?? null,
216
- name: item.name,
217
- quantity: item.quantity,
218
- unit_price: item.unitPrice,
219
- discount: item.discount ?? 0,
220
- total: lineTotal(item),
221
- sort_order: index,
222
- metadata: {
223
- ...item.modifiers ? { modifiers: item.modifiers } : {},
224
- ...item.kitchenNotes ? { kitchenNotes: item.kitchenNotes } : {}
225
- }
226
- }))
227
- );
228
- if (itemsErr) throw new Error(itemsErr.message);
229
- }
230
- const created = await loadOne(order.id);
231
- if (!created) throw new Error("The order was created but is not readable \u2014 check the orders.read permission");
232
- return created;
233
- },
234
- async updateOrderStatus(input) {
235
- requireWrites();
236
- const client = db();
237
- const { error } = await client.from("orders").update({ status: input.status }).eq("id", input.orderId);
238
- if (error) throw new Error(error.message);
239
- const order = await loadOne(input.orderId);
240
- if (!order) throw new Error("Order not found after the status change");
241
- return order;
242
- },
243
- async updateOrder(id, data) {
244
- requireWrites();
245
- const client = db();
246
- const patch = {};
247
- if (data.status !== void 0) patch.status = data.status;
248
- if (data.notes !== void 0) patch.notes = data.notes;
249
- if (data.partyId !== void 0) patch.party_id = data.partyId;
250
- if (data.assigneeId !== void 0) patch.assignee_id = data.assigneeId;
251
- if (data.discount !== void 0) patch.discount = data.discount;
252
- if (data.tax !== void 0) patch.tax = data.tax;
253
- if (Object.keys(patch).length) {
254
- const { error } = await client.from("orders").update(patch).eq("id", id);
255
- if (error) throw new Error(error.message);
256
- }
257
- const order = await loadOne(id);
258
- if (!order) throw new Error("Order not found after the update");
259
- return order;
260
- },
261
- async cancelOrder(id, reason) {
262
- requireWrites();
263
- const client = db();
264
- const { error } = await client.from("orders").update({ status: "cancelled", ...reason ? { notes: reason } : {} }).eq("id", id);
265
- if (error) throw new Error(error.message);
266
- },
267
- async addOrderItem(orderId, item) {
268
- requireWrites();
269
- const client = db();
270
- const { count } = await client.from("items").select("id", { count: "exact", head: true }).eq("order_id", orderId);
271
- const { data, error } = await client.from("items").insert({
272
- order_id: orderId,
273
- product_id: item.productId ?? null,
274
- name: item.name,
275
- quantity: item.quantity,
276
- unit_price: item.unitPrice,
277
- discount: item.discount ?? 0,
278
- total: lineTotal(item),
279
- sort_order: count ?? 0,
280
- metadata: {
281
- ...item.modifiers ? { modifiers: item.modifiers } : {},
282
- ...item.kitchenNotes ? { kitchenNotes: item.kitchenNotes } : {}
283
- }
284
- }).select("id, order_id, product_id, name, description, quantity, unit_price, discount, total, sort_order, metadata, created_at").single();
285
- if (error) throw new Error(error.message);
286
- await recalc(orderId);
287
- return toItem(data);
288
- },
289
- async removeOrderItem(itemId) {
290
- requireWrites();
291
- const client = db();
292
- const orderId = await orderIdOfItem(itemId);
293
- const { error } = await client.from("items").delete().eq("id", itemId);
294
- if (error) throw new Error(error.message);
295
- await recalc(orderId);
296
- },
297
- async updateOrderItem(itemId, data) {
298
- requireWrites();
299
- const client = db();
300
- const orderId = await orderIdOfItem(itemId);
301
- const patch = {};
302
- if (data.name !== void 0) patch.name = data.name;
303
- if (data.quantity !== void 0) patch.quantity = data.quantity;
304
- if (data.unitPrice !== void 0) patch.unit_price = data.unitPrice;
305
- if (data.discount !== void 0) patch.discount = data.discount;
306
- if (data.quantity !== void 0 || data.unitPrice !== void 0 || data.discount !== void 0) {
307
- const { data: current, error: readErr } = await client.from("items").select("quantity, unit_price, discount").eq("id", itemId).single();
308
- if (readErr) throw new Error(readErr.message);
309
- patch.total = lineTotal({
310
- quantity: Number(data.quantity ?? current.quantity) || 0,
311
- unitPrice: Number(data.unitPrice ?? current.unit_price) || 0,
312
- discount: Number(data.discount ?? current.discount) || 0
313
- });
314
- }
315
- const { data: row, error } = await client.from("items").update(patch).eq("id", itemId).select("id, order_id, product_id, name, description, quantity, unit_price, discount, total, sort_order, metadata, created_at").single();
316
- if (error) throw new Error(error.message);
317
- await recalc(orderId);
318
- return toItem(row);
319
- },
320
- async getSummary(dateRange) {
321
- const page = await load({ pageSize: 500, ...dateRange ? { dateRange } : {} });
322
- const live = page.data.filter((o) => o.status !== "cancelled");
323
- const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
324
- const todays = live.filter((o) => o.createdAt.slice(0, 10) === today);
325
- const revenue = todays.reduce((sum, o) => sum + o.total, 0);
326
- const byKind = {};
327
- const byStatus = {};
328
- for (const o of live) {
329
- byKind[o.kind] = (byKind[o.kind] ?? 0) + 1;
330
- byStatus[o.status] = (byStatus[o.status] ?? 0) + 1;
331
- }
332
- return {
333
- todayOrderCount: todays.length,
334
- todayRevenue: revenue,
335
- averageTicket: todays.length ? revenue / todays.length : 0,
336
- activeOrderCount: live.filter((o) => o.status !== "completed").length,
337
- ordersByKind: byKind,
338
- ordersByStatus: byStatus,
339
- topItems: []
340
- };
341
- }
342
- };
343
- }
344
-
345
- // src/types.ts
346
- var STATUS_FLOW = {
347
- dine_in: ["draft", "new", "confirmed", "preparing", "ready", "served", "completed"],
348
- takeout: ["draft", "new", "confirmed", "preparing", "ready", "picked_up", "completed"],
349
- delivery: ["draft", "new", "confirmed", "preparing", "ready", "dispatched", "delivered", "completed"]
350
- };
351
- var OUT_STATUSES = ["served", "picked_up", "dispatched", "delivered"];
352
- function getNextStatus(kind, current) {
353
- const flow = STATUS_FLOW[kind];
354
- let idx = flow.indexOf(current);
355
- if (idx === -1 && OUT_STATUSES.includes(current)) {
356
- idx = flow.findIndex((status) => OUT_STATUSES.includes(status));
357
- }
358
- return idx >= 0 && idx < flow.length - 1 ? flow[idx + 1] : null;
359
- }
360
- var ADVANCE_VERB = {
361
- draft: "Salvar rascunho",
362
- new: "Enviar",
363
- confirmed: "Confirmar",
364
- preparing: "Preparar",
365
- ready: "Marcar pronto",
366
- served: "Servir",
367
- picked_up: "Entregar",
368
- dispatched: "Despachar",
369
- delivered: "Confirmar entrega",
370
- completed: "Concluir",
371
- cancelled: "Cancelar"
372
- };
373
- function getPreviousStatus(kind, current) {
374
- const flow = STATUS_FLOW[kind];
375
- const idx = flow.indexOf(current);
376
- return idx > 0 ? flow[idx - 1] : null;
377
- }
378
- function mapToKanbanColumn(status) {
379
- if (["served", "picked_up", "dispatched", "delivered"].includes(status)) return "out";
380
- if (["new", "confirmed", "preparing", "ready", "completed", "cancelled"].includes(status)) {
381
- return status;
382
- }
383
- return "new";
384
- }
385
- var KANBAN_COLUMNS = ["new", "confirmed", "preparing", "ready", "out", "completed"];
386
- var DEFAULT_STATUS_CONFIGS = [
387
- { value: "new", label: "New", color: "#6366f1", icon: "PlusCircle" },
388
- { value: "confirmed", label: "Confirmed", color: "#3b82f6", icon: "CheckCircle" },
389
- { value: "preparing", label: "Preparing", color: "#f59e0b", icon: "ChefHat" },
390
- { value: "ready", label: "Ready", color: "#10b981", icon: "Bell" },
391
- { value: "served", label: "Served", color: "#06b6d4", icon: "Utensils" },
392
- { value: "picked_up", label: "Picked Up", color: "#06b6d4", icon: "ShoppingBag" },
393
- { value: "dispatched", label: "Dispatched", color: "#8b5cf6", icon: "Truck" },
394
- { value: "delivered", label: "Delivered", color: "#06b6d4", icon: "PackageCheck" },
395
- { value: "completed", label: "Completed", color: "#22c55e", icon: "CircleCheck" },
396
- { value: "cancelled", label: "Cancelled", color: "#ef4444", icon: "XCircle" }
397
- ];
398
-
399
- // src/store.ts
400
- var ACTIVE_STATUSES = [
401
- "new",
402
- "confirmed",
403
- "preparing",
404
- "ready",
405
- // The `Saiu` column: one word per kind for the same moment.
406
- "served",
407
- "picked_up",
408
- "dispatched",
409
- "delivered"
410
- ];
411
- function emitOrderLifecycleEvent(key, order) {
412
- emitDomainEvent(key, {
413
- order_id: order.id,
414
- reference_number: order.referenceNumber,
415
- total: order.total,
416
- item_count: order.items.length,
417
- source: order.source
418
- }, {
419
- tenantId: order.tenantId,
420
- subject: { type: "order", id: order.id }
421
- });
422
- }
423
- async function runLifecycleHook(label, order, hook) {
424
- if (!hook) return;
425
- try {
426
- await hook(order);
427
- } catch (error) {
428
- const message2 = errorMessage(error);
429
- throw new Error(`Order was ${label}, but downstream synchronization is pending: ${message2}`);
430
- }
431
- }
432
- function createOrdersStore(provider, hooks = {}) {
433
- return createStore((set, get) => ({
434
- orders: [],
435
- ordersTotal: 0,
436
- ordersLoading: false,
437
- orderQuery: {},
438
- activeOrders: [],
439
- activeOrdersLoading: false,
440
- summary: null,
441
- summaryLoading: false,
442
- selectedOrderId: null,
443
- async fetchOrders(query) {
444
- return dedup("orders:list:" + JSON.stringify(query), async () => {
445
- set({ ordersLoading: true, orderQuery: query });
446
- const result = await provider.getOrders(query);
447
- set({ orders: result.data, ordersTotal: result.total, ordersLoading: false });
448
- });
449
- },
450
- async fetchActiveOrders() {
451
- return dedup("orders:active", async () => {
452
- set({ activeOrdersLoading: true });
453
- const result = await provider.getOrders({ status: [...ACTIVE_STATUSES] });
454
- set({ activeOrders: result.data, activeOrdersLoading: false });
455
- });
456
- },
457
- async fetchSummary(dateRange) {
458
- return dedup("orders:summary", async () => {
459
- set({ summaryLoading: true });
460
- const summary = await provider.getSummary(dateRange);
461
- set({ summary, summaryLoading: false });
462
- });
463
- },
464
- selectOrder(id) {
465
- set({ selectedOrderId: id });
466
- },
467
- async createOrder(input) {
468
- try {
469
- const order = await provider.createOrder(input);
470
- const query = get().orderQuery;
471
- const [result, summary] = await Promise.all([
472
- provider.getOrders(query),
473
- provider.getSummary()
474
- ]);
475
- set({ orders: result.data, ordersTotal: result.total, summary });
476
- toast.success("Pedido criado");
477
- return order;
478
- } catch (err) {
479
- toast.error("N\xE3o foi poss\xEDvel criar o pedido", { description: err?.message });
480
- throw err;
481
- }
482
- },
483
- async advanceOrderStatus(orderId) {
484
- try {
485
- const { orders, activeOrders } = get();
486
- const order = orders.find((o) => o.id === orderId) ?? activeOrders.find((o) => o.id === orderId);
487
- if (!order) throw new Error("Order not found");
488
- const nextStatus = getNextStatus(order.kind, order.status);
489
- if (!nextStatus) throw new Error("No next status available");
490
- const updated = await provider.updateOrderStatus({ orderId, status: nextStatus });
491
- if (updated.status === "completed") {
492
- emitOrderLifecycleEvent("orders.order_completed", updated);
493
- await runLifecycleHook("completed", updated, hooks.onOrderCompleted);
494
- }
495
- const activeResult = await provider.getOrders({ status: [...ACTIVE_STATUSES] });
496
- set({ activeOrders: activeResult.data });
497
- toast.success("Pedido avan\xE7ado");
498
- } catch (err) {
499
- toast.error("N\xE3o foi poss\xEDvel avan\xE7ar o pedido", { description: err?.message });
500
- throw err;
501
- }
502
- },
503
- async updateOrderStatus(input) {
504
- try {
505
- const before = await provider.getOrderById(input.orderId);
506
- const updated = await provider.updateOrderStatus(input);
507
- if (updated.status === "completed") {
508
- if (before?.status !== "completed") emitOrderLifecycleEvent("orders.order_completed", updated);
509
- await runLifecycleHook("completed", updated, hooks.onOrderCompleted);
510
- }
511
- const query = get().orderQuery;
512
- const [result, summary] = await Promise.all([
513
- provider.getOrders(query),
514
- provider.getSummary()
515
- ]);
516
- set({ orders: result.data, ordersTotal: result.total, summary });
517
- toast.success("Status atualizado");
518
- } catch (err) {
519
- toast.error("N\xE3o foi poss\xEDvel atualizar o status", { description: err?.message });
520
- throw err;
521
- }
522
- },
523
- async cancelOrder(id, reason) {
524
- try {
525
- const before = await provider.getOrderById(id);
526
- await provider.cancelOrder(id, reason);
527
- const cancelled = await provider.getOrderById(id);
528
- const order = cancelled ?? (before ? { ...before, status: "cancelled" } : null);
529
- if (order) {
530
- if (before?.status !== "cancelled") emitOrderLifecycleEvent("orders.order_cancelled", order);
531
- await runLifecycleHook("cancelled", order, hooks.onOrderCancelled);
532
- }
533
- const query = get().orderQuery;
534
- const [result, summary] = await Promise.all([
535
- provider.getOrders(query),
536
- provider.getSummary()
537
- ]);
538
- set({ orders: result.data, ordersTotal: result.total, summary });
539
- toast.success("Pedido cancelado");
540
- } catch (err) {
541
- toast.error("N\xE3o foi poss\xEDvel cancelar o pedido", { description: err?.message });
542
- throw err;
543
- }
544
- },
545
- async addOrderItem(orderId, item) {
546
- try {
547
- await provider.addOrderItem(orderId, item);
548
- const query = get().orderQuery;
549
- const result = await provider.getOrders(query);
550
- set({ orders: result.data, ordersTotal: result.total });
551
- toast.success("Item adicionado");
552
- } catch (err) {
553
- toast.error("N\xE3o foi poss\xEDvel adicionar o item", { description: err?.message });
554
- throw err;
555
- }
556
- },
557
- async removeOrderItem(itemId) {
558
- try {
559
- await provider.removeOrderItem(itemId);
560
- const query = get().orderQuery;
561
- const result = await provider.getOrders(query);
562
- set({ orders: result.data, ordersTotal: result.total });
563
- toast.success("Item removido");
564
- } catch (err) {
565
- toast.error("N\xE3o foi poss\xEDvel remover o item", { description: err?.message });
566
- throw err;
567
- }
568
- }
569
- }));
570
- }
11
+ export { ADVANCE_VERB, DEFAULT_STATUS_CONFIGS, KANBAN_COLUMNS, STATUS_FLOW, getNextStatus, getPreviousStatus, mapToKanbanColumn } from '@fayz-ai/orders/domain/order';
12
+ export { createFayzOrdersProvider } from '@fayz-ai/orders/data/platform';
13
+ export { createMockOrdersProvider } from '@fayz-ai/orders/data/mock';
571
14
 
572
15
  // src/data/registries.ts
573
16
  var orderSourceEntity = {
@@ -1587,7 +1030,7 @@ function amountText(value) {
1587
1030
  if (value === null || value === void 0) return "";
1588
1031
  return String(value).replace(".", ",");
1589
1032
  }
1590
- function AmountRow({ label, description, hint, value, onCommit }) {
1033
+ function AmountRow({ label, description, hint, value, onCommit, pending }) {
1591
1034
  const [text, setText] = React.useState(() => amountText(value));
1592
1035
  const [invalid, setInvalid] = React.useState(false);
1593
1036
  React.useEffect(() => {
@@ -1596,6 +1039,7 @@ function AmountRow({ label, description, hint, value, onCommit }) {
1596
1039
  return /* @__PURE__ */ jsx(
1597
1040
  TextRow,
1598
1041
  {
1042
+ pending,
1599
1043
  label,
1600
1044
  description,
1601
1045
  value: text,
@@ -1667,6 +1111,7 @@ function DeliverySettings() {
1667
1111
  /* @__PURE__ */ jsx(
1668
1112
  ToggleRow,
1669
1113
  {
1114
+ pending: true,
1670
1115
  label: "A casa entrega",
1671
1116
  description: "Desligado, nenhum canal novo nasce como entrega.",
1672
1117
  checked: value.enabled !== false,
@@ -1676,6 +1121,7 @@ function DeliverySettings() {
1676
1121
  /* @__PURE__ */ jsx(
1677
1122
  AmountRow,
1678
1123
  {
1124
+ pending: true,
1679
1125
  label: "Taxa de entrega",
1680
1126
  description: "Cobrada por pedido, na moeda da casa.",
1681
1127
  hint: "Zero = entrega sem taxa.",
@@ -1686,6 +1132,7 @@ function DeliverySettings() {
1686
1132
  /* @__PURE__ */ jsx(
1687
1133
  AmountRow,
1688
1134
  {
1135
+ pending: true,
1689
1136
  label: "Frete gr\xE1tis acima de",
1690
1137
  description: "Acima deste valor de pedido a taxa \xE9 zerada.",
1691
1138
  hint: "Vazio = a taxa vale sempre.",
@@ -1696,6 +1143,7 @@ function DeliverySettings() {
1696
1143
  /* @__PURE__ */ jsx(
1697
1144
  AmountRow,
1698
1145
  {
1146
+ pending: true,
1699
1147
  label: "Pedido m\xEDnimo",
1700
1148
  description: "Abaixo disso a casa n\xE3o entrega.",
1701
1149
  hint: "Zero = sem m\xEDnimo.",
@@ -1715,6 +1163,7 @@ function DeliverySettings() {
1715
1163
  /* @__PURE__ */ jsx(
1716
1164
  AmountRow,
1717
1165
  {
1166
+ pending: true,
1718
1167
  label: "Tempo estimado (min)",
1719
1168
  description: "Da confirma\xE7\xE3o at\xE9 a porta.",
1720
1169
  value: value.etaMinutes,
@@ -1724,6 +1173,7 @@ function DeliverySettings() {
1724
1173
  /* @__PURE__ */ jsx(
1725
1174
  AmountRow,
1726
1175
  {
1176
+ pending: true,
1727
1177
  label: "Raio de entrega (km)",
1728
1178
  description: "Dist\xE2ncia m\xE1xima a partir da casa.",
1729
1179
  hint: "Zero = sem limite declarado.",
@@ -1780,845 +1230,37 @@ function DeliverySettings() {
1780
1230
  )
1781
1231
  ] });
1782
1232
  }
1783
- var DEFAULT_ORDERS_TABLE = "orders";
1784
- var DEFAULT_ORDER_ITEMS_TABLE = "items";
1785
- var ORDERS_METADATA_KEY = "fayzOrders";
1786
- var ACTIVE_STATUSES2 = /* @__PURE__ */ new Set(["new", "confirmed", "preparing", "ready", "served", "dispatched"]);
1787
- var RESTAURANT_STATUSES = /* @__PURE__ */ new Set([
1788
- "new",
1789
- "confirmed",
1790
- "preparing",
1791
- "ready",
1792
- "served",
1793
- "picked_up",
1794
- "dispatched",
1795
- "delivered",
1796
- "completed",
1797
- "cancelled"
1798
- ]);
1799
- function nowIso() {
1800
- return (/* @__PURE__ */ new Date()).toISOString();
1801
- }
1802
- function numberValue(value) {
1803
- if (typeof value === "number") return value;
1804
- if (typeof value === "string") return Number(value) || 0;
1805
- return 0;
1806
- }
1807
- function dateKey(value) {
1808
- return value.slice(0, 10);
1809
- }
1810
- function referenceNumber() {
1811
- return `ORD-${Date.now().toString().slice(-6)}`;
1812
- }
1813
- function objectValue(value) {
1814
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
1815
- }
1816
- function canonicalStatus(status) {
1817
- if (status === "new") return "draft";
1818
- if (status === "completed" || status === "cancelled") return status;
1819
- return "confirmed";
1820
- }
1821
- function restaurantStatus(rowStatus, metadata) {
1822
- if (rowStatus === "completed" || rowStatus === "cancelled") return rowStatus;
1823
- const stored = metadata.restaurantStatus;
1824
- if (typeof stored === "string" && RESTAURANT_STATUSES.has(stored)) return stored;
1825
- if (rowStatus === "draft") return "new";
1826
- if (typeof rowStatus === "string" && RESTAURANT_STATUSES.has(rowStatus)) return rowStatus;
1827
- return "confirmed";
1828
- }
1829
- function ordersMetadata(metadata) {
1830
- return objectValue(metadata?.[ORDERS_METADATA_KEY]);
1831
- }
1832
- function mergeOrdersMetadata(metadata, patch) {
1833
- const base = { ...metadata ?? {} };
1834
- const current = ordersMetadata(base);
1835
- const definedPatch = Object.fromEntries(
1836
- Object.entries(patch).filter(([, value]) => value !== void 0)
1837
- );
1838
- const next = { ...current, ...definedPatch };
1839
- return { ...base, [ORDERS_METADATA_KEY]: next };
1840
- }
1841
- function itemToRow(item, orderId, sortOrder, tenantId, unitId) {
1842
- const discount = item.discount ?? 0;
1843
- return {
1844
- order_id: orderId,
1845
- ...tenantId ? { tenant_id: tenantId } : {},
1846
- ...unitId ? { unit_id: unitId } : {},
1847
- product_id: item.productId ?? null,
1848
- name: item.name,
1849
- quantity: item.quantity,
1850
- unit_price: item.unitPrice,
1851
- discount,
1852
- total: item.quantity * item.unitPrice - discount,
1853
- sort_order: sortOrder,
1854
- metadata: mergeOrdersMetadata(void 0, {
1855
- modifiers: item.modifiers ?? null,
1856
- kitchenNotes: item.kitchenNotes ?? null
1857
- })
1858
- };
1859
- }
1860
- function rowToItem(row) {
1861
- const quantity = numberValue(row.quantity);
1862
- const unitPrice = numberValue(row.unit_price);
1863
- const discount = numberValue(row.discount);
1864
- const restaurant = ordersMetadata(row.metadata);
1865
- return {
1866
- id: row.id,
1867
- orderId: row.order_id ?? "",
1868
- productId: row.product_id ?? void 0,
1869
- name: row.name ?? "Item",
1870
- description: row.description ?? void 0,
1871
- quantity,
1872
- unitPrice,
1873
- discount,
1874
- total: numberValue(row.total) || quantity * unitPrice - discount,
1875
- sortOrder: row.sort_order ?? 0,
1876
- modifiers: row.modifiers ?? (typeof restaurant.modifiers === "string" ? restaurant.modifiers : void 0),
1877
- kitchenNotes: row.kitchen_notes ?? (typeof restaurant.kitchenNotes === "string" ? restaurant.kitchenNotes : void 0),
1878
- metadata: row.metadata ?? {},
1879
- createdAt: row.created_at ?? nowIso()
1880
- };
1881
- }
1882
- function rowToOrder(row, items = []) {
1883
- const subtotal = numberValue(row.subtotal) || items.reduce((sum, item) => sum + item.total, 0);
1884
- const discount = numberValue(row.discount);
1885
- const tax = numberValue(row.tax);
1886
- const restaurant = ordersMetadata(row.metadata);
1887
- return {
1888
- id: row.id,
1889
- referenceNumber: row.reference_number ?? row.id,
1890
- kind: row.kind ?? "dine_in",
1891
- status: restaurantStatus(row.status, restaurant),
1892
- partyId: row.party_id ?? void 0,
1893
- partyName: row.party_name ?? (typeof restaurant.partyName === "string" ? restaurant.partyName : void 0),
1894
- assigneeId: row.assignee_id ?? void 0,
1895
- assigneeName: row.assignee_name ?? (typeof restaurant.assigneeName === "string" ? restaurant.assigneeName : void 0),
1896
- locationId: row.location_id ?? void 0,
1897
- subtotal,
1898
- discount,
1899
- tax,
1900
- total: numberValue(row.total) || subtotal - discount + tax,
1901
- currency: row.currency ?? "BRL",
1902
- notes: row.notes ?? void 0,
1903
- tags: row.tags ?? [],
1904
- source: row.source ?? (typeof restaurant.source === "string" ? restaurant.source : "pos"),
1905
- tableId: row.table_id ?? (typeof restaurant.tableId === "string" ? restaurant.tableId : void 0),
1906
- tableName: row.table_name ?? (typeof restaurant.tableName === "string" ? restaurant.tableName : void 0),
1907
- estimatedMinutes: row.estimated_minutes ?? (typeof restaurant.estimatedMinutes === "number" ? restaurant.estimatedMinutes : void 0),
1908
- items,
1909
- metadata: row.metadata ?? {},
1910
- tenantId: row.tenant_id ?? "runtime-tenant",
1911
- unitId: row.unit_id ?? void 0,
1912
- createdAt: row.created_at ?? nowIso(),
1913
- updatedAt: row.updated_at ?? row.created_at ?? nowIso(),
1914
- completedAt: row.completed_at ?? void 0
1915
- };
1916
- }
1917
- function orderPayload(input) {
1918
- const subtotal = input.items.reduce((sum, item) => sum + item.quantity * item.unitPrice - (item.discount ?? 0), 0);
1919
- return {
1920
- reference_number: referenceNumber(),
1921
- kind: input.kind,
1922
- status: "draft",
1923
- party_id: input.partyId ?? null,
1924
- assignee_id: input.assigneeId ?? null,
1925
- notes: input.notes ?? null,
1926
- subtotal,
1927
- discount: 0,
1928
- tax: 0,
1929
- total: subtotal,
1930
- currency: "BRL",
1931
- tags: [],
1932
- metadata: mergeOrdersMetadata(void 0, {
1933
- source: input.source ?? "pos",
1934
- tableId: input.tableId ?? null,
1935
- estimatedMinutes: input.estimatedMinutes ?? null,
1936
- restaurantStatus: "new"
1937
- })
1938
- };
1939
- }
1940
- function updatePayload(data, existingMetadata) {
1941
- const payload = {};
1942
- if (data.referenceNumber !== void 0) payload.reference_number = data.referenceNumber;
1943
- if (data.kind !== void 0) payload.kind = data.kind;
1944
- if (data.status !== void 0) payload.status = canonicalStatus(data.status);
1945
- if (data.partyId !== void 0) payload.party_id = data.partyId;
1946
- if (data.assigneeId !== void 0) payload.assignee_id = data.assigneeId;
1947
- if (data.locationId !== void 0) payload.location_id = data.locationId;
1948
- if (data.subtotal !== void 0) payload.subtotal = data.subtotal;
1949
- if (data.discount !== void 0) payload.discount = data.discount;
1950
- if (data.tax !== void 0) payload.tax = data.tax;
1951
- if (data.total !== void 0) payload.total = data.total;
1952
- if (data.currency !== void 0) payload.currency = data.currency;
1953
- if (data.notes !== void 0) payload.notes = data.notes;
1954
- if (data.tags !== void 0) payload.tags = data.tags;
1955
- const metadataBase = data.metadata !== void 0 ? { ...existingMetadata ?? {}, ...data.metadata } : existingMetadata;
1956
- const metadataPatch = {
1957
- partyName: data.partyName,
1958
- assigneeName: data.assigneeName,
1959
- source: data.source,
1960
- tableId: data.tableId,
1961
- tableName: data.tableName,
1962
- estimatedMinutes: data.estimatedMinutes,
1963
- restaurantStatus: data.status
1964
- };
1965
- if (data.metadata !== void 0 || Object.values(metadataPatch).some((value) => value !== void 0)) {
1966
- payload.metadata = mergeOrdersMetadata(metadataBase, metadataPatch);
1967
- }
1968
- if (data.completedAt !== void 0) payload.completed_at = data.completedAt;
1969
- return payload;
1970
- }
1971
- function filtersFromQuery(query) {
1972
- const filters = [];
1973
- if (query.kind && !Array.isArray(query.kind)) filters.push({ column: "kind", operator: "eq", value: query.kind });
1974
- if (query.assigneeId) filters.push({ column: "assignee_id", operator: "eq", value: query.assigneeId });
1975
- return filters;
1976
- }
1977
- function matchesClientQuery(order, query) {
1978
- if (Array.isArray(query.kind) && !query.kind.includes(order.kind)) return false;
1979
- if (Array.isArray(query.status) && !query.status.includes(order.status)) return false;
1980
- if (query.status && !Array.isArray(query.status) && order.status !== query.status) return false;
1981
- if (query.source && order.source !== query.source) return false;
1982
- if (query.tableId && order.tableId !== query.tableId) return false;
1983
- if (query.assigneeId && order.assigneeId !== query.assigneeId) return false;
1984
- if (query.dateRange) {
1985
- const created = dateKey(order.createdAt);
1986
- if (created < query.dateRange.from || created > query.dateRange.to) return false;
1987
- }
1988
- if (query.search) {
1989
- const search = query.search.toLowerCase();
1990
- return order.referenceNumber.toLowerCase().includes(search) || (order.partyName?.toLowerCase().includes(search) ?? false) || (order.tableName?.toLowerCase().includes(search) ?? false) || order.items.some((item) => item.name.toLowerCase().includes(search));
1991
- }
1992
- return true;
1993
- }
1994
- function paginate(items, page, pageSize) {
1995
- const currentPage = page ?? 1;
1996
- const limit = pageSize ?? 20;
1997
- const start = (currentPage - 1) * limit;
1998
- return { data: items.slice(start, start + limit), total: items.length };
1999
- }
2000
- function summarize(orders, dateRange) {
2001
- const today = dateKey(nowIso());
2002
- const from = dateRange?.from ?? today;
2003
- const to = dateRange?.to ?? today;
2004
- const inRange = orders.filter((order) => {
2005
- const created = dateKey(order.createdAt);
2006
- return created >= from && created <= to;
2007
- });
2008
- const billable = inRange.filter((order) => order.status !== "cancelled");
2009
- const revenue = billable.reduce((sum, order) => sum + order.total, 0);
2010
- const ordersByKind = { dine_in: 0, takeout: 0, delivery: 0 };
2011
- const ordersByStatus = {};
2012
- const top = /* @__PURE__ */ new Map();
2013
- for (const order of inRange) {
2014
- ordersByKind[order.kind] = (ordersByKind[order.kind] ?? 0) + 1;
2015
- ordersByStatus[order.status] = (ordersByStatus[order.status] ?? 0) + 1;
2016
- if (order.status === "cancelled") continue;
2017
- for (const item of order.items) {
2018
- const current = top.get(item.name) ?? { name: item.name, quantity: 0, revenue: 0 };
2019
- current.quantity += item.quantity;
2020
- current.revenue += item.total;
2021
- top.set(item.name, current);
2022
- }
2023
- }
2024
- return {
2025
- todayOrderCount: inRange.length,
2026
- todayRevenue: revenue,
2027
- averageTicket: billable.length > 0 ? revenue / billable.length : 0,
2028
- activeOrderCount: orders.filter((order) => ACTIVE_STATUSES2.has(order.status)).length,
2029
- ordersByKind,
2030
- ordersByStatus,
2031
- topItems: [...top.values()].sort((a, b) => b.quantity - a.quantity).slice(0, 5)
2032
- };
2033
- }
2034
- function createFayzOrdersProvider(options = {}) {
2035
- const client = createFayzClient(options);
2036
- const ordersTable = options.ordersTable ?? DEFAULT_ORDERS_TABLE;
2037
- const orderItemsTable = options.orderItemsTable ?? DEFAULT_ORDER_ITEMS_TABLE;
2038
- const tableOptions = { projectId: options.projectId, schema: options.schema, runtime: options.runtime };
2039
- function resolveTenant() {
2040
- const value = typeof options.tenantId === "function" ? options.tenantId() : options.tenantId;
2041
- return value ?? void 0;
2042
- }
2043
- function resolveUnit() {
2044
- const value = typeof options.unitId === "function" ? options.unitId() : options.unitId;
2045
- return value ?? void 0;
2046
- }
2047
- function withTenant(filters) {
2048
- const tenantId = resolveTenant();
2049
- return tenantId ? [{ column: "tenant_id", operator: "eq", value: tenantId }, ...filters] : filters;
2050
- }
2051
- async function listItemRows(orderIds) {
2052
- if (orderIds.length === 0) return [];
2053
- const rows = [];
2054
- await Promise.all(orderIds.map(async (orderId) => {
2055
- const response = await client.data.listRows({
2056
- ...tableOptions,
2057
- table: orderItemsTable,
2058
- filters: [{ column: "order_id", operator: "eq", value: orderId }],
2059
- sortColumn: "sort_order",
2060
- sortDirection: "asc",
2061
- limit: 200
2062
- });
2063
- rows.push(...response.rows);
2064
- }));
2065
- return rows;
2066
- }
2067
- async function hydrate(rows) {
2068
- const itemRows = await listItemRows(rows.map((row) => row.id));
2069
- const byOrder = /* @__PURE__ */ new Map();
2070
- for (const itemRow of itemRows) {
2071
- const item = rowToItem(itemRow);
2072
- const list = byOrder.get(item.orderId) ?? [];
2073
- list.push(item);
2074
- byOrder.set(item.orderId, list);
2075
- }
2076
- return rows.map((row) => rowToOrder(row, byOrder.get(row.id) ?? []));
2077
- }
2078
- async function listOrders(query = {}) {
2079
- const response = await client.data.listRows({
2080
- ...tableOptions,
2081
- table: ordersTable,
2082
- filters: withTenant(filtersFromQuery(query)),
2083
- sortColumn: "created_at",
2084
- sortDirection: "desc",
2085
- limit: 500
2086
- });
2087
- return (await hydrate(response.rows)).filter((order) => matchesClientQuery(order, query));
2088
- }
2089
- async function getById(id) {
2090
- const response = await client.data.listRows({
2091
- ...tableOptions,
2092
- table: ordersTable,
2093
- filters: withTenant([{ column: "id", operator: "eq", value: id }]),
2094
- limit: 1
2095
- });
2096
- return (await hydrate(response.rows))[0] ?? null;
2097
- }
2098
- return {
2099
- async getOrders(query) {
2100
- const orders = await listOrders(query);
2101
- return paginate(orders, query.page, query.pageSize);
2102
- },
2103
- async getOrderById(id) {
2104
- return getById(id);
2105
- },
2106
- async createOrder(input) {
2107
- const tenantId = resolveTenant();
2108
- const unitId = resolveUnit();
2109
- const orderRow = await client.data.createRow({
2110
- ...tableOptions,
2111
- table: ordersTable,
2112
- row: {
2113
- ...orderPayload(input),
2114
- ...tenantId ? { tenant_id: tenantId } : {},
2115
- ...unitId ? { unit_id: unitId } : {}
2116
- }
2117
- });
2118
- await Promise.all(input.items.map((item, index) => client.data.createRow({
2119
- ...tableOptions,
2120
- table: orderItemsTable,
2121
- row: itemToRow(item, orderRow.id, index, tenantId, unitId)
2122
- })));
2123
- return await getById(orderRow.id) ?? rowToOrder(orderRow);
2124
- },
2125
- async updateOrderStatus(input) {
2126
- const completedAt = input.status === "completed" ? nowIso() : void 0;
2127
- return this.updateOrder(input.orderId, { status: input.status, completedAt });
2128
- },
2129
- async updateOrder(id, data) {
2130
- const existing = await getById(id);
2131
- const row = await client.data.updateRow({
2132
- ...tableOptions,
2133
- table: ordersTable,
2134
- primaryKeys: { id },
2135
- row: updatePayload(data, existing?.metadata)
2136
- });
2137
- return await getById(row.id) ?? rowToOrder(row);
2138
- },
2139
- async cancelOrder(id, reason) {
2140
- const order = await getById(id);
2141
- await this.updateOrder(id, {
2142
- status: "cancelled",
2143
- notes: reason ? `${order?.notes ? `${order.notes}
2144
- ` : ""}Cancelled: ${reason}` : order?.notes
2145
- });
2146
- },
2147
- async addOrderItem(orderId, item) {
2148
- const order = await getById(orderId);
2149
- const row = await client.data.createRow({
2150
- ...tableOptions,
2151
- table: orderItemsTable,
2152
- row: itemToRow(item, orderId, order?.items.length ?? 0, order?.tenantId, order?.unitId ?? resolveUnit())
2153
- });
2154
- const created = rowToItem(row);
2155
- const items = [...order?.items ?? [], created];
2156
- await this.updateOrder(orderId, {
2157
- subtotal: items.reduce((sum, orderItem) => sum + orderItem.total, 0),
2158
- total: items.reduce((sum, orderItem) => sum + orderItem.total, 0) - (order?.discount ?? 0) + (order?.tax ?? 0)
2159
- });
2160
- return created;
2161
- },
2162
- async removeOrderItem(itemId) {
2163
- const orders = await listOrders();
2164
- const order = orders.find((item) => item.items.some((orderItem) => orderItem.id === itemId));
2165
- await client.data.deleteRows({ ...tableOptions, table: orderItemsTable, rows: [{ id: itemId }] });
2166
- if (order) {
2167
- const items = order.items.filter((item) => item.id !== itemId);
2168
- const subtotal = items.reduce((sum, item) => sum + item.total, 0);
2169
- await this.updateOrder(order.id, { subtotal, total: subtotal - order.discount + order.tax });
2170
- }
2171
- },
2172
- async updateOrderItem(itemId, data) {
2173
- const existingResult = await client.data.listRows({
2174
- ...tableOptions,
2175
- table: orderItemsTable,
2176
- filters: [{ column: "id", operator: "eq", value: itemId }],
2177
- limit: 1
2178
- });
2179
- const existingMetadata = existingResult.rows[0]?.metadata ?? void 0;
2180
- const metadataPatch = {
2181
- modifiers: data.modifiers,
2182
- kitchenNotes: data.kitchenNotes
2183
- };
2184
- const row = await client.data.updateRow({
2185
- ...tableOptions,
2186
- table: orderItemsTable,
2187
- primaryKeys: { id: itemId },
2188
- row: {
2189
- product_id: data.productId,
2190
- name: data.name,
2191
- description: data.description,
2192
- quantity: data.quantity,
2193
- unit_price: data.unitPrice,
2194
- discount: data.discount,
2195
- total: data.total,
2196
- sort_order: data.sortOrder,
2197
- metadata: data.metadata !== void 0 || Object.values(metadataPatch).some((value) => value !== void 0) ? mergeOrdersMetadata(
2198
- data.metadata !== void 0 ? { ...existingMetadata ?? {}, ...data.metadata } : existingMetadata,
2199
- metadataPatch
2200
- ) : void 0
2201
- }
2202
- });
2203
- return rowToItem(row);
2204
- },
2205
- async getSummary(dateRange) {
2206
- return summarize(await listOrders({ dateRange }), dateRange);
2207
- }
2208
- };
2209
- }
2210
-
2211
- // src/data/mock.ts
2212
- var uid = 100;
2213
- function nextId(prefix) {
2214
- return prefix + "-" + ++uid;
2215
- }
2216
- var now = (/* @__PURE__ */ new Date()).toISOString();
2217
- function makeItem(orderId, name, quantity, unitPrice, sortOrder, productId) {
2218
- const id = nextId("item");
2219
- return {
2220
- id,
2221
- orderId,
2222
- productId,
2223
- name,
2224
- quantity,
2225
- unitPrice,
2226
- discount: 0,
2227
- total: quantity * unitPrice,
2228
- sortOrder,
2229
- createdAt: now
2230
- };
2231
- }
2232
- function createSeedOrders() {
2233
- const order1Id = nextId("order");
2234
- const order1Items = [
2235
- makeItem(order1Id, "Classic Burger", 1, 32, 0, "prod-burger-classic"),
2236
- makeItem(order1Id, "Fries", 1, 15, 1, "prod-fries")
2237
- ];
2238
- const order1 = {
2239
- id: order1Id,
2240
- referenceNumber: "ORD-0001",
2241
- kind: "dine_in",
2242
- status: "preparing",
2243
- source: "pos",
2244
- tableId: "table-3",
2245
- tableName: "Table 3",
2246
- subtotal: 47,
2247
- discount: 0,
2248
- tax: 0,
2249
- total: 47,
2250
- currency: "BRL",
2251
- tags: [],
2252
- items: order1Items,
2253
- tenantId: "tenant-mock",
2254
- createdAt: now,
2255
- updatedAt: now
2256
- };
2257
- const order2Id = nextId("order");
2258
- const order2Items = [
2259
- makeItem(order2Id, "Cheese Burger", 1, 36, 0, "prod-burger-cheese")
2260
- ];
2261
- const order2 = {
2262
- id: order2Id,
2263
- referenceNumber: "ORD-0002",
2264
- kind: "takeout",
2265
- status: "ready",
2266
- source: "pos",
2267
- subtotal: 36,
2268
- discount: 0,
2269
- tax: 0,
2270
- total: 36,
2271
- currency: "BRL",
2272
- tags: [],
2273
- items: order2Items,
2274
- tenantId: "tenant-mock",
2275
- createdAt: now,
2276
- updatedAt: now
2277
- };
2278
- const order3Id = nextId("order");
2279
- const order3Items = [
2280
- makeItem(order3Id, "Margherita Pizza", 1, 38, 0, "prod-pizza-margherita"),
2281
- makeItem(order3Id, "Caesar Salad", 1, 22, 1, "prod-salad-caesar"),
2282
- makeItem(order3Id, "Soda 350ml", 1, 12, 2, "prod-soda")
2283
- ];
2284
- const order3 = {
2285
- id: order3Id,
2286
- referenceNumber: "ORD-0003",
2287
- kind: "delivery",
2288
- status: "confirmed",
2289
- source: "ifood",
2290
- subtotal: 72,
2291
- discount: 0,
2292
- tax: 0,
2293
- total: 72,
2294
- currency: "BRL",
2295
- tags: [],
2296
- items: order3Items,
2297
- tenantId: "tenant-mock",
2298
- createdAt: now,
2299
- updatedAt: now
2300
- };
2301
- const order4Id = nextId("order");
2302
- const order4Items = [
2303
- makeItem(order4Id, "BBQ Bacon Burger", 1, 42, 0, "prod-burger-bbq")
2304
- ];
2305
- const order4 = {
2306
- id: order4Id,
2307
- referenceNumber: "ORD-0004",
2308
- kind: "dine_in",
2309
- status: "new",
2310
- source: "pos",
2311
- tableId: "table-7",
2312
- tableName: "Table 7",
2313
- subtotal: 42,
2314
- discount: 0,
2315
- tax: 0,
2316
- total: 42,
2317
- currency: "BRL",
2318
- tags: [],
2319
- items: order4Items,
2320
- tenantId: "tenant-mock",
2321
- createdAt: now,
2322
- updatedAt: now
2323
- };
2324
- const order5Id = nextId("order");
2325
- const order5Items = [
2326
- makeItem(order5Id, "Classic Burger", 2, 32, 0, "prod-burger-classic"),
2327
- makeItem(order5Id, "Fries", 1, 15, 1, "prod-fries"),
2328
- makeItem(order5Id, "Onion Rings", 1, 18, 2, "prod-onion-rings"),
2329
- makeItem(order5Id, "Milkshake", 1, 23, 3, "prod-milkshake")
2330
- ];
2331
- const order5 = {
2332
- id: order5Id,
2333
- referenceNumber: "ORD-0005",
2334
- kind: "dine_in",
2335
- status: "completed",
2336
- source: "pos",
2337
- tableId: "table-1",
2338
- tableName: "Table 1",
2339
- subtotal: 120,
2340
- discount: 0,
2341
- tax: 0,
2342
- total: 120,
2343
- currency: "BRL",
2344
- tags: [],
2345
- items: order5Items,
2346
- tenantId: "tenant-mock",
2347
- createdAt: now,
2348
- updatedAt: now,
2349
- completedAt: now
2350
- };
2351
- return [order1, order2, order3, order4, order5];
2352
- }
2353
- function recomputeTotals(order) {
2354
- order.subtotal = order.items.reduce((sum, i) => sum + i.total, 0);
2355
- order.total = order.subtotal - order.discount + order.tax;
2356
- }
2357
- var refCounter = 5;
2358
- function generateReferenceNumber() {
2359
- refCounter++;
2360
- return "ORD-" + String(refCounter).padStart(4, "0");
2361
- }
2362
- function toDateStr(d) {
2363
- return d.toISOString().slice(0, 10);
2364
- }
2365
- function createMockOrdersProvider() {
2366
- const orders = createSeedOrders();
2367
- function findOrder(id) {
2368
- return orders.find((o) => o.id === id);
2369
- }
2370
- function findItem(itemId) {
2371
- for (const order of orders) {
2372
- const index = order.items.findIndex((i) => i.id === itemId);
2373
- if (index !== -1) return { order, item: order.items[index], index };
2374
- }
2375
- return void 0;
2376
- }
2377
- const provider = {
2378
- // ------------------------------------------------------------------
2379
- // getOrders
2380
- // ------------------------------------------------------------------
2381
- async getOrders(query) {
2382
- let result = [...orders];
2383
- if (query.kind) {
2384
- const kinds = Array.isArray(query.kind) ? query.kind : [query.kind];
2385
- result = result.filter((o) => kinds.includes(o.kind));
2386
- }
2387
- if (query.status) {
2388
- const statuses = Array.isArray(query.status) ? query.status : [query.status];
2389
- result = result.filter((o) => statuses.includes(o.status));
2390
- }
2391
- if (query.source) {
2392
- result = result.filter((o) => o.source === query.source);
2393
- }
2394
- if (query.tableId) {
2395
- result = result.filter((o) => o.tableId === query.tableId);
2396
- }
2397
- if (query.assigneeId) {
2398
- result = result.filter((o) => o.assigneeId === query.assigneeId);
2399
- }
2400
- if (query.search) {
2401
- const q = query.search.toLowerCase();
2402
- result = result.filter(
2403
- (o) => o.referenceNumber.toLowerCase().includes(q) || o.partyName?.toLowerCase().includes(q) || o.tableName?.toLowerCase().includes(q) || o.items.some((i) => i.name.toLowerCase().includes(q))
2404
- );
2405
- }
2406
- if (query.dateRange) {
2407
- const from = query.dateRange.from;
2408
- const to = query.dateRange.to;
2409
- result = result.filter((o) => {
2410
- const d = o.createdAt.slice(0, 10);
2411
- return d >= from && d <= to;
2412
- });
2413
- }
2414
- result.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
2415
- const total = result.length;
2416
- const page = query.page ?? 1;
2417
- const pageSize = query.pageSize ?? 20;
2418
- const start = (page - 1) * pageSize;
2419
- const data = result.slice(start, start + pageSize);
2420
- return { data, total };
2421
- },
2422
- // ------------------------------------------------------------------
2423
- // getOrderById
2424
- // ------------------------------------------------------------------
2425
- async getOrderById(id) {
2426
- return findOrder(id) ?? null;
2427
- },
2428
- // ------------------------------------------------------------------
2429
- // createOrder
2430
- // ------------------------------------------------------------------
2431
- async createOrder(input) {
2432
- const orderId = nextId("order");
2433
- const items = input.items.map((item, idx) => ({
2434
- id: nextId("item"),
2435
- orderId,
2436
- productId: item.productId,
2437
- name: item.name,
2438
- quantity: item.quantity,
2439
- unitPrice: item.unitPrice,
2440
- discount: item.discount ?? 0,
2441
- total: item.quantity * item.unitPrice - (item.discount ?? 0),
2442
- sortOrder: idx,
2443
- modifiers: item.modifiers,
2444
- kitchenNotes: item.kitchenNotes,
2445
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
2446
- }));
2447
- const subtotal = items.reduce((sum, i) => sum + i.total, 0);
2448
- const order = {
2449
- id: orderId,
2450
- referenceNumber: generateReferenceNumber(),
2451
- kind: input.kind,
2452
- status: "new",
2453
- source: input.source ?? "pos",
2454
- tableId: input.tableId,
2455
- partyId: input.partyId,
2456
- assigneeId: input.assigneeId,
2457
- notes: input.notes,
2458
- estimatedMinutes: input.estimatedMinutes,
2459
- subtotal,
2460
- discount: 0,
2461
- tax: 0,
2462
- total: subtotal,
2463
- currency: "BRL",
2464
- tags: [],
2465
- items,
2466
- tenantId: "tenant-mock",
2467
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2468
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
2469
- };
2470
- orders.push(order);
2471
- return order;
2472
- },
2473
- // ------------------------------------------------------------------
2474
- // updateOrderStatus
2475
- // ------------------------------------------------------------------
2476
- async updateOrderStatus(input) {
2477
- const order = findOrder(input.orderId);
2478
- if (!order) throw new Error(`Order not found: ${input.orderId}`);
2479
- if (input.status !== "cancelled") {
2480
- const flow = STATUS_FLOW[order.kind];
2481
- const currentIdx = flow.indexOf(order.status);
2482
- const targetIdx = flow.indexOf(input.status);
2483
- if (targetIdx < 0 || targetIdx !== currentIdx && targetIdx !== currentIdx + 1) {
2484
- const next = getNextStatus(order.kind, order.status);
2485
- throw new Error(
2486
- `Invalid status transition: ${order.status} \u2192 ${input.status}. ` + (next ? `Expected next status: ${next}` : "Order is already in a terminal state.")
2487
- );
2488
- }
2489
- }
2490
- order.status = input.status;
2491
- order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2492
- if (input.status === "completed") {
2493
- order.completedAt = order.updatedAt;
2494
- }
2495
- return order;
2496
- },
2497
- // ------------------------------------------------------------------
2498
- // updateOrder
2499
- // ------------------------------------------------------------------
2500
- async updateOrder(id, data) {
2501
- const order = findOrder(id);
2502
- if (!order) throw new Error(`Order not found: ${id}`);
2503
- const { id: _id, items: _items, tenantId: _t, createdAt: _c, ...safe } = data;
2504
- Object.assign(order, safe);
2505
- order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2506
- return order;
2507
- },
2508
- // ------------------------------------------------------------------
2509
- // cancelOrder
2510
- // ------------------------------------------------------------------
2511
- async cancelOrder(id, reason) {
2512
- const order = findOrder(id);
2513
- if (!order) throw new Error(`Order not found: ${id}`);
2514
- order.status = "cancelled";
2515
- order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2516
- if (reason) {
2517
- order.notes = order.notes ? `${order.notes}
2518
- Cancelled: ${reason}` : `Cancelled: ${reason}`;
2519
- }
2520
- },
2521
- // ------------------------------------------------------------------
2522
- // addOrderItem
2523
- // ------------------------------------------------------------------
2524
- async addOrderItem(orderId, item) {
2525
- const order = findOrder(orderId);
2526
- if (!order) throw new Error(`Order not found: ${orderId}`);
2527
- const newItem = {
2528
- id: nextId("item"),
2529
- orderId,
2530
- productId: item.productId,
2531
- name: item.name,
2532
- quantity: item.quantity,
2533
- unitPrice: item.unitPrice,
2534
- discount: item.discount ?? 0,
2535
- total: item.quantity * item.unitPrice - (item.discount ?? 0),
2536
- sortOrder: order.items.length,
2537
- modifiers: item.modifiers,
2538
- kitchenNotes: item.kitchenNotes,
2539
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
2540
- };
2541
- order.items.push(newItem);
2542
- recomputeTotals(order);
2543
- order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2544
- return newItem;
2545
- },
2546
- // ------------------------------------------------------------------
2547
- // removeOrderItem
2548
- // ------------------------------------------------------------------
2549
- async removeOrderItem(itemId) {
2550
- const found = findItem(itemId);
2551
- if (!found) throw new Error(`Order item not found: ${itemId}`);
2552
- found.order.items.splice(found.index, 1);
2553
- recomputeTotals(found.order);
2554
- found.order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2555
- },
2556
- // ------------------------------------------------------------------
2557
- // updateOrderItem
2558
- // ------------------------------------------------------------------
2559
- async updateOrderItem(itemId, data) {
2560
- const found = findItem(itemId);
2561
- if (!found) throw new Error(`Order item not found: ${itemId}`);
2562
- const { id: _id, orderId: _oid, createdAt: _c, ...safe } = data;
2563
- Object.assign(found.item, safe);
2564
- found.item.total = found.item.quantity * found.item.unitPrice - found.item.discount;
2565
- recomputeTotals(found.order);
2566
- found.order.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2567
- return found.item;
2568
- },
2569
- // ------------------------------------------------------------------
2570
- // getSummary
2571
- // ------------------------------------------------------------------
2572
- async getSummary(dateRange) {
2573
- const today = toDateStr(/* @__PURE__ */ new Date());
2574
- const from = dateRange?.from ?? today;
2575
- const to = dateRange?.to ?? today;
2576
- const inRange = orders.filter((o) => {
2577
- const d = o.createdAt.slice(0, 10);
2578
- return d >= from && d <= to;
2579
- });
2580
- const completed = inRange.filter((o) => o.status !== "cancelled");
2581
- const revenue = completed.reduce((sum, o) => sum + o.total, 0);
2582
- const activeStatuses = /* @__PURE__ */ new Set(["new", "confirmed", "preparing", "ready", "served", "dispatched"]);
2583
- const active = orders.filter((o) => activeStatuses.has(o.status));
2584
- const ordersByKind = { dine_in: 0, takeout: 0, delivery: 0 };
2585
- const ordersByStatus = {};
2586
- for (const o of inRange) {
2587
- ordersByKind[o.kind] = (ordersByKind[o.kind] || 0) + 1;
2588
- ordersByStatus[o.status] = (ordersByStatus[o.status] || 0) + 1;
2589
- }
2590
- const itemMap = /* @__PURE__ */ new Map();
2591
- for (const o of completed) {
2592
- for (const item of o.items) {
2593
- const existing = itemMap.get(item.name);
2594
- if (existing) {
2595
- existing.quantity += item.quantity;
2596
- existing.revenue += item.total;
2597
- } else {
2598
- itemMap.set(item.name, { name: item.name, quantity: item.quantity, revenue: item.total });
2599
- }
2600
- }
2601
- }
2602
- const topItems = Array.from(itemMap.values()).sort((a, b) => b.quantity - a.quantity).slice(0, 5);
2603
- return {
2604
- todayOrderCount: inRange.length,
2605
- todayRevenue: revenue,
2606
- averageTicket: completed.length > 0 ? revenue / completed.length : 0,
2607
- activeOrderCount: active.length,
2608
- ordersByKind,
2609
- ordersByStatus,
2610
- topItems
2611
- };
2612
- }
2613
- };
2614
- return provider;
2615
- }
2616
-
2617
- // src/index.ts
2618
- var OrdersPage = React.lazy(() => import('./OrdersPage-5326V62H.js').then((m) => ({ default: m.OrdersPage })));
2619
- var OrderDetailRoute = React.lazy(() => import('./OrderDetailRoute-LTPDQXQU.js').then((m) => ({ default: m.OrderDetailRoute })));
1233
+ var ordersV1SettingsTabs = [
1234
+ defineSettingsTab({
1235
+ id: "orders-scale",
1236
+ label: tl("Scale & sale by weight", "Balan\xE7a e venda por peso"),
1237
+ icon: "Scale",
1238
+ section: "operations",
1239
+ requiresFacet: "scale",
1240
+ pending: true,
1241
+ defaults: { "scale.auto_launch": false, "scale.min_weight_g": 10, "scale.label_enabled": false, "scale.label_prefix": "2", "scale.label_code_length": 4, "scale.label_value_kind": "price" },
1242
+ sections: [
1243
+ { title: tl("Weighing", "Pesagem"), fields: [
1244
+ { key: "scale.auto_launch", type: "boolean", scope: "unit", label: tl("Launch on its own once the weight settles", "Lan\xE7ar sozinho quando o peso estabilizar") },
1245
+ { key: "scale.min_weight_g", type: "number", scope: "unit", min: 1, max: 5e3, label: tl("Minimum weight (g)", "Peso m\xEDnimo (g)") }
1246
+ ] },
1247
+ { title: tl("Scale labels", "Etiqueta da balan\xE7a"), fields: [
1248
+ { key: "scale.label_enabled", type: "boolean", scope: "unit", label: tl("Read scale labels at the POS", "Ler etiqueta de balan\xE7a no PDV") },
1249
+ { key: "scale.label_prefix", type: "string", scope: "unit", label: tl("Barcode prefix", "Prefixo do c\xF3digo") },
1250
+ { key: "scale.label_code_length", type: "number", scope: "unit", min: 4, max: 6, label: tl("Product code digits", "D\xEDgitos do c\xF3digo do produto") },
1251
+ { key: "scale.label_value_kind", type: "select", scope: "unit", label: tl("The label carries", "A etiqueta traz"), options: [
1252
+ { value: "price", label: tl("Price", "Pre\xE7o") },
1253
+ { value: "weight", label: tl("Weight", "Peso") }
1254
+ ] }
1255
+ ] }
1256
+ ]
1257
+ })
1258
+ ];
1259
+ var OrdersPage = React.lazy(() => import('./OrdersPage-3KNCFC7K.js').then((m) => ({ default: m.OrdersPage })));
1260
+ var OrderDetailRoute = React.lazy(() => import('./OrderDetailRoute-QGZIMEQ3.js').then((m) => ({ default: m.OrderDetailRoute })));
2620
1261
  var DEFAULT_LABELS = {
2621
1262
  pageTitle: "Orders",
1263
+ moduleName: tl("Orders & POS", "Pedidos e PDV"),
2622
1264
  kanban: "Orders",
2623
1265
  newOrder: "New Order",
2624
1266
  orderList: "History"
@@ -2649,7 +1291,7 @@ function resolveConfig(options) {
2649
1291
  }
2650
1292
  function createOrdersPlugin(options) {
2651
1293
  const config = resolveConfig(options);
2652
- const provider = options?.dataProvider ?? createCoreOrdersProvider();
1294
+ const provider = options?.dataProvider ?? createSupabaseOrdersProvider();
2653
1295
  const store7 = createOrdersStore(provider, {
2654
1296
  onOrderCompleted: config.onOrderCompleted,
2655
1297
  onOrderCancelled: config.onOrderCancelled
@@ -2669,16 +1311,11 @@ function createOrdersPlugin(options) {
2669
1311
  );
2670
1312
  return {
2671
1313
  id: "orders",
2672
- // Como esta conta refaz o módulo com as opções DELA. Ver PluginRebuild:
2673
- // a fábrica roda no carregamento do aplicativo, muito antes de a
2674
- // configuração da conta existir, e sem isto `app.tenant_plugins.config`
2675
- // não tinha como chegar aqui. A fusão é RASA e por bloco — a conta troca
2676
- // `modules` inteiro ou não o troca —, que é o mesmo contrato que a chamada
2677
- // do aplicativo já tem.
1314
+ // The tenant's config arrives after load; the merge is shallow, per block, like the app's own call.
2678
1315
  rebuild: (tenantConfig) => createOrdersPlugin({ ...options, ...tenantConfig }),
2679
1316
  defaultAgentRole: "operations",
2680
- name: config.labels.pageTitle,
2681
- icon: "ClipboardList",
1317
+ name: config.labels.moduleName,
1318
+ icon: "Coins",
2682
1319
  version: "1.0.0",
2683
1320
  scope: options?.scope ?? "vertical",
2684
1321
  verticalId: options?.verticalId,
@@ -2729,9 +1366,7 @@ function createOrdersPlugin(options) {
2729
1366
  }
2730
1367
  }
2731
1368
  ],
2732
- // Orders/month quota. NOTE: order creation currently flows only through the
2733
- // store/AI-tool (createOrder) with no dedicated UI create handler, so no
2734
- // client-side guard is wired yet — the declaration keeps the cap countable.
1369
+ // No client-side guard yet: creation goes through the AI tool; the declaration keeps the cap countable.
2735
1370
  declaredLimits: [
2736
1371
  { key: "orders_month", label: "Orders / month", table: "orders", kindFilter: "order", period: "month" }
2737
1372
  ],
@@ -2741,7 +1376,7 @@ function createOrdersPlugin(options) {
2741
1376
  position: options?.navPosition ?? 2,
2742
1377
  label: config.labels.pageTitle,
2743
1378
  route: "/orders",
2744
- icon: "ClipboardList",
1379
+ icon: "Coins",
2745
1380
  permission: { feature: "orders", action: "read" }
2746
1381
  }
2747
1382
  ],
@@ -2818,7 +1453,12 @@ function createOrdersPlugin(options) {
2818
1453
  }
2819
1454
  ],
2820
1455
  registries: ordersRegistries,
1456
+ facets: [
1457
+ { id: "scale", label: "Balan\xE7a", description: "Venda por peso com balan\xE7a e etiqueta." },
1458
+ { id: "delivery", label: "Delivery e iFood", description: "Entrega pr\xF3pria e pedidos do iFood e outros marketplaces.", defaultEnabled: true }
1459
+ ],
2821
1460
  settings: [
1461
+ ...ordersV1SettingsTabs,
2822
1462
  {
2823
1463
  id: "orders",
2824
1464
  label: config.labels.pageTitle,
@@ -2835,14 +1475,12 @@ function createOrdersPlugin(options) {
2835
1475
  order: 22,
2836
1476
  permission: { feature: "orders", action: "read" }
2837
1477
  },
2838
- // Entrega — política da casa (taxa, mínimo, tempo, raio) e os
2839
- // marketplaces que trazem o pedido. Só existe onde o delivery existe: um
2840
- // app sem `modules.delivery` não ganha uma tela para configurar um
2841
- // serviço que não presta.
2842
1478
  ...config.modules.delivery ? [{
2843
1479
  id: "orders-delivery",
2844
1480
  label: "Delivery",
2845
1481
  icon: "Bike",
1482
+ // Delivery is sold apart: its settings appear once the account turns it on.
1483
+ requiresFacet: "delivery",
2846
1484
  component: (() => {
2847
1485
  const DeliverySettingsTab = () => React.createElement(
2848
1486
  React.Suspense,
@@ -2853,14 +1491,12 @@ function createOrdersPlugin(options) {
2853
1491
  return DeliverySettingsTab;
2854
1492
  })(),
2855
1493
  order: 23,
2856
- // Quanto a casa cobra para entregar é decisão do dono, não de quem
2857
- // despacha: mesma régua da taxa de serviço em plugin-tables.
1494
+ // The delivery fee is the owner's decision, like the service charge in plugin-tables.
2858
1495
  permission: { feature: "orders", action: "edit" }
2859
1496
  }] : []
2860
1497
  ],
2861
1498
  locales: ordersLocales,
2862
- // Offered regardless of `modules.delivery` — a takeout-only house still takes
2863
- // iFood retirada orders. Control plane only: src/integrations/DELIVERY-MARKETPLACES.md.
1499
+ // Offered regardless of `modules.delivery`: a takeout-only house still takes iFood pickup orders.
2864
1500
  connectors: [
2865
1501
  ifoodConnectorDef,
2866
1502
  nineNineFoodConnectorDef,
@@ -2872,6 +1508,6 @@ function createOrdersPlugin(options) {
2872
1508
  };
2873
1509
  }
2874
1510
 
2875
- export { ADVANCE_VERB, AIQFOME_CONNECTOR_ID, AIQFOME_SETTINGS, AUTO_ACCEPT_SETTING, DEFAULT_STATUS_CONFIGS, IFOOD_CONNECTOR_ID, IFOOD_SETTINGS, KANBAN_COLUMNS, KEETA_CONNECTOR_ID, KEETA_SETTINGS, NINETY_NINE_FOOD_CONNECTOR_ID, NINETY_NINE_FOOD_SETTINGS, PREP_TIME_SETTING, RAPPI_CONNECTOR_ID, RAPPI_SETTINGS, STATUS_FLOW, UBER_EATS_CONNECTOR_ID, UBER_EATS_SETTINGS, aiqfomeConnectorDef, createCoreOrdersProvider, createFayzOrdersProvider, createMockOrdersProvider, createOrdersPlugin, getNextStatus, getPreviousStatus, ifoodConnectorDef, keetaConnectorDef, mapToKanbanColumn, marketplacePermissions, nineNineFoodConnectorDef, rappiConnectorDef, uberEatsConnectorDef };
1511
+ export { AIQFOME_CONNECTOR_ID, AIQFOME_SETTINGS, AUTO_ACCEPT_SETTING, IFOOD_CONNECTOR_ID, IFOOD_SETTINGS, KEETA_CONNECTOR_ID, KEETA_SETTINGS, NINETY_NINE_FOOD_CONNECTOR_ID, NINETY_NINE_FOOD_SETTINGS, PREP_TIME_SETTING, RAPPI_CONNECTOR_ID, RAPPI_SETTINGS, UBER_EATS_CONNECTOR_ID, UBER_EATS_SETTINGS, aiqfomeConnectorDef, createOrdersPlugin, ifoodConnectorDef, keetaConnectorDef, marketplacePermissions, nineNineFoodConnectorDef, rappiConnectorDef, uberEatsConnectorDef };
2876
1512
  //# sourceMappingURL=index.js.map
2877
1513
  //# sourceMappingURL=index.js.map