@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,566 @@
1
+ import { H as e, a as t, et as ee, i as te, n as ne, r as n, t as re, tt as ie } from "./PmGuard-CjJBisaN.js";
2
+ import { a as ae, i as oe, o as se, t as ce } from "./PmTable-BuXZQZCU.js";
3
+ import { n as le, t as ue } from "./format-UOyOu75i.js";
4
+ import { f as de, p as fe, r as pe } from "./constants-BrA_hfAI.js";
5
+ import { useMemo as me, useState as r } from "react";
6
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
7
+ import { v4 as he } from "uuid";
8
+ import { Alert as o, Box as s, Button as c, Chip as ge, Dialog as l, DialogActions as u, DialogContent as d, DialogTitle as f, FormControl as _e, FormHelperText as ve, InputAdornment as ye, InputLabel as be, MenuItem as p, Select as xe, Skeleton as Se, Stack as m, TableBody as Ce, TableCell as h, TableHead as we, TableRow as g, TextField as _, Typography as v } from "@mui/material";
9
+ import y from "@mui/icons-material/AddRounded";
10
+ import Te from "@mui/icons-material/RefreshRounded";
11
+ import { showToast as b } from "@/common/toaster/toaster";
12
+ import { useNavigate as Ee } from "react-router-dom";
13
+ import { alpha as x } from "@mui/material/styles";
14
+ import De from "@mui/icons-material/MoveDownRounded";
15
+ import Oe from "@mui/icons-material/SearchRounded";
16
+ import ke from "@mui/icons-material/AssignmentReturnRounded";
17
+ //#region src/views/PickupsPage.jsx
18
+ function Ae(e) {
19
+ switch (e) {
20
+ case "OPEN": return "info";
21
+ case "RETURNED": return "success";
22
+ case "CANCELLED": return "default";
23
+ default: return "default";
24
+ }
25
+ }
26
+ function S() {
27
+ let S = Ee(), C = te().has("update.manage.productManagement.pickup"), [w, je] = r([]), [T, E] = r(!0), [D, O] = r(""), [k, Me] = r(""), [A, j] = r({
28
+ open: !1,
29
+ pickup: null
30
+ }), [M, N] = r({
31
+ returnedQty: "",
32
+ wastageReason: "",
33
+ notes: ""
34
+ }), [P, F] = r({
35
+ open: !1,
36
+ pickup: null
37
+ }), [I, L] = r({
38
+ additionalQty: "",
39
+ notes: ""
40
+ }), [R, z] = r(!1);
41
+ async function B() {
42
+ E(!0), O("");
43
+ try {
44
+ je(await e());
45
+ } catch (e) {
46
+ let t = e?.response?.data?.message ?? e?.message ?? "Failed to load pickups";
47
+ O(t), b({
48
+ message: t,
49
+ type: "error"
50
+ });
51
+ } finally {
52
+ E(!1);
53
+ }
54
+ }
55
+ n("view.manage.productManagement.pickup", () => {
56
+ B();
57
+ }, []);
58
+ let V = me(() => {
59
+ let e = k.trim().toLowerCase();
60
+ return e ? w.filter((t) => `${t.productName ?? ""} ${t.facilityName ?? ""} ${t.userName ?? ""} ${t.lotNumber ?? ""} ${t.notes ?? ""}`.toLowerCase().includes(e)) : w;
61
+ }, [w, k]);
62
+ function Ne(e) {
63
+ let t = e.expectedRemainingQty ?? 0;
64
+ N({
65
+ returnedQty: String(t),
66
+ wastageReason: "",
67
+ notes: ""
68
+ }), j({
69
+ open: !0,
70
+ pickup: e
71
+ });
72
+ }
73
+ function H() {
74
+ R || j({
75
+ open: !1,
76
+ pickup: null
77
+ });
78
+ }
79
+ function Pe(e) {
80
+ L({
81
+ additionalQty: "1",
82
+ notes: ""
83
+ }), F({
84
+ open: !0,
85
+ pickup: e
86
+ });
87
+ }
88
+ function U() {
89
+ R || F({
90
+ open: !1,
91
+ pickup: null
92
+ });
93
+ }
94
+ let W = Number(I.additionalQty), G = !Number.isInteger(W) || W <= 0 ? "Enter a whole number greater than 0." : "";
95
+ async function K() {
96
+ if (!(G || !P.pickup)) {
97
+ z(!0);
98
+ try {
99
+ await ie(P.pickup.id, {
100
+ id: he(),
101
+ additionalQty: W,
102
+ notes: I.notes || null
103
+ }), b({
104
+ message: `Topped up ${W} unit${W === 1 ? "" : "s"}.`,
105
+ type: "success"
106
+ }), U(), await B();
107
+ } catch (e) {
108
+ b({
109
+ message: e?.response?.data?.message ?? e?.message ?? "Failed to top up",
110
+ type: "error"
111
+ });
112
+ } finally {
113
+ z(!1);
114
+ }
115
+ }
116
+ }
117
+ let q = A.pickup?.expectedRemainingQty ?? 0, J = Number(M.returnedQty), Y = Number.isFinite(J) && J >= 0 && J <= q ? q - J : null, X = !Number.isInteger(J) || J < 0 ? "Enter a whole number from 0 to the expected remaining." : J > q ? `At most ${q} can be returned.` : "", Z = Y != null && Y > 0 || (A.pickup?.openVials ?? []).length > 0, Q = Z && !M.wastageReason ? "A reason is required for the wastage being recorded." : "", $ = !X && !Q;
118
+ async function Fe() {
119
+ if (!(!$ || !A.pickup)) {
120
+ z(!0);
121
+ try {
122
+ await ee(A.pickup.id, {
123
+ returnedQty: J,
124
+ wastageReason: Z ? M.wastageReason : null,
125
+ notes: M.notes || null
126
+ }), b({
127
+ message: Y > 0 ? `Returned ${J}, wasted ${Y}.` : `Returned ${J} unit${J === 1 ? "" : "s"}.`,
128
+ type: "success"
129
+ }), H(), await B();
130
+ } catch (e) {
131
+ b({
132
+ message: e?.response?.data?.message ?? e?.message ?? "Failed to record return",
133
+ type: "error"
134
+ });
135
+ } finally {
136
+ z(!1);
137
+ }
138
+ }
139
+ }
140
+ return /* @__PURE__ */ a(s, { children: [
141
+ /* @__PURE__ */ i(ne, {}),
142
+ /* @__PURE__ */ i(re, {
143
+ perm: "view.manage.productManagement.pickup",
144
+ children: /* @__PURE__ */ a(t, {
145
+ title: "Stock Pickups",
146
+ subtitle: "Stock you're carrying for field work. Record returns and any items lost or used.",
147
+ actions: /* @__PURE__ */ a(m, {
148
+ direction: "row",
149
+ spacing: 1,
150
+ children: [/* @__PURE__ */ i(c, {
151
+ variant: "outlined",
152
+ startIcon: /* @__PURE__ */ i(Te, {}),
153
+ onClick: () => void B(),
154
+ children: "Refresh"
155
+ }), C ? /* @__PURE__ */ i(c, {
156
+ variant: "contained",
157
+ startIcon: /* @__PURE__ */ i(y, {}),
158
+ onClick: () => S("/ui/medplat/manage/pm/pickups/new"),
159
+ children: "New Pickup"
160
+ }) : null]
161
+ }),
162
+ children: [D ? /* @__PURE__ */ i(o, {
163
+ severity: "error",
164
+ sx: { mb: 2 },
165
+ children: D
166
+ }) : null, /* @__PURE__ */ a(se, {
167
+ eyebrow: "Operations",
168
+ title: "Pickups",
169
+ subtitle: T ? "Loading…" : `${V.length} ${V.length === 1 ? "pickup" : "pickups"}`,
170
+ children: [/* @__PURE__ */ i(m, {
171
+ direction: {
172
+ xs: "column",
173
+ md: "row"
174
+ },
175
+ spacing: 1.5,
176
+ sx: { mb: 2 },
177
+ children: /* @__PURE__ */ i(_, {
178
+ size: "small",
179
+ fullWidth: !0,
180
+ placeholder: "Search by product, facility, user, lot, notes…",
181
+ value: k,
182
+ onChange: (e) => Me(e.target.value),
183
+ InputProps: { startAdornment: /* @__PURE__ */ i(ye, {
184
+ position: "start",
185
+ children: /* @__PURE__ */ i(Oe, { fontSize: "small" })
186
+ }) }
187
+ })
188
+ }), /* @__PURE__ */ a(ae, {
189
+ dense: !0,
190
+ children: [/* @__PURE__ */ i(we, { children: /* @__PURE__ */ a(g, { children: [
191
+ /* @__PURE__ */ i(h, { children: "Ref" }),
192
+ /* @__PURE__ */ i(h, { children: "Product" }),
193
+ /* @__PURE__ */ i(h, { children: "Facility" }),
194
+ /* @__PURE__ */ i(h, { children: "User" }),
195
+ /* @__PURE__ */ i(h, {
196
+ align: "right",
197
+ children: "Qty"
198
+ }),
199
+ /* @__PURE__ */ i(h, { children: "Picked" }),
200
+ /* @__PURE__ */ i(h, { children: "Status" }),
201
+ /* @__PURE__ */ i(h, {
202
+ align: "right",
203
+ children: "Action"
204
+ })
205
+ ] }) }), /* @__PURE__ */ i(Ce, { children: T ? Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */ i(g, { children: Array.from({ length: 8 }).map((e, t) => /* @__PURE__ */ i(h, { children: /* @__PURE__ */ i(Se, { height: 22 }) }, t)) }, t)) : V.length === 0 ? /* @__PURE__ */ i(ce, {
206
+ colSpan: 8,
207
+ icon: De,
208
+ title: k.trim() === "" ? "No pickups yet" : "No pickups match your search",
209
+ hint: "Check out stock from a facility to use in the field.",
210
+ action: C ? /* @__PURE__ */ i(c, {
211
+ variant: "contained",
212
+ size: "small",
213
+ startIcon: /* @__PURE__ */ i(y, {}),
214
+ onClick: () => S("/ui/medplat/manage/pm/pickups/new"),
215
+ children: "Record first pickup"
216
+ }) : null
217
+ }) : V.map((e) => /* @__PURE__ */ a(g, {
218
+ hover: !0,
219
+ children: [
220
+ /* @__PURE__ */ i(h, { children: /* @__PURE__ */ i(oe, { id: e.serialId }) }),
221
+ /* @__PURE__ */ a(h, { children: [/* @__PURE__ */ i(v, {
222
+ variant: "body2",
223
+ sx: { fontWeight: 700 },
224
+ children: e.productName ?? "—"
225
+ }), e.lotNumber ? /* @__PURE__ */ i(v, {
226
+ variant: "caption",
227
+ sx: {
228
+ fontFamily: "monospace",
229
+ color: "text.secondary"
230
+ },
231
+ children: e.lotNumber
232
+ }) : null] }),
233
+ /* @__PURE__ */ i(h, { children: e.facilityName ?? "—" }),
234
+ /* @__PURE__ */ i(h, { children: e.userName ?? "—" }),
235
+ /* @__PURE__ */ a(h, {
236
+ align: "right",
237
+ children: [/* @__PURE__ */ i(v, {
238
+ sx: {
239
+ fontWeight: 700,
240
+ fontVariantNumeric: "tabular-nums"
241
+ },
242
+ children: e.pickedQty
243
+ }), e.status === "OPEN" && e.expectedRemainingQty != null ? /* @__PURE__ */ a(v, {
244
+ variant: "caption",
245
+ color: "text.secondary",
246
+ children: [e.expectedRemainingQty, " left on user"]
247
+ }) : e.status === "RETURNED" ? /* @__PURE__ */ a(v, {
248
+ variant: "caption",
249
+ color: "text.secondary",
250
+ children: [
251
+ e.returnedQty,
252
+ " returned",
253
+ e.wastedQty > 0 ? ` · ${e.wastedQty} wasted` : ""
254
+ ]
255
+ }) : null]
256
+ }),
257
+ /* @__PURE__ */ i(h, { children: /* @__PURE__ */ i(v, {
258
+ variant: "body2",
259
+ children: ue(e.pickedOn)
260
+ }) }),
261
+ /* @__PURE__ */ i(h, { children: /* @__PURE__ */ i(ge, {
262
+ size: "small",
263
+ label: fe(pe, e.status),
264
+ color: Ae(e.status)
265
+ }) }),
266
+ /* @__PURE__ */ i(h, {
267
+ align: "right",
268
+ children: e.status === "OPEN" && C ? /* @__PURE__ */ a(m, {
269
+ direction: "row",
270
+ spacing: 1,
271
+ justifyContent: "flex-end",
272
+ children: [/* @__PURE__ */ i(c, {
273
+ size: "small",
274
+ variant: "outlined",
275
+ startIcon: /* @__PURE__ */ i(y, {}),
276
+ onClick: () => Pe(e),
277
+ children: "Top Up"
278
+ }), /* @__PURE__ */ i(c, {
279
+ size: "small",
280
+ variant: "outlined",
281
+ startIcon: /* @__PURE__ */ i(ke, {}),
282
+ onClick: () => Ne(e),
283
+ children: "End Session"
284
+ })]
285
+ }) : /* @__PURE__ */ i(v, {
286
+ variant: "caption",
287
+ color: "text.disabled",
288
+ children: "—"
289
+ })
290
+ })
291
+ ]
292
+ }, e.id)) })]
293
+ })]
294
+ })]
295
+ })
296
+ }),
297
+ /* @__PURE__ */ a(l, {
298
+ open: A.open,
299
+ onClose: H,
300
+ maxWidth: "sm",
301
+ fullWidth: !0,
302
+ children: [
303
+ /* @__PURE__ */ a(f, { children: ["End outreach session #", A.pickup?.serialId] }),
304
+ /* @__PURE__ */ i(d, { children: A.pickup ? /* @__PURE__ */ a(m, {
305
+ spacing: 2,
306
+ sx: { mt: 1 },
307
+ children: [
308
+ /* @__PURE__ */ a(s, {
309
+ sx: (e) => ({
310
+ p: 1.5,
311
+ borderRadius: 3,
312
+ bgcolor: x(e.palette.primary.main, .04),
313
+ border: `1px solid ${x(e.palette.primary.main, .12)}`
314
+ }),
315
+ children: [
316
+ /* @__PURE__ */ i(v, {
317
+ variant: "body2",
318
+ children: /* @__PURE__ */ i("strong", { children: A.pickup.productName })
319
+ }),
320
+ /* @__PURE__ */ a(v, {
321
+ variant: "caption",
322
+ color: "text.secondary",
323
+ sx: { display: "block" },
324
+ children: [
325
+ "Picked ",
326
+ A.pickup.pickedQty,
327
+ " on ",
328
+ le(A.pickup.pickedOn),
329
+ " from ",
330
+ A.pickup.facilityName
331
+ ]
332
+ }),
333
+ /* @__PURE__ */ a(v, {
334
+ variant: "caption",
335
+ color: "text.secondary",
336
+ sx: {
337
+ display: "block",
338
+ mt: .5
339
+ },
340
+ children: [
341
+ "Sealed units expected on user: ",
342
+ /* @__PURE__ */ i("strong", { children: q }),
343
+ " ",
344
+ "(",
345
+ (A.pickup.pickedQty ?? 0) - q - (A.pickup.openVials ?? []).length,
346
+ " already administered / wasted during the day)"
347
+ ]
348
+ })
349
+ ]
350
+ }),
351
+ /* @__PURE__ */ i(_, {
352
+ required: !0,
353
+ size: "small",
354
+ type: "number",
355
+ label: "Sealed Units Returned",
356
+ inputProps: {
357
+ min: 0,
358
+ max: q
359
+ },
360
+ value: M.returnedQty,
361
+ onChange: (e) => N((t) => ({
362
+ ...t,
363
+ returnedQty: e.target.value
364
+ })),
365
+ error: !!X,
366
+ helperText: X || `Out of ${q} sealed units expected to remain`
367
+ }),
368
+ Y != null && Y > 0 ? /* @__PURE__ */ a(o, {
369
+ severity: "warning",
370
+ variant: "outlined",
371
+ children: [
372
+ /* @__PURE__ */ i("strong", { children: Y }),
373
+ " sealed ",
374
+ Y === 1 ? "unit" : "units",
375
+ " unaccounted for — will be marked as wastage."
376
+ ]
377
+ }) : null,
378
+ (A.pickup.openVials ?? []).length > 0 ? /* @__PURE__ */ a(o, {
379
+ severity: "info",
380
+ variant: "outlined",
381
+ children: [
382
+ /* @__PURE__ */ a(v, {
383
+ variant: "body2",
384
+ sx: {
385
+ fontWeight: 700,
386
+ mb: .5
387
+ },
388
+ children: [
389
+ A.pickup.openVials.length,
390
+ " open vial",
391
+ A.pickup.openVials.length === 1 ? "" : "s",
392
+ " on you will be closed with wastage"
393
+ ]
394
+ }),
395
+ /* @__PURE__ */ i(m, {
396
+ spacing: .25,
397
+ sx: { mt: .5 },
398
+ children: A.pickup.openVials.map((e) => /* @__PURE__ */ a(v, {
399
+ variant: "caption",
400
+ color: "text.secondary",
401
+ children: [
402
+ "Lot ",
403
+ e.lotNumber || "—",
404
+ " · ",
405
+ Number(e.volumeRemainingMl ?? 0).toFixed(2),
406
+ " ml remaining"
407
+ ]
408
+ }, e.id))
409
+ }),
410
+ /* @__PURE__ */ i(v, {
411
+ variant: "caption",
412
+ color: "text.secondary",
413
+ sx: {
414
+ display: "block",
415
+ mt: .75
416
+ },
417
+ children: "These volumes will be recorded as wastage using the reason picked below."
418
+ })
419
+ ]
420
+ }) : null,
421
+ /* @__PURE__ */ a(_e, {
422
+ size: "small",
423
+ disabled: !Z,
424
+ error: !!Q,
425
+ children: [
426
+ /* @__PURE__ */ a(be, { children: ["Wastage Reason", Z ? " *" : ""] }),
427
+ /* @__PURE__ */ a(xe, {
428
+ label: `Wastage Reason${Z ? " *" : ""}`,
429
+ value: M.wastageReason,
430
+ onChange: (e) => N((t) => ({
431
+ ...t,
432
+ wastageReason: e.target.value
433
+ })),
434
+ children: [/* @__PURE__ */ i(p, {
435
+ value: "",
436
+ children: /* @__PURE__ */ i("em", { children: "—" })
437
+ }), de.map((e) => /* @__PURE__ */ i(p, {
438
+ value: e.value,
439
+ children: e.label
440
+ }, e.value))]
441
+ }),
442
+ /* @__PURE__ */ i(ve, { children: Q || (Z ? "Required — same reason covers both unaccounted sealed units and any open-vial remaining volume." : "Not needed — nothing being wasted.") })
443
+ ]
444
+ }),
445
+ /* @__PURE__ */ i(_, {
446
+ size: "small",
447
+ multiline: !0,
448
+ minRows: 2,
449
+ label: "Notes (optional)",
450
+ value: M.notes,
451
+ onChange: (e) => N((t) => ({
452
+ ...t,
453
+ notes: e.target.value
454
+ }))
455
+ })
456
+ ]
457
+ }) : null }),
458
+ /* @__PURE__ */ a(u, { children: [/* @__PURE__ */ i(c, {
459
+ onClick: H,
460
+ disabled: R,
461
+ children: "Cancel"
462
+ }), /* @__PURE__ */ i(c, {
463
+ variant: "contained",
464
+ onClick: () => void Fe(),
465
+ disabled: !$ || R,
466
+ children: R ? "Submitting…" : "End Session"
467
+ })] })
468
+ ]
469
+ }),
470
+ /* @__PURE__ */ a(l, {
471
+ open: P.open,
472
+ onClose: U,
473
+ maxWidth: "xs",
474
+ fullWidth: !0,
475
+ children: [
476
+ /* @__PURE__ */ a(f, { children: ["Top up session #", P.pickup?.serialId] }),
477
+ /* @__PURE__ */ i(d, { children: P.pickup ? /* @__PURE__ */ a(m, {
478
+ spacing: 2,
479
+ sx: { mt: 1 },
480
+ children: [
481
+ /* @__PURE__ */ a(s, {
482
+ sx: (e) => ({
483
+ p: 1.5,
484
+ borderRadius: 3,
485
+ bgcolor: x(e.palette.primary.main, .04),
486
+ border: `1px solid ${x(e.palette.primary.main, .12)}`
487
+ }),
488
+ children: [
489
+ /* @__PURE__ */ i(v, {
490
+ variant: "body2",
491
+ children: /* @__PURE__ */ i("strong", { children: P.pickup.productName })
492
+ }),
493
+ /* @__PURE__ */ a(v, {
494
+ variant: "caption",
495
+ color: "text.secondary",
496
+ sx: { display: "block" },
497
+ children: [
498
+ "Source: ",
499
+ P.pickup.facilityName,
500
+ " · Lot ",
501
+ P.pickup.lotNumber || "—"
502
+ ]
503
+ }),
504
+ /* @__PURE__ */ a(v, {
505
+ variant: "caption",
506
+ color: "text.secondary",
507
+ sx: { display: "block" },
508
+ children: [
509
+ "Currently picked: ",
510
+ P.pickup.pickedQty,
511
+ " · remaining sealed on user: ",
512
+ P.pickup.expectedRemainingQty ?? 0
513
+ ]
514
+ })
515
+ ]
516
+ }),
517
+ /* @__PURE__ */ i(o, {
518
+ severity: "info",
519
+ variant: "outlined",
520
+ children: "Top-ups come from the same source batch as the original pickup so lot / expiry stays consistent. To pick from a different batch, end this session first."
521
+ }),
522
+ /* @__PURE__ */ i(_, {
523
+ required: !0,
524
+ size: "small",
525
+ type: "number",
526
+ label: "Additional Quantity",
527
+ inputProps: { min: 1 },
528
+ value: I.additionalQty,
529
+ onChange: (e) => L((t) => ({
530
+ ...t,
531
+ additionalQty: e.target.value
532
+ })),
533
+ error: !!G,
534
+ helperText: G || "Sealed units to add to this session."
535
+ }),
536
+ /* @__PURE__ */ i(_, {
537
+ size: "small",
538
+ multiline: !0,
539
+ minRows: 2,
540
+ label: "Notes (optional)",
541
+ value: I.notes,
542
+ onChange: (e) => L((t) => ({
543
+ ...t,
544
+ notes: e.target.value
545
+ }))
546
+ })
547
+ ]
548
+ }) : null }),
549
+ /* @__PURE__ */ a(u, { children: [/* @__PURE__ */ i(c, {
550
+ onClick: U,
551
+ disabled: R,
552
+ children: "Cancel"
553
+ }), /* @__PURE__ */ i(c, {
554
+ variant: "contained",
555
+ onClick: () => void K(),
556
+ disabled: !!G || R,
557
+ children: R ? "Submitting…" : "Top Up"
558
+ })] })
559
+ ]
560
+ })
561
+ ] });
562
+ }
563
+ //#endregion
564
+ export { S as default };
565
+
566
+ //# sourceMappingURL=PickupsPage-Ci2Ll0Kn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PickupsPage-Ci2Ll0Kn.js","names":[],"sources":["../src/views/PickupsPage.jsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControl,\n FormHelperText,\n InputAdornment,\n InputLabel,\n MenuItem,\n Select,\n Skeleton,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport { alpha } from '@mui/material/styles';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\nimport SearchRoundedIcon from '@mui/icons-material/SearchRounded';\nimport MoveDownRoundedIcon from '@mui/icons-material/MoveDownRounded';\nimport AssignmentReturnRoundedIcon from '@mui/icons-material/AssignmentReturnRounded';\nimport { showToast } from '@/common/toaster/toaster';\nimport PmPageShell from '@pm/components/PmPageShell';\nimport PmNav from '@pm/components/PmNav';\nimport PmGuard from '@pm/components/PmGuard';\nimport { usePermissionedEffect, usePmPermissions } from '@pm/utils/permissions';\nimport {\n PmEmptyRow,\n PmRef,\n PmTable,\n PmTableCard,\n} from '@pm/components/PmTable';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n listPickups,\n recordPickupReturn,\n recordPickupTopup,\n} from '@pm/services/pmApi';\nimport { formatDate, formatDateTime } from '@pm/utils/format';\nimport { PICKUP_STATUSES, WASTAGE_REASONS, labelOf } from '@pm/utils/constants';\n\nfunction statusChipColor(status) {\n switch (status) {\n case 'OPEN': return 'info';\n case 'RETURNED': return 'success';\n case 'CANCELLED': return 'default';\n default: return 'default';\n }\n}\n\nexport default function PickupsPage() {\n const navigate = useNavigate();\n const perms = usePmPermissions();\n const canCreate = perms.has('update.manage.productManagement.pickup');\n const [rows, setRows] = useState([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState('');\n const [search, setSearch] = useState('');\n const [returnDialog, setReturnDialog] = useState({ open: false, pickup: null });\n const [returnForm, setReturnForm] = useState({ returnedQty: '', wastageReason: '', notes: '' });\n const [topupDialog, setTopupDialog] = useState({ open: false, pickup: null });\n const [topupForm, setTopupForm] = useState({ additionalQty: '', notes: '' });\n const [submitting, setSubmitting] = useState(false);\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n setRows(await listPickups());\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load pickups';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect('view.manage.productManagement.pickup', () => { void load(); }, []);\n\n const filtered = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return rows;\n return rows.filter((r) => {\n const hay = `${r.productName ?? ''} ${r.facilityName ?? ''} ${r.userName ?? ''} ${r.lotNumber ?? ''} ${r.notes ?? ''}`.toLowerCase();\n return hay.includes(q);\n });\n }, [rows, search]);\n\n function openReturn(p) {\n const expected = p.expectedRemainingQty ?? 0;\n setReturnForm({\n // Default to \"return everything that's expected to remain\" — no wastage.\n returnedQty: String(expected),\n wastageReason: '',\n notes: '',\n });\n setReturnDialog({ open: true, pickup: p });\n }\n\n function closeReturn() {\n if (submitting) return;\n setReturnDialog({ open: false, pickup: null });\n }\n\n function openTopup(p) {\n setTopupForm({ additionalQty: '1', notes: '' });\n setTopupDialog({ open: true, pickup: p });\n }\n\n function closeTopup() {\n if (submitting) return;\n setTopupDialog({ open: false, pickup: null });\n }\n\n const topupAdditionalQty = Number(topupForm.additionalQty);\n const topupQtyError = !Number.isInteger(topupAdditionalQty) || topupAdditionalQty <= 0\n ? 'Enter a whole number greater than 0.'\n : '';\n\n async function submitTopup() {\n if (topupQtyError || !topupDialog.pickup) return;\n setSubmitting(true);\n try {\n await recordPickupTopup(topupDialog.pickup.id, {\n id: uuidv4(),\n additionalQty: topupAdditionalQty,\n notes: topupForm.notes || null,\n });\n showToast({\n message: `Topped up ${topupAdditionalQty} unit${topupAdditionalQty === 1 ? '' : 's'}.`,\n type: 'success',\n });\n closeTopup();\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to top up';\n showToast({ message, type: 'error' });\n } finally {\n setSubmitting(false);\n }\n }\n\n const expectedRemaining = returnDialog.pickup?.expectedRemainingQty ?? 0;\n const returnedQty = Number(returnForm.returnedQty);\n const wastedQty = Number.isFinite(returnedQty) && returnedQty >= 0 && returnedQty <= expectedRemaining\n ? expectedRemaining - returnedQty\n : null;\n const returnedQtyError = !Number.isInteger(returnedQty) || returnedQty < 0\n ? 'Enter a whole number from 0 to the expected remaining.'\n : returnedQty > expectedRemaining\n ? `At most ${expectedRemaining} can be returned.`\n : '';\n // Reason is required whenever ANY wastage will be written — either the\n // sealed-units gap is > 0, or there are open vials to close (their\n // remaining volume becomes wastage).\n const reasonRequired = (wastedQty != null && wastedQty > 0)\n || ((returnDialog.pickup?.openVials ?? []).length > 0);\n const reasonError = reasonRequired && !returnForm.wastageReason\n ? 'A reason is required for the wastage being recorded.'\n : '';\n const returnFormValid = !returnedQtyError && !reasonError;\n\n async function submitReturn() {\n if (!returnFormValid || !returnDialog.pickup) return;\n setSubmitting(true);\n try {\n await recordPickupReturn(returnDialog.pickup.id, {\n returnedQty,\n wastageReason: reasonRequired ? returnForm.wastageReason : null,\n notes: returnForm.notes || null,\n });\n showToast({\n message: wastedQty > 0\n ? `Returned ${returnedQty}, wasted ${wastedQty}.`\n : `Returned ${returnedQty} unit${returnedQty === 1 ? '' : 's'}.`,\n type: 'success',\n });\n closeReturn();\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to record return';\n showToast({ message, type: 'error' });\n } finally {\n setSubmitting(false);\n }\n }\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement.pickup'}>\n <PmPageShell\n title=\"Stock Pickups\"\n subtitle=\"Stock you're carrying for field work. Record returns and any items lost or used.\"\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n {canCreate ? (\n <Button variant=\"contained\" startIcon={<AddRoundedIcon />}\n onClick={() => navigate('/ui/medplat/manage/pm/pickups/new')}>\n New Pickup\n </Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Operations\"\n title=\"Pickups\"\n subtitle={loading ? 'Loading…' : `${filtered.length} ${filtered.length === 1 ? 'pickup' : 'pickups'}`}\n >\n <Stack direction={{ xs: 'column', md: 'row' }} spacing={1.5} sx={{ mb: 2 }}>\n <TextField\n size=\"small\" fullWidth\n placeholder=\"Search by product, facility, user, lot, notes…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n InputProps={{\n startAdornment: <InputAdornment position=\"start\"><SearchRoundedIcon fontSize=\"small\" /></InputAdornment>,\n }}\n />\n </Stack>\n\n <PmTable dense>\n <TableHead>\n <TableRow>\n <TableCell>Ref</TableCell>\n <TableCell>Product</TableCell>\n <TableCell>Facility</TableCell>\n <TableCell>User</TableCell>\n <TableCell align=\"right\">Qty</TableCell>\n <TableCell>Picked</TableCell>\n <TableCell>Status</TableCell>\n <TableCell align=\"right\">Action</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n Array.from({ length: 4 }).map((_, i) => (\n <TableRow key={i}>\n {Array.from({ length: 8 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : filtered.length === 0 ? (\n <PmEmptyRow\n colSpan={8}\n icon={MoveDownRoundedIcon}\n title={search.trim() !== '' ? 'No pickups match your search' : 'No pickups yet'}\n hint=\"Check out stock from a facility to use in the field.\"\n action={canCreate ? (\n <Button variant=\"contained\" size=\"small\" startIcon={<AddRoundedIcon />}\n onClick={() => navigate('/ui/medplat/manage/pm/pickups/new')}>\n Record first pickup\n </Button>\n ) : null}\n />\n ) : filtered.map((r) => (\n <TableRow key={r.id} hover>\n <TableCell><PmRef id={r.serialId} /></TableCell>\n <TableCell>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>{r.productName ?? '—'}</Typography>\n {r.lotNumber ? (\n <Typography variant=\"caption\" sx={{ fontFamily: 'monospace', color: 'text.secondary' }}>\n {r.lotNumber}\n </Typography>\n ) : null}\n </TableCell>\n <TableCell>{r.facilityName ?? '—'}</TableCell>\n <TableCell>{r.userName ?? '—'}</TableCell>\n <TableCell align=\"right\">\n <Typography sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{r.pickedQty}</Typography>\n {r.status === 'OPEN' && r.expectedRemainingQty != null ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {r.expectedRemainingQty} left on user\n </Typography>\n ) : r.status === 'RETURNED' ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {r.returnedQty} returned{r.wastedQty > 0 ? ` · ${r.wastedQty} wasted` : ''}\n </Typography>\n ) : null}\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">{formatDate(r.pickedOn)}</Typography>\n </TableCell>\n <TableCell>\n <Chip size=\"small\" label={labelOf(PICKUP_STATUSES, r.status)} color={statusChipColor(r.status)} />\n </TableCell>\n <TableCell align=\"right\">\n {r.status === 'OPEN' && canCreate ? (\n <Stack direction=\"row\" spacing={1} justifyContent=\"flex-end\">\n <Button size=\"small\" variant=\"outlined\" startIcon={<AddRoundedIcon />}\n onClick={() => openTopup(r)}>\n Top Up\n </Button>\n <Button size=\"small\" variant=\"outlined\" startIcon={<AssignmentReturnRoundedIcon />}\n onClick={() => openReturn(r)}>\n End Session\n </Button>\n </Stack>\n ) : (\n <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n </PmGuard>\n\n {/* ---------- End Outreach Session dialog ---------- */}\n <Dialog open={returnDialog.open} onClose={closeReturn} maxWidth=\"sm\" fullWidth>\n <DialogTitle>End outreach session #{returnDialog.pickup?.serialId}</DialogTitle>\n <DialogContent>\n {returnDialog.pickup ? (\n <Stack spacing={2} sx={{ mt: 1 }}>\n <Box sx={(t) => ({\n p: 1.5, borderRadius: 3,\n bgcolor: alpha(t.palette.primary.main, 0.04),\n border: `1px solid ${alpha(t.palette.primary.main, 0.12)}`,\n })}>\n <Typography variant=\"body2\"><strong>{returnDialog.pickup.productName}</strong></Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block' }}>\n Picked {returnDialog.pickup.pickedQty} on {formatDateTime(returnDialog.pickup.pickedOn)} from {returnDialog.pickup.facilityName}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mt: 0.5 }}>\n Sealed units expected on user: <strong>{expectedRemaining}</strong>\n {' '}({(returnDialog.pickup.pickedQty ?? 0) - expectedRemaining - ((returnDialog.pickup.openVials ?? []).length)} already administered / wasted during the day)\n </Typography>\n </Box>\n\n <TextField\n required size=\"small\" type=\"number\"\n label=\"Sealed Units Returned\"\n inputProps={{ min: 0, max: expectedRemaining }}\n value={returnForm.returnedQty}\n onChange={(e) => setReturnForm((f) => ({ ...f, returnedQty: e.target.value }))}\n error={!!returnedQtyError}\n helperText={returnedQtyError || `Out of ${expectedRemaining} sealed units expected to remain`}\n />\n\n {wastedQty != null && wastedQty > 0 ? (\n <Alert severity=\"warning\" variant=\"outlined\">\n <strong>{wastedQty}</strong> sealed {wastedQty === 1 ? 'unit' : 'units'} unaccounted for — will be marked as wastage.\n </Alert>\n ) : null}\n\n {/* Open-vial wastage preview. Any vial opened during outreach\n does not return to the facility — it's closed with wastage\n as part of this end-session action. Volume shown so the\n operator knows what's being written off. */}\n {(returnDialog.pickup.openVials ?? []).length > 0 ? (\n <Alert severity=\"info\" variant=\"outlined\">\n <Typography variant=\"body2\" sx={{ fontWeight: 700, mb: 0.5 }}>\n {returnDialog.pickup.openVials.length} open vial{returnDialog.pickup.openVials.length === 1 ? '' : 's'} on you will be closed with wastage\n </Typography>\n <Stack spacing={0.25} sx={{ mt: 0.5 }}>\n {returnDialog.pickup.openVials.map((v) => (\n <Typography key={v.id} variant=\"caption\" color=\"text.secondary\">\n Lot {v.lotNumber || '—'} · {Number(v.volumeRemainingMl ?? 0).toFixed(2)} ml remaining\n </Typography>\n ))}\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mt: 0.75 }}>\n These volumes will be recorded as wastage using the reason picked below.\n </Typography>\n </Alert>\n ) : null}\n\n <FormControl size=\"small\" disabled={!reasonRequired} error={!!reasonError}>\n <InputLabel>Wastage Reason{reasonRequired ? ' *' : ''}</InputLabel>\n <Select\n label={`Wastage Reason${reasonRequired ? ' *' : ''}`}\n value={returnForm.wastageReason}\n onChange={(e) => setReturnForm((f) => ({ ...f, wastageReason: e.target.value }))}\n >\n <MenuItem value=\"\"><em>—</em></MenuItem>\n {WASTAGE_REASONS.map((r) => (\n <MenuItem key={r.value} value={r.value}>{r.label}</MenuItem>\n ))}\n </Select>\n <FormHelperText>\n {reasonError\n || (reasonRequired\n ? 'Required — same reason covers both unaccounted sealed units and any open-vial remaining volume.'\n : 'Not needed — nothing being wasted.')}\n </FormHelperText>\n </FormControl>\n\n <TextField\n size=\"small\" multiline minRows={2}\n label=\"Notes (optional)\"\n value={returnForm.notes}\n onChange={(e) => setReturnForm((f) => ({ ...f, notes: e.target.value }))}\n />\n </Stack>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={closeReturn} disabled={submitting}>Cancel</Button>\n <Button variant=\"contained\" onClick={() => void submitReturn()}\n disabled={!returnFormValid || submitting}>\n {submitting ? 'Submitting…' : 'End Session'}\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* ---------- Top Up dialog ---------- */}\n <Dialog open={topupDialog.open} onClose={closeTopup} maxWidth=\"xs\" fullWidth>\n <DialogTitle>Top up session #{topupDialog.pickup?.serialId}</DialogTitle>\n <DialogContent>\n {topupDialog.pickup ? (\n <Stack spacing={2} sx={{ mt: 1 }}>\n <Box sx={(t) => ({\n p: 1.5, borderRadius: 3,\n bgcolor: alpha(t.palette.primary.main, 0.04),\n border: `1px solid ${alpha(t.palette.primary.main, 0.12)}`,\n })}>\n <Typography variant=\"body2\"><strong>{topupDialog.pickup.productName}</strong></Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block' }}>\n Source: {topupDialog.pickup.facilityName} · Lot {topupDialog.pickup.lotNumber || '—'}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block' }}>\n Currently picked: {topupDialog.pickup.pickedQty} · remaining sealed on user: {topupDialog.pickup.expectedRemainingQty ?? 0}\n </Typography>\n </Box>\n\n <Alert severity=\"info\" variant=\"outlined\">\n Top-ups come from the same source batch as the original pickup so lot / expiry stays consistent. To pick from a different batch, end this session first.\n </Alert>\n\n <TextField\n required size=\"small\" type=\"number\"\n label=\"Additional Quantity\"\n inputProps={{ min: 1 }}\n value={topupForm.additionalQty}\n onChange={(e) => setTopupForm((f) => ({ ...f, additionalQty: e.target.value }))}\n error={!!topupQtyError}\n helperText={topupQtyError || 'Sealed units to add to this session.'}\n />\n\n <TextField\n size=\"small\" multiline minRows={2}\n label=\"Notes (optional)\"\n value={topupForm.notes}\n onChange={(e) => setTopupForm((f) => ({ ...f, notes: e.target.value }))}\n />\n </Stack>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={closeTopup} disabled={submitting}>Cancel</Button>\n <Button variant=\"contained\" onClick={() => void submitTopup()}\n disabled={!!topupQtyError || submitting}>\n {submitting ? 'Submitting…' : 'Top Up'}\n </Button>\n </DialogActions>\n </Dialog>\n </Box>\n );\n}\n"],"mappings":"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"}