@feedmepos/mf-inventory-portal 1.7.0-dev.3 → 1.7.0-dev.5

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 (97) hide show
  1. package/dist/{App-Bf4PZRE5.js → App-Dy8S0KRt.js} +4 -4
  2. package/dist/{ApprovalView-NQXKjhsD.js → ApprovalView-DjJI93rS.js} +8 -8
  3. package/dist/{BindingsDialog-CAh8K8Nq.js → BindingsDialog-D--FhGpZ.js} +2 -2
  4. package/dist/{BindingsPicker-D66IvEmP.js → BindingsPicker-XsEHl2xi.js} +2 -2
  5. package/dist/{BindingsTable-CMts66hx.js → BindingsTable-BklChwvo.js} +3 -3
  6. package/dist/{BulkReceiveRequestView-BpTTCA7i.js → BulkReceiveRequestView-Czz40o9P.js} +19 -19
  7. package/dist/{ChangeLocationComponent.vue_vue_type_script_setup_true_lang-CCAojZKC.js → ChangeLocationComponent.vue_vue_type_script_setup_true_lang-WtLADzmS.js} +1 -1
  8. package/dist/{ClosingDraftView-C4slty2p.js → ClosingDraftView-4UP_hqXM.js} +15 -15
  9. package/dist/{ClosingHistoryView-CdHPRQs5.js → ClosingHistoryView-BxPiqt9O.js} +5 -5
  10. package/dist/{ClosingTemplateView-DJn30Bje.js → ClosingTemplateView-BlRJQaNt.js} +14 -14
  11. package/dist/{DefaultView-DTo4X0Mb.js → DefaultView-CsSsO8eT.js} +2 -2
  12. package/dist/{DeliveryOrderPrintPreview-Cgwnu2_k.js → DeliveryOrderPrintPreview-RXp9AXeV.js} +2 -2
  13. package/dist/{EmailDialog.vue_vue_type_script_setup_true_lang-Cfqls6sa.js → EmailDialog.vue_vue_type_script_setup_true_lang-C6wahz4p.js} +23 -23
  14. package/dist/{FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-Ba2S-Ehm.js → FmDateRangePickerChip.vue_vue_type_script_setup_true_lang-BoIkrjeO.js} +1 -1
  15. package/dist/{FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-crOhvHNQ.js → FmFilterableMenuOptions.vue_vue_type_script_setup_true_lang-C0526zpI.js} +2 -2
  16. package/dist/{FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-BWfo-uOB.js → FmInventoryTableToolbar.vue_vue_type_script_setup_true_lang-DzmXMjXi.js} +2 -2
  17. package/dist/{FmMultiselectDialog-B1TM-j4P.js → FmMultiselectDialog-BKOope7A.js} +1 -1
  18. package/dist/{FmMultiselectDialog-c49ktpZN.js → FmMultiselectDialog-CxGDMX78.js} +2 -2
  19. package/dist/{FmUnitInput.vue_vue_type_script_setup_true_lang-02BB80Ob.js → FmUnitInput.vue_vue_type_script_setup_true_lang-CEpk3BEP.js} +5 -5
  20. package/dist/{ImportView-hv8X-TCq.js → ImportView-BHxX1hqT.js} +6 -6
  21. package/dist/{IngredientBindedItem.vue_vue_type_script_setup_true_lang-DYCmjg_3.js → IngredientBindedItem.vue_vue_type_script_setup_true_lang-CQ_oSSOb.js} +1 -1
  22. package/dist/{IngredientGroupView-CCxr6zYz.js → IngredientGroupView-DByeVT7v.js} +5 -5
  23. package/dist/{IngredientsView-CJMXqVQ1.js → IngredientsView-CPgE5eqn.js} +15 -15
  24. package/dist/{IntegrationExplorerView-CIwbQ5H9.js → IntegrationExplorerView-CrXHD7rd.js} +4 -4
  25. package/dist/{IntegrationView-D13Y-qje.js → IntegrationView-DzFBFmzL.js} +13 -13
  26. package/dist/{InventoryBindingForm-_WuPbABB.js → InventoryBindingForm-B58ZezqT.js} +1 -1
  27. package/dist/{InventoryBindingForm.vue_vue_type_script_setup_true_lang-DyjfOkrg.js → InventoryBindingForm.vue_vue_type_script_setup_true_lang-09qFxTZJ.js} +5 -5
  28. package/dist/{InventoryBindingSummary-t0mFbWUH.js → InventoryBindingSummary-WjQDrDji.js} +1 -1
  29. package/dist/{NumberPrecisionInput.vue_vue_type_script_setup_true_lang-_UcJ1ziZ.js → NumberPrecisionInput.vue_vue_type_script_setup_true_lang-DoUxZyJS.js} +1 -1
  30. package/dist/{PremiumBadge.vue_vue_type_script_setup_true_lang-DI8p0xlB.js → PremiumBadge.vue_vue_type_script_setup_true_lang-CaohrG8R.js} +1 -1
  31. package/dist/ProductionView-9s0UPdgF.js +1441 -0
  32. package/dist/{PublishView-DZIW6xCU.js → PublishView-CZ-sgofx.js} +3 -3
  33. package/dist/{PurchaseOrderPrintPreview-DMeW_-2J.js → PurchaseOrderPrintPreview-BRfOlr1A.js} +2 -2
  34. package/dist/{ReceiveRequestView-OPR03bDr.js → ReceiveRequestView-DOpcBlPk.js} +13 -13
  35. package/dist/{RecipeView-BOvq8atF.js → RecipeView-CqqtIJv3.js} +17 -17
  36. package/dist/{SettingsView-DVOb_E6y.js → SettingsView-CPqrpICj.js} +4 -4
  37. package/dist/{StockView-CpWHT6nQ.js → StockView-DL16QIzP.js} +21 -21
  38. package/dist/{SubsidiaryTreeDialog.vue_vue_type_script_setup_true_lang-4oVW5EaG.js → SubsidiaryTreeDialog.vue_vue_type_script_setup_true_lang-CRLRbY8r.js} +1 -1
  39. package/dist/{SupplierView-7-4K5z4H.js → SupplierView-BKYDTRly.js} +12 -12
  40. package/dist/{SurchargeView-BzXicsxg.js → SurchargeView-BXHVfmHS.js} +6 -6
  41. package/dist/{SystemTrailDialog.vue_vue_type_script_setup_true_lang-B38vJLeG.js → SystemTrailDialog.vue_vue_type_script_setup_true_lang-DZgTmzRk.js} +2 -2
  42. package/dist/{TemplatePublishDialog.vue_vue_type_script_setup_true_lang-DMbogm55.js → TemplatePublishDialog.vue_vue_type_script_setup_true_lang-D0JkImSa.js} +1 -1
  43. package/dist/TransferDetails.vue_vue_type_script_setup_true_lang-dBmVI2CQ.js +4660 -0
  44. package/dist/{TransferTemplateView-DBz4HvEF.js → TransferTemplateView-CI9TVc67.js} +20 -20
  45. package/dist/{UnitCostHistoryView-DGJkZl4K.js → UnitCostHistoryView-D3TUepMk.js} +4 -4
  46. package/dist/{UnitDisplayControl.vue_vue_type_script_setup_true_lang-C4tkaSh6.js → UnitDisplayControl.vue_vue_type_script_setup_true_lang-C518diLn.js} +4 -4
  47. package/dist/{UnitView-BcEBsYh3.js → UnitView-BHNkFYA8.js} +7 -7
  48. package/dist/{WarehouseView-BO6BcOsI.js → WarehouseView-Bh391caS.js} +5 -5
  49. package/dist/{WastageTemplateView-LvCjlAom.js → WastageTemplateView-Dgi21iCN.js} +14 -14
  50. package/dist/api/production.d.ts +1 -0
  51. package/dist/{app-Cac6Riab.js → app-CMeYC_Q8.js} +32 -20
  52. package/dist/app.d.ts +8 -0
  53. package/dist/app.js +1 -1
  54. package/dist/{closing-template-CelNDftu.js → closing-template-CA09sApB.js} +1 -1
  55. package/dist/{date2-DzRI3DJ0.js → date2-CzejXWLl.js} +1 -1
  56. package/dist/{dayjs.min-DvUGnfHA.js → dayjs.min-Bt3TyY_o.js} +1 -1
  57. package/dist/{decimal-BnqzATY_.js → decimal-5fD_ux1d.js} +2 -2
  58. package/dist/{defineDeepModel-JMjuMK73.js → defineDeepModel-Dm7rseSW.js} +1 -1
  59. package/dist/{duplicate-template-DNHR5oYw.js → duplicate-template-BufbAoPU.js} +1 -1
  60. package/dist/{feature-DVmi3wGL.js → feature-eNVOuvir.js} +2 -2
  61. package/dist/{format-time-from-id-C4pKwYHc.js → format-time-from-id-W3Y0GVAS.js} +1 -1
  62. package/dist/{format-unit-display-WTC4G_Rj.js → format-unit-display-Bl9U8EY8.js} +12 -12
  63. package/dist/{import-export.helper-FeLt7RUk.js → import-export.helper-DoKOvdUD.js} +6 -6
  64. package/dist/{index-DJpdYLd2.js → index-CDkRQHsH.js} +1 -1
  65. package/dist/{index-wEP1VICe.js → index-CkYWKMMm.js} +1 -1
  66. package/dist/{index-C9GO_oZU.js → index-O88uLh8G.js} +3 -3
  67. package/dist/{inventory-core-dart.default-BHOV69Dk.js → inventory-core-dart.default-w9TD2218.js} +387 -358
  68. package/dist/{jszip.min-C-wwpC8m.js → jszip.min-B_IXYK70.js} +2 -2
  69. package/dist/{lz-string-DTc5Agas.js → lz-string-B1yTzLvw.js} +1 -1
  70. package/dist/{netsuite-BPBNGwWs.js → netsuite-044jD35H.js} +2 -2
  71. package/dist/{number-DthDHdF6.js → number-BRWq97Cn.js} +3 -3
  72. package/dist/{predefined-templates-By5l7sJo.js → predefined-templates-Bux2_3lt.js} +1 -1
  73. package/dist/{purchase-order-template-Bg_l1WuQ.js → purchase-order-template-Caf8z-jM.js} +1 -1
  74. package/dist/{recalculationUtils-ChEGSDlt.js → recalculationUtils-CfRcpX6e.js} +1 -1
  75. package/dist/{rules-UTJoyvPL.js → rules-BZ4IEShU.js} +2 -2
  76. package/dist/{stock-Ba7g6IoT.js → stock-CPjd7Xin.js} +1 -1
  77. package/dist/{stock-Bwpkf9s7.js → stock-Csd8P79g.js} +3 -3
  78. package/dist/{supplier-HBYyn_V5.js → supplier-EkV-Jm3U.js} +2 -2
  79. package/dist/{surcharge-CVBnmp8_.js → surcharge-DbTgB3SV.js} +1 -1
  80. package/dist/tsconfig.app.tsbuildinfo +1 -1
  81. package/dist/{uom-rules-C9-Y4QWC.js → uom-rules-DjZk24TE.js} +1 -1
  82. package/dist/{use-ingredient-select-dialog-CSWRZqUa.js → use-ingredient-select-dialog-UyT2i0Xd.js} +2 -2
  83. package/dist/{use-inventory-binding-dialog-cyvShT5s.js → use-inventory-binding-dialog-DqiIIjP-.js} +2 -2
  84. package/dist/{use-template-enabled-locations-Dj3gcxtG.js → use-template-enabled-locations-DCS26PkR.js} +2 -2
  85. package/dist/{use-transfer-locations-Bo_A-RNx.js → use-transfer-locations-ASNqbq4F.js} +2 -2
  86. package/dist/{useHrmPermission-DA3IQT4A.js → useHrmPermission-CJghd6jy.js} +1 -1
  87. package/dist/{useNavigationMenu-BbUR6K4Q.js → useNavigationMenu-BmYGiYHz.js} +2 -2
  88. package/dist/{useSseClient-BrPItoGx.js → useSseClient-CjdMXh9s.js} +1 -1
  89. package/dist/views/production/ProductionCompletionDialog.vue.d.ts +4 -0
  90. package/dist/views/production/ProductionDetailSheet.vue.d.ts +4 -0
  91. package/dist/views/production/ProductionDuplicateDialog.vue.d.ts +6 -4
  92. package/dist/views/production/ProductionPrepareBuilder.vue.d.ts +278 -2
  93. package/dist/{vue-i18n-D8xieG1-.js → vue-i18n-DGE7TahE.js} +1 -1
  94. package/dist/{xlsx.util-BXUW183g.js → xlsx.util-DTNSgR0e.js} +2 -2
  95. package/package.json +4 -4
  96. package/dist/ProductionView-pVOiqb3z.js +0 -1330
  97. package/dist/TransferDetails.vue_vue_type_script_setup_true_lang-DD85kn-o.js +0 -4607
@@ -1,1330 +0,0 @@
1
- import { defineComponent as ue, ref as N, createElementBlock as i, openBlock as l, createElementVNode as e, createBlock as J, createTextVNode as G, toDisplayString as s, normalizeClass as ie, Teleport as ke, createCommentVNode as R, Fragment as T, normalizeStyle as he, renderList as E, computed as k, watch as re, resolveComponent as O, withCtx as X, createVNode as V, onMounted as we, h as P, reactive as $e, withDirectives as Se, vModelText as Ie, unref as Ce } from "vue";
2
- import { _ as Fe } from "./SingleColumnLayout.vue_vue_type_script_setup_true_lang-DwrLsWX_.js";
3
- import { useDialog as Be, useSnackbar as ve, components as le } from "@feedmepos/ui-library";
4
- import { m as De, u as ye, a as ge } from "./app-Cac6Riab.js";
5
- import { _ as qe } from "./ChangeLocationComponent.vue_vue_type_script_setup_true_lang-CCAojZKC.js";
6
- import { useI18n as Ne } from "@feedmepos/mf-common";
7
- import { c as be } from "./inventory-core-dart.default-BHOV69Dk.js";
8
- import { u as Me } from "./stock-Bwpkf9s7.js";
9
- import { a as Pe } from "./FmMultiselectDialog-c49ktpZN.js";
10
- import { e as Te, _ as Ve } from "./FmUnitInput.vue_vue_type_script_setup_true_lang-02BB80Ob.js";
11
- import { u as Ae } from "./stock-Ba7g6IoT.js";
12
- const xe = De((Y, $) => {
13
- const b = ye(), d = () => `${Y.inventoryBackendUrl}/${b.currentLocationDBName}/production`;
14
- return {
15
- async list(m) {
16
- const _ = m ? `?status=${m}` : "";
17
- return await $.get(`${d()}${_}`);
18
- },
19
- async read(m) {
20
- return await $.get(`${d()}/${m}`);
21
- },
22
- async create(m) {
23
- return await $.post(d(), m);
24
- },
25
- async update(m, _) {
26
- return await $.patch(`${d()}/${m}`, _);
27
- },
28
- async request(m) {
29
- return await $.post(`${d()}/${m}/request`);
30
- },
31
- // `items` are the per-item quantities produced in THIS completion record;
32
- // omit to produce the remaining (requested − already-produced) of every item.
33
- async complete(m, _) {
34
- return await $.post(`${d()}/${m}/complete`, _ ? { items: _ } : void 0);
35
- },
36
- async cancel(m, _) {
37
- return await $.post(`${d()}/${m}/cancel`, { reason: _ });
38
- }
39
- };
40
- }), Re = {
41
- key: 0,
42
- class: "w-fit whitespace-nowrap rounded-full bg-fm-color-neutral-gray-100 px-12 py-4 text-fm-color-typo-secondary",
43
- title: "This item has no ingredient bindings — no stock will be deducted, but it can still be prepared."
44
- }, je = {
45
- key: 1,
46
- class: "w-fit"
47
- }, ze = { class: "uppercase text-fm-color-typo-secondary" }, Ue = { class: "text-fm-color-typo-secondary" }, Le = /* @__PURE__ */ ue({
48
- __name: "ProductionBindingsCell",
49
- props: {
50
- count: {},
51
- unit: {},
52
- lines: {}
53
- },
54
- setup(Y) {
55
- const $ = N(!1), b = N(null), d = N({ top: 0, left: 0 });
56
- function m() {
57
- if (!$.value && b.value) {
58
- const S = b.value.getBoundingClientRect();
59
- d.value = { top: S.bottom + 4, left: S.left };
60
- }
61
- $.value = !$.value;
62
- }
63
- function _(S) {
64
- return `${parseFloat(S.toFixed(2))}`;
65
- }
66
- return (S, M) => S.count === 0 ? (l(), i("span", Re, " No bindings ")) : (l(), i("div", je, [
67
- e("button", {
68
- ref_key: "btn",
69
- ref: b,
70
- type: "button",
71
- class: "flex w-fit items-center gap-4 whitespace-nowrap rounded-full bg-fm-color-neutral-gray-100 px-12 py-4 text-fm-color-typo-secondary",
72
- onClick: m
73
- }, [
74
- M[1] || (M[1] = e("span", { class: "text-orange-500" }, "•••", -1)),
75
- G(" " + s(S.count) + " ingredients ", 1),
76
- e("span", {
77
- class: ie(["text-fm-color-typo-secondary", { "rotate-180": $.value }])
78
- }, "⌄", 2)
79
- ], 512),
80
- (l(), J(ke, { to: "body" }, [
81
- $.value ? (l(), i(T, { key: 0 }, [
82
- e("div", {
83
- class: "fixed inset-0",
84
- style: { "z-index": "1000" },
85
- onClick: M[0] || (M[0] = (f) => $.value = !1)
86
- }),
87
- e("div", {
88
- class: "fixed rounded-8 border border-fm-color-line p-12",
89
- style: he({
90
- top: `${d.value.top}px`,
91
- left: `${d.value.left}px`,
92
- background: "#fff",
93
- minWidth: "240px",
94
- zIndex: 1001,
95
- boxShadow: "0 8px 24px rgba(0, 0, 0, 0.12)"
96
- })
97
- }, [
98
- e("div", ze, " Per 1 " + s(S.unit), 1),
99
- (l(!0), i(T, null, E(S.lines, (f) => (l(), i("div", {
100
- key: f.id,
101
- class: "mt-4 flex items-center justify-between gap-16"
102
- }, [
103
- e("span", null, s(f.name), 1),
104
- e("span", Ue, s(_(f.amount)) + " " + s(f.unit), 1)
105
- ]))), 128))
106
- ], 4)
107
- ], 64)) : R("", !0)
108
- ]))
109
- ]));
110
- }
111
- }), He = { class: "flex flex-col gap-8" }, Ee = {
112
- key: 0,
113
- class: "py-12 text-fm-color-typo-secondary"
114
- }, Oe = ["onClick"], We = { class: "flex min-w-0 flex-1 flex-col" }, Ge = { class: "truncate" }, Qe = { class: "truncate text-fm-color-typo-secondary" }, Ke = { class: "whitespace-nowrap text-fm-color-typo-secondary" }, Je = /* @__PURE__ */ ue({
115
- __name: "ProductionDuplicateDialog",
116
- props: {
117
- batches: {}
118
- },
119
- emits: ["selected"],
120
- setup(Y, { emit: $ }) {
121
- const b = Y, d = $, m = N(!1), _ = N(null);
122
- function S(y) {
123
- if (!y) return "—";
124
- const r = new Date(y);
125
- return Number.isNaN(r.getTime()) ? "—" : r.toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
126
- }
127
- function M(y) {
128
- var r;
129
- return (r = y.name) != null && r.trim() ? y.name.trim() : y.batchNo ? `Production #${y.batchNo}` : `Production · ${S(y.createdAt)}`;
130
- }
131
- const f = {
132
- draft: "Draft",
133
- requested: "Requested",
134
- completed: "Completed",
135
- cancelled: "Cancelled"
136
- }, p = k(() => [...b.batches].sort((y, r) => r._id.localeCompare(y._id))), j = k(() => !!_.value);
137
- re(m, (y) => {
138
- y && (_.value = null);
139
- });
140
- function W() {
141
- const y = p.value.find((r) => r._id === _.value);
142
- y && (m.value = !1, d("selected", y));
143
- }
144
- return (y, r) => {
145
- const g = O("FmButton"), z = O("FmIcon"), H = O("FmDialog");
146
- return l(), J(H, {
147
- modelValue: m.value,
148
- "onUpdate:modelValue": r[0] || (r[0] = (q) => m.value = q),
149
- overlay: !0,
150
- "min-width": 640
151
- }, {
152
- "dialog-button": X(() => [
153
- V(g, {
154
- label: "Duplicate from",
155
- variant: "secondary",
156
- "prepend-icon": "content_copy"
157
- })
158
- ]),
159
- "dialog-header": X(() => r[1] || (r[1] = [
160
- e("div", null, "Duplicate from a batch", -1)
161
- ])),
162
- "dialog-footer": X(() => [
163
- V(g, {
164
- class: "ml-auto",
165
- label: "Duplicate",
166
- disabled: !j.value,
167
- onClick: W
168
- }, null, 8, ["disabled"])
169
- ]),
170
- default: X(() => [
171
- e("div", He, [
172
- r[2] || (r[2] = e("div", { class: "text-fm-color-typo-secondary" }, " Pick a batch to copy its items into this prepare. ", -1)),
173
- p.value.length ? R("", !0) : (l(), i("div", Ee, " No previous batches to duplicate. ")),
174
- (l(!0), i(T, null, E(p.value, (q) => (l(), i("button", {
175
- key: q._id,
176
- type: "button",
177
- class: ie([
178
- "flex items-center gap-8 fm-corner-radius-md border p-12 text-left",
179
- _.value === q._id ? "border-orange-500 bg-orange-50" : "border-fm-color-line"
180
- ]),
181
- onClick: (C) => _.value = q._id
182
- }, [
183
- e("div", We, [
184
- e("span", Ge, s(M(q)), 1),
185
- e("span", Qe, s(q.items.length) + " item" + s(q.items.length === 1 ? "" : "s") + " · " + s(f[q.status]), 1)
186
- ]),
187
- e("span", Ke, s(S(q.createdAt)), 1),
188
- _.value === q._id ? (l(), J(z, {
189
- key: 0,
190
- name: "check",
191
- class: "text-orange-500"
192
- })) : R("", !0)
193
- ], 10, Oe))), 128))
194
- ])
195
- ]),
196
- _: 1
197
- }, 8, ["modelValue"]);
198
- };
199
- }
200
- }), Xe = { class: "flex items-start gap-16" }, Ye = { class: "flex-1" }, Ze = { class: "flex flex-col gap-4 p-12" }, et = { class: "flex items-center gap-12 border-b border-fm-color-line p-12" }, tt = { class: "text-fm-color-typo-secondary" }, ot = { class: "ml-auto flex items-center gap-12" }, nt = { class: "flex items-center gap-16 p-16" }, st = { class: "text-fm-color-typo-secondary" }, at = { class: "ml-auto flex items-center gap-12" }, lt = { class: "w-[360px] shrink-0 overflow-hidden rounded-lg border border-fm-color-line" }, rt = { class: "border-b border-fm-color-line p-16" }, it = { class: "mt-12" }, ut = { class: "inline-flex items-center gap-4 rounded-full bg-fm-color-neutral-gray-100 px-12 py-4" }, ct = { class: "ml-4" }, dt = { class: "grid grid-cols-2 divide-x divide-fm-color-line border-b border-fm-color-line" }, mt = { class: "p-16" }, pt = { class: "mt-4 text-2xl font-semibold" }, ft = { class: "text-fm-color-typo-secondary" }, vt = { class: "p-16" }, yt = { class: "mt-4 text-2xl font-semibold text-fm-color-typo-secondary" }, gt = { class: "text-fm-color-typo-secondary" }, bt = {
201
- key: 0,
202
- class: "flex flex-col items-center gap-12 p-24 text-center"
203
- }, xt = { class: "flex h-[56px] w-[56px] items-center justify-center rounded-full bg-fm-color-neutral-gray-100" }, _t = {
204
- key: 1,
205
- class: "p-16"
206
- }, kt = { class: "flex items-center" }, ht = { class: "mt-4 text-sm text-fm-color-typo-secondary" }, wt = {
207
- key: 0,
208
- class: "mt-4 flex flex-col gap-4 text-sm"
209
- }, $t = /* @__PURE__ */ ue({
210
- __name: "ProductionPrepareBuilder",
211
- emits: ["created"],
212
- setup(Y, { emit: $ }) {
213
- const b = $, d = xe(), m = ge(), _ = Me(), S = Be(), { t: M } = Ne(), f = ve(), p = N([]), j = N([]), W = N(""), y = N(!1), r = N("");
214
- function g() {
215
- const t = /* @__PURE__ */ new Date();
216
- return `${`${t.getHours()}`.padStart(2, "0")}:${`${t.getMinutes()}`.padStart(2, "0")}`;
217
- }
218
- async function z() {
219
- await _.readStockBalance(), r.value = g();
220
- }
221
- we(async () => {
222
- await z(), j.value = await d.list();
223
- });
224
- const H = k(() => m.skus);
225
- function q(t) {
226
- return t ? t.amount / Math.pow(10, t.precision) : 0;
227
- }
228
- function C(t) {
229
- return `${parseFloat(t.toFixed(2))}`;
230
- }
231
- const Z = k(
232
- () => new Map((_.stockBalance.skus ?? []).map((t) => [t.id, t.balance]))
233
- );
234
- function ee(t) {
235
- return q(Z.value.get(t));
236
- }
237
- function oe() {
238
- return (m.skus ?? []).map((t) => ({
239
- doc: t,
240
- balance: Z.value.get(t._id) ?? { amount: 0, precision: 0 },
241
- abbrev: t.unit.abbrev,
242
- uom: []
243
- }));
244
- }
245
- const L = be({
246
- env: {
247
- stocks: oe(),
248
- recipes: m.recipes ?? []
249
- }
250
- }), Q = N(0);
251
- re(
252
- () => [m.skus, m.recipes],
253
- () => {
254
- L.updateEnv({
255
- stocks: oe(),
256
- recipes: m.recipes ?? []
257
- }), Q.value++;
258
- }
259
- ), re(Z, () => {
260
- L.updateBalances(oe()), Q.value++;
261
- }), re(
262
- p,
263
- () => {
264
- var t;
265
- L.resetState(), L.addItems(
266
- p.value.map((n) => ({
267
- doc: n.sku,
268
- balance: Z.value.get(n.sku._id) ?? { amount: 0, precision: 0 },
269
- abbrev: n.sku.unit.abbrev,
270
- uom: []
271
- }))
272
- );
273
- for (const n of p.value)
274
- L.updateItem(n.sku._id, n.model.amount, (t = n.model.measurement) == null ? void 0 : t.id);
275
- Q.value++;
276
- },
277
- { deep: !0, immediate: !0 }
278
- );
279
- const ce = k(() => (Q.value, new Map(L.getItemBreakdown().map((t) => [t.item.key, t]))));
280
- function ne(t) {
281
- const n = ce.value.get(t);
282
- return ((n == null ? void 0 : n.lines) ?? []).map((h) => ({
283
- id: h.skuId,
284
- name: h.name,
285
- amount: h.perUnit,
286
- unit: h.unit
287
- }));
288
- }
289
- function c(t) {
290
- return ne(t).length;
291
- }
292
- function v() {
293
- const t = H.value.map((n) => ({
294
- label: n.name,
295
- sublabel: n.code,
296
- value: n._id,
297
- tags: L.itemHasBindings(n._id) ? void 0 : ["No bindings"]
298
- }));
299
- S.open({
300
- title: M("inventory.transfer.form.items.selectItem"),
301
- closeButton: !0,
302
- contentComponent: Pe,
303
- contentComponentProps: {
304
- modelValue: p.value.map((n) => n.sku._id),
305
- items: t,
306
- virtualScroll: !0
307
- },
308
- primaryActions: { text: M("common.confirm"), close: !0 },
309
- secondaryActions: { text: M("common.close"), close: !0, variant: "tertiary" }
310
- }).onPrimary((n) => {
311
- const h = new Map(p.value.map((w) => [w.sku._id, w]));
312
- p.value = n.map(
313
- (w) => h.get(w) ?? {
314
- sku: m.skuById[w],
315
- model: Te()
316
- }
317
- ).filter((w) => !!w.sku);
318
- });
319
- }
320
- function B(t) {
321
- p.value = p.value.filter((n) => n.sku._id !== t);
322
- }
323
- function K() {
324
- p.value = [];
325
- }
326
- function A(t) {
327
- const n = [];
328
- for (const h of t.items) {
329
- const w = m.skuById[h.skuId];
330
- w && n.push({
331
- sku: w,
332
- model: { amount: h.amount, measurement: h.measurement ?? null }
333
- });
334
- }
335
- p.value = n;
336
- }
337
- const te = k(() => (Q.value, L.getIngredientImpacts().map((t) => ({ ...t, status: String(t.status) })))), se = k(() => {
338
- Q.value;
339
- const t = /* @__PURE__ */ new Map(), n = (h) => {
340
- let w = t.get(h);
341
- return w || (w = { producers: [], consumers: [] }, t.set(h, w)), w;
342
- };
343
- for (const h of L.getItemBreakdown()) {
344
- if (h.qty <= 0) continue;
345
- const w = h.item.inventoryStock.doc.name;
346
- n(h.item.key).producers.push({ name: w, amount: h.qty });
347
- for (const de of h.lines)
348
- de.total > 0 && n(de.skuId).consumers.push({ name: w, amount: de.total });
349
- }
350
- return t;
351
- });
352
- function ae(t) {
353
- var n;
354
- return ((n = se.value.get(t)) == null ? void 0 : n.producers) ?? [];
355
- }
356
- function pe(t) {
357
- var n;
358
- return ((n = se.value.get(t)) == null ? void 0 : n.consumers) ?? [];
359
- }
360
- const a = k(() => p.value.filter((t) => q(t.model.amount) > 0)), o = k(
361
- () => a.value.filter((t) => L.itemHasBindings(t.sku._id)).length
362
- ), x = k(() => te.value.filter((t) => t.status !== "ok").length), F = k(() => a.value.length > 0);
363
- function u() {
364
- return a.value.map((t) => ({
365
- skuId: t.sku._id,
366
- sku: t.sku,
367
- amount: t.model.amount,
368
- measurement: t.model.measurement ?? void 0
369
- }));
370
- }
371
- async function I() {
372
- if (F.value) {
373
- y.value = !0;
374
- try {
375
- await d.create({
376
- name: W.value.trim() || void 0,
377
- items: u()
378
- }), f == null || f.open({
379
- title: `Saved ${a.value.length} item(s) as draft`,
380
- type: "success"
381
- }), p.value = [], W.value = "", b("created");
382
- } catch (t) {
383
- f == null || f.open({ title: "Failed to save draft", message: `${(t == null ? void 0 : t.message) ?? t}`, type: "error" });
384
- } finally {
385
- y.value = !1;
386
- }
387
- }
388
- }
389
- const U = [
390
- {
391
- id: "item",
392
- header: () => "Production item",
393
- minSize: 220,
394
- enableSorting: !1,
395
- cell: (t) => {
396
- var w;
397
- const n = t.row.original.sku, h = [];
398
- return n.operationalGroup && h.push(P("span", {}, n.operationalGroup)), (w = n.customAttributes) != null && w.perishable && h.push(
399
- P(
400
- "span",
401
- { class: "rounded-full bg-orange-100 px-8 py-4 text-orange-600" },
402
- "Perishable"
403
- )
404
- ), P("div", { class: "flex flex-col" }, [
405
- P("span", { class: "" }, n.name),
406
- P("span", { class: "flex items-center gap-8 text-fm-color-typo-secondary" }, h)
407
- ]);
408
- }
409
- },
410
- {
411
- id: "unit",
412
- header: () => "Unit",
413
- size: 70,
414
- enableSorting: !1,
415
- cell: (t) => P("span", { class: "" }, t.row.original.sku.unit.abbrev)
416
- },
417
- {
418
- id: "balance",
419
- header: () => "Current balance",
420
- size: 130,
421
- enableSorting: !1,
422
- cell: (t) => {
423
- const n = t.row.original.sku;
424
- return P("div", { class: "flex flex-col items-end" }, [
425
- P("span", { class: "" }, C(ee(n._id))),
426
- P("span", { class: "text-fm-color-typo-secondary" }, n.unit.abbrev)
427
- ]);
428
- }
429
- },
430
- {
431
- id: "bindings",
432
- header: () => "Bindings",
433
- minSize: 200,
434
- enableSorting: !1,
435
- cell: (t) => P(Le, {
436
- count: c(t.row.original.sku._id),
437
- unit: t.row.original.sku.unit.abbrev,
438
- lines: ne(t.row.original.sku._id)
439
- })
440
- },
441
- {
442
- id: "qty",
443
- header: () => "Prepare qty",
444
- minSize: 200,
445
- enableSorting: !1,
446
- cell: (t) => {
447
- const n = t.row.original, h = t.row.index;
448
- return P(Ve, {
449
- key: n.sku._id,
450
- modelValue: n.model,
451
- unit: n.sku.unit,
452
- "onUpdate:modelValue": (w) => {
453
- w && (p.value = [
454
- ...p.value.slice(0, h),
455
- { ...n, model: w },
456
- ...p.value.slice(h + 1)
457
- ]);
458
- }
459
- });
460
- }
461
- },
462
- {
463
- id: "remove",
464
- header: () => "",
465
- size: 48,
466
- enableSorting: !1,
467
- cell: (t) => P("div", { class: "flex justify-end" }, [
468
- P(le.FmButton, {
469
- icon: "close",
470
- variant: "tertiary",
471
- size: "md",
472
- onClick: () => B(t.row.original.sku._id)
473
- })
474
- ])
475
- }
476
- ];
477
- return (t, n) => {
478
- const h = O("FmTextField"), w = O("FmButton"), de = O("FmTable"), _e = O("FmIcon");
479
- return l(), i("div", Xe, [
480
- e("div", Ye, [
481
- e("div", Ze, [
482
- n[1] || (n[1] = e("span", { class: "text-fm-color-typo-secondary" }, "Batch name (optional)", -1)),
483
- V(h, {
484
- modelValue: W.value,
485
- "onUpdate:modelValue": n[0] || (n[0] = (D) => W.value = D),
486
- placeholder: "e.g. Afternoon top-up"
487
- }, null, 8, ["modelValue"])
488
- ]),
489
- e("div", et, [
490
- V(w, {
491
- label: "Add items",
492
- "prepend-icon": "add",
493
- onClick: v
494
- }),
495
- e("span", tt, s(p.value.length) + " selected ", 1),
496
- e("div", ot, [
497
- V(Je, {
498
- batches: j.value,
499
- onSelected: A
500
- }, null, 8, ["batches"]),
501
- V(w, {
502
- label: "Clear all",
503
- variant: "tertiary",
504
- onClick: K
505
- })
506
- ])
507
- ]),
508
- V(de, {
509
- "column-defs": U,
510
- "row-data": p.value,
511
- "row-key": (D) => D.sku._id,
512
- "hide-footer": !0,
513
- "empty-text": "No items queued. Use “Add items” to pick what to produce."
514
- }, null, 8, ["row-data", "row-key"]),
515
- e("div", nt, [
516
- e("span", st, [
517
- e("b", null, s(a.value.length), 1),
518
- n[2] || (n[2] = G(" items queued · ")),
519
- e("b", null, s(te.value.length), 1),
520
- n[3] || (n[3] = G(" ingredients impacted "))
521
- ]),
522
- e("div", at, [
523
- V(w, {
524
- label: `Save draft · ${a.value.length} item${a.value.length === 1 ? "" : "s"}`,
525
- disabled: !F.value,
526
- loading: y.value,
527
- onClick: I
528
- }, null, 8, ["label", "disabled", "loading"])
529
- ])
530
- ])
531
- ]),
532
- e("div", lt, [
533
- e("div", rt, [
534
- n[6] || (n[6] = e("div", { class: "text-lg font-semibold" }, "Ingredient impact", -1)),
535
- n[7] || (n[7] = e("div", { class: "mt-4 text-fm-color-typo-secondary" }, " Live deductions across all queued rows. Shortages are flagged, not blocking. ", -1)),
536
- e("div", it, [
537
- e("span", ut, [
538
- n[4] || (n[4] = e("span", { class: "h-8 w-8 rounded-full bg-green-500" }, null, -1)),
539
- n[5] || (n[5] = G(" Balances as of ")),
540
- e("b", ct, s(r.value), 1)
541
- ])
542
- ])
543
- ]),
544
- e("div", dt, [
545
- e("div", mt, [
546
- n[8] || (n[8] = e("div", { class: "text-xs uppercase text-fm-color-typo-secondary" }, "Ingredients used", -1)),
547
- e("div", pt, s(te.value.length), 1),
548
- e("div", ft, "across " + s(o.value) + " items", 1)
549
- ]),
550
- e("div", vt, [
551
- n[9] || (n[9] = e("div", { class: "text-xs uppercase text-fm-color-typo-secondary" }, "Warnings", -1)),
552
- e("div", yt, s(x.value), 1),
553
- e("div", gt, s(x.value) + " low-stock", 1)
554
- ])
555
- ]),
556
- te.value.length === 0 ? (l(), i("div", bt, [
557
- e("span", xt, [
558
- V(_e, {
559
- name: "deployed_code",
560
- size: "md",
561
- class: "text-fm-color-typo-secondary"
562
- })
563
- ]),
564
- n[10] || (n[10] = e("span", { class: "text-fm-color-typo-secondary" }, " Enter a prepare quantity to preview ingredient deductions. ", -1))
565
- ])) : (l(), i("div", _t, [
566
- (l(!0), i(T, null, E(te.value, (D) => (l(), i("div", {
567
- key: D.skuId,
568
- class: "border-b border-dashed border-fm-color-line py-12"
569
- }, [
570
- e("div", kt, [
571
- e("span", null, s(D.name), 1),
572
- e("span", {
573
- class: ie([
574
- "ml-auto rounded-full px-8 py-4",
575
- D.status === "ok" ? "bg-green-100 text-green-700" : "bg-red-100 text-red-700"
576
- ])
577
- }, s(D.status === "ok" ? "✓ Ok" : D.status === "low" ? "Low" : "Short"), 3)
578
- ]),
579
- e("div", ht, [
580
- e("b", {
581
- class: ie(D.delta > 0 ? "text-green-600" : D.delta < 0 ? "text-red-600" : "")
582
- }, s(D.delta > 0 ? "+" : "") + s(C(D.delta)) + " " + s(D.unit), 3),
583
- G(" · stock " + s(C(D.current)) + " → ", 1),
584
- e("b", null, s(C(D.after)), 1),
585
- G(" " + s(D.unit), 1)
586
- ]),
587
- ae(D.skuId).length || pe(D.skuId).length ? (l(), i("div", wt, [
588
- (l(!0), i(T, null, E(ae(D.skuId), (me, fe) => (l(), i("div", {
589
- key: `p${fe}`,
590
- class: "text-green-600"
591
- }, " +" + s(C(me.amount)) + " " + s(D.unit) + " from " + s(me.name), 1))), 128)),
592
- (l(!0), i(T, null, E(pe(D.skuId), (me, fe) => (l(), i("div", {
593
- key: `c${fe}`,
594
- class: "text-red-600"
595
- }, " −" + s(C(me.amount)) + " " + s(D.unit) + " to " + s(me.name), 1))), 128))
596
- ])) : R("", !0)
597
- ]))), 128))
598
- ]))
599
- ])
600
- ]);
601
- };
602
- }
603
- }), St = { class: "flex flex-col gap-4" }, It = { class: "flex items-start justify-between gap-8 py-4" }, Ct = { class: "flex min-w-0 flex-1 flex-col" }, Ft = { class: "truncate" }, Bt = { class: "truncate text-fm-color-typo-secondary" }, Dt = { class: "flex w-[180px] shrink-0 flex-col items-end gap-4" }, qt = {
604
- key: 0,
605
- class: "text-fm-color-typo-secondary"
606
- }, Nt = {
607
- key: 0,
608
- class: "border-b border-fm-color-line"
609
- }, Mt = /* @__PURE__ */ ue({
610
- __name: "ProductionCompletionDialog",
611
- props: {
612
- batch: {}
613
- },
614
- emits: ["submitted"],
615
- setup(Y, { emit: $ }) {
616
- const b = Y, d = $, m = N(!1);
617
- function _(r) {
618
- return r ? r.amount / Math.pow(10, r.precision) : 0;
619
- }
620
- function S(r, g) {
621
- return { amount: Math.round(r * Math.pow(10, g)), precision: g };
622
- }
623
- function M(r) {
624
- return `${parseFloat(r.toFixed(2))}`;
625
- }
626
- const f = k(() => {
627
- const r = /* @__PURE__ */ new Map();
628
- for (const g of b.batch.completions ?? [])
629
- for (const z of g.items)
630
- r.set(z.skuId, (r.get(z.skuId) ?? 0) + _(z.amount));
631
- return r;
632
- }), p = k(
633
- () => b.batch.items.map((r) => {
634
- var H;
635
- const g = _(r.amount), z = f.value.get(r.skuId) ?? 0;
636
- return {
637
- skuId: r.skuId,
638
- name: r.sku.name,
639
- code: r.sku.code,
640
- unit: ((H = r.measurement) == null ? void 0 : H.abbrev) ?? r.sku.unit.abbrev,
641
- requested: g,
642
- produced: z,
643
- remaining: Math.max(0, g - z),
644
- precision: r.amount.precision
645
- };
646
- })
647
- ), j = $e({});
648
- re(m, (r) => {
649
- if (r) for (const g of p.value) j[g.skuId] = g.remaining;
650
- });
651
- const W = k(() => p.value.some((r) => (j[r.skuId] ?? 0) > 0));
652
- function y() {
653
- const r = p.value.filter((g) => (j[g.skuId] ?? 0) > 0).map((g) => ({ skuId: g.skuId, amount: S(j[g.skuId], g.precision) }));
654
- m.value = !1, d("submitted", r);
655
- }
656
- return (r, g) => {
657
- const z = O("FmButton"), H = O("FmStepperField"), q = O("FmDialog");
658
- return l(), J(q, {
659
- modelValue: m.value,
660
- "onUpdate:modelValue": g[0] || (g[0] = (C) => m.value = C),
661
- overlay: !0,
662
- "min-width": 640
663
- }, {
664
- "dialog-button": X(() => [
665
- V(z, {
666
- label: "Mark as completed",
667
- "prepend-icon": "check"
668
- })
669
- ]),
670
- "dialog-header": X(() => g[1] || (g[1] = [
671
- e("div", null, "Complete production · select items", -1)
672
- ])),
673
- "dialog-footer": X(() => [
674
- V(z, {
675
- class: "ml-auto",
676
- label: "Confirm completion",
677
- disabled: !W.value,
678
- onClick: y
679
- }, null, 8, ["disabled"])
680
- ]),
681
- default: X(() => [
682
- e("div", St, [
683
- g[2] || (g[2] = e("div", { class: "text-fm-color-typo-secondary" }, "Quantity to produce now", -1)),
684
- (l(!0), i(T, null, E(p.value, (C, Z) => (l(), i(T, {
685
- key: C.skuId
686
- }, [
687
- e("div", It, [
688
- e("div", Ct, [
689
- e("span", Ft, s(C.name), 1),
690
- e("span", Bt, s(C.code), 1)
691
- ]),
692
- e("div", Dt, [
693
- V(H, {
694
- modelValue: j[C.skuId],
695
- "onUpdate:modelValue": (ee) => j[C.skuId] = ee,
696
- label: "Quantity",
697
- min: 0,
698
- disabled: C.remaining <= 0,
699
- "append-text": C.unit,
700
- "helper-text": `Produced ${M(C.produced)} / ${M(C.requested)}`
701
- }, null, 8, ["modelValue", "onUpdate:modelValue", "disabled", "append-text", "helper-text"]),
702
- (j[C.skuId] ?? 0) <= 0 ? (l(), i("span", qt, " Skipped (zero quantity) ")) : R("", !0)
703
- ])
704
- ]),
705
- Z < p.value.length - 1 ? (l(), i("div", Nt)) : R("", !0)
706
- ], 64))), 128))
707
- ])
708
- ]),
709
- _: 1
710
- }, 8, ["modelValue"]);
711
- };
712
- }
713
- }), Pt = { class: "flex h-full flex-col" }, Tt = { class: "px-16 pt-16" }, Vt = { class: "flex flex-1 flex-col gap-16 overflow-y-auto p-16" }, At = { class: "border border-fm-color-neutral-gray-200 fm-corner-radius-lg p-16" }, Rt = { class: "flex items-center gap-8" }, jt = { class: "mt-16 flex flex-col" }, zt = { class: "flex flex-col gap-4 border-b border-fm-color-line pb-12" }, Ut = { class: "flex flex-col gap-4 border-b border-fm-color-line py-12" }, Lt = { class: "flex flex-col gap-4 border-b border-fm-color-line py-12" }, Ht = { class: "flex flex-col gap-4 pt-12" }, Et = {
714
- key: 0,
715
- class: "fm-corner-radius-md bg-fm-color-neutral-gray-100 p-12"
716
- }, Ot = { class: "border border-fm-color-neutral-gray-200 fm-corner-radius-lg p-16" }, Wt = { class: "mt-16 flex flex-col" }, Gt = { class: "flex items-start gap-8" }, Qt = { class: "flex flex-col" }, Kt = { class: "text-fm-color-typo-secondary" }, Jt = { class: "ml-auto flex flex-col items-end gap-4" }, Xt = { class: "text-fm-color-typo-secondary" }, Yt = {
717
- key: 0,
718
- class: "flex flex-col gap-4 fm-corner-radius-md bg-fm-color-neutral-gray-100 p-8"
719
- }, Zt = { class: "text-fm-color-typo-secondary" }, eo = {
720
- key: 1,
721
- class: "border border-fm-color-neutral-gray-200 fm-corner-radius-lg p-16"
722
- }, to = { class: "mt-16 flex flex-col gap-12" }, oo = { class: "flex items-center gap-8" }, no = { class: "ml-auto text-fm-color-typo-secondary" }, so = { class: "text-fm-color-typo-secondary" }, ao = { class: "flex flex-col gap-4" }, lo = { class: "text-fm-color-typo-secondary" }, ro = {
723
- key: 0,
724
- class: "flex flex-col gap-4 fm-corner-radius-md bg-fm-color-neutral-gray-100 p-8"
725
- }, io = { class: "text-fm-color-typo-secondary" }, uo = {
726
- key: 2,
727
- class: "border border-fm-color-neutral-gray-200 fm-corner-radius-lg p-16"
728
- }, co = { class: "mt-12 flex flex-col gap-8" }, mo = { class: "flex flex-wrap items-center gap-8" }, po = { class: "whitespace-nowrap text-fm-color-typo-secondary" }, fo = {
729
- key: 0,
730
- class: "flex flex-col"
731
- }, vo = { class: "flex flex-col" }, yo = { class: "text-fm-color-typo-secondary" }, go = { class: "text-fm-color-typo-secondary" }, bo = {
732
- key: 1,
733
- class: "text-fm-color-typo-secondary"
734
- }, xo = { class: "border-t border-fm-color-line p-16" }, _o = {
735
- key: 0,
736
- class: "flex flex-col gap-8"
737
- }, ko = { class: "flex justify-end gap-8" }, ho = {
738
- key: 1,
739
- class: "flex items-center gap-8"
740
- }, wo = { class: "ml-auto flex gap-8" }, $o = /* @__PURE__ */ ue({
741
- __name: "ProductionDetailSheet",
742
- props: {
743
- batch: {}
744
- },
745
- emits: ["request", "complete", "cancel", "close"],
746
- setup(Y, { emit: $ }) {
747
- const b = Y, d = $, m = ge(), _ = Ae(), S = N("overview"), M = [
748
- { label: "Overview", value: "overview" },
749
- { label: "Activity log", value: "activity" }
750
- ];
751
- function f(a) {
752
- return `${parseFloat(a.toFixed(2))}`;
753
- }
754
- function p(a) {
755
- return a ? a.amount / Math.pow(10, a.precision) : 0;
756
- }
757
- const j = k(
758
- () => ({ draft: "Draft", requested: "Requested", completed: "Completed", cancelled: "Cancelled" })[b.batch.status]
759
- ), W = k(
760
- () => ({
761
- draft: "bg-fm-color-neutral-gray-100 text-fm-color-typo-secondary",
762
- requested: "bg-amber-100 text-amber-700",
763
- completed: "bg-green-100 text-green-700",
764
- cancelled: "bg-fm-color-neutral-gray-100 text-fm-color-typo-secondary"
765
- })[b.batch.status]
766
- );
767
- function y(a) {
768
- return `${a}`.padStart(2, "0");
769
- }
770
- const r = k(() => {
771
- const a = b.batch.createdAt;
772
- if (!a) return "—";
773
- const o = new Date(a);
774
- return Number.isNaN(o.getTime()) ? "—" : o.toDateString() === (/* @__PURE__ */ new Date()).toDateString() ? `Today · ${y(o.getHours())}:${y(o.getMinutes())}` : o.toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
775
- }), g = k(() => {
776
- var a;
777
- return ((a = b.batch.createdBy) == null ? void 0 : a.name) || "—";
778
- }), z = {
779
- create: "Created",
780
- update: "Edited",
781
- request: "Requested",
782
- complete: "Completed",
783
- cancel: "Cancelled"
784
- };
785
- function H(a) {
786
- if (!a) return "";
787
- const o = new Date(a);
788
- return Number.isNaN(o.getTime()) ? "" : o.toLocaleString();
789
- }
790
- const q = k(() => [...b.batch.activityLogs ?? []].reverse()), C = k(() => {
791
- const a = b.batch.items.map((I) => I.sku), o = new Set(a.map((I) => I._id)), F = {
792
- stocks: [
793
- ...a,
794
- ...(m.skus ?? []).filter((I) => !o.has(I._id))
795
- ].map((I) => ({
796
- doc: I,
797
- balance: { amount: 0, precision: 0 },
798
- abbrev: I.unit.abbrev,
799
- uom: []
800
- })),
801
- recipes: m.recipes ?? []
802
- }, u = be({ env: F });
803
- return u.seedFromBatchItems(b.batch.items), u;
804
- }), Z = k(() => {
805
- const a = /* @__PURE__ */ new Map();
806
- for (const o of b.batch.completions ?? [])
807
- for (const x of o.items)
808
- a.set(x.skuId, (a.get(x.skuId) ?? 0) + p(x.amount));
809
- return a;
810
- }), ee = k(
811
- () => C.value.getItemBreakdown().map((a, o) => {
812
- var F;
813
- const x = ((F = b.batch.items[o]) == null ? void 0 : F.skuId) ?? "";
814
- return {
815
- key: a.item.key,
816
- skuId: x,
817
- name: a.item.inventoryStock.doc.name,
818
- code: a.item.inventoryStock.doc.code,
819
- unit: a.item.inventoryStock.doc.unit.abbrev,
820
- qty: a.qty,
821
- produced: Z.value.get(x) ?? 0,
822
- ingredients: a.lines.length,
823
- lines: a.lines
824
- };
825
- })
826
- ), oe = k(() => C.value.getIngredientDeductions()), L = k(() => {
827
- const a = /* @__PURE__ */ new Map();
828
- for (const o of ee.value)
829
- for (const x of o.lines) {
830
- const F = a.get(x.skuId) ?? [];
831
- F.includes(o.name) || F.push(o.name), a.set(x.skuId, F);
832
- }
833
- return a;
834
- });
835
- function Q(a) {
836
- return L.value.get(a) ?? [];
837
- }
838
- const ce = k(() => {
839
- const a = /* @__PURE__ */ new Map();
840
- for (const o of ee.value) a.set(o.skuId, o.name);
841
- return a;
842
- });
843
- function ne(a) {
844
- return ce.value.get(a) ?? a;
845
- }
846
- const c = N({});
847
- re(
848
- () => b.batch.completions,
849
- async (a) => {
850
- for (const o of a ?? [])
851
- o.adjustmentId && !(o.adjustmentId in c.value) && (c.value[o.adjustmentId] = await _.readSingleAdjustment(o.adjustmentId));
852
- },
853
- { immediate: !0 }
854
- );
855
- const v = k(() => [...b.batch.completions ?? []].reverse());
856
- function B(a) {
857
- const o = c.value[a];
858
- return o != null && o.skus ? o.skus.map((x) => {
859
- const F = x.amounts.reduce((u, I) => u + p(I.amount), 0);
860
- return { name: x.sku.name, amount: F, unit: x.sku.unit.abbrev };
861
- }).filter((x) => x.amount < 0).map((x) => ({ ...x, amount: Math.abs(x.amount) })) : [];
862
- }
863
- const K = k(() => (b.batch.completions ?? []).length > 0), A = k(() => {
864
- if (!K.value)
865
- return oe.value.map((o) => ({
866
- skuId: o.skuId,
867
- name: o.name,
868
- unit: o.unit,
869
- total: o.total,
870
- sources: Q(o.skuId)
871
- }));
872
- const a = /* @__PURE__ */ new Map();
873
- for (const o of b.batch.completions ?? []) {
874
- const x = c.value[o.adjustmentId];
875
- if (x != null && x.skus)
876
- for (const F of x.skus) {
877
- const u = F.amounts.reduce((t, n) => t + p(n.amount), 0);
878
- if (u >= 0) continue;
879
- const I = F.sku._id, U = a.get(I) ?? { skuId: I, name: F.sku.name, unit: F.sku.unit.abbrev, total: 0, sources: /* @__PURE__ */ new Set() };
880
- U.total += u;
881
- for (const t of F.amounts) t.ref && U.sources.add(ne(t.ref));
882
- a.set(I, U);
883
- }
884
- }
885
- return [...a.values()].map((o) => ({ ...o, total: Math.abs(o.total), sources: [...o.sources] }));
886
- }), te = k(
887
- () => b.batch.status === "draft" || b.batch.status === "requested"
888
- ), se = N(!1), ae = N("");
889
- function pe() {
890
- d("cancel", ae.value.trim()), se.value = !1, ae.value = "";
891
- }
892
- return (a, o) => {
893
- const x = O("FmTabs"), F = O("FmButton");
894
- return l(), i("div", Pt, [
895
- e("div", Tt, [
896
- V(x, {
897
- "model-value": S.value,
898
- "onUpdate:modelValue": o[0] || (o[0] = (u) => S.value = u),
899
- items: M
900
- }, null, 8, ["model-value"])
901
- ]),
902
- e("div", Vt, [
903
- S.value === "overview" ? (l(), i(T, { key: 0 }, [
904
- e("section", At, [
905
- e("div", Rt, [
906
- o[7] || (o[7] = e("span", null, "Request summary", -1)),
907
- e("span", {
908
- class: ie(["ml-auto w-fit rounded-full px-12 py-4", W.value])
909
- }, s(j.value), 3)
910
- ]),
911
- e("div", jt, [
912
- e("div", zt, [
913
- o[8] || (o[8] = e("span", { class: "text-fm-color-typo-secondary" }, "Created at", -1)),
914
- e("span", null, s(r.value), 1)
915
- ]),
916
- e("div", Ut, [
917
- o[9] || (o[9] = e("span", { class: "text-fm-color-typo-secondary" }, "Created by", -1)),
918
- e("span", null, s(g.value), 1)
919
- ]),
920
- e("div", Lt, [
921
- o[10] || (o[10] = e("span", { class: "text-fm-color-typo-secondary" }, "Items requested", -1)),
922
- e("span", null, s(a.batch.items.length), 1)
923
- ]),
924
- e("div", Ht, [
925
- o[11] || (o[11] = e("span", { class: "text-fm-color-typo-secondary" }, " Ingredient deductions ", -1)),
926
- e("span", null, s(A.value.length), 1)
927
- ])
928
- ])
929
- ]),
930
- a.batch.status === "cancelled" && a.batch.cancelReason ? (l(), i("div", Et, [
931
- o[12] || (o[12] = e("span", { class: "text-fm-color-typo-secondary" }, "Cancel reason:", -1)),
932
- G(" " + s(a.batch.cancelReason), 1)
933
- ])) : R("", !0),
934
- e("section", Ot, [
935
- o[13] || (o[13] = e("div", { class: "flex items-center gap-8" }, [
936
- e("span", null, "Production items")
937
- ], -1)),
938
- e("div", Wt, [
939
- (l(!0), i(T, null, E(ee.value, (u, I) => (l(), i("div", {
940
- key: u.key,
941
- class: ie(["flex flex-col gap-8 py-12", {
942
- "border-b border-fm-color-line": I < ee.value.length - 1,
943
- "pt-0": I === 0
944
- }])
945
- }, [
946
- e("div", Gt, [
947
- e("div", Qt, [
948
- e("span", null, s(u.name), 1),
949
- e("span", Kt, s(u.code) + " · " + s(u.ingredients) + " ingredient" + s(u.ingredients === 1 ? "" : "s"), 1)
950
- ]),
951
- e("div", Jt, [
952
- e("span", null, [
953
- e("b", null, s(f(u.produced)), 1),
954
- e("span", Xt, " / " + s(f(u.qty)) + " " + s(u.unit), 1)
955
- ])
956
- ])
957
- ]),
958
- u.lines.length ? (l(), i("div", Yt, [
959
- (l(!0), i(T, null, E(u.lines, (U) => (l(), i("div", {
960
- key: U.skuId,
961
- class: "flex items-center justify-between"
962
- }, [
963
- e("span", null, s(U.name), 1),
964
- e("span", Zt, [
965
- G(s(f(U.perUnit)) + " × " + s(f(u.qty)) + " = ", 1),
966
- e("b", null, s(f(U.total)), 1),
967
- G(" " + s(U.unit), 1)
968
- ])
969
- ]))), 128))
970
- ])) : R("", !0)
971
- ], 2))), 128))
972
- ])
973
- ]),
974
- v.value.length ? (l(), i("section", eo, [
975
- o[15] || (o[15] = e("span", null, "Completions", -1)),
976
- e("div", to, [
977
- (l(!0), i(T, null, E(v.value, (u, I) => {
978
- var U;
979
- return l(), i("div", {
980
- key: u.adjustmentId,
981
- class: "flex flex-col gap-8 fm-corner-radius-md border border-fm-color-line p-12"
982
- }, [
983
- e("div", oo, [
984
- e("span", null, "Record #" + s(v.value.length - I), 1),
985
- e("span", no, s(H(u.completedAt)), 1)
986
- ]),
987
- e("span", so, " by " + s(((U = u.completedBy) == null ? void 0 : U.name) || "Unknown"), 1),
988
- e("div", ao, [
989
- (l(!0), i(T, null, E(u.items, (t) => (l(), i("div", {
990
- key: t.skuId,
991
- class: "flex items-center justify-between"
992
- }, [
993
- e("span", null, s(ne(t.skuId)), 1),
994
- e("span", lo, " +" + s(f(p(t.amount))), 1)
995
- ]))), 128))
996
- ]),
997
- B(u.adjustmentId).length ? (l(), i("div", ro, [
998
- o[14] || (o[14] = e("span", { class: "text-fm-color-typo-secondary" }, "Deducted", -1)),
999
- (l(!0), i(T, null, E(B(u.adjustmentId), (t) => (l(), i("div", {
1000
- key: t.name,
1001
- class: "flex items-center justify-between"
1002
- }, [
1003
- e("span", null, s(t.name), 1),
1004
- e("span", io, "−" + s(f(t.amount)) + " " + s(t.unit), 1)
1005
- ]))), 128))
1006
- ])) : R("", !0)
1007
- ]);
1008
- }), 128))
1009
- ])
1010
- ])) : R("", !0),
1011
- A.value.length ? (l(), i("section", uo, [
1012
- o[16] || (o[16] = e("span", null, "Total ingredient deduction", -1)),
1013
- e("div", co, [
1014
- (l(!0), i(T, null, E(A.value, (u) => (l(), i("div", {
1015
- key: u.skuId,
1016
- class: "flex items-center justify-between gap-8"
1017
- }, [
1018
- e("div", mo, [
1019
- e("span", null, s(u.name), 1),
1020
- (l(!0), i(T, null, E(u.sources, (I) => (l(), i("span", {
1021
- key: I,
1022
- class: "w-fit rounded-full bg-fm-color-neutral-gray-100 px-8 py-4 text-fm-color-typo-secondary"
1023
- }, s(I), 1))), 128))
1024
- ]),
1025
- e("span", po, " −" + s(f(u.total)) + " " + s(u.unit), 1)
1026
- ]))), 128))
1027
- ])
1028
- ])) : R("", !0)
1029
- ], 64)) : (l(), i(T, { key: 1 }, [
1030
- q.value.length ? (l(), i("div", fo, [
1031
- (l(!0), i(T, null, E(q.value, (u, I) => {
1032
- var U;
1033
- return l(), i("div", {
1034
- key: I,
1035
- class: "flex items-start gap-12 border-l-2 border-fm-color-line py-4 pl-12"
1036
- }, [
1037
- o[17] || (o[17] = e("span", { class: "mt-4 -ml-[13px] h-8 w-8 shrink-0 rounded-full bg-orange-500" }, null, -1)),
1038
- e("div", vo, [
1039
- e("span", null, [
1040
- G(s(z[u.action]) + " ", 1),
1041
- e("span", yo, " by " + s(((U = u.performedBy) == null ? void 0 : U.name) || "Unknown"), 1)
1042
- ]),
1043
- e("span", go, [
1044
- G(s(H(u.performedAt)), 1),
1045
- u.remark ? (l(), i(T, { key: 0 }, [
1046
- G(" · " + s(u.remark), 1)
1047
- ], 64)) : R("", !0)
1048
- ])
1049
- ])
1050
- ]);
1051
- }), 128))
1052
- ])) : (l(), i("div", bo, "No activity yet."))
1053
- ], 64))
1054
- ]),
1055
- e("div", xo, [
1056
- se.value ? (l(), i("div", _o, [
1057
- Se(e("textarea", {
1058
- "onUpdate:modelValue": o[1] || (o[1] = (u) => ae.value = u),
1059
- class: "w-full fm-corner-radius-md border border-fm-color-line p-8",
1060
- rows: "2",
1061
- placeholder: "Reason for cancelling (optional)"
1062
- }, null, 512), [
1063
- [Ie, ae.value]
1064
- ]),
1065
- e("div", ko, [
1066
- V(F, {
1067
- label: "Back",
1068
- variant: "secondary",
1069
- onClick: o[2] || (o[2] = (u) => se.value = !1)
1070
- }),
1071
- V(F, {
1072
- label: "Confirm cancel",
1073
- variant: "primary",
1074
- onClick: pe
1075
- })
1076
- ])
1077
- ])) : (l(), i("div", ho, [
1078
- te.value ? (l(), J(F, {
1079
- key: 0,
1080
- label: "Cancel",
1081
- variant: "tertiary",
1082
- onClick: o[3] || (o[3] = (u) => se.value = !0)
1083
- })) : R("", !0),
1084
- e("div", wo, [
1085
- V(F, {
1086
- label: "Close",
1087
- variant: "secondary",
1088
- onClick: o[4] || (o[4] = (u) => d("close"))
1089
- }),
1090
- a.batch.status === "draft" ? (l(), J(F, {
1091
- key: 0,
1092
- label: "Submit request",
1093
- onClick: o[5] || (o[5] = (u) => d("request"))
1094
- })) : R("", !0),
1095
- a.batch.status === "requested" ? (l(), J(Mt, {
1096
- key: 1,
1097
- batch: a.batch,
1098
- onSubmitted: o[6] || (o[6] = (u) => d("complete", u))
1099
- }, null, 8, ["batch"])) : R("", !0)
1100
- ])
1101
- ]))
1102
- ])
1103
- ]);
1104
- };
1105
- }
1106
- }), So = { class: "flex flex-col gap-16 p-16" }, Io = { class: "flex items-center gap-8" }, Co = { class: "p-16" }, jo = /* @__PURE__ */ ue({
1107
- __name: "ProductionView",
1108
- setup(Y) {
1109
- const $ = xe(), b = ye(), d = ve(), m = N([]), _ = N(!1), S = N(null), M = N(!1), f = N(null), p = N(!1);
1110
- function j(c) {
1111
- f.value = c, p.value = !0;
1112
- }
1113
- const W = [
1114
- { label: "Refresh", value: "refresh", prependIcon: "refresh" },
1115
- { label: "New production prepare", value: "new", prependIcon: "add" }
1116
- ];
1117
- async function y() {
1118
- _.value = !0;
1119
- try {
1120
- m.value = await $.list();
1121
- } finally {
1122
- _.value = !1;
1123
- }
1124
- }
1125
- b.watchLocation(y);
1126
- function r(c) {
1127
- c === "new" ? M.value = !0 : c === "refresh" && y();
1128
- }
1129
- function g() {
1130
- M.value = !1, y();
1131
- }
1132
- function z(c) {
1133
- return { draft: "Draft", requested: "Requested", completed: "Completed", cancelled: "Cancelled" }[c];
1134
- }
1135
- async function H(c) {
1136
- S.value = c._id;
1137
- try {
1138
- await $.request(c._id), await y();
1139
- } catch (v) {
1140
- d == null || d.open({ title: "Failed to request", message: `${(v == null ? void 0 : v.message) ?? v}`, type: "error" });
1141
- } finally {
1142
- S.value = null;
1143
- }
1144
- }
1145
- async function q(c, v) {
1146
- S.value = c._id;
1147
- try {
1148
- const B = await $.complete(c._id, v);
1149
- B.warnings.length > 0 ? d == null || d.open({
1150
- title: "Completed with warnings",
1151
- message: `${B.warnings.length} item(s) had no ingredient deduction.`,
1152
- type: "warning"
1153
- }) : d == null || d.open({ title: "Production completed", type: "success" }), await y();
1154
- } catch (B) {
1155
- d == null || d.open({ title: "Failed to complete", message: `${(B == null ? void 0 : B.message) ?? B}`, type: "error" });
1156
- } finally {
1157
- S.value = null;
1158
- }
1159
- }
1160
- async function C(c, v) {
1161
- S.value = c._id;
1162
- try {
1163
- await $.cancel(c._id, v), d == null || d.open({ title: "Production cancelled", type: "success" }), p.value = !1, await y();
1164
- } catch (B) {
1165
- d == null || d.open({ title: "Failed to cancel", message: `${(B == null ? void 0 : B.message) ?? B}`, type: "error" });
1166
- } finally {
1167
- S.value = null;
1168
- }
1169
- }
1170
- async function Z() {
1171
- f.value && await H(f.value), p.value = !1;
1172
- }
1173
- async function ee(c) {
1174
- f.value && await q(f.value, c), p.value = !1;
1175
- }
1176
- async function oe(c) {
1177
- f.value && await C(f.value, c);
1178
- }
1179
- function L(c) {
1180
- if (!c) return "—";
1181
- const v = new Date(c);
1182
- return Number.isNaN(v.getTime()) ? "—" : v.toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
1183
- }
1184
- function Q(c) {
1185
- var v;
1186
- return (v = c.name) != null && v.trim() ? c.name.trim() : c.batchNo ? `Production #${c.batchNo}` : `Production · ${L(c.createdAt)}`;
1187
- }
1188
- const ce = {
1189
- draft: "bg-fm-color-neutral-gray-100 text-fm-color-typo-secondary",
1190
- requested: "bg-amber-100 text-amber-700",
1191
- completed: "bg-green-100 text-green-700",
1192
- cancelled: "bg-fm-color-neutral-gray-100 text-fm-color-typo-secondary"
1193
- }, ne = [
1194
- {
1195
- id: "createdAt",
1196
- header: () => "Created",
1197
- minSize: 170,
1198
- enableSorting: !1,
1199
- cell: (c) => L(c.row.original.createdAt)
1200
- },
1201
- {
1202
- id: "name",
1203
- header: () => "Name",
1204
- minSize: 240,
1205
- enableSorting: !1,
1206
- cell: (c) => Q(c.row.original)
1207
- },
1208
- {
1209
- id: "items",
1210
- header: () => "Total items",
1211
- size: 110,
1212
- enableSorting: !1,
1213
- cell: (c) => `${c.row.original.items.length}`
1214
- },
1215
- {
1216
- id: "status",
1217
- header: () => "Status",
1218
- size: 130,
1219
- enableSorting: !1,
1220
- cell: (c) => P(
1221
- "span",
1222
- { class: `w-fit rounded-full px-12 py-4 ${ce[c.row.original.status]}` },
1223
- z(c.row.original.status)
1224
- )
1225
- },
1226
- {
1227
- id: "actions",
1228
- header: () => "",
1229
- size: 64,
1230
- enableSorting: !1,
1231
- cell: (c) => {
1232
- const v = c.row.original, B = (A) => (te) => {
1233
- te.stopPropagation(), A();
1234
- }, K = [];
1235
- return v.status === "draft" && K.push(
1236
- P(le.FmMenuItem, {
1237
- label: "Submit request",
1238
- onClick: B(() => H(v))
1239
- })
1240
- ), v.status === "requested" && K.push(
1241
- P(le.FmMenuItem, {
1242
- label: "Mark complete",
1243
- onClick: B(() => q(v))
1244
- })
1245
- ), K.push(
1246
- P(le.FmMenuItem, { label: "View details", onClick: B(() => j(v)) })
1247
- ), P(
1248
- "div",
1249
- { class: "flex justify-end", onClick: (A) => A.stopPropagation() },
1250
- [
1251
- P(
1252
- le.FmMenu,
1253
- { closeOnClick: !0 },
1254
- {
1255
- "menu-button": () => P(le.FmButton, { icon: "more_vert", variant: "tertiary" }),
1256
- default: () => K
1257
- }
1258
- )
1259
- ]
1260
- );
1261
- }
1262
- }
1263
- ];
1264
- return (c, v) => {
1265
- const B = O("FmTable"), K = O("FmSideSheet");
1266
- return l(), J(Fe, {
1267
- title: "Production Item",
1268
- actions: W,
1269
- "onClick:action": r
1270
- }, {
1271
- default: X(() => [
1272
- e("div", So, [
1273
- e("div", Io, [
1274
- Ce(b)._currentLocation ? (l(), J(qe, { key: 0 })) : R("", !0)
1275
- ]),
1276
- V(B, {
1277
- "column-defs": ne,
1278
- "row-data": m.value,
1279
- "row-key": (A) => A._id,
1280
- loading: _.value,
1281
- "hide-footer": !0,
1282
- "empty-text": "No production batches yet. Start a new production prepare to add stock.",
1283
- onRowClick: v[0] || (v[0] = (A) => j(A.original))
1284
- }, null, 8, ["row-data", "row-key", "loading"])
1285
- ]),
1286
- V(K, {
1287
- "dismiss-away": "",
1288
- "max-width": 9999,
1289
- "model-value": M.value,
1290
- "onUpdate:modelValue": v[1] || (v[1] = (A) => M.value = A),
1291
- header: "New production prepare"
1292
- }, {
1293
- default: X(() => [
1294
- e("div", Co, [
1295
- M.value ? (l(), J($t, {
1296
- key: 0,
1297
- onCreated: g
1298
- })) : R("", !0)
1299
- ])
1300
- ]),
1301
- _: 1
1302
- }, 8, ["model-value"]),
1303
- V(K, {
1304
- "dismiss-away": "",
1305
- "max-width": 9999,
1306
- "model-value": p.value,
1307
- "onUpdate:modelValue": v[3] || (v[3] = (A) => p.value = A),
1308
- header: f.value ? Q(f.value) : "Production batch"
1309
- }, {
1310
- default: X(() => [
1311
- p.value && f.value ? (l(), J($o, {
1312
- key: 0,
1313
- batch: f.value,
1314
- onRequest: Z,
1315
- onComplete: ee,
1316
- onCancel: oe,
1317
- onClose: v[2] || (v[2] = (A) => p.value = !1)
1318
- }, null, 8, ["batch"])) : R("", !0)
1319
- ]),
1320
- _: 1
1321
- }, 8, ["model-value", "header"])
1322
- ]),
1323
- _: 1
1324
- });
1325
- };
1326
- }
1327
- });
1328
- export {
1329
- jo as default
1330
- };