@argusoft/medplat-product-management 1.0.2 → 1.0.4

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 (83) hide show
  1. package/dist/{BrandsPage-CSA3meke.js → BrandsPage-BE3kn-8b.js} +77 -75
  2. package/dist/BrandsPage-BE3kn-8b.js.map +1 -0
  3. package/dist/{CategoriesPage-BrspzkJL.js → CategoriesPage-COqi3pMi.js} +71 -70
  4. package/dist/{CategoriesPage-BrspzkJL.js.map → CategoriesPage-COqi3pMi.js.map} +1 -1
  5. package/dist/{DashboardPage-CqaquOs2.js → DashboardPage-C_H1Jrey.js} +90 -89
  6. package/dist/DashboardPage-C_H1Jrey.js.map +1 -0
  7. package/dist/{FacilityPicker-Dv_H95WW.js → FacilityPicker-Diq2hnYg.js} +2 -2
  8. package/dist/{FacilityPicker-Dv_H95WW.js.map → FacilityPicker-Diq2hnYg.js.map} +1 -1
  9. package/dist/{InventoryPage-CPbzfDMR.js → InventoryPage-Bjpw6vTz.js} +106 -115
  10. package/dist/InventoryPage-Bjpw6vTz.js.map +1 -0
  11. package/dist/{MemberProfileCard-0vjO3Gzd.js → MemberProfileCard-BLUVRILO.js} +10 -9
  12. package/dist/MemberProfileCard-BLUVRILO.js.map +1 -0
  13. package/dist/{PaymentCreatePage-BYmDZAIB.js → PaymentCreatePage-B5VOgTx9.js} +173 -177
  14. package/dist/PaymentCreatePage-B5VOgTx9.js.map +1 -0
  15. package/dist/{PaymentsPage-BXPvKon-.js → PaymentsPage-DY6BclkN.js} +24 -23
  16. package/dist/{PaymentsPage-BXPvKon-.js.map → PaymentsPage-DY6BclkN.js.map} +1 -1
  17. package/dist/PickupCreatePage-CCSiyFQF.js +706 -0
  18. package/dist/PickupCreatePage-CCSiyFQF.js.map +1 -0
  19. package/dist/{PickupsPage-D66_Wta4.js → PickupsPage-DGi6T5Of.js} +83 -90
  20. package/dist/PickupsPage-DGi6T5Of.js.map +1 -0
  21. package/dist/PmGuard-C90yhpsN.js +592 -0
  22. package/dist/PmGuard-C90yhpsN.js.map +1 -0
  23. package/dist/{PmTable-B9970kPY.js → PmTable-BkK65bJQ.js} +98 -98
  24. package/dist/PmTable-BkK65bJQ.js.map +1 -0
  25. package/dist/{ProductEditPage-B8qFTCW9.js → ProductEditPage-CQj9egzW.js} +138 -137
  26. package/dist/ProductEditPage-CQj9egzW.js.map +1 -0
  27. package/dist/{ProductsPage-C7_r9cKn.js → ProductsPage-i8QVw_Jm.js} +65 -64
  28. package/dist/{ProductsPage-C7_r9cKn.js.map → ProductsPage-i8QVw_Jm.js.map} +1 -1
  29. package/dist/PurchaseCreatePage-Bp6bl9n8.js +591 -0
  30. package/dist/PurchaseCreatePage-Bp6bl9n8.js.map +1 -0
  31. package/dist/{PurchaseRequestDetailPage-C7aAwEqw.js → PurchaseRequestDetailPage-CNAqIFef.js} +216 -215
  32. package/dist/PurchaseRequestDetailPage-CNAqIFef.js.map +1 -0
  33. package/dist/{PurchaseRequestsPage-BwCkbpaX.js → PurchaseRequestsPage-BJqDlNrc.js} +57 -56
  34. package/dist/{PurchaseRequestsPage-BwCkbpaX.js.map → PurchaseRequestsPage-BJqDlNrc.js.map} +1 -1
  35. package/dist/{PurchasesPage-CvaZouVy.js → PurchasesPage-BQEToymQ.js} +76 -75
  36. package/dist/{PurchasesPage-CvaZouVy.js.map → PurchasesPage-BQEToymQ.js.map} +1 -1
  37. package/dist/{SaleCreatePage-DP1Qmltu.js → SaleCreatePage-DbfBK4PH.js} +149 -173
  38. package/dist/SaleCreatePage-DbfBK4PH.js.map +1 -0
  39. package/dist/{SalesPage-CO3cdYX5.js → SalesPage-CTBJMxZe.js} +50 -49
  40. package/dist/SalesPage-CTBJMxZe.js.map +1 -0
  41. package/dist/SettingsPage-CiwVmzM3.js +663 -0
  42. package/dist/SettingsPage-CiwVmzM3.js.map +1 -0
  43. package/dist/{StorageUnitsPage-B9Hr_RkW.js → StorageUnitsPage-BV7nK_iE.js} +57 -56
  44. package/dist/{StorageUnitsPage-B9Hr_RkW.js.map → StorageUnitsPage-BV7nK_iE.js.map} +1 -1
  45. package/dist/{TransactionsPage-HKIGwEZN.js → TransactionsPage-Cocn4901.js} +55 -54
  46. package/dist/TransactionsPage-Cocn4901.js.map +1 -0
  47. package/dist/TransferCreatePage-DbjcjuOg.js +316 -0
  48. package/dist/TransferCreatePage-DbjcjuOg.js.map +1 -0
  49. package/dist/TransfersPage-BFVF7Xvc.js +471 -0
  50. package/dist/TransfersPage-BFVF7Xvc.js.map +1 -0
  51. package/dist/VialsPage-BNzYTLVd.js +321 -0
  52. package/dist/VialsPage-BNzYTLVd.js.map +1 -0
  53. package/dist/index.js +652 -34
  54. package/dist/index.js.map +1 -1
  55. package/dist/settingsStore-KW217unV.js +417 -0
  56. package/dist/settingsStore-KW217unV.js.map +1 -0
  57. package/package.json +1 -1
  58. package/dist/BrandsPage-CSA3meke.js.map +0 -1
  59. package/dist/DashboardPage-CqaquOs2.js.map +0 -1
  60. package/dist/InventoryPage-CPbzfDMR.js.map +0 -1
  61. package/dist/MemberProfileCard-0vjO3Gzd.js.map +0 -1
  62. package/dist/PaymentCreatePage-BYmDZAIB.js.map +0 -1
  63. package/dist/PickupCreatePage-CMGwoAXj.js +0 -426
  64. package/dist/PickupCreatePage-CMGwoAXj.js.map +0 -1
  65. package/dist/PickupsPage-D66_Wta4.js.map +0 -1
  66. package/dist/PmTable-B9970kPY.js.map +0 -1
  67. package/dist/ProductEditPage-B8qFTCW9.js.map +0 -1
  68. package/dist/PurchaseCreatePage-CDfNDcKG.js +0 -627
  69. package/dist/PurchaseCreatePage-CDfNDcKG.js.map +0 -1
  70. package/dist/PurchaseRequestDetailPage-C7aAwEqw.js.map +0 -1
  71. package/dist/SaleCreatePage-DP1Qmltu.js.map +0 -1
  72. package/dist/SalesPage-CO3cdYX5.js.map +0 -1
  73. package/dist/SettingsPage-DvVRwSFw.js +0 -711
  74. package/dist/SettingsPage-DvVRwSFw.js.map +0 -1
  75. package/dist/TransactionsPage-HKIGwEZN.js.map +0 -1
  76. package/dist/TransferCreatePage-DMuZqQ3c.js +0 -363
  77. package/dist/TransferCreatePage-DMuZqQ3c.js.map +0 -1
  78. package/dist/TransfersPage-COIyouL4.js +0 -480
  79. package/dist/TransfersPage-COIyouL4.js.map +0 -1
  80. package/dist/VialsPage-BNPUwGCU.js +0 -922
  81. package/dist/VialsPage-BNPUwGCU.js.map +0 -1
  82. package/dist/currency-ClRLIEg2.js +0 -1372
  83. package/dist/currency-ClRLIEg2.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,45 +1,663 @@
1
- import { lazy as e } from "react";
2
- import { jsx as t } from "react/jsx-runtime";
1
+ import { E as e, H as t, O as n, S as r, k as i, r as a } from "./settingsStore-KW217unV.js";
2
+ import { o } from "./PmTable-BkK65bJQ.js";
3
+ import "./constants-5ZCZo-Zm.js";
4
+ import { n as s, r as c, t as l } from "./format-UOyOu75i.js";
5
+ import { m as u, t as d, u as f } from "./validation-Ba7puFIO.js";
6
+ import { t as p } from "./useFieldErrors-hDG8ox_x.js";
7
+ import { lazy as m, useEffect as h, useMemo as g, useState as _ } from "react";
8
+ import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
9
+ import x from "prop-types";
10
+ import { Alert as S, Box as ee, Button as C, Chip as w, Dialog as te, DialogActions as ne, DialogContent as re, DialogTitle as ie, LinearProgress as ae, Radio as oe, Stack as T, Table as E, TableBody as D, TableCell as O, TableContainer as se, TableHead as ce, TableRow as k, TextField as le, Typography as A } from "@mui/material";
11
+ import ue from "@mui/icons-material/VaccinesRounded";
12
+ import { showToast as de } from "@/common/toaster/toaster";
3
13
  //#region routes/routes.jsx
4
- var n = e(() => import("@/views/feature-components/VerifyRoute.jsx")), r = e(() => import("./DashboardPage-CqaquOs2.js")), i = e(() => import("./CategoriesPage-BrspzkJL.js")), a = e(() => import("./BrandsPage-CSA3meke.js")), o = e(() => import("./ProductsPage-C7_r9cKn.js")), s = e(() => import("./ProductEditPage-B8qFTCW9.js")), c = e(() => import("./StorageUnitsPage-B9Hr_RkW.js")), l = e(() => import("./InventoryPage-CPbzfDMR.js")), u = e(() => import("./PurchasesPage-CvaZouVy.js")), d = e(() => import("./PurchaseCreatePage-CDfNDcKG.js")), f = e(() => import("./PurchaseRequestsPage-BwCkbpaX.js")), p = e(() => import("./PurchaseRequestDetailPage-C7aAwEqw.js")), m = e(() => import("./PickupsPage-D66_Wta4.js")), h = e(() => import("./PickupCreatePage-CMGwoAXj.js")), g = e(() => import("./TransfersPage-COIyouL4.js")), _ = e(() => import("./TransferCreatePage-DMuZqQ3c.js")), v = e(() => import("./SalesPage-CO3cdYX5.js")), y = e(() => import("./SaleCreatePage-DP1Qmltu.js")), b = e(() => import("./PaymentsPage-BXPvKon-.js")), x = e(() => import("./PaymentCreatePage-BYmDZAIB.js")), S = e(() => import("./VialsPage-BNPUwGCU.js")), C = e(() => import("./TransactionsPage-HKIGwEZN.js")), w = e(() => import("./SettingsPage-DvVRwSFw.js")), T = "Product Management";
5
- function E(e, r, i = "General") {
14
+ var fe = m(() => import("@/views/feature-components/VerifyRoute.jsx")), j = m(() => import("./DashboardPage-C_H1Jrey.js")), M = m(() => import("./CategoriesPage-COqi3pMi.js")), N = m(() => import("./BrandsPage-BE3kn-8b.js")), P = m(() => import("./ProductsPage-i8QVw_Jm.js")), pe = m(() => import("./ProductEditPage-CQj9egzW.js")), F = m(() => import("./StorageUnitsPage-BV7nK_iE.js")), I = m(() => import("./InventoryPage-Bjpw6vTz.js")), L = m(() => import("./PurchasesPage-BQEToymQ.js")), R = m(() => import("./PurchaseCreatePage-Bp6bl9n8.js")), z = m(() => import("./PurchaseRequestsPage-BJqDlNrc.js")), me = m(() => import("./PurchaseRequestDetailPage-CNAqIFef.js")), he = m(() => import("./PickupsPage-DGi6T5Of.js")), B = m(() => import("./PickupCreatePage-CCSiyFQF.js")), V = m(() => import("./TransfersPage-BFVF7Xvc.js")), ge = m(() => import("./TransferCreatePage-DbjcjuOg.js")), H = m(() => import("./SalesPage-CTBJMxZe.js")), U = m(() => import("./SaleCreatePage-DbfBK4PH.js")), W = m(() => import("./PaymentsPage-DY6BclkN.js")), G = m(() => import("./PaymentCreatePage-B5VOgTx9.js")), _e = m(() => import("./VialsPage-BNzYTLVd.js")), K = m(() => import("./TransactionsPage-Cocn4901.js")), q = m(() => import("./SettingsPage-CiwVmzM3.js")), J = "Product Management";
15
+ function Y(e, t, n = "General") {
6
16
  return {
7
17
  path: e,
8
- element: /* @__PURE__ */ t(n, {
9
- headerTitle: T,
10
- pageTitle: i,
18
+ element: /* @__PURE__ */ y(fe, {
19
+ headerTitle: J,
20
+ pageTitle: n,
11
21
  url: "medplat/manage/pm",
12
- component: r
22
+ component: t
13
23
  })
14
24
  };
15
25
  }
16
- var D = [
17
- E("medplat/manage/pm", r, "Dashboard"),
18
- E("medplat/manage/pm/categories", i, "Categories"),
19
- E("medplat/manage/pm/brands", a, "Brands"),
20
- E("medplat/manage/pm/products", o, "Products"),
21
- E("medplat/manage/pm/products/:productId", s, "Product"),
22
- E("medplat/manage/pm/storage-units", c, "Storage Units"),
23
- E("medplat/manage/pm/inventory", l, "Inventory"),
24
- E("medplat/manage/pm/purchases", u, "Purchases"),
25
- E("medplat/manage/pm/purchases/new", d, "New Purchase"),
26
- E("medplat/manage/pm/purchase-requests", f, "Purchase Requests"),
27
- E("medplat/manage/pm/purchase-requests/:requestId", p, "Purchase Request"),
28
- E("medplat/manage/pm/pickups", m, "Pickups"),
29
- E("medplat/manage/pm/pickups/new", h, "New Pickup"),
30
- E("medplat/manage/pm/transfers", g, "Transfers"),
31
- E("medplat/manage/pm/transfers/new", _, "New Transfer"),
32
- E("medplat/manage/pm/sales", v, "Sales"),
33
- E("medplat/manage/pm/sales/new", y, "New Sale"),
34
- E("medplat/manage/pm/sales/new/:memberId", y, "New Sale"),
35
- E("medplat/manage/pm/payments", b, "Payments"),
36
- E("medplat/manage/pm/payments/new", x, "Collect Payment"),
37
- E("medplat/manage/pm/payments/new/:memberId", x, "Collect Payment"),
38
- E("medplat/manage/pm/vials", S, "Open Vials"),
39
- E("medplat/manage/pm/transactions", C, "Stock Ledger"),
40
- E("medplat/manage/pm/settings", w, "Settings")
26
+ var X = [
27
+ Y("medplat/manage/pm", j, "Dashboard"),
28
+ Y("medplat/manage/pm/categories", M, "Categories"),
29
+ Y("medplat/manage/pm/brands", N, "Brands"),
30
+ Y("medplat/manage/pm/products", P, "Products"),
31
+ Y("medplat/manage/pm/products/:productId", pe, "Product"),
32
+ Y("medplat/manage/pm/storage-units", F, "Storage Units"),
33
+ Y("medplat/manage/pm/inventory", I, "Inventory"),
34
+ Y("medplat/manage/pm/purchases", L, "Purchases"),
35
+ Y("medplat/manage/pm/purchases/new", R, "New Purchase"),
36
+ Y("medplat/manage/pm/purchase-requests", z, "Purchase Requests"),
37
+ Y("medplat/manage/pm/purchase-requests/:requestId", me, "Purchase Request"),
38
+ Y("medplat/manage/pm/pickups", he, "Pickups"),
39
+ Y("medplat/manage/pm/pickups/new", B, "New Pickup"),
40
+ Y("medplat/manage/pm/transfers", V, "Transfers"),
41
+ Y("medplat/manage/pm/transfers/new", ge, "New Transfer"),
42
+ Y("medplat/manage/pm/sales", H, "Sales"),
43
+ Y("medplat/manage/pm/sales/new", U, "New Sale"),
44
+ Y("medplat/manage/pm/sales/new/:memberId", U, "New Sale"),
45
+ Y("medplat/manage/pm/payments", W, "Payments"),
46
+ Y("medplat/manage/pm/payments/new", G, "Collect Payment"),
47
+ Y("medplat/manage/pm/payments/new/:memberId", G, "Collect Payment"),
48
+ Y("medplat/manage/pm/vials", _e, "Open Vials"),
49
+ Y("medplat/manage/pm/transactions", K, "Stock Ledger"),
50
+ Y("medplat/manage/pm/settings", q, "Settings")
41
51
  ];
42
52
  //#endregion
43
- export { D as routes };
53
+ //#region src/components/ProductAdministrationDialog.jsx
54
+ function Z(e) {
55
+ let t = e.expiresAt ? new Date(e.expiresAt).getTime() : Infinity, n = Infinity;
56
+ if (e.batchExpiryDate) {
57
+ let t = new Date(e.batchExpiryDate);
58
+ t.setHours(23, 59, 59, 999), n = t.getTime();
59
+ }
60
+ return Math.min(t, n);
61
+ }
62
+ function Q(e) {
63
+ return e.expiryDate ? new Date(e.expiryDate).getTime() : Infinity;
64
+ }
65
+ var ve = {
66
+ step: "product",
67
+ mode: "use-existing",
68
+ productId: "",
69
+ ownerType: "",
70
+ ownerId: "",
71
+ personalSource: "",
72
+ allVials: [],
73
+ allBatches: [],
74
+ sources: [],
75
+ vialCandidates: [],
76
+ batchCandidates: [],
77
+ selectedVialId: "",
78
+ selectedBatchId: "",
79
+ volumeMl: "",
80
+ loading: !1
81
+ };
82
+ function $({ open: m, preselectedProductId: x, onConfirm: fe, onCancel: j }) {
83
+ let [M, N] = _(ve), [P, pe] = _([]), [F, I] = _([]), [L, R] = _([]), [z, me] = _([]), [he, B] = _(!1), V = p(), ge = a()?.allowPersonalPurchase !== !1;
84
+ h(() => {
85
+ if (m) {
86
+ V.reset(), N({
87
+ ...ve,
88
+ productId: x || ""
89
+ });
90
+ async function t() {
91
+ B(!0);
92
+ try {
93
+ let [t, a, o, s] = await Promise.all([
94
+ r(),
95
+ e(),
96
+ n().catch(() => []),
97
+ i().catch(() => [])
98
+ ]);
99
+ pe(t), I(a), R(o), me(s);
100
+ } catch (e) {
101
+ de({
102
+ message: e?.message || "Failed to load metadata",
103
+ type: "error"
104
+ });
105
+ } finally {
106
+ B(!1);
107
+ }
108
+ }
109
+ t();
110
+ }
111
+ }, [m, x]), h(() => {
112
+ m && x && N((e) => ({
113
+ ...e,
114
+ productId: x
115
+ }));
116
+ }, [m, x]);
117
+ let H = g(() => {
118
+ let e = P.filter((e) => e.categoryCode === "VACCINES" && e.isActive).sort((e, t) => e.name.localeCompare(t.name));
119
+ return x ? e.filter((e) => e.id === x) : e;
120
+ }, [P, x]);
121
+ function U(e, t = F) {
122
+ let n = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0);
123
+ return t.filter((t) => t.productId === e && t.qtyRemaining > 0 && !t.isQuarantined && (!t.expiryDate || new Date(t.expiryDate).getTime() >= n)).sort((e, t) => Q(e) - Q(t));
124
+ }
125
+ function W(e, t, n, r, i) {
126
+ if (!n) return {
127
+ vials: [],
128
+ batches: []
129
+ };
130
+ let a = n === "USER" && i ? i === "OUTREACH" ? "PICKUP" : "PURCHASE" : null;
131
+ return {
132
+ vials: e.filter((e) => e.ownerType === n && (n === "USER" ? !a || e.batchSourceType === a : e.ownerId === r)),
133
+ batches: t.filter((e) => e.ownerType === n && (n === "USER" ? !a || e.sourceType === a : e.ownerId === r))
134
+ };
135
+ }
136
+ async function G() {
137
+ if (!M.productId) {
138
+ V.markAllTouched();
139
+ return;
140
+ }
141
+ N((e) => ({
142
+ ...e,
143
+ loading: !0
144
+ }));
145
+ try {
146
+ let [r, i, a] = await Promise.all([
147
+ t(M.productId),
148
+ e().catch(() => F),
149
+ n().catch(() => L)
150
+ ]);
151
+ I(i), R(a);
152
+ let o = Date.now(), s = r.filter((e) => e.status === "OPEN" && !e.expired && Z(e) > o && Number(e.volumeRemainingMl) > 0).sort((e, t) => Z(e) - Z(t)), c = r.reduce((e, t) => (t.status === "OPEN" && (e[t.batchId] = (e[t.batchId] || 0) + 1), e), {}), l = P.find((e) => e.id === M.productId)?.vaccineConfig, u = l?.maxConcurrentOpenVials ?? 2, d = U(M.productId, i).filter((e) => (c[e.id] || 0) < u), f = /* @__PURE__ */ new Set(), p = [];
153
+ function m(e, t, n, r = "") {
154
+ let i = `${e}::${t ?? ""}::${r ?? ""}`;
155
+ f.has(i) || (f.add(i), p.push({
156
+ key: i,
157
+ ownerType: e,
158
+ ownerId: t ?? null,
159
+ personalSource: r || null,
160
+ label: n
161
+ }));
162
+ }
163
+ (s.some((e) => e.ownerType === "USER" && e.batchSourceType === "PICKUP") || d.some((e) => e.ownerType === "USER" && e.sourceType === "PICKUP")) && m("USER", null, "Personal (Outreach)", "OUTREACH");
164
+ let h = s.some((e) => e.ownerType === "USER" && e.batchSourceType === "PURCHASE") || d.some((e) => e.ownerType === "USER" && e.sourceType === "PURCHASE");
165
+ ge && h && m("USER", null, "Personal (Purchase)", "PURCHASE");
166
+ let g = /* @__PURE__ */ new Set();
167
+ s.forEach((e) => {
168
+ e.ownerType === "FACILITY" && e.ownerId && g.add(e.ownerId);
169
+ }), d.forEach((e) => {
170
+ e.ownerType === "FACILITY" && e.ownerId && g.add(e.ownerId);
171
+ }), g.forEach((e) => {
172
+ m("FACILITY", e, `Facility — ${a.find((t) => t.id === e)?.name ?? e}`);
173
+ });
174
+ let _ = p.length === 1 ? p[0] : null, v = _?.ownerType ?? "", y = _?.ownerId ?? "", b = _?.personalSource ?? "", x = W(s, d, v, y, b), S = x.vials.length > 0 ? "use-existing" : "open-new";
175
+ N((e) => ({
176
+ ...e,
177
+ loading: !1,
178
+ step: "select",
179
+ mode: S,
180
+ ownerType: v,
181
+ ownerId: y,
182
+ personalSource: b,
183
+ allVials: s,
184
+ allBatches: d,
185
+ sources: p,
186
+ vialCandidates: x.vials,
187
+ batchCandidates: x.batches,
188
+ selectedVialId: x.vials[0]?.id ?? "",
189
+ selectedBatchId: x.batches[0]?.id ?? "",
190
+ volumeMl: S === "use-existing" ? x.vials[0]?.adultDoseMl ?? l?.adultDoseMl ?? "" : l?.adultDoseMl ?? ""
191
+ }));
192
+ } catch (e) {
193
+ N((e) => ({
194
+ ...e,
195
+ loading: !1
196
+ })), de({
197
+ message: e?.message ?? "Failed to load vials",
198
+ type: "error"
199
+ });
200
+ }
201
+ }
202
+ function _e(e) {
203
+ let t = M.sources.find((t) => t.key === e);
204
+ if (!t) return;
205
+ let n = W(M.allVials, M.allBatches, t.ownerType, t.ownerId, t.personalSource), r = P.find((e) => e.id === M.productId)?.vaccineConfig, i = n.vials.length > 0 ? "use-existing" : "open-new";
206
+ N((e) => ({
207
+ ...e,
208
+ ownerType: t.ownerType,
209
+ ownerId: t.ownerId ?? "",
210
+ personalSource: t.personalSource ?? "",
211
+ mode: i,
212
+ vialCandidates: n.vials,
213
+ batchCandidates: n.batches,
214
+ selectedVialId: n.vials[0]?.id ?? "",
215
+ selectedBatchId: n.batches[0]?.id ?? "",
216
+ volumeMl: i === "use-existing" ? n.vials[0]?.adultDoseMl ?? r?.adultDoseMl ?? "" : r?.adultDoseMl ?? ""
217
+ }));
218
+ }
219
+ function K(e) {
220
+ N((t) => ({
221
+ ...t,
222
+ mode: e
223
+ }));
224
+ }
225
+ let q = M.vialCandidates.find((e) => e.id === M.selectedVialId), J = M.batchCandidates.find((e) => e.id === M.selectedBatchId), Y = P.find((e) => e.id === M.productId)?.vaccineConfig, X = (() => {
226
+ if (M.step === "product") return { productId: u(M.productId, "Vaccine") };
227
+ let e = {
228
+ ownerType: u(M.ownerType, "Source"),
229
+ volumeMl: f(M.volumeMl, "Volume", { required: !0 })
230
+ };
231
+ if (M.mode === "use-existing") {
232
+ if (e.selectedVialId = u(M.selectedVialId, "Vial"), !e.volumeMl && q) {
233
+ let t = Number(M.volumeMl), n = Number(q.volumeRemainingMl);
234
+ t > n && (e.volumeMl = M.batchCandidates.length > 0 ? `Only ${n.toFixed(2)} ml remaining in this vial — open another vial instead.` : `Only ${n.toFixed(2)} ml remaining in this vial.`);
235
+ }
236
+ } else if (e.selectedBatchId = u(M.selectedBatchId, "Batch"), !e.volumeMl && Y?.vialVolumeMl) {
237
+ let t = Number(M.volumeMl), n = Number(Y.vialVolumeMl);
238
+ t > n && (e.volumeMl = `A fresh vial holds ${n.toFixed(2)} ml`);
239
+ }
240
+ return e;
241
+ })(), $ = d(X);
242
+ function ye() {
243
+ if (!$) {
244
+ V.markAllTouched();
245
+ return;
246
+ }
247
+ let e = {
248
+ productId: M.productId,
249
+ ownerType: M.ownerType,
250
+ ownerId: M.ownerType === "FACILITY" && M.ownerId || null,
251
+ personalSource: M.ownerType === "USER" && M.personalSource || null,
252
+ volumeMl: Number(M.volumeMl)
253
+ };
254
+ M.mode === "use-existing" ? (e.openVialId = q.id, e.batchId = q.batchId) : (e.batchId = J.id, e.openVialId = null), fe(e);
255
+ }
256
+ function be() {
257
+ N((e) => ({
258
+ ...e,
259
+ step: "product",
260
+ vialCandidates: [],
261
+ batchCandidates: [],
262
+ sources: []
263
+ }));
264
+ }
265
+ return /* @__PURE__ */ b(te, {
266
+ open: m,
267
+ onClose: j,
268
+ fullWidth: !0,
269
+ maxWidth: "md",
270
+ children: [
271
+ /* @__PURE__ */ y(ie, { children: M.step === "product" ? "Administer Vaccine — Select Vaccine" : M.mode === "use-existing" ? "Administer Vaccine — Select Open Vial" : "Administer Vaccine — Open & Administer" }),
272
+ /* @__PURE__ */ b(re, {
273
+ dividers: !0,
274
+ children: [he ? /* @__PURE__ */ y(ae, {}) : null, M.step === "product" ? /* @__PURE__ */ b(ee, {
275
+ sx: { mt: 1 },
276
+ children: [x && H.length === 0 ? /* @__PURE__ */ y(S, {
277
+ severity: "error",
278
+ sx: { mb: 2 },
279
+ children: "No PM product is linked to this vaccine. Administration cannot proceed."
280
+ }) : null, /* @__PURE__ */ y(o, {
281
+ label: "Vaccine",
282
+ required: !0,
283
+ value: M.productId,
284
+ onChange: (e) => N({
285
+ ...M,
286
+ productId: e
287
+ }),
288
+ onBlur: V.onBlur("productId"),
289
+ error: V.show("productId") && !!X.productId,
290
+ options: H.map((e) => ({
291
+ value: e.id,
292
+ label: `${e.name}${e.vaccineConfig?.vaccineCode ? ` · ${e.vaccineConfig.vaccineCode}` : ""}`
293
+ })),
294
+ noOptionsText: "No active vaccine products",
295
+ helperText: V.show("productId") && X.productId ? X.productId : "Open vials for this vaccine will be shown next. If none are open, a fresh vial can be opened on the same screen."
296
+ })]
297
+ }) : /* @__PURE__ */ b(T, {
298
+ spacing: 2,
299
+ sx: { pt: 1 },
300
+ children: [
301
+ M.loading ? /* @__PURE__ */ y(ae, {}) : null,
302
+ M.sources.length === 0 ? /* @__PURE__ */ y(S, {
303
+ severity: "warning",
304
+ children: "No stock available for this vaccine — neither in your personal stock nor at an assigned facility."
305
+ }) : M.sources.length > 1 ? /* @__PURE__ */ y(o, {
306
+ label: "Administer from",
307
+ required: !0,
308
+ value: M.ownerType ? `${M.ownerType}::${M.ownerId ?? ""}::${M.personalSource ?? ""}` : "",
309
+ onChange: (e) => _e(e),
310
+ onBlur: V.onBlur("ownerType"),
311
+ error: V.show("ownerType") && !!X.ownerType,
312
+ options: M.sources.map((e) => ({
313
+ value: e.key,
314
+ label: e.label
315
+ })),
316
+ helperText: V.show("ownerType") && X.ownerType ? X.ownerType : "Personal (outreach), personal (purchase) and facility stock are separate vial pools — pick which one this dose comes from."
317
+ }) : /* @__PURE__ */ b(S, {
318
+ severity: "info",
319
+ children: [
320
+ "Administering from",
321
+ " ",
322
+ /* @__PURE__ */ y("strong", { children: M.sources[0]?.label }),
323
+ "."
324
+ ]
325
+ }),
326
+ M.ownerType === "USER" && M.personalSource === "OUTREACH" && z[0] ? /* @__PURE__ */ b(ee, {
327
+ sx: {
328
+ p: 1.5,
329
+ borderRadius: 2,
330
+ border: "1px solid",
331
+ borderColor: "divider",
332
+ bgcolor: (e) => e.palette.action.hover
333
+ },
334
+ children: [
335
+ /* @__PURE__ */ y(A, {
336
+ variant: "overline",
337
+ sx: {
338
+ fontWeight: 800,
339
+ letterSpacing: .6,
340
+ color: "text.secondary"
341
+ },
342
+ children: "Outreach session"
343
+ }),
344
+ /* @__PURE__ */ y(A, {
345
+ variant: "body2",
346
+ sx: { fontWeight: 800 },
347
+ children: z[0].sessionName || "—"
348
+ }),
349
+ z[0].sessionSite ? /* @__PURE__ */ b(A, {
350
+ variant: "caption",
351
+ color: "text.secondary",
352
+ sx: { display: "block" },
353
+ children: ["Site: ", z[0].sessionSite]
354
+ }) : null,
355
+ /* @__PURE__ */ b(A, {
356
+ variant: "caption",
357
+ color: "text.secondary",
358
+ sx: { display: "block" },
359
+ children: [z[0].sessionStartTime ? s(z[0].sessionStartTime) : "—", z[0].sessionExpectedEndTime ? ` → ${s(z[0].sessionExpectedEndTime)}` : ""]
360
+ }),
361
+ z[0].sessionDescription ? /* @__PURE__ */ y(A, {
362
+ variant: "caption",
363
+ color: "text.secondary",
364
+ sx: {
365
+ display: "block",
366
+ mt: .5,
367
+ whiteSpace: "pre-wrap"
368
+ },
369
+ children: z[0].sessionDescription
370
+ }) : null
371
+ ]
372
+ }) : null,
373
+ M.mode === "use-existing" ? /* @__PURE__ */ b(v, { children: [M.ownerType ? (() => {
374
+ let e = Number(M.volumeMl), t = !Number.isNaN(e) && e > 0 && M.vialCandidates.some((t) => Number(t.volumeRemainingMl) >= e);
375
+ return /* @__PURE__ */ y(S, {
376
+ severity: "info",
377
+ action: t ? null : /* @__PURE__ */ y(C, {
378
+ color: "inherit",
379
+ size: "small",
380
+ onClick: () => K("open-new"),
381
+ children: "Open another vial instead"
382
+ }),
383
+ children: t ? "Pick an open vial — earliest-expiry-first is preselected. An existing vial can hold the requested dose, so no new vial is needed." : "Pick an open vial — earliest-expiry-first is preselected. The requested dose does not fit in any open vial; you can open another vial from stock."
384
+ });
385
+ })() : /* @__PURE__ */ y(S, {
386
+ severity: "info",
387
+ children: "Pick an administration source above to see the available open vials."
388
+ }), /* @__PURE__ */ y(se, { children: /* @__PURE__ */ b(E, {
389
+ size: "small",
390
+ children: [/* @__PURE__ */ y(ce, { children: /* @__PURE__ */ b(k, { children: [
391
+ /* @__PURE__ */ y(O, {}),
392
+ /* @__PURE__ */ y(O, {
393
+ sx: { fontWeight: 800 },
394
+ children: "Lot"
395
+ }),
396
+ /* @__PURE__ */ y(O, {
397
+ sx: { fontWeight: 800 },
398
+ children: "Vial expires"
399
+ }),
400
+ /* @__PURE__ */ y(O, {
401
+ sx: { fontWeight: 800 },
402
+ children: "Batch expires"
403
+ }),
404
+ /* @__PURE__ */ y(O, {
405
+ sx: { fontWeight: 800 },
406
+ align: "right",
407
+ children: "Remaining (ml)"
408
+ })
409
+ ] }) }), /* @__PURE__ */ y(D, { children: M.vialCandidates.length === 0 ? /* @__PURE__ */ y(k, { children: /* @__PURE__ */ y(O, {
410
+ colSpan: 5,
411
+ sx: {
412
+ py: 4,
413
+ textAlign: "center"
414
+ },
415
+ children: /* @__PURE__ */ b(T, {
416
+ alignItems: "center",
417
+ spacing: 1,
418
+ children: [
419
+ /* @__PURE__ */ y(ue, { sx: {
420
+ fontSize: 36,
421
+ color: "text.disabled",
422
+ opacity: .7
423
+ } }),
424
+ /* @__PURE__ */ y(A, {
425
+ variant: "body2",
426
+ sx: { fontWeight: 700 },
427
+ children: "No usable open vials for this vaccine"
428
+ }),
429
+ M.batchCandidates.length > 0 ? /* @__PURE__ */ y(C, {
430
+ size: "small",
431
+ variant: "outlined",
432
+ onClick: () => K("open-new"),
433
+ children: "Open a new vial instead"
434
+ }) : /* @__PURE__ */ y(A, {
435
+ variant: "caption",
436
+ color: "text.secondary",
437
+ children: "No stock available either — receive a purchase first."
438
+ })
439
+ ]
440
+ })
441
+ }) }) : M.vialCandidates.map((e, t) => {
442
+ let n = M.selectedVialId === e.id;
443
+ return /* @__PURE__ */ b(k, {
444
+ hover: !0,
445
+ selected: n,
446
+ onClick: () => N({
447
+ ...M,
448
+ selectedVialId: e.id,
449
+ volumeMl: e.adultDoseMl ?? M.volumeMl
450
+ }),
451
+ sx: { cursor: "pointer" },
452
+ children: [
453
+ /* @__PURE__ */ y(O, {
454
+ padding: "checkbox",
455
+ children: /* @__PURE__ */ y(oe, { checked: n })
456
+ }),
457
+ /* @__PURE__ */ b(O, {
458
+ sx: { fontFamily: "monospace" },
459
+ children: [e.lotNumber || "—", t === 0 ? /* @__PURE__ */ y(w, {
460
+ size: "small",
461
+ color: "primary",
462
+ label: "Use first",
463
+ sx: { ml: 1 }
464
+ }) : null]
465
+ }),
466
+ /* @__PURE__ */ y(O, { children: s(e.expiresAt) }),
467
+ /* @__PURE__ */ y(O, { children: e.batchExpiryDate ? l(e.batchExpiryDate) : "—" }),
468
+ /* @__PURE__ */ b(O, {
469
+ align: "right",
470
+ sx: { fontWeight: 700 },
471
+ children: [
472
+ c(e.volumeRemainingMl),
473
+ " /",
474
+ " ",
475
+ c(e.volumeTotalMl)
476
+ ]
477
+ })
478
+ ]
479
+ }, e.id);
480
+ }) })]
481
+ }) })] }) : /* @__PURE__ */ y(v, { children: M.ownerType ? M.batchCandidates.length === 0 ? /* @__PURE__ */ y(S, {
482
+ severity: "error",
483
+ action: M.vialCandidates.length > 0 ? /* @__PURE__ */ y(C, {
484
+ color: "inherit",
485
+ size: "small",
486
+ onClick: () => K("use-existing"),
487
+ children: "Use an open vial"
488
+ }) : null,
489
+ children: "No batches available — every batch is either out of stock, expired, or already at the maximum concurrent open vials. Receive a purchase or finish the open vials first."
490
+ }) : /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y(S, {
491
+ severity: "warning",
492
+ action: M.vialCandidates.length > 0 ? /* @__PURE__ */ y(C, {
493
+ color: "inherit",
494
+ size: "small",
495
+ onClick: () => K("use-existing"),
496
+ children: "Use an open vial instead"
497
+ }) : null,
498
+ children: M.vialCandidates.length > 0 ? "Opening a new vial from stock. Existing open vials are still available if the dose fits." : "No open vials for this vaccine. A new vial will be opened from the selected batch and the dose recorded in one step."
499
+ }), /* @__PURE__ */ y(se, { children: /* @__PURE__ */ b(E, {
500
+ size: "small",
501
+ children: [/* @__PURE__ */ y(ce, { children: /* @__PURE__ */ b(k, { children: [
502
+ /* @__PURE__ */ y(O, {}),
503
+ /* @__PURE__ */ y(O, {
504
+ sx: { fontWeight: 800 },
505
+ children: "Lot"
506
+ }),
507
+ /* @__PURE__ */ y(O, {
508
+ sx: { fontWeight: 800 },
509
+ children: "Batch expires"
510
+ }),
511
+ /* @__PURE__ */ y(O, {
512
+ sx: { fontWeight: 800 },
513
+ align: "right",
514
+ children: "Qty available"
515
+ }),
516
+ /* @__PURE__ */ y(O, {
517
+ sx: { fontWeight: 800 },
518
+ children: "Storage"
519
+ })
520
+ ] }) }), /* @__PURE__ */ y(D, { children: M.batchCandidates.map((e, t) => {
521
+ let n = M.selectedBatchId === e.id;
522
+ return /* @__PURE__ */ b(k, {
523
+ hover: !0,
524
+ selected: n,
525
+ onClick: () => N({
526
+ ...M,
527
+ selectedBatchId: e.id
528
+ }),
529
+ sx: { cursor: "pointer" },
530
+ children: [
531
+ /* @__PURE__ */ y(O, {
532
+ padding: "checkbox",
533
+ children: /* @__PURE__ */ y(oe, { checked: n })
534
+ }),
535
+ /* @__PURE__ */ b(O, {
536
+ sx: { fontFamily: "monospace" },
537
+ children: [e.lotNumber || "—", t === 0 ? /* @__PURE__ */ y(w, {
538
+ size: "small",
539
+ color: "primary",
540
+ label: "Use first",
541
+ sx: { ml: 1 }
542
+ }) : null]
543
+ }),
544
+ /* @__PURE__ */ y(O, { children: e.expiryDate ? l(e.expiryDate) : "—" }),
545
+ /* @__PURE__ */ y(O, {
546
+ align: "right",
547
+ sx: { fontWeight: 700 },
548
+ children: e.qtyRemaining
549
+ }),
550
+ /* @__PURE__ */ y(O, { children: e.storageUnitName || "—" })
551
+ ]
552
+ }, e.id);
553
+ }) })]
554
+ }) })] }) : /* @__PURE__ */ y(S, {
555
+ severity: "info",
556
+ children: "Pick an administration source above to see the available batches."
557
+ }) }),
558
+ M.mode === "use-existing" && q || M.mode === "open-new" && J ? /* @__PURE__ */ b(T, {
559
+ direction: "row",
560
+ spacing: 1,
561
+ alignItems: "center",
562
+ flexWrap: "wrap",
563
+ children: [M.mode === "use-existing" ? /* @__PURE__ */ b(v, { children: [q.adultDoseMl ? /* @__PURE__ */ b(C, {
564
+ size: "small",
565
+ onClick: () => N({
566
+ ...M,
567
+ volumeMl: q.adultDoseMl
568
+ }),
569
+ children: [
570
+ "Adult dose (",
571
+ q.adultDoseMl,
572
+ " ml)"
573
+ ]
574
+ }) : null, q.childDoseMl ? /* @__PURE__ */ b(C, {
575
+ size: "small",
576
+ onClick: () => N({
577
+ ...M,
578
+ volumeMl: q.childDoseMl
579
+ }),
580
+ children: [
581
+ "Child dose (",
582
+ q.childDoseMl,
583
+ " ml)"
584
+ ]
585
+ }) : null] }) : /* @__PURE__ */ b(v, { children: [Y?.adultDoseMl ? /* @__PURE__ */ b(C, {
586
+ size: "small",
587
+ onClick: () => N({
588
+ ...M,
589
+ volumeMl: Y.adultDoseMl
590
+ }),
591
+ children: [
592
+ "Adult dose (",
593
+ Y.adultDoseMl,
594
+ " ml)"
595
+ ]
596
+ }) : null, Y?.childDoseMl ? /* @__PURE__ */ b(C, {
597
+ size: "small",
598
+ onClick: () => N({
599
+ ...M,
600
+ volumeMl: Y.childDoseMl
601
+ }),
602
+ children: [
603
+ "Child dose (",
604
+ Y.childDoseMl,
605
+ " ml)"
606
+ ]
607
+ }) : null] }), /* @__PURE__ */ y(le, {
608
+ required: !0,
609
+ label: "Volume (ml)",
610
+ size: "small",
611
+ type: "number",
612
+ inputProps: {
613
+ step: "0.01",
614
+ min: 0,
615
+ max: M.mode === "use-existing" ? q?.volumeRemainingMl : Y?.vialVolumeMl
616
+ },
617
+ value: M.volumeMl,
618
+ onChange: (e) => N({
619
+ ...M,
620
+ volumeMl: e.target.value
621
+ }),
622
+ onBlur: V.onBlur("volumeMl"),
623
+ error: V.show("volumeMl") && !!X.volumeMl,
624
+ helperText: V.show("volumeMl") ? X.volumeMl : ""
625
+ })]
626
+ }) : null
627
+ ]
628
+ })]
629
+ }),
630
+ /* @__PURE__ */ b(ne, { children: [
631
+ /* @__PURE__ */ y(C, {
632
+ onClick: j,
633
+ children: "Cancel"
634
+ }),
635
+ M.step === "select" ? /* @__PURE__ */ y(C, {
636
+ onClick: be,
637
+ children: "Back"
638
+ }) : null,
639
+ M.step === "product" ? /* @__PURE__ */ y(C, {
640
+ variant: "contained",
641
+ disabled: !M.productId || M.loading || x && H.length === 0,
642
+ onClick: () => void G(),
643
+ children: "Next"
644
+ }) : /* @__PURE__ */ y(C, {
645
+ variant: "contained",
646
+ disabled: !$ || M.loading,
647
+ onClick: ye,
648
+ children: M.mode === "use-existing" ? "Administer" : "Open & Administer"
649
+ })
650
+ ] })
651
+ ]
652
+ });
653
+ }
654
+ $.propTypes = {
655
+ open: x.bool.isRequired,
656
+ preselectedProductId: x.string,
657
+ onConfirm: x.func.isRequired,
658
+ onCancel: x.func.isRequired
659
+ };
660
+ //#endregion
661
+ export { $ as ProductAdministrationDialog, r as getProducts, n as listFacilities, X as routes };
44
662
 
45
663
  //# sourceMappingURL=index.js.map