@argusoft/medplat-product-management 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/BrandsPage-DCMCVvDY.js +334 -0
  2. package/dist/BrandsPage-DCMCVvDY.js.map +1 -0
  3. package/dist/CategoriesPage-BpRhwfrc.js +284 -0
  4. package/dist/CategoriesPage-BpRhwfrc.js.map +1 -0
  5. package/dist/DashboardPage-BNKUQj46.js +436 -0
  6. package/dist/DashboardPage-BNKUQj46.js.map +1 -0
  7. package/dist/FacilityPicker-Coi8I3yE.js +79 -0
  8. package/dist/FacilityPicker-Coi8I3yE.js.map +1 -0
  9. package/dist/InventoryPage-BR6jOzg2.js +517 -0
  10. package/dist/InventoryPage-BR6jOzg2.js.map +1 -0
  11. package/dist/MemberProfileCard-DbHZCS5n.js +272 -0
  12. package/dist/MemberProfileCard-DbHZCS5n.js.map +1 -0
  13. package/dist/PaymentCreatePage-Ci3ERnby.js +487 -0
  14. package/dist/PaymentCreatePage-Ci3ERnby.js.map +1 -0
  15. package/dist/PaymentsPage-sdg902zX.js +157 -0
  16. package/dist/PaymentsPage-sdg902zX.js.map +1 -0
  17. package/dist/PickupCreatePage-CieMsgWV.js +310 -0
  18. package/dist/PickupCreatePage-CieMsgWV.js.map +1 -0
  19. package/dist/PickupsPage-Ci2Ll0Kn.js +566 -0
  20. package/dist/PickupsPage-Ci2Ll0Kn.js.map +1 -0
  21. package/dist/PmGuard-CjJBisaN.js +1195 -0
  22. package/dist/PmGuard-CjJBisaN.js.map +1 -0
  23. package/dist/PmTable-BuXZQZCU.js +302 -0
  24. package/dist/PmTable-BuXZQZCU.js.map +1 -0
  25. package/dist/ProductEditPage-DL8gy85Y.js +666 -0
  26. package/dist/ProductEditPage-DL8gy85Y.js.map +1 -0
  27. package/dist/ProductsPage-BANTKxLb.js +221 -0
  28. package/dist/ProductsPage-BANTKxLb.js.map +1 -0
  29. package/dist/PurchaseCreatePage-C3KMfBxJ.js +626 -0
  30. package/dist/PurchaseCreatePage-C3KMfBxJ.js.map +1 -0
  31. package/dist/PurchaseRequestDetailPage-C0GYFJDl.js +586 -0
  32. package/dist/PurchaseRequestDetailPage-C0GYFJDl.js.map +1 -0
  33. package/dist/PurchaseRequestsPage-DvFH_tWe.js +265 -0
  34. package/dist/PurchaseRequestsPage-DvFH_tWe.js.map +1 -0
  35. package/dist/PurchasesPage-BCvLvSp4.js +295 -0
  36. package/dist/PurchasesPage-BCvLvSp4.js.map +1 -0
  37. package/dist/SaleCreatePage-DpkQMoTq.js +548 -0
  38. package/dist/SaleCreatePage-DpkQMoTq.js.map +1 -0
  39. package/dist/SalesPage-DUwgkEO-.js +315 -0
  40. package/dist/SalesPage-DUwgkEO-.js.map +1 -0
  41. package/dist/SettingsPage-CusC0jqJ.js +710 -0
  42. package/dist/SettingsPage-CusC0jqJ.js.map +1 -0
  43. package/dist/StorageUnitsPage-BlC2AgrJ.js +469 -0
  44. package/dist/StorageUnitsPage-BlC2AgrJ.js.map +1 -0
  45. package/dist/TransactionsPage-DDaK4VyY.js +714 -0
  46. package/dist/TransactionsPage-DDaK4VyY.js.map +1 -0
  47. package/dist/TransferCreatePage-BxudLfhS.js +363 -0
  48. package/dist/TransferCreatePage-BxudLfhS.js.map +1 -0
  49. package/dist/TransfersPage-zgmt7teZ.js +480 -0
  50. package/dist/TransfersPage-zgmt7teZ.js.map +1 -0
  51. package/dist/VialsPage-CjqPfgpV.js +855 -0
  52. package/dist/VialsPage-CjqPfgpV.js.map +1 -0
  53. package/dist/constants-BrA_hfAI.js +254 -0
  54. package/dist/constants-BrA_hfAI.js.map +1 -0
  55. package/dist/currency-BDDCDgeE.js +169 -0
  56. package/dist/currency-BDDCDgeE.js.map +1 -0
  57. package/dist/format-UOyOu75i.js +52 -0
  58. package/dist/format-UOyOu75i.js.map +1 -0
  59. package/dist/index.js +45 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/useFieldErrors-hDG8ox_x.js +29 -0
  62. package/dist/useFieldErrors-hDG8ox_x.js.map +1 -0
  63. package/dist/validation-Ba7puFIO.js +109 -0
  64. package/dist/validation-Ba7puFIO.js.map +1 -0
  65. package/package.json +36 -0
@@ -0,0 +1,855 @@
1
+ import { A as e, I as t, P as n, X as r, a as i, f as a, h as ee, i as o, n as te, r as s, t as ne, z as c } from "./PmGuard-CjJBisaN.js";
2
+ import { a as l, o as u, t as d } from "./PmTable-BuXZQZCU.js";
3
+ import { m as f, t as p, u as m } from "./validation-Ba7puFIO.js";
4
+ import { t as h } from "./useFieldErrors-hDG8ox_x.js";
5
+ import { n as g, r as _, t as re } from "./format-UOyOu75i.js";
6
+ import { d as ie, f as ae, p as oe } from "./constants-BrA_hfAI.js";
7
+ import { useMemo as se, useState as v } from "react";
8
+ import { Fragment as y, jsx as b, jsxs as x } from "react/jsx-runtime";
9
+ import { v4 as ce } from "uuid";
10
+ import { Alert as S, Box as C, Button as w, Chip as T, Dialog as le, DialogActions as ue, DialogContent as de, DialogTitle as fe, FormControl as E, FormHelperText as pe, InputLabel as me, LinearProgress as D, MenuItem as O, Radio as he, Select as k, Stack as A, Table as ge, TableBody as j, TableCell as M, TableContainer as _e, TableHead as N, TableRow as P, TextField as ve, Tooltip as ye, Typography as F } from "@mui/material";
11
+ import be from "@mui/icons-material/RefreshRounded";
12
+ import { showToast as I } from "@/common/toaster/toaster";
13
+ import xe from "@mui/icons-material/VaccinesRounded";
14
+ //#region src/views/VialsPage.jsx
15
+ function L(e) {
16
+ let t = e.expiresAt ? new Date(e.expiresAt).getTime() : Infinity, n = Infinity;
17
+ if (e.batchExpiryDate) {
18
+ let t = new Date(e.batchExpiryDate);
19
+ t.setHours(23, 59, 59, 999), n = t.getTime();
20
+ }
21
+ return Math.min(t, n);
22
+ }
23
+ function Se(e) {
24
+ return e.expiryDate ? new Date(e.expiryDate).getTime() : Infinity;
25
+ }
26
+ var R = {
27
+ open: !1,
28
+ step: "product",
29
+ mode: "use-existing",
30
+ productId: "",
31
+ ownerType: "",
32
+ ownerId: "",
33
+ allVials: [],
34
+ allBatches: [],
35
+ sources: [],
36
+ vialCandidates: [],
37
+ batchCandidates: [],
38
+ selectedVialId: "",
39
+ selectedBatchId: "",
40
+ volumeMl: "",
41
+ loading: !1
42
+ };
43
+ function Ce() {
44
+ let Ce = o().has("update.manage.productManagement.vial"), [z, we] = v([]), [Te, Ee] = v([]), [B, De] = v([]), [Oe, ke] = v([]), [V, Ae] = v(!1), [je, Me] = v(""), [H, U] = v({
45
+ open: !1,
46
+ vial: null,
47
+ reason: "TIME_EXPIRATION",
48
+ comments: ""
49
+ }), [W, G] = v(R), K = h(), q = h();
50
+ async function J() {
51
+ Ae(!0), Me("");
52
+ try {
53
+ let [r, i, a, ee] = await Promise.all([
54
+ c(),
55
+ n(),
56
+ e(),
57
+ t().catch(() => [])
58
+ ]);
59
+ we(r), Ee(i), De(a), ke(ee);
60
+ } catch (e) {
61
+ Me(e?.response?.data?.message ?? e?.message ?? "Failed to load"), I({
62
+ message: e?.message || "Failed to load",
63
+ type: "error"
64
+ });
65
+ } finally {
66
+ Ae(!1);
67
+ }
68
+ }
69
+ s("view.manage.productManagement.vial", () => {
70
+ J();
71
+ }, []);
72
+ let Ne = se(() => B.filter((e) => e.categoryCode === "VACCINES" && e.isActive).sort((e, t) => e.name.localeCompare(t.name)), [B]), Y = { wastageReason: f(H.reason, "Reason") }, Pe = p(Y);
73
+ async function Fe() {
74
+ if (H.vial) {
75
+ if (!Pe) {
76
+ K.markAllTouched();
77
+ return;
78
+ }
79
+ try {
80
+ await ee({
81
+ id: ce(),
82
+ openVialId: H.vial.id,
83
+ wastageReason: H.reason,
84
+ comments: H.comments || null
85
+ }), I({
86
+ message: "Vial closed.",
87
+ type: "success"
88
+ }), U({
89
+ open: !1,
90
+ vial: null,
91
+ reason: "TIME_EXPIRATION",
92
+ comments: ""
93
+ }), await J();
94
+ } catch (e) {
95
+ I({
96
+ message: e?.response?.data?.message ?? e?.message ?? "Failed",
97
+ type: "error"
98
+ });
99
+ }
100
+ }
101
+ }
102
+ function Ie() {
103
+ q.reset(), G(R);
104
+ }
105
+ function Le(e, t = Te) {
106
+ let n = (/* @__PURE__ */ new Date()).setHours(0, 0, 0, 0);
107
+ return t.filter((t) => t.productId === e && t.qtyRemaining > 0 && !t.isQuarantined && (!t.expiryDate || new Date(t.expiryDate).getTime() >= n)).sort((e, t) => Se(e) - Se(t));
108
+ }
109
+ async function Re() {
110
+ if (!W.productId) {
111
+ q.markAllTouched();
112
+ return;
113
+ }
114
+ G((e) => ({
115
+ ...e,
116
+ loading: !0
117
+ }));
118
+ try {
119
+ let [e, i, a] = await Promise.all([
120
+ r(W.productId),
121
+ n().catch(() => Te),
122
+ t().catch(() => Oe)
123
+ ]);
124
+ Ee(i), ke(a);
125
+ let ee = Date.now(), o = e.filter((e) => e.status === "OPEN" && !e.expired && L(e) > ee && Number(e.volumeRemainingMl) > 0).sort((e, t) => L(e) - L(t)), te = e.reduce((e, t) => (t.status === "OPEN" && (e[t.batchId] = (e[t.batchId] || 0) + 1), e), {}), s = B.find((e) => e.id === W.productId)?.vaccineConfig, ne = s?.maxConcurrentOpenVials ?? 2, c = Le(W.productId, i).filter((e) => (te[e.id] || 0) < ne), l = /* @__PURE__ */ new Set(), u = [];
126
+ function d(e, t, n) {
127
+ let r = `${e}::${t ?? ""}`;
128
+ l.has(r) || (l.add(r), u.push({
129
+ key: r,
130
+ ownerType: e,
131
+ ownerId: t ?? null,
132
+ label: n
133
+ }));
134
+ }
135
+ (o.some((e) => e.ownerType === "USER") || c.some((e) => e.ownerType === "USER")) && d("USER", null, "Personal (outreach)");
136
+ let f = /* @__PURE__ */ new Set();
137
+ o.forEach((e) => {
138
+ e.ownerType === "FACILITY" && e.ownerId && f.add(e.ownerId);
139
+ }), c.forEach((e) => {
140
+ e.ownerType === "FACILITY" && e.ownerId && f.add(e.ownerId);
141
+ }), f.forEach((e) => {
142
+ d("FACILITY", e, `Facility — ${a.find((t) => t.id === e)?.name ?? e}`);
143
+ });
144
+ let p = u.length === 1 ? u[0] : null, m = p?.ownerType ?? "", h = p?.ownerId ?? "", g = ze(o, c, m, h), _ = g.vials.length > 0 ? "use-existing" : "open-new";
145
+ G((e) => ({
146
+ ...e,
147
+ loading: !1,
148
+ step: "select",
149
+ mode: _,
150
+ ownerType: m,
151
+ ownerId: h,
152
+ allVials: o,
153
+ allBatches: c,
154
+ sources: u,
155
+ vialCandidates: g.vials,
156
+ batchCandidates: g.batches,
157
+ selectedVialId: g.vials[0]?.id ?? "",
158
+ selectedBatchId: g.batches[0]?.id ?? "",
159
+ volumeMl: _ === "use-existing" ? g.vials[0]?.adultDoseMl ?? s?.adultDoseMl ?? "" : s?.adultDoseMl ?? ""
160
+ }));
161
+ } catch (e) {
162
+ G((e) => ({
163
+ ...e,
164
+ loading: !1
165
+ })), I({
166
+ message: e?.response?.data?.message ?? e?.message ?? "Failed to load vials",
167
+ type: "error"
168
+ });
169
+ }
170
+ }
171
+ function ze(e, t, n, r) {
172
+ return n ? {
173
+ vials: e.filter((e) => e.ownerType === n && (n === "USER" || e.ownerId === r)),
174
+ batches: t.filter((e) => e.ownerType === n && (n === "USER" || e.ownerId === r))
175
+ } : {
176
+ vials: [],
177
+ batches: []
178
+ };
179
+ }
180
+ function Be(e) {
181
+ let t = W.sources.find((t) => t.key === e);
182
+ if (!t) return;
183
+ let n = ze(W.allVials, W.allBatches, t.ownerType, t.ownerId), r = B.find((e) => e.id === W.productId)?.vaccineConfig, i = n.vials.length > 0 ? "use-existing" : "open-new";
184
+ G((e) => ({
185
+ ...e,
186
+ ownerType: t.ownerType,
187
+ ownerId: t.ownerId ?? "",
188
+ mode: i,
189
+ vialCandidates: n.vials,
190
+ batchCandidates: n.batches,
191
+ selectedVialId: n.vials[0]?.id ?? "",
192
+ selectedBatchId: n.batches[0]?.id ?? "",
193
+ volumeMl: i === "use-existing" ? n.vials[0]?.adultDoseMl ?? r?.adultDoseMl ?? "" : r?.adultDoseMl ?? ""
194
+ }));
195
+ }
196
+ function X(e) {
197
+ G((t) => ({
198
+ ...t,
199
+ mode: e
200
+ }));
201
+ }
202
+ let Z = W.vialCandidates.find((e) => e.id === W.selectedVialId), Ve = W.batchCandidates.find((e) => e.id === W.selectedBatchId), Q = B.find((e) => e.id === W.productId)?.vaccineConfig, $ = (() => {
203
+ if (W.step === "product") return { productId: f(W.productId, "Vaccine") };
204
+ let e = {
205
+ ownerType: f(W.ownerType, "Source"),
206
+ volumeMl: m(W.volumeMl, "Volume", { required: !0 })
207
+ };
208
+ if (W.mode === "use-existing") {
209
+ if (e.selectedVialId = f(W.selectedVialId, "Vial"), !e.volumeMl && Z) {
210
+ let t = Number(W.volumeMl), n = Number(Z.volumeRemainingMl);
211
+ t > n && (e.volumeMl = W.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.`);
212
+ }
213
+ } else if (e.selectedBatchId = f(W.selectedBatchId, "Batch"), !e.volumeMl && Q?.vialVolumeMl) {
214
+ let t = Number(W.volumeMl), n = Number(Q.vialVolumeMl);
215
+ t > n && (e.volumeMl = `A fresh vial holds ${n.toFixed(2)} ml`);
216
+ }
217
+ return e;
218
+ })(), He = p($);
219
+ async function Ue() {
220
+ if (!He) {
221
+ q.markAllTouched();
222
+ return;
223
+ }
224
+ try {
225
+ let e = {
226
+ id: ce(),
227
+ productId: W.productId,
228
+ volumeMl: Number(W.volumeMl),
229
+ ownerType: W.ownerType,
230
+ ownerId: W.ownerType === "FACILITY" && W.ownerId || null
231
+ };
232
+ W.mode === "use-existing" ? e.openVialId = Z.id : e.batchId = Ve.id, await a(e), I({
233
+ message: W.mode === "use-existing" ? "Dose administered." : "New vial opened and dose administered.",
234
+ type: "success"
235
+ }), Ie(), await J();
236
+ } catch (e) {
237
+ I({
238
+ message: e?.response?.data?.message ?? e?.message ?? "Failed",
239
+ type: "error"
240
+ });
241
+ }
242
+ }
243
+ return /* @__PURE__ */ x(C, { children: [/* @__PURE__ */ b(te, {}), /* @__PURE__ */ x(ne, {
244
+ perm: "view.manage.productManagement.vial",
245
+ children: [
246
+ /* @__PURE__ */ x(i, {
247
+ title: "Open Vials",
248
+ subtitle: "Open vaccine vials in use. Close them at the end of the day and record any waste.",
249
+ chips: ["Vaccine"],
250
+ actions: /* @__PURE__ */ x(A, {
251
+ direction: "row",
252
+ spacing: 1,
253
+ children: [/* @__PURE__ */ b(w, {
254
+ variant: "outlined",
255
+ startIcon: /* @__PURE__ */ b(be, {}),
256
+ onClick: () => void J(),
257
+ children: "Refresh"
258
+ }), !1]
259
+ }),
260
+ children: [
261
+ je ? /* @__PURE__ */ b(S, {
262
+ severity: "error",
263
+ sx: { mb: 2 },
264
+ children: je
265
+ }) : null,
266
+ V ? /* @__PURE__ */ b(D, { sx: { mb: 2 } }) : null,
267
+ /* @__PURE__ */ b(u, {
268
+ eyebrow: "In use",
269
+ title: "Open vials",
270
+ subtitle: V ? "Loading…" : `${z.length} ${z.length === 1 ? "vial" : "vials"} currently in use`,
271
+ children: /* @__PURE__ */ x(l, {
272
+ dense: !0,
273
+ children: [/* @__PURE__ */ b(N, { children: /* @__PURE__ */ x(P, { children: [
274
+ /* @__PURE__ */ b(M, { children: "Product" }),
275
+ /* @__PURE__ */ b(M, { children: "Lot" }),
276
+ /* @__PURE__ */ b(M, { children: "Owner" }),
277
+ /* @__PURE__ */ b(M, { children: "Opened" }),
278
+ /* @__PURE__ */ b(M, { children: "Expires" }),
279
+ /* @__PURE__ */ b(M, { children: "Volume remaining" }),
280
+ /* @__PURE__ */ b(M, { children: "Status" }),
281
+ /* @__PURE__ */ b(M, {
282
+ align: "right",
283
+ children: "Action"
284
+ })
285
+ ] }) }), /* @__PURE__ */ b(j, { children: z.length === 0 && !V ? /* @__PURE__ */ b(d, {
286
+ colSpan: 8,
287
+ icon: xe,
288
+ title: "No open vials",
289
+ hint: "Use Administer Vaccine to open and dose a vial."
290
+ }) : z.map((e) => {
291
+ let t = e.volumeTotalMl ? (1 - Number(e.volumeRemainingMl) / Number(e.volumeTotalMl)) * 100 : 0;
292
+ return /* @__PURE__ */ x(P, {
293
+ hover: !0,
294
+ children: [
295
+ /* @__PURE__ */ b(M, { children: /* @__PURE__ */ b(F, {
296
+ variant: "body2",
297
+ sx: { fontWeight: 700 },
298
+ children: e.productName
299
+ }) }),
300
+ /* @__PURE__ */ b(M, { children: e.lotNumber ? /* @__PURE__ */ b(C, {
301
+ component: "span",
302
+ sx: {
303
+ display: "inline-flex",
304
+ px: .7,
305
+ py: .1,
306
+ borderRadius: 1,
307
+ bgcolor: "grey.100",
308
+ fontFamily: "monospace",
309
+ fontSize: "0.72rem",
310
+ fontWeight: 700
311
+ },
312
+ children: e.lotNumber
313
+ }) : /* @__PURE__ */ b(F, {
314
+ variant: "caption",
315
+ color: "text.disabled",
316
+ children: "—"
317
+ }) }),
318
+ /* @__PURE__ */ x(M, { children: [/* @__PURE__ */ b(F, {
319
+ variant: "body2",
320
+ sx: { fontWeight: 700 },
321
+ children: e.ownerName || (e.ownerType === "USER" ? "Personal" : "Facility")
322
+ }), /* @__PURE__ */ b(F, {
323
+ variant: "caption",
324
+ color: "text.secondary",
325
+ children: e.ownerType ?? "—"
326
+ })] }),
327
+ /* @__PURE__ */ b(M, { children: /* @__PURE__ */ b(F, {
328
+ variant: "caption",
329
+ sx: { fontWeight: 600 },
330
+ children: g(e.openedAt)
331
+ }) }),
332
+ /* @__PURE__ */ b(M, { children: /* @__PURE__ */ b(ye, {
333
+ title: e.expired ? "Expired — close out immediately" : "",
334
+ children: /* @__PURE__ */ b(T, {
335
+ size: "small",
336
+ color: e.expired ? "error" : "success",
337
+ label: g(e.expiresAt),
338
+ sx: {
339
+ fontWeight: 700,
340
+ borderRadius: 1.5,
341
+ height: 22
342
+ }
343
+ })
344
+ }) }),
345
+ /* @__PURE__ */ b(M, { children: /* @__PURE__ */ x(A, {
346
+ direction: "row",
347
+ alignItems: "center",
348
+ spacing: 1,
349
+ children: [/* @__PURE__ */ x(F, {
350
+ variant: "body2",
351
+ sx: {
352
+ fontWeight: 800,
353
+ fontVariantNumeric: "tabular-nums",
354
+ minWidth: 80
355
+ },
356
+ children: [
357
+ _(e.volumeRemainingMl),
358
+ " /",
359
+ " ",
360
+ _(e.volumeTotalMl),
361
+ " ml"
362
+ ]
363
+ }), /* @__PURE__ */ b(C, {
364
+ sx: { width: 80 },
365
+ children: /* @__PURE__ */ b(D, {
366
+ variant: "determinate",
367
+ value: t,
368
+ sx: {
369
+ height: 4,
370
+ borderRadius: 2
371
+ },
372
+ color: t > 75 ? "warning" : "primary"
373
+ })
374
+ })]
375
+ }) }),
376
+ /* @__PURE__ */ b(M, { children: /* @__PURE__ */ b(T, {
377
+ size: "small",
378
+ color: e.expired ? "error" : "info",
379
+ label: e.expired ? "Expired" : oe(ie, e.status),
380
+ sx: {
381
+ fontWeight: 700,
382
+ borderRadius: 1.5,
383
+ height: 22
384
+ }
385
+ }) }),
386
+ /* @__PURE__ */ b(M, {
387
+ align: "right",
388
+ children: Ce ? /* @__PURE__ */ b(w, {
389
+ size: "small",
390
+ variant: "outlined",
391
+ color: "error",
392
+ onClick: () => {
393
+ K.reset(), U({
394
+ open: !0,
395
+ vial: e,
396
+ reason: "TIME_EXPIRATION",
397
+ comments: ""
398
+ });
399
+ },
400
+ children: "Close"
401
+ }) : null
402
+ })
403
+ ]
404
+ }, e.id);
405
+ }) })]
406
+ })
407
+ })
408
+ ]
409
+ }),
410
+ /* @__PURE__ */ x(le, {
411
+ open: W.open,
412
+ onClose: Ie,
413
+ fullWidth: !0,
414
+ maxWidth: "md",
415
+ children: [
416
+ /* @__PURE__ */ b(fe, { children: W.step === "product" ? "Administer Vaccine — Select Vaccine" : W.mode === "use-existing" ? "Administer Vaccine — Select Open Vial" : "Administer Vaccine — Open & Administer" }),
417
+ /* @__PURE__ */ b(de, {
418
+ dividers: !0,
419
+ children: W.step === "product" ? /* @__PURE__ */ x(E, {
420
+ required: !0,
421
+ fullWidth: !0,
422
+ size: "small",
423
+ sx: { mt: 1 },
424
+ error: q.show("productId") && !!$.productId,
425
+ children: [
426
+ /* @__PURE__ */ b(me, { children: "Vaccine" }),
427
+ /* @__PURE__ */ x(k, {
428
+ label: "Vaccine",
429
+ value: W.productId,
430
+ onChange: (e) => G({
431
+ ...W,
432
+ productId: e.target.value
433
+ }),
434
+ onBlur: q.onBlur("productId"),
435
+ children: [Ne.length === 0 ? /* @__PURE__ */ b(O, {
436
+ value: "",
437
+ disabled: !0,
438
+ children: /* @__PURE__ */ b("em", { children: "No active vaccine products" })
439
+ }) : null, Ne.map((e) => /* @__PURE__ */ x(O, {
440
+ value: e.id,
441
+ children: [e.name, e.vaccineConfig?.vaccineCode ? ` · ${e.vaccineConfig.vaccineCode}` : ""]
442
+ }, e.id))]
443
+ }),
444
+ /* @__PURE__ */ b(pe, { children: q.show("productId") && $.productId ? $.productId : "Open vials for this vaccine will be shown next. If none are open, a fresh vial can be opened on the same screen." })
445
+ ]
446
+ }) : /* @__PURE__ */ x(A, {
447
+ spacing: 2,
448
+ sx: { pt: 1 },
449
+ children: [
450
+ W.loading ? /* @__PURE__ */ b(D, {}) : null,
451
+ W.sources.length === 0 ? /* @__PURE__ */ b(S, {
452
+ severity: "warning",
453
+ children: "No stock available for this vaccine — neither in your personal stock nor at an assigned facility."
454
+ }) : W.sources.length > 1 ? /* @__PURE__ */ x(E, {
455
+ required: !0,
456
+ fullWidth: !0,
457
+ size: "small",
458
+ error: q.show("ownerType") && !!$.ownerType,
459
+ children: [
460
+ /* @__PURE__ */ b(me, { children: "Administer from" }),
461
+ /* @__PURE__ */ b(k, {
462
+ label: "Administer from",
463
+ value: W.ownerType ? `${W.ownerType}::${W.ownerId ?? ""}` : "",
464
+ onChange: (e) => Be(e.target.value),
465
+ onBlur: q.onBlur("ownerType"),
466
+ children: W.sources.map((e) => /* @__PURE__ */ b(O, {
467
+ value: e.key,
468
+ children: e.label
469
+ }, e.key))
470
+ }),
471
+ /* @__PURE__ */ b(pe, { children: q.show("ownerType") && $.ownerType ? $.ownerType : "Personal stock (outreach) and facility stock are separate vial pools — pick which one this dose comes from." })
472
+ ]
473
+ }) : /* @__PURE__ */ x(S, {
474
+ severity: "info",
475
+ children: [
476
+ "Administering from",
477
+ " ",
478
+ /* @__PURE__ */ b("strong", { children: W.sources[0]?.label }),
479
+ "."
480
+ ]
481
+ }),
482
+ W.mode === "use-existing" ? /* @__PURE__ */ x(y, { children: [W.ownerType ? (() => {
483
+ let e = Number(W.volumeMl), t = !Number.isNaN(e) && e > 0 && W.vialCandidates.some((t) => Number(t.volumeRemainingMl) >= e);
484
+ return /* @__PURE__ */ b(S, {
485
+ severity: "info",
486
+ action: t ? null : /* @__PURE__ */ b(w, {
487
+ color: "inherit",
488
+ size: "small",
489
+ onClick: () => X("open-new"),
490
+ children: "Open another vial instead"
491
+ }),
492
+ 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."
493
+ });
494
+ })() : /* @__PURE__ */ b(S, {
495
+ severity: "info",
496
+ children: "Pick an administration source above to see the available open vials."
497
+ }), /* @__PURE__ */ b(_e, { children: /* @__PURE__ */ x(ge, {
498
+ size: "small",
499
+ children: [/* @__PURE__ */ b(N, { children: /* @__PURE__ */ x(P, { children: [
500
+ /* @__PURE__ */ b(M, {}),
501
+ /* @__PURE__ */ b(M, {
502
+ sx: { fontWeight: 800 },
503
+ children: "Lot"
504
+ }),
505
+ /* @__PURE__ */ b(M, {
506
+ sx: { fontWeight: 800 },
507
+ children: "Vial expires"
508
+ }),
509
+ /* @__PURE__ */ b(M, {
510
+ sx: { fontWeight: 800 },
511
+ children: "Batch expires"
512
+ }),
513
+ /* @__PURE__ */ b(M, {
514
+ sx: { fontWeight: 800 },
515
+ align: "right",
516
+ children: "Remaining (ml)"
517
+ })
518
+ ] }) }), /* @__PURE__ */ b(j, { children: W.vialCandidates.length === 0 ? /* @__PURE__ */ b(P, { children: /* @__PURE__ */ b(M, {
519
+ colSpan: 5,
520
+ sx: {
521
+ py: 4,
522
+ textAlign: "center"
523
+ },
524
+ children: /* @__PURE__ */ x(A, {
525
+ alignItems: "center",
526
+ spacing: 1,
527
+ children: [
528
+ /* @__PURE__ */ b(xe, { sx: {
529
+ fontSize: 36,
530
+ color: "text.disabled",
531
+ opacity: .7
532
+ } }),
533
+ /* @__PURE__ */ b(F, {
534
+ variant: "body2",
535
+ sx: { fontWeight: 700 },
536
+ children: "No usable open vials for this vaccine"
537
+ }),
538
+ W.batchCandidates.length > 0 ? /* @__PURE__ */ b(w, {
539
+ size: "small",
540
+ variant: "outlined",
541
+ onClick: () => X("open-new"),
542
+ children: "Open a new vial instead"
543
+ }) : /* @__PURE__ */ b(F, {
544
+ variant: "caption",
545
+ color: "text.secondary",
546
+ children: "No stock available either — receive a purchase first."
547
+ })
548
+ ]
549
+ })
550
+ }) }) : W.vialCandidates.map((e, t) => {
551
+ let n = W.selectedVialId === e.id;
552
+ return /* @__PURE__ */ x(P, {
553
+ hover: !0,
554
+ selected: n,
555
+ onClick: () => G({
556
+ ...W,
557
+ selectedVialId: e.id,
558
+ volumeMl: e.adultDoseMl ?? W.volumeMl
559
+ }),
560
+ sx: { cursor: "pointer" },
561
+ children: [
562
+ /* @__PURE__ */ b(M, {
563
+ padding: "checkbox",
564
+ children: /* @__PURE__ */ b(he, { checked: n })
565
+ }),
566
+ /* @__PURE__ */ x(M, {
567
+ sx: { fontFamily: "monospace" },
568
+ children: [e.lotNumber || "—", t === 0 ? /* @__PURE__ */ b(T, {
569
+ size: "small",
570
+ color: "primary",
571
+ label: "Use first",
572
+ sx: { ml: 1 }
573
+ }) : null]
574
+ }),
575
+ /* @__PURE__ */ b(M, { children: g(e.expiresAt) }),
576
+ /* @__PURE__ */ b(M, { children: e.batchExpiryDate ? re(e.batchExpiryDate) : "—" }),
577
+ /* @__PURE__ */ x(M, {
578
+ align: "right",
579
+ sx: { fontWeight: 700 },
580
+ children: [
581
+ _(e.volumeRemainingMl),
582
+ " /",
583
+ " ",
584
+ _(e.volumeTotalMl)
585
+ ]
586
+ })
587
+ ]
588
+ }, e.id);
589
+ }) })]
590
+ }) })] }) : /* @__PURE__ */ b(y, { children: W.ownerType ? W.batchCandidates.length === 0 ? /* @__PURE__ */ b(S, {
591
+ severity: "error",
592
+ action: W.vialCandidates.length > 0 ? /* @__PURE__ */ b(w, {
593
+ color: "inherit",
594
+ size: "small",
595
+ onClick: () => X("use-existing"),
596
+ children: "Use an open vial"
597
+ }) : null,
598
+ 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."
599
+ }) : /* @__PURE__ */ x(y, { children: [/* @__PURE__ */ b(S, {
600
+ severity: "warning",
601
+ action: W.vialCandidates.length > 0 ? /* @__PURE__ */ b(w, {
602
+ color: "inherit",
603
+ size: "small",
604
+ onClick: () => X("use-existing"),
605
+ children: "Use an open vial instead"
606
+ }) : null,
607
+ children: W.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."
608
+ }), /* @__PURE__ */ b(_e, { children: /* @__PURE__ */ x(ge, {
609
+ size: "small",
610
+ children: [/* @__PURE__ */ b(N, { children: /* @__PURE__ */ x(P, { children: [
611
+ /* @__PURE__ */ b(M, {}),
612
+ /* @__PURE__ */ b(M, {
613
+ sx: { fontWeight: 800 },
614
+ children: "Lot"
615
+ }),
616
+ /* @__PURE__ */ b(M, {
617
+ sx: { fontWeight: 800 },
618
+ children: "Batch expires"
619
+ }),
620
+ /* @__PURE__ */ b(M, {
621
+ sx: { fontWeight: 800 },
622
+ align: "right",
623
+ children: "Qty available"
624
+ }),
625
+ /* @__PURE__ */ b(M, {
626
+ sx: { fontWeight: 800 },
627
+ children: "Storage"
628
+ })
629
+ ] }) }), /* @__PURE__ */ b(j, { children: W.batchCandidates.map((e, t) => {
630
+ let n = W.selectedBatchId === e.id;
631
+ return /* @__PURE__ */ x(P, {
632
+ hover: !0,
633
+ selected: n,
634
+ onClick: () => G({
635
+ ...W,
636
+ selectedBatchId: e.id
637
+ }),
638
+ sx: { cursor: "pointer" },
639
+ children: [
640
+ /* @__PURE__ */ b(M, {
641
+ padding: "checkbox",
642
+ children: /* @__PURE__ */ b(he, { checked: n })
643
+ }),
644
+ /* @__PURE__ */ x(M, {
645
+ sx: { fontFamily: "monospace" },
646
+ children: [e.lotNumber || "—", t === 0 ? /* @__PURE__ */ b(T, {
647
+ size: "small",
648
+ color: "primary",
649
+ label: "Use first",
650
+ sx: { ml: 1 }
651
+ }) : null]
652
+ }),
653
+ /* @__PURE__ */ b(M, { children: e.expiryDate ? re(e.expiryDate) : "—" }),
654
+ /* @__PURE__ */ b(M, {
655
+ align: "right",
656
+ sx: { fontWeight: 700 },
657
+ children: e.qtyRemaining
658
+ }),
659
+ /* @__PURE__ */ b(M, { children: e.storageUnitName || "—" })
660
+ ]
661
+ }, e.id);
662
+ }) })]
663
+ }) })] }) : /* @__PURE__ */ b(S, {
664
+ severity: "info",
665
+ children: "Pick an administration source above to see the available batches."
666
+ }) }),
667
+ W.mode === "use-existing" && Z || W.mode === "open-new" && Ve ? /* @__PURE__ */ x(A, {
668
+ direction: "row",
669
+ spacing: 1,
670
+ alignItems: "center",
671
+ flexWrap: "wrap",
672
+ children: [W.mode === "use-existing" ? /* @__PURE__ */ x(y, { children: [Z.adultDoseMl ? /* @__PURE__ */ x(w, {
673
+ size: "small",
674
+ onClick: () => G({
675
+ ...W,
676
+ volumeMl: Z.adultDoseMl
677
+ }),
678
+ children: [
679
+ "Adult dose (",
680
+ Z.adultDoseMl,
681
+ " ml)"
682
+ ]
683
+ }) : null, Z.childDoseMl ? /* @__PURE__ */ x(w, {
684
+ size: "small",
685
+ onClick: () => G({
686
+ ...W,
687
+ volumeMl: Z.childDoseMl
688
+ }),
689
+ children: [
690
+ "Child dose (",
691
+ Z.childDoseMl,
692
+ " ml)"
693
+ ]
694
+ }) : null] }) : /* @__PURE__ */ x(y, { children: [Q?.adultDoseMl ? /* @__PURE__ */ x(w, {
695
+ size: "small",
696
+ onClick: () => G({
697
+ ...W,
698
+ volumeMl: Q.adultDoseMl
699
+ }),
700
+ children: [
701
+ "Adult dose (",
702
+ Q.adultDoseMl,
703
+ " ml)"
704
+ ]
705
+ }) : null, Q?.childDoseMl ? /* @__PURE__ */ x(w, {
706
+ size: "small",
707
+ onClick: () => G({
708
+ ...W,
709
+ volumeMl: Q.childDoseMl
710
+ }),
711
+ children: [
712
+ "Child dose (",
713
+ Q.childDoseMl,
714
+ " ml)"
715
+ ]
716
+ }) : null] }), /* @__PURE__ */ b(ve, {
717
+ required: !0,
718
+ label: "Volume (ml)",
719
+ size: "small",
720
+ type: "number",
721
+ inputProps: {
722
+ step: "0.01",
723
+ min: 0,
724
+ max: W.mode === "use-existing" ? Z?.volumeRemainingMl : Q?.vialVolumeMl
725
+ },
726
+ value: W.volumeMl,
727
+ onChange: (e) => G({
728
+ ...W,
729
+ volumeMl: e.target.value
730
+ }),
731
+ onBlur: q.onBlur("volumeMl"),
732
+ error: q.show("volumeMl") && !!$.volumeMl,
733
+ helperText: q.show("volumeMl") ? $.volumeMl : ""
734
+ })]
735
+ }) : null
736
+ ]
737
+ })
738
+ }),
739
+ /* @__PURE__ */ x(ue, { children: [
740
+ /* @__PURE__ */ b(w, {
741
+ onClick: Ie,
742
+ children: "Cancel"
743
+ }),
744
+ W.step === "select" ? /* @__PURE__ */ b(w, {
745
+ onClick: () => G({
746
+ ...R,
747
+ open: !0,
748
+ productId: W.productId
749
+ }),
750
+ children: "Back"
751
+ }) : null,
752
+ W.step === "product" ? /* @__PURE__ */ b(w, {
753
+ variant: "contained",
754
+ disabled: !W.productId || W.loading,
755
+ onClick: () => void Re(),
756
+ children: "Next"
757
+ }) : /* @__PURE__ */ b(w, {
758
+ variant: "contained",
759
+ disabled: !He,
760
+ onClick: () => void Ue(),
761
+ children: W.mode === "use-existing" ? "Administer" : "Open & Administer"
762
+ })
763
+ ] })
764
+ ]
765
+ }),
766
+ /* @__PURE__ */ x(le, {
767
+ open: H.open,
768
+ onClose: () => U({
769
+ open: !1,
770
+ vial: null,
771
+ reason: "TIME_EXPIRATION",
772
+ comments: ""
773
+ }),
774
+ fullWidth: !0,
775
+ maxWidth: "sm",
776
+ children: [
777
+ /* @__PURE__ */ b(fe, { children: "Close Vial (record remaining as wastage)" }),
778
+ /* @__PURE__ */ b(de, {
779
+ dividers: !0,
780
+ children: /* @__PURE__ */ x(A, {
781
+ spacing: 2,
782
+ sx: { pt: 1 },
783
+ children: [
784
+ /* @__PURE__ */ x(F, {
785
+ variant: "body2",
786
+ children: [
787
+ H.vial?.productName,
788
+ " ·",
789
+ " ",
790
+ _(H.vial?.volumeRemainingMl),
791
+ " ml will be marked as wasted."
792
+ ]
793
+ }),
794
+ /* @__PURE__ */ x(E, {
795
+ required: !0,
796
+ fullWidth: !0,
797
+ size: "small",
798
+ error: K.show("wastageReason") && !!Y.wastageReason,
799
+ children: [
800
+ /* @__PURE__ */ b(me, { children: "Reason" }),
801
+ /* @__PURE__ */ b(k, {
802
+ label: "Reason",
803
+ value: H.reason,
804
+ onChange: (e) => U({
805
+ ...H,
806
+ reason: e.target.value
807
+ }),
808
+ onBlur: K.onBlur("wastageReason"),
809
+ children: ae.map((e) => /* @__PURE__ */ b(O, {
810
+ value: e.value,
811
+ children: e.label
812
+ }, e.value))
813
+ }),
814
+ K.show("wastageReason") && Y.wastageReason ? /* @__PURE__ */ b(pe, { children: Y.wastageReason }) : null
815
+ ]
816
+ }),
817
+ /* @__PURE__ */ b(ve, {
818
+ label: "Comments",
819
+ size: "small",
820
+ multiline: !0,
821
+ minRows: 2,
822
+ fullWidth: !0,
823
+ value: H.comments,
824
+ onChange: (e) => U({
825
+ ...H,
826
+ comments: e.target.value
827
+ })
828
+ })
829
+ ]
830
+ })
831
+ }),
832
+ /* @__PURE__ */ x(ue, { children: [/* @__PURE__ */ b(w, {
833
+ onClick: () => U({
834
+ open: !1,
835
+ vial: null,
836
+ reason: "TIME_EXPIRATION",
837
+ comments: ""
838
+ }),
839
+ children: "Cancel"
840
+ }), /* @__PURE__ */ b(w, {
841
+ variant: "contained",
842
+ color: "error",
843
+ disabled: !Pe,
844
+ onClick: () => void Fe(),
845
+ children: "Close Vial"
846
+ })] })
847
+ ]
848
+ })
849
+ ]
850
+ })] });
851
+ }
852
+ //#endregion
853
+ export { Ce as default };
854
+
855
+ //# sourceMappingURL=VialsPage-CjqPfgpV.js.map