@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 @@
1
+ {"version":3,"file":"VialsPage-CjqPfgpV.js","names":[],"sources":["../src/views/VialsPage.jsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControl,\n FormHelperText,\n InputLabel,\n LinearProgress,\n MenuItem,\n Radio,\n Select,\n Stack,\n Table,\n TableBody,\n TableCell,\n TableContainer,\n TableHead,\n TableRow,\n TextField,\n Tooltip,\n Typography,\n} from \"@mui/material\";\nimport RefreshRoundedIcon from \"@mui/icons-material/RefreshRounded\";\nimport VaccinesRoundedIcon from \"@mui/icons-material/VaccinesRounded\";\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 { PmEmptyRow, PmTable, PmTableCard } from \"@pm/components/PmTable\";\nimport {\n administerDose,\n closeVial,\n getProducts,\n listFacilities,\n listOpenVials,\n listVialsForProduct,\n listBatches,\n} from \"@pm/services/pmApi\";\nimport {\n VACCINES_CATEGORY_CODE,\n VIAL_STATUSES,\n WASTAGE_REASONS,\n labelOf,\n} from \"@pm/utils/constants\";\nimport { formatDate, formatDateTime, formatNumber } from \"@pm/utils/format\";\nimport {\n isClean,\n validatePositiveNumber,\n validateRequired,\n} from \"@pm/utils/validation\";\nimport { useFieldErrors } from \"@pm/utils/useFieldErrors\";\n\n// Earliest-expiry-first: a vial is unusable past whichever date arrives first —\n// its own open-vial validity (expiresAt) or its parent batch's printed expiry.\n//\n// The batch's expiryDate is a date-only field; the batch is valid through the\n// whole of that day, so we shift it to end-of-day before comparing. Without\n// this, a batch printed-expiry of today is treated as \"expired at 00:00\",\n// which incorrectly filters out otherwise-usable open vials mid-day.\nfunction effectiveVialExpiry(v) {\n const vialT = v.expiresAt ? new Date(v.expiresAt).getTime() : Infinity;\n let batchT = Infinity;\n if (v.batchExpiryDate) {\n const d = new Date(v.batchExpiryDate);\n d.setHours(23, 59, 59, 999);\n batchT = d.getTime();\n }\n return Math.min(vialT, batchT);\n}\n\nfunction batchExpiryMs(b) {\n return b.expiryDate ? new Date(b.expiryDate).getTime() : Infinity;\n}\n\nconst EMPTY_VACCINE_DIALOG = {\n open: false,\n step: \"product\", // 'product' | 'select'\n mode: \"use-existing\", // 'use-existing' (open vials available) | 'open-new' (need to open from a batch)\n productId: \"\",\n // Source = administration context. USER (outreach, consume from personal\n // pickup stock) or FACILITY (consume from a facility the user is assigned\n // to). Each source has an isolated open-vial pool — a facility vial cannot\n // satisfy an outreach administration and vice-versa.\n ownerType: \"\", // 'USER' | 'FACILITY'\n ownerId: \"\", // facility uuid when ownerType=FACILITY; empty for USER\n // Unfiltered candidate pools (pre-source-filter). Used to recompute the\n // displayed vialCandidates / batchCandidates when the user changes source.\n allVials: [],\n allBatches: [],\n // The per-source available source list, computed in proceedFromProductStep\n // so the source picker only shows owners with actual stock for this product.\n sources: [],\n vialCandidates: [],\n batchCandidates: [],\n selectedVialId: \"\",\n selectedBatchId: \"\",\n volumeMl: \"\",\n loading: false,\n};\n\nexport default function VialsPage() {\n const perms = usePmPermissions();\n const canWrite = perms.has(\"update.manage.productManagement.vial\");\n const [vials, setVials] = useState([]);\n const [batches, setBatches] = useState([]);\n const [products, setProducts] = useState([]);\n // Assigned facilities — used to label the source picker on the administer\n // dialog (\"Facility — <name>\"). The user can only administer from\n // facilities they're assigned to.\n const [facilities, setFacilities] = useState([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState(\"\");\n const [closeDialog, setCloseDialog] = useState({\n open: false,\n vial: null,\n reason: \"TIME_EXPIRATION\",\n comments: \"\",\n });\n // Single consolidated \"Administer Vaccine\" flow: pick vaccine → pick open vial OR\n // pick a sealed batch and open-and-administer in one call.\n const [vaccineDialog, setVaccineDialog] = useState(EMPTY_VACCINE_DIALOG);\n const closeFieldErrors = useFieldErrors();\n const vaccineFieldErrors = useFieldErrors();\n\n async function load() {\n setLoading(true);\n setError(\"\");\n try {\n const [v, b, p, f] = await Promise.all([\n listOpenVials(),\n listBatches(),\n getProducts(),\n // Empty array if perm-gated — the dialog falls back to USER-only sources.\n listFacilities().catch(() => []),\n ]);\n setVials(v);\n setBatches(b);\n setProducts(p);\n setFacilities(f);\n } catch (err) {\n setError(\n err?.response?.data?.message ?? err?.message ?? \"Failed to load\",\n );\n showToast({ message: err?.message || \"Failed to load\", type: \"error\" });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect(\n \"view.manage.productManagement.vial\",\n () => {\n void load();\n },\n [],\n );\n\n // Vaccine products with a vaccine config — used by the administer dialog.\n const vaccineProducts = useMemo(\n () =>\n products\n .filter((p) => p.categoryCode === VACCINES_CATEGORY_CODE && p.isActive)\n .sort((a, b) => a.name.localeCompare(b.name)),\n [products],\n );\n\n const closeErrors = {\n wastageReason: validateRequired(closeDialog.reason, \"Reason\"),\n };\n const closeIsValid = isClean(closeErrors);\n\n async function doClose() {\n if (!closeDialog.vial) return;\n if (!closeIsValid) {\n closeFieldErrors.markAllTouched();\n return;\n }\n try {\n await closeVial({\n id: uuidv4(),\n openVialId: closeDialog.vial.id,\n wastageReason: closeDialog.reason,\n comments: closeDialog.comments || null,\n });\n showToast({ message: \"Vial closed.\", type: \"success\" });\n setCloseDialog({\n open: false,\n vial: null,\n reason: \"TIME_EXPIRATION\",\n comments: \"\",\n });\n await load();\n } catch (err) {\n showToast({\n message: err?.response?.data?.message ?? err?.message ?? \"Failed\",\n type: \"error\",\n });\n }\n }\n\n // -------- Administer flow --------\n function closeVaccineDialog() {\n vaccineFieldErrors.reset();\n setVaccineDialog(EMPTY_VACCINE_DIALOG);\n }\n\n // Takes the batch pool to filter as an arg so callers can use either the\n // cached `batches` state or a freshly-fetched list (e.g. when the dialog\n // refreshes mid-flow after the user did a pickup elsewhere).\n function fefoBatchesForProduct(productId, pool = batches) {\n const todayMs = new Date().setHours(0, 0, 0, 0);\n return pool\n .filter(\n (b) =>\n b.productId === productId &&\n b.qtyRemaining > 0 &&\n !b.isQuarantined &&\n (!b.expiryDate || new Date(b.expiryDate).getTime() >= todayMs),\n )\n .sort((a, b) => batchExpiryMs(a) - batchExpiryMs(b));\n }\n\n async function proceedFromProductStep() {\n if (!vaccineDialog.productId) {\n vaccineFieldErrors.markAllTouched();\n return;\n }\n setVaccineDialog((d) => ({ ...d, loading: true }));\n try {\n // Re-fetch live batches + facilities here too. The page-mount load only\n // runs once, so a pickup or new facility assignment made elsewhere in\n // the session would otherwise leave the source picker missing options.\n // Vials are already fetched per-product below, so we co-load all three.\n const [list, freshBatches, freshFacilities] = await Promise.all([\n listVialsForProduct(vaccineDialog.productId),\n listBatches().catch(() => batches),\n listFacilities().catch(() => facilities),\n ]);\n setBatches(freshBatches);\n setFacilities(freshFacilities);\n const now = Date.now();\n const usableVials = list\n .filter(\n (v) =>\n v.status === \"OPEN\" &&\n !v.expired &&\n effectiveVialExpiry(v) > now &&\n Number(v.volumeRemainingMl) > 0,\n )\n .sort((a, b) => effectiveVialExpiry(a) - effectiveVialExpiry(b));\n\n // Per-batch OPEN-vial count — used to filter out batches that have already hit\n // the configured maxConcurrentOpenVials cap. Backend will reject those anyway,\n // we just don't want to offer them.\n const openCountByBatch = list.reduce((acc, v) => {\n if (v.status === \"OPEN\") acc[v.batchId] = (acc[v.batchId] || 0) + 1;\n return acc;\n }, {});\n\n const product = products.find((p) => p.id === vaccineDialog.productId);\n const cfg = product?.vaccineConfig;\n const maxConcurrent = cfg?.maxConcurrentOpenVials ?? 2;\n const fefo = fefoBatchesForProduct(\n vaccineDialog.productId,\n freshBatches,\n ).filter((b) => (openCountByBatch[b.id] || 0) < maxConcurrent);\n\n // Derive the source picker options. A source is \"available\" iff the\n // user has either an open usable vial OR a fresh-vialable batch for\n // this product at that owner. Drop sources with no stock so the\n // picker never offers a dead-end.\n const sourceKeys = new Set();\n const sources = [];\n function pushSource(ownerType, ownerId, label) {\n const key = `${ownerType}::${ownerId ?? \"\"}`;\n if (sourceKeys.has(key)) return;\n sourceKeys.add(key);\n sources.push({ key, ownerType, ownerId: ownerId ?? null, label });\n }\n // Personal (outreach) — derived from any USER-owned vial/batch.\n const hasPersonal =\n usableVials.some((v) => v.ownerType === \"USER\") ||\n fefo.some((b) => b.ownerType === \"USER\");\n if (hasPersonal) pushSource(\"USER\", null, \"Personal (outreach)\");\n // Facility sources — one per facility owner with stock for this product.\n const facilityIds = new Set();\n usableVials.forEach((v) => {\n if (v.ownerType === \"FACILITY\" && v.ownerId) facilityIds.add(v.ownerId);\n });\n fefo.forEach((b) => {\n if (b.ownerType === \"FACILITY\" && b.ownerId) facilityIds.add(b.ownerId);\n });\n facilityIds.forEach((fid) => {\n // Use the freshly-fetched facility list, not the cached state —\n // setFacilities() above hasn't committed yet at this point in the\n // render cycle.\n const fac = freshFacilities.find((x) => x.id === fid);\n pushSource(\"FACILITY\", fid, `Facility — ${fac?.name ?? fid}`);\n });\n\n // Default source: single available → autopick; multiple → require the\n // operator to commit (no preselection so the picker is the first thing\n // they interact with).\n const defaultSource = sources.length === 1 ? sources[0] : null;\n const defaultOwnerType = defaultSource?.ownerType ?? \"\";\n const defaultOwnerId = defaultSource?.ownerId ?? \"\";\n\n // Filter candidates by the (possibly-empty) default source. When no\n // default is picked, show empty lists; the operator picks a source first.\n const filtered = filterCandidatesByOwner(\n usableVials,\n fefo,\n defaultOwnerType,\n defaultOwnerId,\n );\n\n const defaultMode =\n filtered.vials.length > 0 ? \"use-existing\" : \"open-new\";\n setVaccineDialog((d) => ({\n ...d,\n loading: false,\n step: \"select\",\n mode: defaultMode,\n ownerType: defaultOwnerType,\n ownerId: defaultOwnerId,\n allVials: usableVials,\n allBatches: fefo,\n sources,\n vialCandidates: filtered.vials,\n batchCandidates: filtered.batches,\n selectedVialId: filtered.vials[0]?.id ?? \"\",\n selectedBatchId: filtered.batches[0]?.id ?? \"\",\n volumeMl:\n defaultMode === \"use-existing\"\n ? (filtered.vials[0]?.adultDoseMl ?? cfg?.adultDoseMl ?? \"\")\n : (cfg?.adultDoseMl ?? \"\"),\n }));\n } catch (err) {\n setVaccineDialog((d) => ({ ...d, loading: false }));\n showToast({\n message:\n err?.response?.data?.message ??\n err?.message ??\n \"Failed to load vials\",\n type: \"error\",\n });\n }\n }\n\n // Slice the full vial / batch pools down to just the rows matching the\n // selected administration source. Pulled out so the source-change handler\n // can reuse it without duplicating the predicate.\n function filterCandidatesByOwner(allVials, allBatches, ownerType, ownerId) {\n if (!ownerType) return { vials: [], batches: [] };\n const matchVial = (v) =>\n v.ownerType === ownerType &&\n (ownerType === \"USER\" || v.ownerId === ownerId);\n const matchBatch = (b) =>\n b.ownerType === ownerType &&\n (ownerType === \"USER\" || b.ownerId === ownerId);\n return {\n vials: allVials.filter(matchVial),\n batches: allBatches.filter(matchBatch),\n };\n }\n\n function pickSource(sourceKey) {\n const next = vaccineDialog.sources.find((s) => s.key === sourceKey);\n if (!next) return;\n const filtered = filterCandidatesByOwner(\n vaccineDialog.allVials,\n vaccineDialog.allBatches,\n next.ownerType,\n next.ownerId,\n );\n const product = products.find((p) => p.id === vaccineDialog.productId);\n const cfg = product?.vaccineConfig;\n // Pick the same mode-default logic as proceedFromProductStep — favour\n // use-existing when a vial is available, fall back to open-new otherwise.\n const nextMode = filtered.vials.length > 0 ? \"use-existing\" : \"open-new\";\n setVaccineDialog((d) => ({\n ...d,\n ownerType: next.ownerType,\n ownerId: next.ownerId ?? \"\",\n mode: nextMode,\n vialCandidates: filtered.vials,\n batchCandidates: filtered.batches,\n selectedVialId: filtered.vials[0]?.id ?? \"\",\n selectedBatchId: filtered.batches[0]?.id ?? \"\",\n // Reset volume so the operator doesn't carry stale dose from a\n // different source — the new vial's adult dose drives it.\n volumeMl:\n nextMode === \"use-existing\"\n ? (filtered.vials[0]?.adultDoseMl ?? cfg?.adultDoseMl ?? \"\")\n : (cfg?.adultDoseMl ?? \"\"),\n }));\n }\n\n function switchMode(nextMode) {\n // Preserve the typed volume across mode flips — the operator is dosing a real patient,\n // the intent doesn't change just because we're picking a different vial/batch.\n setVaccineDialog((d) => ({ ...d, mode: nextMode }));\n }\n\n const vaccineSelectedVial = vaccineDialog.vialCandidates.find(\n (v) => v.id === vaccineDialog.selectedVialId,\n );\n const vaccineSelectedBatch = vaccineDialog.batchCandidates.find(\n (b) => b.id === vaccineDialog.selectedBatchId,\n );\n const vaccineSelectedProduct = products.find(\n (p) => p.id === vaccineDialog.productId,\n );\n const vaccineCfg = vaccineSelectedProduct?.vaccineConfig;\n\n const vaccineErrors = (() => {\n if (vaccineDialog.step === \"product\") {\n return {\n productId: validateRequired(vaccineDialog.productId, \"Vaccine\"),\n };\n }\n const errs = {\n // Source picker is required before the operator can pick a vial /\n // batch — without it the backend can't scope its vial pool.\n ownerType: validateRequired(vaccineDialog.ownerType, \"Source\"),\n volumeMl: validatePositiveNumber(vaccineDialog.volumeMl, \"Volume\", {\n required: true,\n }),\n };\n if (vaccineDialog.mode === \"use-existing\") {\n errs.selectedVialId = validateRequired(\n vaccineDialog.selectedVialId,\n \"Vial\",\n );\n if (!errs.volumeMl && vaccineSelectedVial) {\n const vol = Number(vaccineDialog.volumeMl);\n const remaining = Number(vaccineSelectedVial.volumeRemainingMl);\n if (vol > remaining) {\n errs.volumeMl =\n vaccineDialog.batchCandidates.length > 0\n ? `Only ${remaining.toFixed(2)} ml remaining in this vial — open another vial instead.`\n : `Only ${remaining.toFixed(2)} ml remaining in this vial.`;\n }\n }\n } else {\n errs.selectedBatchId = validateRequired(\n vaccineDialog.selectedBatchId,\n \"Batch\",\n );\n if (!errs.volumeMl && vaccineCfg?.vialVolumeMl) {\n const vol = Number(vaccineDialog.volumeMl);\n const total = Number(vaccineCfg.vialVolumeMl);\n if (vol > total)\n errs.volumeMl = `A fresh vial holds ${total.toFixed(2)} ml`;\n }\n }\n return errs;\n })();\n const vaccineIsValid = isClean(vaccineErrors);\n\n async function doVaccineAdminister() {\n if (!vaccineIsValid) {\n vaccineFieldErrors.markAllTouched();\n return;\n }\n try {\n const payload = {\n id: uuidv4(),\n productId: vaccineDialog.productId,\n volumeMl: Number(vaccineDialog.volumeMl),\n // Owner = administration source. Drives backend's open-vial pool\n // scoping so an outreach administer can't reach into facility stock\n // and vice-versa.\n ownerType: vaccineDialog.ownerType,\n ownerId:\n vaccineDialog.ownerType === \"FACILITY\"\n ? vaccineDialog.ownerId || null\n : null,\n };\n if (vaccineDialog.mode === \"use-existing\") {\n payload.openVialId = vaccineSelectedVial.id;\n } else {\n // Backend opens a fresh vial from this batch and administers in the same transaction.\n payload.batchId = vaccineSelectedBatch.id;\n }\n await administerDose(payload);\n showToast({\n message:\n vaccineDialog.mode === \"use-existing\"\n ? \"Dose administered.\"\n : \"New vial opened and dose administered.\",\n type: \"success\",\n });\n closeVaccineDialog();\n await load();\n } catch (err) {\n showToast({\n message: err?.response?.data?.message ?? err?.message ?? \"Failed\",\n type: \"error\",\n });\n }\n }\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={\"view.manage.productManagement.vial\"}>\n <PmPageShell\n title=\"Open Vials\"\n subtitle=\"Open vaccine vials in use. Close them at the end of the day and record any waste.\"\n chips={[\"Vaccine\"]}\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button\n variant=\"outlined\"\n startIcon={<RefreshRoundedIcon />}\n onClick={() => void load()}\n >\n Refresh\n </Button>\n {/* DEMO-ONLY: the Administer Vaccine entry point lives elsewhere\n in production (a vaccinator's flow passes the open vial id in).\n Unhide the button below to dose from this page for demos. */}\n {false && (\n <Button\n variant=\"contained\"\n startIcon={<VaccinesRoundedIcon />}\n onClick={() => {\n vaccineFieldErrors.reset();\n setVaccineDialog({ ...EMPTY_VACCINE_DIALOG, open: true });\n }}\n >\n Administer Vaccine\n </Button>\n )}\n </Stack>\n }\n >\n {error ? (\n <Alert severity=\"error\" sx={{ mb: 2 }}>\n {error}\n </Alert>\n ) : null}\n {loading ? <LinearProgress sx={{ mb: 2 }} /> : null}\n\n <PmTableCard\n eyebrow=\"In use\"\n title=\"Open vials\"\n subtitle={\n loading\n ? \"Loading…\"\n : `${vials.length} ${vials.length === 1 ? \"vial\" : \"vials\"} currently in use`\n }\n >\n <PmTable dense>\n <TableHead>\n <TableRow>\n <TableCell>Product</TableCell>\n <TableCell>Lot</TableCell>\n <TableCell>Owner</TableCell>\n <TableCell>Opened</TableCell>\n <TableCell>Expires</TableCell>\n <TableCell>Volume remaining</TableCell>\n <TableCell>Status</TableCell>\n <TableCell align=\"right\">Action</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {vials.length === 0 && !loading ? (\n <PmEmptyRow\n colSpan={8}\n icon={VaccinesRoundedIcon}\n title=\"No open vials\"\n hint=\"Use Administer Vaccine to open and dose a vial.\"\n />\n ) : (\n vials.map((v) => {\n const usage = v.volumeTotalMl\n ? (1 -\n Number(v.volumeRemainingMl) /\n Number(v.volumeTotalMl)) *\n 100\n : 0;\n return (\n <TableRow key={v.id} hover>\n <TableCell>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>\n {v.productName}\n </Typography>\n </TableCell>\n <TableCell>\n {v.lotNumber ? (\n <Box\n component=\"span\"\n sx={{\n display: \"inline-flex\",\n px: 0.7,\n py: 0.1,\n borderRadius: 1,\n bgcolor: \"grey.100\",\n fontFamily: \"monospace\",\n fontSize: \"0.72rem\",\n fontWeight: 700,\n }}\n >\n {v.lotNumber}\n </Box>\n ) : (\n <Typography variant=\"caption\" color=\"text.disabled\">\n —\n </Typography>\n )}\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>\n {v.ownerName ||\n (v.ownerType === \"USER\"\n ? \"Personal\"\n : \"Facility\")}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {v.ownerType ?? \"—\"}\n </Typography>\n </TableCell>\n <TableCell>\n <Typography\n variant=\"caption\"\n sx={{ fontWeight: 600 }}\n >\n {formatDateTime(v.openedAt)}\n </Typography>\n </TableCell>\n <TableCell>\n <Tooltip\n title={\n v.expired ? \"Expired — close out immediately\" : \"\"\n }\n >\n <Chip\n size=\"small\"\n color={v.expired ? \"error\" : \"success\"}\n label={formatDateTime(v.expiresAt)}\n sx={{\n fontWeight: 700,\n borderRadius: 1.5,\n height: 22,\n }}\n />\n </Tooltip>\n </TableCell>\n <TableCell>\n <Stack\n direction=\"row\"\n alignItems=\"center\"\n spacing={1}\n >\n <Typography\n variant=\"body2\"\n sx={{\n fontWeight: 800,\n fontVariantNumeric: \"tabular-nums\",\n minWidth: 80,\n }}\n >\n {formatNumber(v.volumeRemainingMl)} /{\" \"}\n {formatNumber(v.volumeTotalMl)} ml\n </Typography>\n <Box sx={{ width: 80 }}>\n <LinearProgress\n variant=\"determinate\"\n value={usage}\n sx={{ height: 4, borderRadius: 2 }}\n color={usage > 75 ? \"warning\" : \"primary\"}\n />\n </Box>\n </Stack>\n </TableCell>\n <TableCell>\n <Chip\n size=\"small\"\n color={v.expired ? \"error\" : \"info\"}\n label={\n v.expired\n ? \"Expired\"\n : labelOf(VIAL_STATUSES, v.status)\n }\n sx={{\n fontWeight: 700,\n borderRadius: 1.5,\n height: 22,\n }}\n />\n </TableCell>\n <TableCell align=\"right\">\n {canWrite ? (\n <Button\n size=\"small\"\n variant=\"outlined\"\n color=\"error\"\n onClick={() => {\n closeFieldErrors.reset();\n setCloseDialog({\n open: true,\n vial: v,\n reason: \"TIME_EXPIRATION\",\n comments: \"\",\n });\n }}\n >\n Close\n </Button>\n ) : null}\n </TableCell>\n </TableRow>\n );\n })\n )}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n\n <Dialog\n open={vaccineDialog.open}\n onClose={closeVaccineDialog}\n fullWidth\n maxWidth=\"md\"\n >\n <DialogTitle>\n {vaccineDialog.step === \"product\"\n ? \"Administer Vaccine — Select Vaccine\"\n : vaccineDialog.mode === \"use-existing\"\n ? \"Administer Vaccine — Select Open Vial\"\n : \"Administer Vaccine — Open & Administer\"}\n </DialogTitle>\n <DialogContent dividers>\n {vaccineDialog.step === \"product\" ? (\n <FormControl\n required\n fullWidth\n size=\"small\"\n sx={{ mt: 1 }}\n error={\n vaccineFieldErrors.show(\"productId\") &&\n !!vaccineErrors.productId\n }\n >\n <InputLabel>Vaccine</InputLabel>\n <Select\n label=\"Vaccine\"\n value={vaccineDialog.productId}\n onChange={(e) =>\n setVaccineDialog({\n ...vaccineDialog,\n productId: e.target.value,\n })\n }\n onBlur={vaccineFieldErrors.onBlur(\"productId\")}\n >\n {vaccineProducts.length === 0 ? (\n <MenuItem value=\"\" disabled>\n <em>No active vaccine products</em>\n </MenuItem>\n ) : null}\n {vaccineProducts.map((p) => (\n <MenuItem key={p.id} value={p.id}>\n {p.name}\n {p.vaccineConfig?.vaccineCode\n ? ` · ${p.vaccineConfig.vaccineCode}`\n : \"\"}\n </MenuItem>\n ))}\n </Select>\n <FormHelperText>\n {vaccineFieldErrors.show(\"productId\") &&\n vaccineErrors.productId\n ? vaccineErrors.productId\n : \"Open vials for this vaccine will be shown next. If none are open, a fresh vial can be opened on the same screen.\"}\n </FormHelperText>\n </FormControl>\n ) : (\n <Stack spacing={2} sx={{ pt: 1 }}>\n {vaccineDialog.loading ? <LinearProgress /> : null}\n\n {/* Source picker — drives which open vials / batches the\n operator can pick from. Hidden when only one source is\n available (autoselected). */}\n {vaccineDialog.sources.length === 0 ? (\n <Alert severity=\"warning\">\n No stock available for this vaccine — neither in your\n personal stock nor at an assigned facility.\n </Alert>\n ) : vaccineDialog.sources.length > 1 ? (\n <FormControl\n required\n fullWidth\n size=\"small\"\n error={\n vaccineFieldErrors.show(\"ownerType\") &&\n !!vaccineErrors.ownerType\n }\n >\n <InputLabel>Administer from</InputLabel>\n <Select\n label=\"Administer from\"\n value={\n vaccineDialog.ownerType\n ? `${vaccineDialog.ownerType}::${vaccineDialog.ownerId ?? \"\"}`\n : \"\"\n }\n onChange={(e) => pickSource(e.target.value)}\n onBlur={vaccineFieldErrors.onBlur(\"ownerType\")}\n >\n {vaccineDialog.sources.map((s) => (\n <MenuItem key={s.key} value={s.key}>\n {s.label}\n </MenuItem>\n ))}\n </Select>\n <FormHelperText>\n {vaccineFieldErrors.show(\"ownerType\") &&\n vaccineErrors.ownerType\n ? vaccineErrors.ownerType\n : \"Personal stock (outreach) and facility stock are separate vial pools — pick which one this dose comes from.\"}\n </FormHelperText>\n </FormControl>\n ) : (\n <Alert severity=\"info\">\n Administering from{\" \"}\n <strong>{vaccineDialog.sources[0]?.label}</strong>.\n </Alert>\n )}\n\n {vaccineDialog.mode === \"use-existing\" ? (\n <>\n {!vaccineDialog.ownerType ? (\n <Alert severity=\"info\">\n Pick an administration source above to see the available\n open vials.\n </Alert>\n ) : (\n (() => {\n // Only offer \"Open another vial\" when no existing open vial can\n // actually hold the requested dose. This stops the operator from\n // opening a new vial unnecessarily and accumulating leftover\n // partial vials.\n const vol = Number(vaccineDialog.volumeMl);\n const validVol = !Number.isNaN(vol) && vol > 0;\n const someVialFits =\n validVol &&\n vaccineDialog.vialCandidates.some(\n (v) => Number(v.volumeRemainingMl) >= vol,\n );\n return (\n <Alert\n severity=\"info\"\n action={\n someVialFits ? null : (\n <Button\n color=\"inherit\"\n size=\"small\"\n onClick={() => switchMode(\"open-new\")}\n >\n Open another vial instead\n </Button>\n )\n }\n >\n {someVialFits\n ? \"Pick an open vial — earliest-expiry-first is preselected. An existing vial can hold the requested dose, so no new vial is needed.\"\n : \"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.\"}\n </Alert>\n );\n })()\n )}\n <TableContainer>\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell />\n <TableCell sx={{ fontWeight: 800 }}>Lot</TableCell>\n <TableCell sx={{ fontWeight: 800 }}>\n Vial expires\n </TableCell>\n <TableCell sx={{ fontWeight: 800 }}>\n Batch expires\n </TableCell>\n <TableCell sx={{ fontWeight: 800 }} align=\"right\">\n Remaining (ml)\n </TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {vaccineDialog.vialCandidates.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={5}\n sx={{ py: 4, textAlign: \"center\" }}\n >\n <Stack alignItems=\"center\" spacing={1}>\n <VaccinesRoundedIcon\n sx={{\n fontSize: 36,\n color: \"text.disabled\",\n opacity: 0.7,\n }}\n />\n <Typography\n variant=\"body2\"\n sx={{ fontWeight: 700 }}\n >\n No usable open vials for this vaccine\n </Typography>\n {vaccineDialog.batchCandidates.length > 0 ? (\n <Button\n size=\"small\"\n variant=\"outlined\"\n onClick={() => switchMode(\"open-new\")}\n >\n Open a new vial instead\n </Button>\n ) : (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n >\n No stock available either — receive a\n purchase first.\n </Typography>\n )}\n </Stack>\n </TableCell>\n </TableRow>\n ) : (\n vaccineDialog.vialCandidates.map((v, idx) => {\n const selected =\n vaccineDialog.selectedVialId === v.id;\n return (\n <TableRow\n key={v.id}\n hover\n selected={selected}\n onClick={() =>\n setVaccineDialog({\n ...vaccineDialog,\n selectedVialId: v.id,\n volumeMl:\n v.adultDoseMl ?? vaccineDialog.volumeMl,\n })\n }\n sx={{ cursor: \"pointer\" }}\n >\n <TableCell padding=\"checkbox\">\n <Radio checked={selected} />\n </TableCell>\n <TableCell sx={{ fontFamily: \"monospace\" }}>\n {v.lotNumber || \"—\"}\n {idx === 0 ? (\n <Chip\n size=\"small\"\n color=\"primary\"\n label=\"Use first\"\n sx={{ ml: 1 }}\n />\n ) : null}\n </TableCell>\n <TableCell>\n {formatDateTime(v.expiresAt)}\n </TableCell>\n <TableCell>\n {v.batchExpiryDate\n ? formatDate(v.batchExpiryDate)\n : \"—\"}\n </TableCell>\n <TableCell\n align=\"right\"\n sx={{ fontWeight: 700 }}\n >\n {formatNumber(v.volumeRemainingMl)} /{\" \"}\n {formatNumber(v.volumeTotalMl)}\n </TableCell>\n </TableRow>\n );\n })\n )}\n </TableBody>\n </Table>\n </TableContainer>\n </>\n ) : (\n <>\n {/* Suppress the empty-state warnings until the source has\n been picked — with no source committed the candidate\n list is intentionally empty and the operator just\n needs to choose, not read a \"no stock\" warning. */}\n {!vaccineDialog.ownerType ? (\n <Alert severity=\"info\">\n Pick an administration source above to see the available\n batches.\n </Alert>\n ) : vaccineDialog.batchCandidates.length === 0 ? (\n <Alert\n severity=\"error\"\n action={\n vaccineDialog.vialCandidates.length > 0 ? (\n <Button\n color=\"inherit\"\n size=\"small\"\n onClick={() => switchMode(\"use-existing\")}\n >\n Use an open vial\n </Button>\n ) : null\n }\n >\n No batches available — every batch is either out of\n stock, expired, or already at the maximum concurrent\n open vials. Receive a purchase or finish the open vials\n first.\n </Alert>\n ) : (\n <>\n <Alert\n severity=\"warning\"\n action={\n vaccineDialog.vialCandidates.length > 0 ? (\n <Button\n color=\"inherit\"\n size=\"small\"\n onClick={() => switchMode(\"use-existing\")}\n >\n Use an open vial instead\n </Button>\n ) : null\n }\n >\n {vaccineDialog.vialCandidates.length > 0\n ? \"Opening a new vial from stock. Existing open vials are still available if the dose fits.\"\n : \"No open vials for this vaccine. A new vial will be opened from the selected batch and the dose recorded in one step.\"}\n </Alert>\n <TableContainer>\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell />\n <TableCell sx={{ fontWeight: 800 }}>\n Lot\n </TableCell>\n <TableCell sx={{ fontWeight: 800 }}>\n Batch expires\n </TableCell>\n <TableCell\n sx={{ fontWeight: 800 }}\n align=\"right\"\n >\n Qty available\n </TableCell>\n <TableCell sx={{ fontWeight: 800 }}>\n Storage\n </TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {vaccineDialog.batchCandidates.map((b, idx) => {\n const selected =\n vaccineDialog.selectedBatchId === b.id;\n return (\n <TableRow\n key={b.id}\n hover\n selected={selected}\n onClick={() =>\n setVaccineDialog({\n ...vaccineDialog,\n selectedBatchId: b.id,\n })\n }\n sx={{ cursor: \"pointer\" }}\n >\n <TableCell padding=\"checkbox\">\n <Radio checked={selected} />\n </TableCell>\n <TableCell sx={{ fontFamily: \"monospace\" }}>\n {b.lotNumber || \"—\"}\n {idx === 0 ? (\n <Chip\n size=\"small\"\n color=\"primary\"\n label=\"Use first\"\n sx={{ ml: 1 }}\n />\n ) : null}\n </TableCell>\n <TableCell>\n {b.expiryDate\n ? formatDate(b.expiryDate)\n : \"—\"}\n </TableCell>\n <TableCell\n align=\"right\"\n sx={{ fontWeight: 700 }}\n >\n {b.qtyRemaining}\n </TableCell>\n <TableCell>\n {b.storageUnitName || \"—\"}\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n </TableContainer>\n </>\n )}\n </>\n )}\n\n {(vaccineDialog.mode === \"use-existing\" &&\n vaccineSelectedVial) ||\n (vaccineDialog.mode === \"open-new\" && vaccineSelectedBatch) ? (\n <Stack\n direction=\"row\"\n spacing={1}\n alignItems=\"center\"\n flexWrap=\"wrap\"\n >\n {vaccineDialog.mode === \"use-existing\" ? (\n <>\n {vaccineSelectedVial.adultDoseMl ? (\n <Button\n size=\"small\"\n onClick={() =>\n setVaccineDialog({\n ...vaccineDialog,\n volumeMl: vaccineSelectedVial.adultDoseMl,\n })\n }\n >\n Adult dose ({vaccineSelectedVial.adultDoseMl} ml)\n </Button>\n ) : null}\n {vaccineSelectedVial.childDoseMl ? (\n <Button\n size=\"small\"\n onClick={() =>\n setVaccineDialog({\n ...vaccineDialog,\n volumeMl: vaccineSelectedVial.childDoseMl,\n })\n }\n >\n Child dose ({vaccineSelectedVial.childDoseMl} ml)\n </Button>\n ) : null}\n </>\n ) : (\n <>\n {vaccineCfg?.adultDoseMl ? (\n <Button\n size=\"small\"\n onClick={() =>\n setVaccineDialog({\n ...vaccineDialog,\n volumeMl: vaccineCfg.adultDoseMl,\n })\n }\n >\n Adult dose ({vaccineCfg.adultDoseMl} ml)\n </Button>\n ) : null}\n {vaccineCfg?.childDoseMl ? (\n <Button\n size=\"small\"\n onClick={() =>\n setVaccineDialog({\n ...vaccineDialog,\n volumeMl: vaccineCfg.childDoseMl,\n })\n }\n >\n Child dose ({vaccineCfg.childDoseMl} ml)\n </Button>\n ) : null}\n </>\n )}\n <TextField\n required\n label=\"Volume (ml)\"\n size=\"small\"\n type=\"number\"\n inputProps={{\n step: \"0.01\",\n min: 0,\n max:\n vaccineDialog.mode === \"use-existing\"\n ? vaccineSelectedVial?.volumeRemainingMl\n : vaccineCfg?.vialVolumeMl,\n }}\n value={vaccineDialog.volumeMl}\n onChange={(e) =>\n setVaccineDialog({\n ...vaccineDialog,\n volumeMl: e.target.value,\n })\n }\n onBlur={vaccineFieldErrors.onBlur(\"volumeMl\")}\n error={\n vaccineFieldErrors.show(\"volumeMl\") &&\n !!vaccineErrors.volumeMl\n }\n helperText={\n vaccineFieldErrors.show(\"volumeMl\")\n ? vaccineErrors.volumeMl\n : \"\"\n }\n />\n </Stack>\n ) : null}\n </Stack>\n )}\n </DialogContent>\n <DialogActions>\n <Button onClick={closeVaccineDialog}>Cancel</Button>\n {vaccineDialog.step === \"select\" ? (\n <Button\n onClick={() =>\n setVaccineDialog({\n ...EMPTY_VACCINE_DIALOG,\n open: true,\n productId: vaccineDialog.productId,\n })\n }\n >\n Back\n </Button>\n ) : null}\n {vaccineDialog.step === \"product\" ? (\n <Button\n variant=\"contained\"\n disabled={!vaccineDialog.productId || vaccineDialog.loading}\n onClick={() => void proceedFromProductStep()}\n >\n Next\n </Button>\n ) : (\n <Button\n variant=\"contained\"\n disabled={!vaccineIsValid}\n onClick={() => void doVaccineAdminister()}\n >\n {vaccineDialog.mode === \"use-existing\"\n ? \"Administer\"\n : \"Open & Administer\"}\n </Button>\n )}\n </DialogActions>\n </Dialog>\n\n <Dialog\n open={closeDialog.open}\n onClose={() =>\n setCloseDialog({\n open: false,\n vial: null,\n reason: \"TIME_EXPIRATION\",\n comments: \"\",\n })\n }\n fullWidth\n maxWidth=\"sm\"\n >\n <DialogTitle>Close Vial (record remaining as wastage)</DialogTitle>\n <DialogContent dividers>\n <Stack spacing={2} sx={{ pt: 1 }}>\n <Typography variant=\"body2\">\n {closeDialog.vial?.productName} ·{\" \"}\n {formatNumber(closeDialog.vial?.volumeRemainingMl)} ml will be\n marked as wasted.\n </Typography>\n <FormControl\n required\n fullWidth\n size=\"small\"\n error={\n closeFieldErrors.show(\"wastageReason\") &&\n !!closeErrors.wastageReason\n }\n >\n <InputLabel>Reason</InputLabel>\n <Select\n label=\"Reason\"\n value={closeDialog.reason}\n onChange={(e) =>\n setCloseDialog({ ...closeDialog, reason: e.target.value })\n }\n onBlur={closeFieldErrors.onBlur(\"wastageReason\")}\n >\n {WASTAGE_REASONS.map((r) => (\n <MenuItem key={r.value} value={r.value}>\n {r.label}\n </MenuItem>\n ))}\n </Select>\n {closeFieldErrors.show(\"wastageReason\") &&\n closeErrors.wastageReason ? (\n <FormHelperText>{closeErrors.wastageReason}</FormHelperText>\n ) : null}\n </FormControl>\n <TextField\n label=\"Comments\"\n size=\"small\"\n multiline\n minRows={2}\n fullWidth\n value={closeDialog.comments}\n onChange={(e) =>\n setCloseDialog({ ...closeDialog, comments: e.target.value })\n }\n />\n </Stack>\n </DialogContent>\n <DialogActions>\n <Button\n onClick={() =>\n setCloseDialog({\n open: false,\n vial: null,\n reason: \"TIME_EXPIRATION\",\n comments: \"\",\n })\n }\n >\n Cancel\n </Button>\n <Button\n variant=\"contained\"\n color=\"error\"\n disabled={!closeIsValid}\n onClick={() => void doClose()}\n >\n Close Vial\n </Button>\n </DialogActions>\n </Dialog>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,254 @@
1
+ //#region src/utils/constants.js
2
+ var e = [
3
+ {
4
+ value: "VIAL",
5
+ label: "Vial"
6
+ },
7
+ {
8
+ value: "PIECE",
9
+ label: "Piece"
10
+ },
11
+ {
12
+ value: "BOX",
13
+ label: "Box"
14
+ },
15
+ {
16
+ value: "BOTTLE",
17
+ label: "Bottle"
18
+ },
19
+ {
20
+ value: "PACK",
21
+ label: "Pack"
22
+ },
23
+ {
24
+ value: "OTHER",
25
+ label: "Other"
26
+ }
27
+ ], t = [
28
+ {
29
+ value: "REFRIGERATOR",
30
+ label: "Refrigerator"
31
+ },
32
+ {
33
+ value: "FREEZER",
34
+ label: "Freezer"
35
+ },
36
+ {
37
+ value: "COLD_ROOM",
38
+ label: "Cold room"
39
+ },
40
+ {
41
+ value: "COOLER_BOX",
42
+ label: "Cooler box"
43
+ },
44
+ {
45
+ value: "AMBIENT",
46
+ label: "Ambient shelf"
47
+ },
48
+ {
49
+ value: "OTHER",
50
+ label: "Other"
51
+ }
52
+ ], n = [
53
+ {
54
+ value: "IM",
55
+ label: "Intramuscular (IM)"
56
+ },
57
+ {
58
+ value: "SC",
59
+ label: "Subcutaneous (SC)"
60
+ },
61
+ {
62
+ value: "ID",
63
+ label: "Intradermal (ID)"
64
+ },
65
+ {
66
+ value: "ORAL",
67
+ label: "Oral"
68
+ },
69
+ {
70
+ value: "NASAL",
71
+ label: "Nasal"
72
+ }
73
+ ], r = [
74
+ {
75
+ value: "CASH",
76
+ label: "Cash"
77
+ },
78
+ {
79
+ value: "UPI",
80
+ label: "UPI"
81
+ },
82
+ {
83
+ value: "CARD",
84
+ label: "Card"
85
+ },
86
+ {
87
+ value: "BANK",
88
+ label: "Bank transfer"
89
+ },
90
+ {
91
+ value: "CREDIT",
92
+ label: "Credit (pay later)"
93
+ }
94
+ ], i = [
95
+ {
96
+ value: "RECALL",
97
+ label: "Recall"
98
+ },
99
+ {
100
+ value: "TEMPERATURE_EXCURSION",
101
+ label: "Temperature excursion"
102
+ },
103
+ {
104
+ value: "INTEGRITY_ISSUE",
105
+ label: "Packaging or integrity issue"
106
+ },
107
+ {
108
+ value: "EXPIRED",
109
+ label: "Expired"
110
+ },
111
+ {
112
+ value: "DAMAGED",
113
+ label: "Damaged"
114
+ },
115
+ {
116
+ value: "LOST",
117
+ label: "Lost"
118
+ },
119
+ {
120
+ value: "OTHER",
121
+ label: "Other"
122
+ }
123
+ ], a = [
124
+ {
125
+ value: "TIME_EXPIRATION",
126
+ label: "Time expired"
127
+ },
128
+ {
129
+ value: "PARTIAL_USE",
130
+ label: "Partial use"
131
+ },
132
+ {
133
+ value: "SINGLE_USE_POLICY",
134
+ label: "Single-use policy"
135
+ },
136
+ {
137
+ value: "CONTAMINATION",
138
+ label: "Contamination"
139
+ },
140
+ {
141
+ value: "ACCIDENTAL_SPILLAGE",
142
+ label: "Accidental spillage"
143
+ },
144
+ {
145
+ value: "INCORRECT_DILUTION",
146
+ label: "Incorrect dilution"
147
+ },
148
+ {
149
+ value: "COLD_CHAIN_EXCURSION",
150
+ label: "Cold chain break"
151
+ },
152
+ {
153
+ value: "DAMAGED",
154
+ label: "Damaged"
155
+ },
156
+ {
157
+ value: "LOST",
158
+ label: "Lost"
159
+ },
160
+ {
161
+ value: "OTHER",
162
+ label: "Other"
163
+ }
164
+ ], o = "VACCINES", s = [
165
+ {
166
+ value: "ACTIVE",
167
+ label: "Active"
168
+ },
169
+ {
170
+ value: "IN_USE",
171
+ label: "In use"
172
+ },
173
+ {
174
+ value: "EXHAUSTED",
175
+ label: "Used up"
176
+ },
177
+ {
178
+ value: "EXPIRED",
179
+ label: "Expired"
180
+ },
181
+ {
182
+ value: "QUARANTINED",
183
+ label: "Quarantined"
184
+ }
185
+ ], c = [
186
+ {
187
+ value: "OPEN",
188
+ label: "Out"
189
+ },
190
+ {
191
+ value: "RETURNED",
192
+ label: "Returned"
193
+ },
194
+ {
195
+ value: "CANCELLED",
196
+ label: "Cancelled"
197
+ }
198
+ ], l = [
199
+ {
200
+ value: "PENDING",
201
+ label: "Awaiting receipt"
202
+ },
203
+ {
204
+ value: "IN_TRANSIT",
205
+ label: "In transit"
206
+ },
207
+ {
208
+ value: "RECEIVED",
209
+ label: "Received"
210
+ },
211
+ {
212
+ value: "CANCELLED",
213
+ label: "Cancelled"
214
+ }
215
+ ], u = [
216
+ {
217
+ value: "OPEN",
218
+ label: "In use"
219
+ },
220
+ {
221
+ value: "IN_USE",
222
+ label: "In use"
223
+ },
224
+ {
225
+ value: "CLOSED",
226
+ label: "Closed"
227
+ },
228
+ {
229
+ value: "EXPIRED",
230
+ label: "Expired"
231
+ }
232
+ ], d = [
233
+ {
234
+ value: "PENDING",
235
+ label: "Pending"
236
+ },
237
+ {
238
+ value: "COMPLETED",
239
+ label: "Synced"
240
+ },
241
+ {
242
+ value: "FAILED",
243
+ label: "Failed"
244
+ }
245
+ ];
246
+ function f(e, t) {
247
+ if (t == null || t === "") return "";
248
+ let n = e.find((e) => e.value === t);
249
+ return n ? n.label : String(t);
250
+ }
251
+ //#endregion
252
+ export { i as a, l as c, u as d, a as f, e as i, o as l, r as n, t as o, f as p, c as r, d as s, s as t, n as u };
253
+
254
+ //# sourceMappingURL=constants-BrA_hfAI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants-BrA_hfAI.js","names":[],"sources":["../src/utils/constants.js"],"sourcesContent":["// Enum option lists rendered in PM dropdowns and chips. Each option carries\n// both the backend enum value (sent on the wire) and the human label shown to\n// the user. Use `labelOf(LIST, value)` for chip lookups so a single label\n// edit here propagates to every consumer.\n\nexport const PRODUCT_UNITS = [\n { value: 'VIAL', label: 'Vial' },\n { value: 'PIECE', label: 'Piece' },\n { value: 'BOX', label: 'Box' },\n { value: 'BOTTLE', label: 'Bottle' },\n { value: 'PACK', label: 'Pack' },\n { value: 'OTHER', label: 'Other' },\n];\n\nexport const STORAGE_UNIT_TYPES = [\n { value: 'REFRIGERATOR', label: 'Refrigerator' },\n { value: 'FREEZER', label: 'Freezer' },\n { value: 'COLD_ROOM', label: 'Cold room' },\n { value: 'COOLER_BOX', label: 'Cooler box' },\n { value: 'AMBIENT', label: 'Ambient shelf' },\n { value: 'OTHER', label: 'Other' },\n];\n\n// Stored as the short code; displayed with the full clinical name.\nexport const VACCINE_ROUTES = [\n { value: 'IM', label: 'Intramuscular (IM)' },\n { value: 'SC', label: 'Subcutaneous (SC)' },\n { value: 'ID', label: 'Intradermal (ID)' },\n { value: 'ORAL', label: 'Oral' },\n { value: 'NASAL', label: 'Nasal' },\n];\n\nexport const PAYMENT_MODES = [\n { value: 'CASH', label: 'Cash' },\n { value: 'UPI', label: 'UPI' },\n { value: 'CARD', label: 'Card' },\n { value: 'BANK', label: 'Bank transfer' },\n { value: 'CREDIT', label: 'Credit (pay later)' },\n];\n\nexport const QUARANTINE_REASONS = [\n { value: 'RECALL', label: 'Recall' },\n { value: 'TEMPERATURE_EXCURSION', label: 'Temperature excursion' },\n { value: 'INTEGRITY_ISSUE', label: 'Packaging or integrity issue' },\n { value: 'EXPIRED', label: 'Expired' },\n { value: 'DAMAGED', label: 'Damaged' },\n { value: 'LOST', label: 'Lost' },\n { value: 'OTHER', label: 'Other' },\n];\n\nexport const WASTAGE_REASONS = [\n { value: 'TIME_EXPIRATION', label: 'Time expired' },\n { value: 'PARTIAL_USE', label: 'Partial use' },\n { value: 'SINGLE_USE_POLICY', label: 'Single-use policy' },\n { value: 'CONTAMINATION', label: 'Contamination' },\n { value: 'ACCIDENTAL_SPILLAGE', label: 'Accidental spillage' },\n { value: 'INCORRECT_DILUTION', label: 'Incorrect dilution' },\n { value: 'COLD_CHAIN_EXCURSION', label: 'Cold chain break' },\n { value: 'DAMAGED', label: 'Damaged' },\n { value: 'LOST', label: 'Lost' },\n { value: 'OTHER', label: 'Other' },\n];\n\nexport const TRANSACTION_TYPES = [\n 'RECEIPT',\n 'VIAL_OPENED',\n 'ADMINISTRATION',\n 'WASTAGE',\n 'EXPIRY',\n 'SALE',\n 'PAYMENT',\n 'QUARANTINE',\n 'UNQUARANTINE',\n 'RECALL',\n 'TRANSFER_OUT',\n 'TRANSFER_IN',\n];\n\nexport const VACCINES_CATEGORY_CODE = 'VACCINES';\n\n// Inventory batch lifecycle states. Derived from the backend enum so the\n// inventory list filter can show every status that may appear in the table.\nexport const BATCH_STATUSES = [\n { value: 'ACTIVE', label: 'Active' },\n { value: 'IN_USE', label: 'In use' },\n { value: 'EXHAUSTED', label: 'Used up' },\n { value: 'EXPIRED', label: 'Expired' },\n { value: 'QUARANTINED', label: 'Quarantined' },\n];\n\n// Status enums shown as chips on listing rows. No dropdown counterparts —\n// kept here so `labelOf` works uniformly across the UI.\nexport const PICKUP_STATUSES = [\n { value: 'OPEN', label: 'Out' },\n { value: 'RETURNED', label: 'Returned' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nexport const TRANSFER_STATUSES = [\n { value: 'PENDING', label: 'Awaiting receipt' },\n { value: 'IN_TRANSIT', label: 'In transit' },\n { value: 'RECEIVED', label: 'Received' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nexport const VIAL_STATUSES = [\n { value: 'OPEN', label: 'In use' },\n { value: 'IN_USE', label: 'In use' },\n { value: 'CLOSED', label: 'Closed' },\n { value: 'EXPIRED', label: 'Expired' },\n];\n\nexport const SYNC_STATUSES = [\n { value: 'PENDING', label: 'Pending' },\n { value: 'COMPLETED', label: 'Synced' },\n { value: 'FAILED', label: 'Failed' },\n];\n\n/**\n * Look up the display label for an enum value against one of the option\n * lists above. Falls back to the raw value (or empty string) when the\n * value isn't recognised — keeps chips from rendering blank if the backend\n * ships a new enum before the frontend catches up.\n */\nexport function labelOf(options, value) {\n if (value == null || value === '') return '';\n const hit = options.find((o) => o.value === value);\n return hit ? hit.label : String(value);\n}\n"],"mappings":"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"}
@@ -0,0 +1,169 @@
1
+ var e = Object.fromEntries([
2
+ {
3
+ code: "INR",
4
+ symbol: "₹",
5
+ name: "Indian Rupee"
6
+ },
7
+ {
8
+ code: "USD",
9
+ symbol: "$",
10
+ name: "US Dollar"
11
+ },
12
+ {
13
+ code: "EUR",
14
+ symbol: "€",
15
+ name: "Euro"
16
+ },
17
+ {
18
+ code: "GBP",
19
+ symbol: "£",
20
+ name: "British Pound"
21
+ },
22
+ {
23
+ code: "JPY",
24
+ symbol: "¥",
25
+ name: "Japanese Yen"
26
+ },
27
+ {
28
+ code: "CNY",
29
+ symbol: "¥",
30
+ name: "Chinese Yuan"
31
+ },
32
+ {
33
+ code: "KRW",
34
+ symbol: "₩",
35
+ name: "South Korean Won"
36
+ },
37
+ {
38
+ code: "THB",
39
+ symbol: "฿",
40
+ name: "Thai Baht"
41
+ },
42
+ {
43
+ code: "VND",
44
+ symbol: "₫",
45
+ name: "Vietnamese Dong"
46
+ },
47
+ {
48
+ code: "NGN",
49
+ symbol: "₦",
50
+ name: "Nigerian Naira"
51
+ },
52
+ {
53
+ code: "BDT",
54
+ symbol: "৳",
55
+ name: "Bangladeshi Taka"
56
+ },
57
+ {
58
+ code: "PKR",
59
+ symbol: "₨",
60
+ name: "Pakistani Rupee"
61
+ },
62
+ {
63
+ code: "LKR",
64
+ symbol: "₨",
65
+ name: "Sri Lankan Rupee"
66
+ },
67
+ {
68
+ code: "NPR",
69
+ symbol: "₨",
70
+ name: "Nepalese Rupee"
71
+ },
72
+ {
73
+ code: "AUD",
74
+ symbol: "A$",
75
+ name: "Australian Dollar"
76
+ },
77
+ {
78
+ code: "CAD",
79
+ symbol: "C$",
80
+ name: "Canadian Dollar"
81
+ },
82
+ {
83
+ code: "CHF",
84
+ symbol: "Fr",
85
+ name: "Swiss Franc"
86
+ },
87
+ {
88
+ code: "SGD",
89
+ symbol: "S$",
90
+ name: "Singapore Dollar"
91
+ },
92
+ {
93
+ code: "HKD",
94
+ symbol: "HK$",
95
+ name: "Hong Kong Dollar"
96
+ },
97
+ {
98
+ code: "MYR",
99
+ symbol: "RM",
100
+ name: "Malaysian Ringgit"
101
+ },
102
+ {
103
+ code: "AED",
104
+ symbol: "د.إ",
105
+ name: "UAE Dirham"
106
+ },
107
+ {
108
+ code: "SAR",
109
+ symbol: "﷼",
110
+ name: "Saudi Riyal"
111
+ },
112
+ {
113
+ code: "ZAR",
114
+ symbol: "R",
115
+ name: "South African Rand"
116
+ },
117
+ {
118
+ code: "BRL",
119
+ symbol: "R$",
120
+ name: "Brazilian Real"
121
+ },
122
+ {
123
+ code: "MXN",
124
+ symbol: "MX$",
125
+ name: "Mexican Peso"
126
+ },
127
+ {
128
+ code: "KES",
129
+ symbol: "KSh",
130
+ name: "Kenyan Shilling"
131
+ },
132
+ {
133
+ code: "GHS",
134
+ symbol: "GH₵",
135
+ name: "Ghanaian Cedi"
136
+ },
137
+ {
138
+ code: "EGP",
139
+ symbol: "E£",
140
+ name: "Egyptian Pound"
141
+ },
142
+ {
143
+ code: "PHP",
144
+ symbol: "₱",
145
+ name: "Philippine Peso"
146
+ },
147
+ {
148
+ code: "IDR",
149
+ symbol: "Rp",
150
+ name: "Indonesian Rupiah"
151
+ },
152
+ {
153
+ code: "TRY",
154
+ symbol: "₺",
155
+ name: "Turkish Lira"
156
+ },
157
+ {
158
+ code: "RUB",
159
+ symbol: "₽",
160
+ name: "Russian Ruble"
161
+ }
162
+ ].map((e) => [e.code, e]));
163
+ function t(t) {
164
+ return t ? e[t]?.symbol ?? t : "₹";
165
+ }
166
+ //#endregion
167
+ export { t };
168
+
169
+ //# sourceMappingURL=currency-BDDCDgeE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"currency-BDDCDgeE.js","names":[],"sources":["../src/utils/currency.js"],"sourcesContent":["// Curated list of currencies the operator can pick from when configuring the\n// module per deployment. Codes are ISO-4217; symbols match what shows up on\n// the local cash register / receipt rather than always falling back to the\n// ISO code. New deployments only need a row added here.\n\nexport const CURRENCY_OPTIONS = [\n { code: 'INR', symbol: '₹', name: 'Indian Rupee' },\n { code: 'USD', symbol: '$', name: 'US Dollar' },\n { code: 'EUR', symbol: '€', name: 'Euro' },\n { code: 'GBP', symbol: '£', name: 'British Pound' },\n { code: 'JPY', symbol: '¥', name: 'Japanese Yen' },\n { code: 'CNY', symbol: '¥', name: 'Chinese Yuan' },\n { code: 'KRW', symbol: '₩', name: 'South Korean Won' },\n { code: 'THB', symbol: '฿', name: 'Thai Baht' },\n { code: 'VND', symbol: '₫', name: 'Vietnamese Dong' },\n { code: 'NGN', symbol: '₦', name: 'Nigerian Naira' },\n { code: 'BDT', symbol: '৳', name: 'Bangladeshi Taka' },\n { code: 'PKR', symbol: '₨', name: 'Pakistani Rupee' },\n { code: 'LKR', symbol: '₨', name: 'Sri Lankan Rupee' },\n { code: 'NPR', symbol: '₨', name: 'Nepalese Rupee' },\n { code: 'AUD', symbol: 'A$', name: 'Australian Dollar' },\n { code: 'CAD', symbol: 'C$', name: 'Canadian Dollar' },\n { code: 'CHF', symbol: 'Fr', name: 'Swiss Franc' },\n { code: 'SGD', symbol: 'S$', name: 'Singapore Dollar' },\n { code: 'HKD', symbol: 'HK$', name: 'Hong Kong Dollar' },\n { code: 'MYR', symbol: 'RM', name: 'Malaysian Ringgit' },\n { code: 'AED', symbol: 'د.إ', name: 'UAE Dirham' },\n { code: 'SAR', symbol: '﷼', name: 'Saudi Riyal' },\n { code: 'ZAR', symbol: 'R', name: 'South African Rand' },\n { code: 'BRL', symbol: 'R$', name: 'Brazilian Real' },\n { code: 'MXN', symbol: 'MX$', name: 'Mexican Peso' },\n { code: 'KES', symbol: 'KSh', name: 'Kenyan Shilling' },\n { code: 'GHS', symbol: 'GH₵', name: 'Ghanaian Cedi' },\n { code: 'EGP', symbol: 'E£', name: 'Egyptian Pound' },\n { code: 'PHP', symbol: '₱', name: 'Philippine Peso' },\n { code: 'IDR', symbol: 'Rp', name: 'Indonesian Rupiah' },\n { code: 'TRY', symbol: '₺', name: 'Turkish Lira' },\n { code: 'RUB', symbol: '₽', name: 'Russian Ruble' },\n];\n\nconst CODE_TO_OPTION = Object.fromEntries(CURRENCY_OPTIONS.map((c) => [c.code, c]));\n\n/** Resolve an ISO code to a render symbol; unknown codes fall back to the code itself. */\nexport function currencySymbol(code) {\n if (!code) return '₹';\n return CODE_TO_OPTION[code]?.symbol ?? code;\n}\n\n/** Human label, e.g. \"Indian Rupee (₹)\". */\nexport function currencyLabel(code) {\n const opt = CODE_TO_OPTION[code];\n if (!opt) return code || '';\n return `${opt.name} (${opt.symbol})`;\n}\n"],"mappings":"AAwCA,IAAM,IAAiB,OAAO,YAAY;CAlCxC;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAe;CACnD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAY;CAChD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAO;CAC3C;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAgB;CACpD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAe;CACnD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAe;CACnD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAmB;CACvD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAY;CAChD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAkB;CACtD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAiB;CACrD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAmB;CACvD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAkB;CACtD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAmB;CACvD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAiB;CACrD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAoB;CACxD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAkB;CACtD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAc;CAClD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAmB;CACvD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAmB;CACvD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAoB;CACxD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAa;CACjD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAc;CAClD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAqB;CACzD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAiB;CACrD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAe;CACnD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAkB;CACtD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAgB;CACpD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAiB;CACrD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAkB;CACtD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAoB;CACxD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAe;CACnD;EAAE,MAAM;EAAO,QAAQ;EAAO,MAAM;CAAgB;AAGZ,EAAiB,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAGlF,SAAgB,EAAe,GAAM;CAEnC,OADK,IACE,EAAe,IAAO,UAAU,IADrB;AAEpB"}