@fayz-ai/inventory 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 +41 -2
- package/dist/chunk-2FXO63QV.js +1732 -0
- package/dist/chunk-2FXO63QV.js.map +1 -0
- package/dist/chunk-52AJ7H2W.js +116 -0
- package/dist/chunk-52AJ7H2W.js.map +1 -0
- package/dist/chunk-AFUR3HLA.js +84 -0
- package/dist/chunk-AFUR3HLA.js.map +1 -0
- package/dist/chunk-EF5LVTOC.js +65 -0
- package/dist/chunk-EF5LVTOC.js.map +1 -0
- package/dist/chunk-GBIFZCEN.js +33 -0
- package/dist/chunk-GBIFZCEN.js.map +1 -0
- package/dist/chunk-GDEIBHAB.js +14 -0
- package/dist/chunk-GDEIBHAB.js.map +1 -0
- package/dist/chunk-JN5AZ656.js +35 -0
- package/dist/chunk-JN5AZ656.js.map +1 -0
- package/dist/chunk-JX7NCXJQ.js +15 -0
- package/dist/chunk-JX7NCXJQ.js.map +1 -0
- package/dist/chunk-MCWG3PMP.js +549 -0
- package/dist/chunk-MCWG3PMP.js.map +1 -0
- package/dist/chunk-RUOX7OOY.js +30 -0
- package/dist/chunk-RUOX7OOY.js.map +1 -0
- package/dist/chunk-SZXUGORU.js +13 -0
- package/dist/chunk-SZXUGORU.js.map +1 -0
- package/dist/chunk-W36J5END.js +48 -0
- package/dist/chunk-W36J5END.js.map +1 -0
- package/dist/chunk-YZDGJBJD.js +53 -0
- package/dist/chunk-YZDGJBJD.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 +10 -0
- package/dist/data/mock.js.map +1 -0
- package/dist/data/provider.d.ts +120 -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 +3 -0
- package/dist/data/supabase.d.ts.map +1 -0
- package/dist/data/supabase.js +13 -0
- package/dist/data/supabase.js.map +1 -0
- package/dist/data/tables.d.ts +25 -0
- package/dist/data/tables.d.ts.map +1 -0
- package/dist/data/tables.js +3 -0
- package/dist/data/tables.js.map +1 -0
- package/dist/domain/consumption.d.ts +33 -0
- package/dist/domain/consumption.d.ts.map +1 -0
- package/dist/domain/consumption.js +3 -0
- package/dist/domain/consumption.js.map +1 -0
- package/dist/domain/count.d.ts +85 -0
- package/dist/domain/count.d.ts.map +1 -0
- package/dist/domain/count.js +3 -0
- package/dist/domain/count.js.map +1 -0
- package/dist/domain/movement.d.ts +101 -0
- package/dist/domain/movement.d.ts.map +1 -0
- package/dist/domain/movement.js +3 -0
- package/dist/domain/movement.js.map +1 -0
- package/dist/domain/product.d.ts +245 -0
- package/dist/domain/product.d.ts.map +1 -0
- package/dist/domain/product.js +3 -0
- package/dist/domain/product.js.map +1 -0
- package/dist/domain/query.d.ts +12 -0
- package/dist/domain/query.d.ts.map +1 -0
- package/dist/domain/query.js +3 -0
- package/dist/domain/query.js.map +1 -0
- package/dist/domain/recipe-sheet.d.ts +133 -0
- package/dist/domain/recipe-sheet.d.ts.map +1 -0
- package/dist/domain/recipe-sheet.js +3 -0
- package/dist/domain/recipe-sheet.js.map +1 -0
- package/dist/domain/recipe.d.ts +138 -0
- package/dist/domain/recipe.d.ts.map +1 -0
- package/dist/domain/recipe.js +3 -0
- package/dist/domain/recipe.js.map +1 -0
- package/dist/domain/reference-data.d.ts +37 -0
- package/dist/domain/reference-data.d.ts.map +1 -0
- package/dist/domain/reference-data.js +3 -0
- package/dist/domain/reference-data.js.map +1 -0
- package/dist/domain/stock.d.ts +132 -0
- package/dist/domain/stock.d.ts.map +1 -0
- package/dist/domain/stock.js +5 -0
- package/dist/domain/stock.js.map +1 -0
- package/dist/domain/usage-audit.d.ts +95 -0
- package/dist/domain/usage-audit.d.ts.map +1 -0
- package/dist/domain/usage-audit.js +3 -0
- package/dist/domain/usage-audit.js.map +1 -0
- package/dist/lib/idempotency.d.ts +4 -0
- package/dist/lib/idempotency.d.ts.map +1 -0
- package/dist/lib/idempotency.js +3 -0
- package/dist/lib/idempotency.js.map +1 -0
- package/dist/store.d.ts +52 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +193 -0
- package/dist/store.js.map +1 -0
- package/package.json +50 -3
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/data/tables.ts
|
|
2
|
+
var T = {
|
|
3
|
+
stockLocations: "plg_inventory_stock_locations",
|
|
4
|
+
stockMovements: "plg_inventory_stock_movements",
|
|
5
|
+
stockPositions: "plg_inventory_stock_positions",
|
|
6
|
+
recipes: "plg_inventory_recipes",
|
|
7
|
+
recipeIngredients: "plg_inventory_recipe_ingredients",
|
|
8
|
+
measurementUnits: "plg_inventory_measurement_units",
|
|
9
|
+
// The categories archetype, kind PRODUCT_CATEGORY_KIND — not a table of this plugin (migration 024).
|
|
10
|
+
productCategories: "categories",
|
|
11
|
+
productDetails: "plg_inventory_product_details",
|
|
12
|
+
recipeGroups: "plg_inventory_recipe_groups",
|
|
13
|
+
countSessions: "plg_inventory_count_sessions",
|
|
14
|
+
countItems: "plg_inventory_count_items",
|
|
15
|
+
productSettings: "plg_inventory_product_settings",
|
|
16
|
+
reservations: "plg_inventory_reservations",
|
|
17
|
+
productBarcodes: "plg_inventory_product_barcodes",
|
|
18
|
+
productIngredientInfo: "plg_inventory_product_ingredient_info",
|
|
19
|
+
productSaleInfo: "plg_inventory_product_sale_info",
|
|
20
|
+
productSaleChannels: "plg_inventory_product_sale_channels",
|
|
21
|
+
productIntermediateInfo: "plg_inventory_product_intermediate_info",
|
|
22
|
+
productAssetInfo: "plg_inventory_product_asset_info",
|
|
23
|
+
// Owned by plugin-fiscal-br and read here because Fiscal is a section of the product form; absent when fiscal is not installed.
|
|
24
|
+
productTaxInfo: "plg_fiscalbr_product_tax_info"
|
|
25
|
+
};
|
|
26
|
+
var PRODUCT_CATEGORY_KIND = "good";
|
|
27
|
+
|
|
28
|
+
export { PRODUCT_CATEGORY_KIND, T };
|
|
29
|
+
//# sourceMappingURL=chunk-RUOX7OOY.js.map
|
|
30
|
+
//# sourceMappingURL=chunk-RUOX7OOY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/data/tables.ts"],"names":[],"mappings":";AAAO,IAAM,CAAA,GAAI;AAAA,EACf,cAAA,EAAgB,+BAAA;AAAA,EAChB,cAAA,EAAgB,+BAAA;AAAA,EAChB,cAAA,EAAgB,+BAAA;AAAA,EAChB,OAAA,EAAS,uBAAA;AAAA,EACT,iBAAA,EAAmB,kCAAA;AAAA,EACnB,gBAAA,EAAkB,iCAAA;AAAA;AAAA,EAElB,iBAAA,EAAmB,YAAA;AAAA,EACnB,cAAA,EAAgB,+BAAA;AAAA,EAChB,YAAA,EAAc,6BAAA;AAAA,EACd,aAAA,EAAe,8BAAA;AAAA,EACf,UAAA,EAAY,2BAAA;AAAA,EACZ,eAAA,EAAiB,gCAAA;AAAA,EACjB,YAAA,EAAc,4BAAA;AAAA,EACd,eAAA,EAAiB,gCAAA;AAAA,EACjB,qBAAA,EAAuB,uCAAA;AAAA,EACvB,eAAA,EAAiB,iCAAA;AAAA,EACjB,mBAAA,EAAqB,qCAAA;AAAA,EACrB,uBAAA,EAAyB,yCAAA;AAAA,EACzB,gBAAA,EAAkB,kCAAA;AAAA;AAAA,EAElB,cAAA,EAAgB;AAClB;AAGO,IAAM,qBAAA,GAAwB","file":"chunk-RUOX7OOY.js","sourcesContent":["export const T = {\n stockLocations: 'plg_inventory_stock_locations',\n stockMovements: 'plg_inventory_stock_movements',\n stockPositions: 'plg_inventory_stock_positions',\n recipes: 'plg_inventory_recipes',\n recipeIngredients: 'plg_inventory_recipe_ingredients',\n measurementUnits: 'plg_inventory_measurement_units',\n // The categories archetype, kind PRODUCT_CATEGORY_KIND — not a table of this plugin (migration 024).\n productCategories: 'categories',\n productDetails: 'plg_inventory_product_details',\n recipeGroups: 'plg_inventory_recipe_groups',\n countSessions: 'plg_inventory_count_sessions',\n countItems: 'plg_inventory_count_items',\n productSettings: 'plg_inventory_product_settings',\n reservations: 'plg_inventory_reservations',\n productBarcodes: 'plg_inventory_product_barcodes',\n productIngredientInfo: 'plg_inventory_product_ingredient_info',\n productSaleInfo: 'plg_inventory_product_sale_info',\n productSaleChannels: 'plg_inventory_product_sale_channels',\n productIntermediateInfo: 'plg_inventory_product_intermediate_info',\n productAssetInfo: 'plg_inventory_product_asset_info',\n // Owned by plugin-fiscal-br and read here because Fiscal is a section of the product form; absent when fiscal is not installed.\n productTaxInfo: 'plg_fiscalbr_product_tax_info',\n} as const\n\n/** The `categories` kind a product category carries (catalog contract). */\nexport const PRODUCT_CATEGORY_KIND = 'good'\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// src/domain/usage-audit.ts
|
|
2
|
+
function usageLineKey(line) {
|
|
3
|
+
return `${line.itemId}:${line.productId}`;
|
|
4
|
+
}
|
|
5
|
+
function patchUsageEntries(entries, lines, patch) {
|
|
6
|
+
if (!lines.length) return entries;
|
|
7
|
+
const targets = new Set(lines.map(usageLineKey));
|
|
8
|
+
return entries.map((entry) => targets.has(usageLineKey(entry)) ? { ...entry, ...patch } : entry);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { patchUsageEntries, usageLineKey };
|
|
12
|
+
//# sourceMappingURL=chunk-SZXUGORU.js.map
|
|
13
|
+
//# sourceMappingURL=chunk-SZXUGORU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/domain/usage-audit.ts"],"names":[],"mappings":";AA+FO,SAAS,aAAa,IAAA,EAAkC;AAC7D,EAAA,OAAO,CAAA,EAAG,IAAA,CAAK,MAAM,CAAA,CAAA,EAAI,KAAK,SAAS,CAAA,CAAA;AACzC;AAGO,SAAS,iBAAA,CACd,OAAA,EACA,KAAA,EACA,KAAA,EACmB;AACnB,EAAA,IAAI,CAAC,KAAA,CAAM,MAAA,EAAQ,OAAO,OAAA;AAC1B,EAAA,MAAM,UAAU,IAAI,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,YAAY,CAAC,CAAA;AAC/C,EAAA,OAAO,QAAQ,GAAA,CAAI,CAAC,KAAA,KAAW,OAAA,CAAQ,IAAI,YAAA,CAAa,KAAK,CAAC,CAAA,GAAI,EAAE,GAAG,KAAA,EAAO,GAAG,KAAA,KAAU,KAAM,CAAA;AACnG","file":"chunk-SZXUGORU.js","sourcesContent":["/**\n * One product used on one sold line, read back from the ledger. The grain is (item × product), not the\n * movement: one consumption splits into several ledger rows when FIFO crosses batches.\n */\nexport interface UsageAuditEntry {\n itemId: string\n productId: string\n productName?: string\n productSku?: string\n usedAt: string\n movementDate: string\n /** What the sale posted out of stock. */\n postedQuantity: number\n /** Posted plus every audit correction — what the balance actually reflects. */\n netQuantity: number\n /** The recipe's standard for this line. Null when no recipe answers for it. */\n standardQuantity?: number | null\n /** net − standard. Null follows standardQuantity. */\n variance?: number | null\n unitAbbreviation?: string\n totalCost: number\n stockLocationId?: string\n stockLocationName?: string\n /** More than one means the exit crossed batches. */\n locationCount: number\n recipeId?: string\n recipeName?: string\n orderId?: string\n itemName?: string\n orderReference?: string\n performedById?: string\n performedByName?: string\n customerId?: string\n customerName?: string\n correctedAt?: string\n correctionReason?: string\n isCorrected: boolean\n /** `ledger`: the order posted stock. `clinical`: an appointment used the product and nothing left the ledger. */\n source?: 'ledger' | 'clinical'\n /** False on clinical lines, which is what stops the screen promising a reversal with nothing to reverse. */\n stockPosted?: boolean\n}\n\n/** One line of a usage-audit batch: the sold line, the product, and what really left. */\nexport interface UsageAuditCorrection {\n itemId: string\n productId: string\n quantity: number\n}\n\nexport interface UsageAuditCorrectionInput extends UsageAuditCorrection {\n reason: string\n}\n\n/** `linesUnchanged` already matched and emit no movement. */\nexport interface UsageAuditBatchResult {\n operationId?: string\n linesApplied: number\n linesUnchanged: number\n}\n\n/** A line stock accepts, with or without posting it. */\nexport interface UsageAuditApproval {\n itemId: string\n productId: string\n}\n\nexport interface UsageAuditApproveInput {\n /** true is \"post to stock\": accept and deduct. false accepts without touching the balance. */\n post: boolean\n lines: UsageAuditApproval[]\n reason?: string\n}\n\nexport interface UsageAuditApproveResult {\n linesApproved: number\n linesPosted: number\n linesSkipped: number\n /** Lines that could not be posted for lack of balance; they stay pending. */\n linesNoStock?: number\n missing?: Array<{ product: string; needed: number; available: number }>\n}\n\nexport interface UsageAuditQuery {\n search?: string\n /** Only the lines whose net differs from the recipe standard. */\n divergentOnly?: boolean\n page?: number\n pageSize?: number\n /** ISO instant: only usage from this moment on. The queue has a window. */\n from?: string\n /** Only what nobody has reviewed yet. */\n pendingOnly?: boolean\n}\n\nexport function usageLineKey(line: UsageAuditApproval): string {\n return `${line.itemId}:${line.productId}`\n}\n\n/** Applies what an approval wrote to the rows already on screen, without a reload. */\nexport function patchUsageEntries(\n entries: UsageAuditEntry[],\n lines: UsageAuditApproval[],\n patch: Partial<UsageAuditEntry>,\n): UsageAuditEntry[] {\n if (!lines.length) return entries\n const targets = new Set(lines.map(usageLineKey))\n return entries.map((entry) => (targets.has(usageLineKey(entry)) ? { ...entry, ...patch } : entry))\n}\n"]}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/domain/count.ts
|
|
2
|
+
function isCounted(item) {
|
|
3
|
+
return item.countedQuantity !== void 0 && item.countedQuantity !== null;
|
|
4
|
+
}
|
|
5
|
+
function lineVariance(item) {
|
|
6
|
+
if (!isCounted(item)) return null;
|
|
7
|
+
return (Number(item.countedQuantity) || 0) - (Number(item.systemQuantity) || 0);
|
|
8
|
+
}
|
|
9
|
+
function isDivergent(item) {
|
|
10
|
+
const variance = lineVariance(item);
|
|
11
|
+
return variance !== null && variance !== 0;
|
|
12
|
+
}
|
|
13
|
+
function summarizeCount(items) {
|
|
14
|
+
let counted = 0;
|
|
15
|
+
let divergent = 0;
|
|
16
|
+
let variance = 0;
|
|
17
|
+
let varianceValue = 0;
|
|
18
|
+
for (const item of items) {
|
|
19
|
+
const delta = lineVariance(item);
|
|
20
|
+
if (delta === null) continue;
|
|
21
|
+
counted += 1;
|
|
22
|
+
if (delta === 0) continue;
|
|
23
|
+
divergent += 1;
|
|
24
|
+
variance += delta;
|
|
25
|
+
varianceValue += delta * (Number(item.unitCost) || 0);
|
|
26
|
+
}
|
|
27
|
+
return { total: items.length, counted, uncounted: items.length - counted, divergent, variance, varianceValue };
|
|
28
|
+
}
|
|
29
|
+
function divergentLines(items) {
|
|
30
|
+
return items.filter(isDivergent);
|
|
31
|
+
}
|
|
32
|
+
function countProgress(items) {
|
|
33
|
+
const summary = summarizeCount(items.map((item) => ({ ...item, unitCost: 0 })));
|
|
34
|
+
return { itemCount: summary.total, countedCount: summary.counted, divergentCount: summary.divergent };
|
|
35
|
+
}
|
|
36
|
+
function isCountFinal(status) {
|
|
37
|
+
return status === "closed" || status === "cancelled";
|
|
38
|
+
}
|
|
39
|
+
function statusAfterEntry(status) {
|
|
40
|
+
return status === "open" ? "counting" : status;
|
|
41
|
+
}
|
|
42
|
+
function hidesVariance(session) {
|
|
43
|
+
return (session?.blind ?? false) && !isCountFinal(session?.status);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { countProgress, divergentLines, hidesVariance, isCountFinal, isCounted, isDivergent, lineVariance, statusAfterEntry, summarizeCount };
|
|
47
|
+
//# sourceMappingURL=chunk-W36J5END.js.map
|
|
48
|
+
//# sourceMappingURL=chunk-W36J5END.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/domain/count.ts"],"names":[],"mappings":";AA+EO,SAAS,UAAU,IAAA,EAAwD;AAChF,EAAA,OAAO,IAAA,CAAK,eAAA,KAAoB,MAAA,IAAa,IAAA,CAAK,eAAA,KAAoB,IAAA;AACxE;AAGO,SAAS,aAAa,IAAA,EAAiF;AAC5G,EAAA,IAAI,CAAC,SAAA,CAAU,IAAI,CAAA,EAAG,OAAO,IAAA;AAC7B,EAAA,OAAA,CAAQ,MAAA,CAAO,KAAK,eAAe,CAAA,IAAK,MAAM,MAAA,CAAO,IAAA,CAAK,cAAc,CAAA,IAAK,CAAA,CAAA;AAC/E;AAEO,SAAS,YAAY,IAAA,EAA2E;AACrG,EAAA,MAAM,QAAA,GAAW,aAAa,IAAI,CAAA;AAClC,EAAA,OAAO,QAAA,KAAa,QAAQ,QAAA,KAAa,CAAA;AAC3C;AAEO,SAAS,eAAe,KAAA,EAAsC;AACnE,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,KAAA,GAAQ,aAAa,IAAI,CAAA;AAC/B,IAAA,IAAI,UAAU,IAAA,EAAM;AACpB,IAAA,OAAA,IAAW,CAAA;AACX,IAAA,IAAI,UAAU,CAAA,EAAG;AACjB,IAAA,SAAA,IAAa,CAAA;AACb,IAAA,QAAA,IAAY,KAAA;AACZ,IAAA,aAAA,IAAiB,KAAA,IAAS,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,IAAK,CAAA,CAAA;AAAA,EACrD;AACA,EAAA,OAAO,EAAE,KAAA,EAAO,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,SAAA,EAAW,KAAA,CAAM,MAAA,GAAS,OAAA,EAAS,SAAA,EAAW,QAAA,EAAU,aAAA,EAAc;AAC/G;AAGO,SAAS,eAAqF,KAAA,EAAiB;AACpH,EAAA,OAAO,KAAA,CAAM,OAAO,WAAW,CAAA;AACjC;AAEO,SAAS,cAAc,KAAA,EAAyF;AACrH,EAAA,MAAM,OAAA,GAAU,cAAA,CAAe,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,MAAU,EAAE,GAAG,IAAA,EAAM,QAAA,EAAU,CAAA,EAAE,CAAE,CAAC,CAAA;AAC9E,EAAA,OAAO,EAAE,WAAW,OAAA,CAAQ,KAAA,EAAO,cAAc,OAAA,CAAQ,OAAA,EAAS,cAAA,EAAgB,OAAA,CAAQ,SAAA,EAAU;AACtG;AAGO,SAAS,aAAa,MAAA,EAAiD;AAC5E,EAAA,OAAO,MAAA,KAAW,YAAY,MAAA,KAAW,WAAA;AAC3C;AAEO,SAAS,iBAAiB,MAAA,EAAgD;AAC/E,EAAA,OAAO,MAAA,KAAW,SAAS,UAAA,GAAa,MAAA;AAC1C;AAGO,SAAS,cAAc,OAAA,EAAkF;AAC9G,EAAA,OAAA,CAAQ,SAAS,KAAA,IAAS,KAAA,KAAU,CAAC,YAAA,CAAa,SAAS,MAAM,CAAA;AACnE","file":"chunk-W36J5END.js","sourcesContent":["/** `counting` starts at the first entry typed. */\nexport type CountSessionStatus = 'open' | 'counting' | 'closed' | 'cancelled'\n\nexport interface StockCountSession {\n id: string\n reference?: string\n status: CountSessionStatus\n stockLocationId: string\n stockLocationName?: string\n categoryId?: string\n categoryName?: string\n /** Hides the system quantity while counting. */\n blind: boolean\n notes?: string\n itemCount?: number\n countedCount?: number\n divergentCount?: number\n openedAt: string\n closedAt?: string\n tenantId: string\n createdAt: string\n updatedAt: string\n}\n\nexport interface StockCountItem {\n id: string\n sessionId: string\n productId: string\n productName?: string\n productSku?: string\n /** What the system believed when the session opened — never re-read. */\n systemQuantity: number\n /** undefined means nobody counted this line. It is not zero. */\n countedQuantity?: number\n unitCost: number\n notes?: string\n countedAt?: string\n /** The adjustment this line already emitted, if the session is closed. */\n movementId?: string\n tenantId: string\n createdAt: string\n updatedAt: string\n}\n\nexport interface OpenStockCountInput {\n stockLocationId: string\n categoryId?: string\n reference?: string\n blind?: boolean\n notes?: string\n}\n\nexport interface CloseStockCountResult {\n sessionId: string\n adjustmentsCreated: number\n /** True when the session was already closed — nothing was emitted again. */\n alreadyClosed: boolean\n}\n\nexport interface CountSummary {\n total: number\n counted: number\n uncounted: number\n divergent: number\n /** Net units gained or lost across the divergent lines. */\n variance: number\n /** The same, valued at each line's unit cost — what the close costs. */\n varianceValue: number\n}\n\nexport interface CountProgress {\n itemCount: number\n countedCount: number\n divergentCount: number\n}\n\n/** Wider than a count line on purpose: the usage audit feeds its own rows through the same arithmetic. */\nexport type CountableLine = Pick<StockCountItem, 'systemQuantity' | 'countedQuantity' | 'unitCost'>\n\nexport function isCounted(item: Pick<StockCountItem, 'countedQuantity'>): boolean {\n return item.countedQuantity !== undefined && item.countedQuantity !== null\n}\n\n/** counted − system, or null when the line was never counted. */\nexport function lineVariance(item: Pick<StockCountItem, 'systemQuantity' | 'countedQuantity'>): number | null {\n if (!isCounted(item)) return null\n return (Number(item.countedQuantity) || 0) - (Number(item.systemQuantity) || 0)\n}\n\nexport function isDivergent(item: Pick<StockCountItem, 'systemQuantity' | 'countedQuantity'>): boolean {\n const variance = lineVariance(item)\n return variance !== null && variance !== 0\n}\n\nexport function summarizeCount(items: CountableLine[]): CountSummary {\n let counted = 0\n let divergent = 0\n let variance = 0\n let varianceValue = 0\n for (const item of items) {\n const delta = lineVariance(item)\n if (delta === null) continue\n counted += 1\n if (delta === 0) continue\n divergent += 1\n variance += delta\n varianceValue += delta * (Number(item.unitCost) || 0)\n }\n return { total: items.length, counted, uncounted: items.length - counted, divergent, variance, varianceValue }\n}\n\n/** The lines the close will act on, in the order it will act on them. */\nexport function divergentLines<T extends Pick<StockCountItem, 'systemQuantity' | 'countedQuantity'>>(items: T[]): T[] {\n return items.filter(isDivergent)\n}\n\nexport function countProgress(items: Array<Pick<StockCountItem, 'systemQuantity' | 'countedQuantity'>>): CountProgress {\n const summary = summarizeCount(items.map((item) => ({ ...item, unitCost: 0 })))\n return { itemCount: summary.total, countedCount: summary.counted, divergentCount: summary.divergent }\n}\n\n/** A closed count has moved stock and a cancelled one never will; neither takes entries. */\nexport function isCountFinal(status: CountSessionStatus | undefined): boolean {\n return status === 'closed' || status === 'cancelled'\n}\n\nexport function statusAfterEntry(status: CountSessionStatus): CountSessionStatus {\n return status === 'open' ? 'counting' : status\n}\n\n/** Blind counts hide the system figure until the session is final. */\nexport function hidesVariance(session: Pick<StockCountSession, 'blind' | 'status'> | null | undefined): boolean {\n return (session?.blind ?? false) && !isCountFinal(session?.status)\n}\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// src/domain/reference-data.ts
|
|
2
|
+
var DEFAULT_MEASUREMENT_UNITS = [
|
|
3
|
+
{ name: "Unit", abbreviation: "un" },
|
|
4
|
+
{ name: "Box", abbreviation: "box" },
|
|
5
|
+
{ name: "Kilogram", abbreviation: "kg" },
|
|
6
|
+
{ name: "Gram", abbreviation: "g" },
|
|
7
|
+
{ name: "Liter", abbreviation: "L" },
|
|
8
|
+
{ name: "Milliliter", abbreviation: "mL" }
|
|
9
|
+
];
|
|
10
|
+
var DEFAULT_STOCK_LOCATION = {
|
|
11
|
+
name: "Main Storage",
|
|
12
|
+
description: "Primary storage area"
|
|
13
|
+
};
|
|
14
|
+
function getMissingMeasurementUnits(rows) {
|
|
15
|
+
const existing = new Set(
|
|
16
|
+
rows.map((row) => String(row.abbreviation ?? "").trim().toLocaleLowerCase())
|
|
17
|
+
);
|
|
18
|
+
return DEFAULT_MEASUREMENT_UNITS.filter(
|
|
19
|
+
(unit) => !existing.has(unit.abbreviation.toLocaleLowerCase())
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
function getDuplicateDefaultUnitIds(rows) {
|
|
23
|
+
const defaults = new Set(
|
|
24
|
+
DEFAULT_MEASUREMENT_UNITS.map((unit) => unit.abbreviation.toLocaleLowerCase())
|
|
25
|
+
);
|
|
26
|
+
const firstByAbbreviation = /* @__PURE__ */ new Map();
|
|
27
|
+
const duplicates = [];
|
|
28
|
+
for (const row of [...rows].sort(
|
|
29
|
+
(a, b) => String(a.created_at ?? "").localeCompare(String(b.created_at ?? "")) || a.id.localeCompare(b.id)
|
|
30
|
+
)) {
|
|
31
|
+
const abbreviation = String(row.abbreviation ?? "").trim().toLocaleLowerCase();
|
|
32
|
+
if (!defaults.has(abbreviation)) continue;
|
|
33
|
+
const createdAt = row.created_at ? Date.parse(row.created_at) : Number.NaN;
|
|
34
|
+
const firstAt = firstByAbbreviation.get(abbreviation);
|
|
35
|
+
if (firstAt === void 0) {
|
|
36
|
+
if (Number.isFinite(createdAt)) firstByAbbreviation.set(abbreviation, createdAt);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (Number.isFinite(createdAt) && Math.abs(createdAt - firstAt) <= 6e4) duplicates.push(row.id);
|
|
40
|
+
}
|
|
41
|
+
return duplicates;
|
|
42
|
+
}
|
|
43
|
+
function getDuplicateAutoCreatedLocationIds(rows) {
|
|
44
|
+
const defaults = rows.filter((row) => row.name === DEFAULT_STOCK_LOCATION.name && row.created_at).sort((a, b) => String(a.created_at).localeCompare(String(b.created_at)) || a.id.localeCompare(b.id));
|
|
45
|
+
const first = defaults[0];
|
|
46
|
+
if (!first?.created_at) return [];
|
|
47
|
+
const firstAt = Date.parse(first.created_at);
|
|
48
|
+
return defaults.slice(1).filter((row) => Math.abs(Date.parse(String(row.created_at)) - firstAt) <= 6e4).map((row) => row.id);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { DEFAULT_MEASUREMENT_UNITS, DEFAULT_STOCK_LOCATION, getDuplicateAutoCreatedLocationIds, getDuplicateDefaultUnitIds, getMissingMeasurementUnits };
|
|
52
|
+
//# sourceMappingURL=chunk-YZDGJBJD.js.map
|
|
53
|
+
//# sourceMappingURL=chunk-YZDGJBJD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/domain/reference-data.ts"],"names":[],"mappings":";AAAO,IAAM,yBAAA,GAA4B;AAAA,EACvC,EAAE,IAAA,EAAM,MAAA,EAAQ,YAAA,EAAc,IAAA,EAAK;AAAA,EACnC,EAAE,IAAA,EAAM,KAAA,EAAO,YAAA,EAAc,KAAA,EAAM;AAAA,EACnC,EAAE,IAAA,EAAM,UAAA,EAAY,YAAA,EAAc,IAAA,EAAK;AAAA,EACvC,EAAE,IAAA,EAAM,MAAA,EAAQ,YAAA,EAAc,GAAA,EAAI;AAAA,EAClC,EAAE,IAAA,EAAM,OAAA,EAAS,YAAA,EAAc,GAAA,EAAI;AAAA,EACnC,EAAE,IAAA,EAAM,YAAA,EAAc,YAAA,EAAc,IAAA;AACtC;AAEO,IAAM,sBAAA,GAAyB;AAAA,EACpC,IAAA,EAAM,cAAA;AAAA,EACN,WAAA,EAAa;AACf;AAEO,SAAS,2BACd,IAAA,EAC4C;AAC5C,EAAA,MAAM,WAAW,IAAI,GAAA;AAAA,IACnB,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ,MAAA,CAAO,GAAA,CAAI,YAAA,IAAgB,EAAE,CAAA,CAAE,IAAA,EAAK,CAAE,iBAAA,EAAmB;AAAA,GAC7E;AACA,EAAA,OAAO,yBAAA,CAA0B,MAAA;AAAA,IAC/B,CAAC,SAAS,CAAC,QAAA,CAAS,IAAI,IAAA,CAAK,YAAA,CAAa,mBAAmB;AAAA,GAC/D;AACF;AAEO,SAAS,2BACd,IAAA,EACU;AACV,EAAA,MAAM,WAAW,IAAI,GAAA;AAAA,IACnB,0BAA0B,GAAA,CAAI,CAAC,SAAS,IAAA,CAAK,YAAA,CAAa,mBAAmB;AAAA,GAC/E;AACA,EAAA,MAAM,mBAAA,uBAA0B,GAAA,EAAoB;AACpD,EAAA,MAAM,aAAuB,EAAC;AAE9B,EAAA,KAAA,MAAW,GAAA,IAAO,CAAC,GAAG,IAAI,CAAA,CAAE,IAAA;AAAA,IAAK,CAAC,CAAA,EAAG,CAAA,KACnC,OAAO,CAAA,CAAE,UAAA,IAAc,EAAE,CAAA,CAAE,aAAA,CAAc,OAAO,CAAA,CAAE,UAAA,IAAc,EAAE,CAAC,CAAA,IAAK,EAAE,EAAA,CAAG,aAAA,CAAc,EAAE,EAAE;AAAA,GACjG,EAAG;AACD,IAAA,MAAM,YAAA,GAAe,OAAO,GAAA,CAAI,YAAA,IAAgB,EAAE,CAAA,CAAE,IAAA,GAAO,iBAAA,EAAkB;AAC7E,IAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,YAAY,CAAA,EAAG;AACjC,IAAA,MAAM,SAAA,GAAY,IAAI,UAAA,GAAa,IAAA,CAAK,MAAM,GAAA,CAAI,UAAU,IAAI,MAAA,CAAO,GAAA;AACvE,IAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,GAAA,CAAI,YAAY,CAAA;AACpD,IAAA,IAAI,YAAY,MAAA,EAAW;AACzB,MAAA,IAAI,OAAO,QAAA,CAAS,SAAS,GAAG,mBAAA,CAAoB,GAAA,CAAI,cAAc,SAAS,CAAA;AAC/E,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,IAAK,IAAA,CAAK,GAAA,CAAI,SAAA,GAAY,OAAO,CAAA,IAAK,GAAA,EAAQ,UAAA,CAAW,IAAA,CAAK,IAAI,EAAE,CAAA;AAAA,EACnG;AAEA,EAAA,OAAO,UAAA;AACT;AAEO,SAAS,mCACd,IAAA,EACU;AACV,EAAA,MAAM,QAAA,GAAW,IAAA,CACd,MAAA,CAAO,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,KAAS,sBAAA,CAAuB,IAAA,IAAQ,GAAA,CAAI,UAAU,CAAA,CAC1E,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,MAAA,CAAO,CAAA,CAAE,UAAU,CAAA,CAAE,aAAA,CAAc,OAAO,CAAA,CAAE,UAAU,CAAC,CAAA,IAAK,CAAA,CAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAC,CAAA;AACtG,EAAA,MAAM,KAAA,GAAQ,SAAS,CAAC,CAAA;AACxB,EAAA,IAAI,CAAC,KAAA,EAAO,UAAA,EAAY,OAAO,EAAC;AAChC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,UAAU,CAAA;AAI3C,EAAA,OAAO,QAAA,CAAS,KAAA,CAAM,CAAC,CAAA,CACpB,MAAA,CAAO,CAAC,GAAA,KAAQ,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,IAAI,UAAU,CAAC,CAAA,GAAI,OAAO,CAAA,IAAK,GAAM,EAChF,GAAA,CAAI,CAAC,GAAA,KAAQ,GAAA,CAAI,EAAE,CAAA;AACxB","file":"chunk-YZDGJBJD.js","sourcesContent":["export const DEFAULT_MEASUREMENT_UNITS = [\n { name: 'Unit', abbreviation: 'un' },\n { name: 'Box', abbreviation: 'box' },\n { name: 'Kilogram', abbreviation: 'kg' },\n { name: 'Gram', abbreviation: 'g' },\n { name: 'Liter', abbreviation: 'L' },\n { name: 'Milliliter', abbreviation: 'mL' },\n] as const\n\nexport const DEFAULT_STOCK_LOCATION = {\n name: 'Main Storage',\n description: 'Primary storage area',\n} as const\n\nexport function getMissingMeasurementUnits(\n rows: Array<{ abbreviation?: string | null }>,\n): typeof DEFAULT_MEASUREMENT_UNITS[number][] {\n const existing = new Set(\n rows.map((row) => String(row.abbreviation ?? '').trim().toLocaleLowerCase()),\n )\n return DEFAULT_MEASUREMENT_UNITS.filter(\n (unit) => !existing.has(unit.abbreviation.toLocaleLowerCase()),\n )\n}\n\nexport function getDuplicateDefaultUnitIds(\n rows: Array<{ id: string; abbreviation?: string | null; created_at?: string | null }>,\n): string[] {\n const defaults = new Set(\n DEFAULT_MEASUREMENT_UNITS.map((unit) => unit.abbreviation.toLocaleLowerCase()),\n )\n const firstByAbbreviation = new Map<string, number>()\n const duplicates: string[] = []\n\n for (const row of [...rows].sort((a, b) =>\n String(a.created_at ?? '').localeCompare(String(b.created_at ?? '')) || a.id.localeCompare(b.id),\n )) {\n const abbreviation = String(row.abbreviation ?? '').trim().toLocaleLowerCase()\n if (!defaults.has(abbreviation)) continue\n const createdAt = row.created_at ? Date.parse(row.created_at) : Number.NaN\n const firstAt = firstByAbbreviation.get(abbreviation)\n if (firstAt === undefined) {\n if (Number.isFinite(createdAt)) firstByAbbreviation.set(abbreviation, createdAt)\n continue\n }\n // Delete only the near-simultaneous copy created by the former StrictMode\n // race. A same-abbreviation unit created independently later is user data.\n if (Number.isFinite(createdAt) && Math.abs(createdAt - firstAt) <= 60_000) duplicates.push(row.id)\n }\n\n return duplicates\n}\n\nexport function getDuplicateAutoCreatedLocationIds(\n rows: Array<{ id: string; name?: string | null; created_at?: string | null }>,\n): string[] {\n const defaults = rows\n .filter((row) => row.name === DEFAULT_STOCK_LOCATION.name && row.created_at)\n .sort((a, b) => String(a.created_at).localeCompare(String(b.created_at)) || a.id.localeCompare(b.id))\n const first = defaults[0]\n if (!first?.created_at) return []\n const firstAt = Date.parse(first.created_at)\n\n // Only collapse the near-simultaneous copies produced by the former\n // StrictMode race. Locations created independently at another time remain.\n return defaults.slice(1)\n .filter((row) => Math.abs(Date.parse(String(row.created_at)) - firstAt) <= 60_000)\n .map((row) => row.id)\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/data/mock.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAWvD,wBAAgB,2BAA2B,IAAI,qBAAqB,CAumBnE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { createMockInventoryProvider } from '../chunk-MCWG3PMP.js';
|
|
2
|
+
import '../chunk-EF5LVTOC.js';
|
|
3
|
+
import '../chunk-YZDGJBJD.js';
|
|
4
|
+
import '../chunk-52AJ7H2W.js';
|
|
5
|
+
import '../chunk-GDEIBHAB.js';
|
|
6
|
+
import '../chunk-GBIFZCEN.js';
|
|
7
|
+
import '../chunk-W36J5END.js';
|
|
8
|
+
import '../chunk-AFUR3HLA.js';
|
|
9
|
+
//# sourceMappingURL=mock.js.map
|
|
10
|
+
//# sourceMappingURL=mock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"mock.js"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { IngredientCostSuggestion, IngredientInfo, MeasurementUnit, ProductionStation, RecipeAiSuggestion, RecipeCandidate, RecipeExportSheet, RecipeListRow, RecipeOutput, RecipeSheet } from '../domain/recipe-sheet';
|
|
2
|
+
import type { ProductOptionGroup } from '../domain/product';
|
|
3
|
+
import type { CreateProductInput, Product, ProductBarcode, ProductCategory, ProductQuery, ProductVariant, Supplier } from '../domain/product';
|
|
4
|
+
import type { CreateStockMovementInput, MovementQuery, StockMovement } from '../domain/movement';
|
|
5
|
+
import type { CategoryCount, InventorySummary, RestockLine, StockLocation, StockPanelQuery, StockPanelRow, StockPosition } from '../domain/stock';
|
|
6
|
+
import type { CloseStockCountResult, OpenStockCountInput, StockCountItem, StockCountSession } from '../domain/count';
|
|
7
|
+
import type { CreateRecipeIngredientInput, CreateRecipeInput, Recipe, RecipeGroup, RecipeIngredient } from '../domain/recipe';
|
|
8
|
+
import type { ConsumeRecipeForSourceInput, InventoryConsumptionResult, ReverseRecipeConsumptionInput } from '../domain/consumption';
|
|
9
|
+
import type { UsageAuditApproveInput, UsageAuditApproveResult, UsageAuditBatchResult, UsageAuditCorrection, UsageAuditCorrectionInput, UsageAuditEntry, UsageAuditQuery } from '../domain/usage-audit';
|
|
10
|
+
import type { PaginatedResult } from '../domain/query';
|
|
11
|
+
export interface InventoryDataProvider {
|
|
12
|
+
/** Idempotent: forms call it on every fresh mount, including after the active tenant changes. */
|
|
13
|
+
ensureReferenceData?(): Promise<void>;
|
|
14
|
+
getProducts(query: ProductQuery): Promise<PaginatedResult<Product>>;
|
|
15
|
+
getProductById(id: string): Promise<Product | null>;
|
|
16
|
+
createProduct(input: CreateProductInput): Promise<Product>;
|
|
17
|
+
updateProduct(id: string, data: Partial<Product>): Promise<Product>;
|
|
18
|
+
/** Stores a product photo in the tenant-scoped media bucket and persists its URL. */
|
|
19
|
+
uploadProductImage?(productId: string, file: File): Promise<string>;
|
|
20
|
+
getProductBarcodes?(productId: string): Promise<ProductBarcode[]>;
|
|
21
|
+
addProductBarcode?(productId: string, input: ProductBarcode): Promise<void>;
|
|
22
|
+
removeProductBarcode?(id: string): Promise<void>;
|
|
23
|
+
setPrimaryProductBarcode?(productId: string, id: string): Promise<void>;
|
|
24
|
+
getProductVariants?(productId: string): Promise<ProductVariant[]>;
|
|
25
|
+
addProductVariant?(productId: string, input: {
|
|
26
|
+
name: string;
|
|
27
|
+
sku?: string;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
setProductVariantActive?(id: string, active: boolean): Promise<void>;
|
|
30
|
+
getMovements(query: MovementQuery): Promise<PaginatedResult<StockMovement>>;
|
|
31
|
+
createMovement(input: CreateStockMovementInput): Promise<StockMovement>;
|
|
32
|
+
/** Drops a movement and unwinds what it did to the position and to on-hand. */
|
|
33
|
+
reverseMovement(movementId: string): Promise<void>;
|
|
34
|
+
/** What the sales consumed, product by product, against the recipe standard. */
|
|
35
|
+
getUsageAudit(query: UsageAuditQuery): Promise<PaginatedResult<UsageAuditEntry>>;
|
|
36
|
+
/** Posts the difference as an adjustment; the reason is mandatory. */
|
|
37
|
+
correctUsage(input: UsageAuditCorrectionInput): Promise<void>;
|
|
38
|
+
/** N lines under one reason and one operation; the batch, not the line, is the event. */
|
|
39
|
+
correctUsageBatch(input: {
|
|
40
|
+
reason: string;
|
|
41
|
+
lines: UsageAuditCorrection[];
|
|
42
|
+
}): Promise<UsageAuditBatchResult>;
|
|
43
|
+
approveUsageBatch?(input: UsageAuditApproveInput): Promise<UsageAuditApproveResult>;
|
|
44
|
+
getPositions(productId: string): Promise<StockPosition[]>;
|
|
45
|
+
getStockPanel?(query: StockPanelQuery): Promise<StockPanelRow[]>;
|
|
46
|
+
getLocations(): Promise<StockLocation[]>;
|
|
47
|
+
createLocation(data: {
|
|
48
|
+
name: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
unitId?: string;
|
|
51
|
+
}): Promise<StockLocation>;
|
|
52
|
+
getSuppliers(): Promise<Supplier[]>;
|
|
53
|
+
getCategories(): Promise<ProductCategory[]>;
|
|
54
|
+
getCountSessions(): Promise<StockCountSession[]>;
|
|
55
|
+
getCountSession(id: string): Promise<StockCountSession | null>;
|
|
56
|
+
getCountItems(sessionId: string): Promise<StockCountItem[]>;
|
|
57
|
+
/** Creates the session and snapshots what the system believes right now. */
|
|
58
|
+
openCountSession(input: OpenStockCountInput): Promise<StockCountSession>;
|
|
59
|
+
/** `quantity` null clears the entry back to uncounted — which is not zero. */
|
|
60
|
+
saveCountEntry(itemId: string, quantity: number | null, notes?: string): Promise<StockCountItem>;
|
|
61
|
+
/** Atomic and idempotent: re-closing emits no second round of adjustments. */
|
|
62
|
+
closeCountSession(sessionId: string, reason?: string): Promise<CloseStockCountResult>;
|
|
63
|
+
cancelCountSession(sessionId: string): Promise<StockCountSession>;
|
|
64
|
+
getRecipes(): Promise<Recipe[]>;
|
|
65
|
+
getRecipeById(id: string): Promise<Recipe | null>;
|
|
66
|
+
getRecipeIngredients(recipeId: string): Promise<RecipeIngredient[]>;
|
|
67
|
+
/** Every recipe's lines in one round trip, each with its cost basis. */
|
|
68
|
+
getAllRecipeIngredients(): Promise<RecipeIngredient[]>;
|
|
69
|
+
getRecipeGroups(recipeId: string): Promise<RecipeGroup[]>;
|
|
70
|
+
createRecipe(input: CreateRecipeInput): Promise<Recipe>;
|
|
71
|
+
updateRecipe(id: string, patch: Partial<Recipe>): Promise<Recipe>;
|
|
72
|
+
addRecipeIngredient(recipeId: string, input: CreateRecipeIngredientInput): Promise<RecipeIngredient>;
|
|
73
|
+
/** Every active product marked as produced, with its sheet's numbers. */
|
|
74
|
+
getRecipeList?(): Promise<RecipeListRow[]>;
|
|
75
|
+
/** One row of the list, re-read after a write; null when the product left it. */
|
|
76
|
+
getRecipeListRow?(productId: string): Promise<RecipeListRow | null>;
|
|
77
|
+
/** Every produced product with its full sheet, for the spreadsheet export. */
|
|
78
|
+
getRecipeExport?(): Promise<RecipeExportSheet[]>;
|
|
79
|
+
/** The product's active sheet, or null when it has none yet. */
|
|
80
|
+
getRecipeSheet?(productId: string): Promise<RecipeSheet | null>;
|
|
81
|
+
/** Products a sheet makes sense for: Venda, Intermediário or Produzido.
|
|
82
|
+
* A pure ingredient (a disposable cup) is bought, never produced. */
|
|
83
|
+
searchRecipeCandidates?(query: string, kind?: 'sale' | 'intermediate' | null): Promise<RecipeCandidate[]>;
|
|
84
|
+
getRecipeOutputs?(recipeId: string): Promise<RecipeOutput[]>;
|
|
85
|
+
getMeasurementUnitList?(): Promise<MeasurementUnit[]>;
|
|
86
|
+
getProductionStations?(): Promise<ProductionStation[]>;
|
|
87
|
+
getIngredientInfo?(productIds: string[]): Promise<IngredientInfo[]>;
|
|
88
|
+
/** Products a sheet line may use: Insumo or Intermediário switched on. */
|
|
89
|
+
searchIngredients?(query: string): Promise<IngredientInfo[]>;
|
|
90
|
+
/** Replaces the sheet in one transaction; returns the recipe id. Also marks
|
|
91
|
+
* the product as produced and writes `unitCost` as its cost. */
|
|
92
|
+
saveRecipeSheet?(sheet: RecipeSheet, unitCost: number | null): Promise<string>;
|
|
93
|
+
/** The ingredient's cost for every sheet that uses it. */
|
|
94
|
+
setIngredientCost?(productId: string, cost: number): Promise<void>;
|
|
95
|
+
suggestRecipe?(input: {
|
|
96
|
+
productId: string;
|
|
97
|
+
productName: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
imageUrls: string[];
|
|
100
|
+
instructions?: string;
|
|
101
|
+
}): Promise<RecipeAiSuggestion>;
|
|
102
|
+
suggestIngredientCost?(productId: string, name: string): Promise<IngredientCostSuggestion>;
|
|
103
|
+
/** Uploads a reference picture for the AI and returns a URL it can read. */
|
|
104
|
+
uploadAiReference?(file: File): Promise<string>;
|
|
105
|
+
/** Generates a product picture; returns it as base64 PNG, not yet applied. */
|
|
106
|
+
generateProductImage?(input: {
|
|
107
|
+
productId: string;
|
|
108
|
+
instructions?: string;
|
|
109
|
+
referenceUrls: string[];
|
|
110
|
+
}): Promise<string>;
|
|
111
|
+
getProductOptionGroups?(productId: string): Promise<ProductOptionGroup[]>;
|
|
112
|
+
saveProductOptionGroups?(productId: string, groups: ProductOptionGroup[]): Promise<ProductOptionGroup[]>;
|
|
113
|
+
/** Explodes the active recipe of a sold product; the source line makes a replay a no-op. */
|
|
114
|
+
consumeRecipeForSource(input: ConsumeRecipeForSourceInput): Promise<InventoryConsumptionResult>;
|
|
115
|
+
reverseRecipeConsumption(input: ReverseRecipeConsumptionInput): Promise<InventoryConsumptionResult>;
|
|
116
|
+
getSummary(): Promise<InventorySummary>;
|
|
117
|
+
getRestockList?(limit?: number): Promise<RestockLine[]>;
|
|
118
|
+
getCategoryDistribution?(): Promise<CategoryCount[]>;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/data/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"provider.js"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"supabase.d.ts","sourceRoot":"","sources":["../../src/data/supabase.ts"],"names":[],"mappings":"AAsCA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAA;AA+vBvD,wBAAgB,+BAA+B,IAAI,qBAAqB,CAixCvE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { createSupabaseInventoryProvider } from '../chunk-2FXO63QV.js';
|
|
2
|
+
import '../chunk-JN5AZ656.js';
|
|
3
|
+
import '../chunk-JX7NCXJQ.js';
|
|
4
|
+
import '../chunk-EF5LVTOC.js';
|
|
5
|
+
import '../chunk-YZDGJBJD.js';
|
|
6
|
+
import '../chunk-52AJ7H2W.js';
|
|
7
|
+
import '../chunk-GDEIBHAB.js';
|
|
8
|
+
import '../chunk-RUOX7OOY.js';
|
|
9
|
+
import '../chunk-GBIFZCEN.js';
|
|
10
|
+
import '../chunk-W36J5END.js';
|
|
11
|
+
import '../chunk-AFUR3HLA.js';
|
|
12
|
+
//# sourceMappingURL=supabase.js.map
|
|
13
|
+
//# sourceMappingURL=supabase.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"supabase.js"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const T: {
|
|
2
|
+
readonly stockLocations: "plg_inventory_stock_locations";
|
|
3
|
+
readonly stockMovements: "plg_inventory_stock_movements";
|
|
4
|
+
readonly stockPositions: "plg_inventory_stock_positions";
|
|
5
|
+
readonly recipes: "plg_inventory_recipes";
|
|
6
|
+
readonly recipeIngredients: "plg_inventory_recipe_ingredients";
|
|
7
|
+
readonly measurementUnits: "plg_inventory_measurement_units";
|
|
8
|
+
readonly productCategories: "categories";
|
|
9
|
+
readonly productDetails: "plg_inventory_product_details";
|
|
10
|
+
readonly recipeGroups: "plg_inventory_recipe_groups";
|
|
11
|
+
readonly countSessions: "plg_inventory_count_sessions";
|
|
12
|
+
readonly countItems: "plg_inventory_count_items";
|
|
13
|
+
readonly productSettings: "plg_inventory_product_settings";
|
|
14
|
+
readonly reservations: "plg_inventory_reservations";
|
|
15
|
+
readonly productBarcodes: "plg_inventory_product_barcodes";
|
|
16
|
+
readonly productIngredientInfo: "plg_inventory_product_ingredient_info";
|
|
17
|
+
readonly productSaleInfo: "plg_inventory_product_sale_info";
|
|
18
|
+
readonly productSaleChannels: "plg_inventory_product_sale_channels";
|
|
19
|
+
readonly productIntermediateInfo: "plg_inventory_product_intermediate_info";
|
|
20
|
+
readonly productAssetInfo: "plg_inventory_product_asset_info";
|
|
21
|
+
readonly productTaxInfo: "plg_fiscalbr_product_tax_info";
|
|
22
|
+
};
|
|
23
|
+
/** The `categories` kind a product category carries (catalog contract). */
|
|
24
|
+
export declare const PRODUCT_CATEGORY_KIND = "good";
|
|
25
|
+
//# sourceMappingURL=tables.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../src/data/tables.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;CAuBJ,CAAA;AAEV,2EAA2E;AAC3E,eAAO,MAAM,qBAAqB,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"tables.js"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** A business line that consumes the active recipe of one catalogue product. */
|
|
2
|
+
export interface ConsumeRecipeForSourceInput {
|
|
3
|
+
/** Stable vocabulary owned by the caller, for example `order_item`. */
|
|
4
|
+
sourceType: string;
|
|
5
|
+
/** Stable source-line id. It is also the exactly-once boundary. */
|
|
6
|
+
sourceId: string;
|
|
7
|
+
/** Product produced by the recipe (the item that was sold). */
|
|
8
|
+
productId: string;
|
|
9
|
+
/** Number of recipe outputs consumed by this source line. */
|
|
10
|
+
quantity: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ReverseRecipeConsumptionInput {
|
|
13
|
+
sourceType: string;
|
|
14
|
+
sourceId: string;
|
|
15
|
+
reason: string;
|
|
16
|
+
}
|
|
17
|
+
export type InventoryConsumptionStatus = 'confirmed' | 'reversed' | 'skipped';
|
|
18
|
+
export type InventoryConsumptionSkipReason = 'no_active_recipe' | 'nothing_to_reverse';
|
|
19
|
+
export interface InventoryConsumptionResult {
|
|
20
|
+
sourceType: string;
|
|
21
|
+
sourceId: string;
|
|
22
|
+
idempotencyKey: string;
|
|
23
|
+
status: InventoryConsumptionStatus;
|
|
24
|
+
recipeId?: string;
|
|
25
|
+
lineCount: number;
|
|
26
|
+
skipReason?: InventoryConsumptionSkipReason;
|
|
27
|
+
}
|
|
28
|
+
/** The source line is the idempotency boundary: replaying it never moves stock twice. */
|
|
29
|
+
export declare function consumptionKey(sourceType: string, sourceId: string): string;
|
|
30
|
+
export declare function assertConsumable(input: ConsumeRecipeForSourceInput): void;
|
|
31
|
+
export declare function assertReversible(input: ReverseRecipeConsumptionInput): void;
|
|
32
|
+
export declare function skippedConsumption(input: Pick<ConsumeRecipeForSourceInput, 'sourceType' | 'sourceId'>, skipReason: InventoryConsumptionSkipReason): InventoryConsumptionResult;
|
|
33
|
+
//# sourceMappingURL=consumption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consumption.d.ts","sourceRoot":"","sources":["../../src/domain/consumption.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,WAAW,2BAA2B;IAC1C,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAA;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAA;IACjB,6DAA6D;IAC7D,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,6BAA6B;IAC5C,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,0BAA0B,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,CAAA;AAC7E,MAAM,MAAM,8BAA8B,GAAG,kBAAkB,GAAG,oBAAoB,CAAA;AAEtF,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,0BAA0B,CAAA;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,8BAA8B,CAAA;CAC5C;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3E;AAOD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,2BAA2B,GAAG,IAAI,CAMzE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,6BAA6B,GAAG,IAAI,CAG3E;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,CAAC,2BAA2B,EAAE,YAAY,GAAG,UAAU,CAAC,EACnE,UAAU,EAAE,8BAA8B,GACzC,0BAA0B,CAS5B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"consumption.js"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** `counting` starts at the first entry typed. */
|
|
2
|
+
export type CountSessionStatus = 'open' | 'counting' | 'closed' | 'cancelled';
|
|
3
|
+
export interface StockCountSession {
|
|
4
|
+
id: string;
|
|
5
|
+
reference?: string;
|
|
6
|
+
status: CountSessionStatus;
|
|
7
|
+
stockLocationId: string;
|
|
8
|
+
stockLocationName?: string;
|
|
9
|
+
categoryId?: string;
|
|
10
|
+
categoryName?: string;
|
|
11
|
+
/** Hides the system quantity while counting. */
|
|
12
|
+
blind: boolean;
|
|
13
|
+
notes?: string;
|
|
14
|
+
itemCount?: number;
|
|
15
|
+
countedCount?: number;
|
|
16
|
+
divergentCount?: number;
|
|
17
|
+
openedAt: string;
|
|
18
|
+
closedAt?: string;
|
|
19
|
+
tenantId: string;
|
|
20
|
+
createdAt: string;
|
|
21
|
+
updatedAt: string;
|
|
22
|
+
}
|
|
23
|
+
export interface StockCountItem {
|
|
24
|
+
id: string;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
productId: string;
|
|
27
|
+
productName?: string;
|
|
28
|
+
productSku?: string;
|
|
29
|
+
/** What the system believed when the session opened — never re-read. */
|
|
30
|
+
systemQuantity: number;
|
|
31
|
+
/** undefined means nobody counted this line. It is not zero. */
|
|
32
|
+
countedQuantity?: number;
|
|
33
|
+
unitCost: number;
|
|
34
|
+
notes?: string;
|
|
35
|
+
countedAt?: string;
|
|
36
|
+
/** The adjustment this line already emitted, if the session is closed. */
|
|
37
|
+
movementId?: string;
|
|
38
|
+
tenantId: string;
|
|
39
|
+
createdAt: string;
|
|
40
|
+
updatedAt: string;
|
|
41
|
+
}
|
|
42
|
+
export interface OpenStockCountInput {
|
|
43
|
+
stockLocationId: string;
|
|
44
|
+
categoryId?: string;
|
|
45
|
+
reference?: string;
|
|
46
|
+
blind?: boolean;
|
|
47
|
+
notes?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface CloseStockCountResult {
|
|
50
|
+
sessionId: string;
|
|
51
|
+
adjustmentsCreated: number;
|
|
52
|
+
/** True when the session was already closed — nothing was emitted again. */
|
|
53
|
+
alreadyClosed: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface CountSummary {
|
|
56
|
+
total: number;
|
|
57
|
+
counted: number;
|
|
58
|
+
uncounted: number;
|
|
59
|
+
divergent: number;
|
|
60
|
+
/** Net units gained or lost across the divergent lines. */
|
|
61
|
+
variance: number;
|
|
62
|
+
/** The same, valued at each line's unit cost — what the close costs. */
|
|
63
|
+
varianceValue: number;
|
|
64
|
+
}
|
|
65
|
+
export interface CountProgress {
|
|
66
|
+
itemCount: number;
|
|
67
|
+
countedCount: number;
|
|
68
|
+
divergentCount: number;
|
|
69
|
+
}
|
|
70
|
+
/** Wider than a count line on purpose: the usage audit feeds its own rows through the same arithmetic. */
|
|
71
|
+
export type CountableLine = Pick<StockCountItem, 'systemQuantity' | 'countedQuantity' | 'unitCost'>;
|
|
72
|
+
export declare function isCounted(item: Pick<StockCountItem, 'countedQuantity'>): boolean;
|
|
73
|
+
/** counted − system, or null when the line was never counted. */
|
|
74
|
+
export declare function lineVariance(item: Pick<StockCountItem, 'systemQuantity' | 'countedQuantity'>): number | null;
|
|
75
|
+
export declare function isDivergent(item: Pick<StockCountItem, 'systemQuantity' | 'countedQuantity'>): boolean;
|
|
76
|
+
export declare function summarizeCount(items: CountableLine[]): CountSummary;
|
|
77
|
+
/** The lines the close will act on, in the order it will act on them. */
|
|
78
|
+
export declare function divergentLines<T extends Pick<StockCountItem, 'systemQuantity' | 'countedQuantity'>>(items: T[]): T[];
|
|
79
|
+
export declare function countProgress(items: Array<Pick<StockCountItem, 'systemQuantity' | 'countedQuantity'>>): CountProgress;
|
|
80
|
+
/** A closed count has moved stock and a cancelled one never will; neither takes entries. */
|
|
81
|
+
export declare function isCountFinal(status: CountSessionStatus | undefined): boolean;
|
|
82
|
+
export declare function statusAfterEntry(status: CountSessionStatus): CountSessionStatus;
|
|
83
|
+
/** Blind counts hide the system figure until the session is final. */
|
|
84
|
+
export declare function hidesVariance(session: Pick<StockCountSession, 'blind' | 'status'> | null | undefined): boolean;
|
|
85
|
+
//# sourceMappingURL=count.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"count.d.ts","sourceRoot":"","sources":["../../src/domain/count.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"count.js"}
|