@argusoft/medplat-product-management 1.0.1 → 1.0.2

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VialsPage-BNPUwGCU.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 listMyOpenPickups,\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\";\nimport { usePmSettings } from \"@pm/utils/settingsStore\";\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 // For ownerType=USER only: which personal pool — 'OUTREACH' (pickup) or\n // 'PURCHASE' (personal-purchase stock). Empty for FACILITY.\n personalSource: \"\",\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 // The user's active outreach session(s) — the OPEN pickup. Shown on the\n // administer screen when the chosen source is Personal (Outreach).\n const [openSessions, setOpenSessions] = useState([]);\n const settings = usePmSettings();\n const allowPersonalPurchase = settings?.allowPersonalPurchase !== false;\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, sessions] = 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 listMyOpenPickups().catch(() => []),\n ]);\n setVials(v);\n setBatches(b);\n setProducts(p);\n setFacilities(f);\n setOpenSessions(sessions);\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, personalSource = \"\") {\n const key = `${ownerType}::${ownerId ?? \"\"}::${personalSource ?? \"\"}`;\n if (sourceKeys.has(key)) return;\n sourceKeys.add(key);\n sources.push({ key, ownerType, ownerId: ownerId ?? null, personalSource: personalSource || null, label });\n }\n // Personal (Outreach) — USER stock minted by a pickup (batch source PICKUP).\n const hasOutreach =\n usableVials.some((v) => v.ownerType === \"USER\" && v.batchSourceType === \"PICKUP\") ||\n fefo.some((b) => b.ownerType === \"USER\" && b.sourceType === \"PICKUP\");\n if (hasOutreach) pushSource(\"USER\", null, \"Personal (Outreach)\", \"OUTREACH\");\n // Personal (Purchase) — USER stock from a personal-use purchase. Only\n // offered when the deployment allows personal purchases AND such stock\n // actually exists for this product.\n const hasPurchase =\n usableVials.some((v) => v.ownerType === \"USER\" && v.batchSourceType === \"PURCHASE\") ||\n fefo.some((b) => b.ownerType === \"USER\" && b.sourceType === \"PURCHASE\");\n if (allowPersonalPurchase && hasPurchase) pushSource(\"USER\", null, \"Personal (Purchase)\", \"PURCHASE\");\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 const defaultPersonalSource = defaultSource?.personalSource ?? \"\";\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 defaultPersonalSource,\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 personalSource: defaultPersonalSource,\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, personalSource) {\n if (!ownerType) return { vials: [], batches: [] };\n // For USER stock, the personal source selects which batch provenance to\n // draw from: OUTREACH → PICKUP batches, PURCHASE → PURCHASE batches.\n const wantSource = ownerType === \"USER\" && personalSource\n ? (personalSource === \"OUTREACH\" ? \"PICKUP\" : \"PURCHASE\")\n : null;\n const matchVial = (v) =>\n v.ownerType === ownerType &&\n (ownerType === \"USER\"\n ? (!wantSource || v.batchSourceType === wantSource)\n : v.ownerId === ownerId);\n const matchBatch = (b) =>\n b.ownerType === ownerType &&\n (ownerType === \"USER\"\n ? (!wantSource || b.sourceType === wantSource)\n : 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 next.personalSource,\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 personalSource: next.personalSource ?? \"\",\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 // For USER stock, tell the backend which personal pool to draw from\n // so Outreach and Personal-purchase stay separate.\n personalSource:\n vaccineDialog.ownerType === \"USER\"\n ? vaccineDialog.personalSource || 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 {true && (\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 ?? \"\"}::${vaccineDialog.personalSource ?? \"\"}`\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 {/* Outreach session context — shown when drawing from personal\n pickup stock so the operator sees which session this is. */}\n {vaccineDialog.ownerType === \"USER\" &&\n vaccineDialog.personalSource === \"OUTREACH\" &&\n openSessions[0] ? (\n <Box\n sx={{\n p: 1.5,\n borderRadius: 2,\n border: \"1px solid\",\n borderColor: \"divider\",\n bgcolor: (t) => t.palette.action.hover,\n }}\n >\n <Typography\n variant=\"overline\"\n sx={{ fontWeight: 800, letterSpacing: 0.6, color: \"text.secondary\" }}\n >\n Outreach session\n </Typography>\n <Typography variant=\"body2\" sx={{ fontWeight: 800 }}>\n {openSessions[0].sessionName || \"—\"}\n </Typography>\n {openSessions[0].sessionSite ? (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: \"block\" }}>\n Site: {openSessions[0].sessionSite}\n </Typography>\n ) : null}\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: \"block\" }}>\n {openSessions[0].sessionStartTime\n ? formatDateTime(openSessions[0].sessionStartTime)\n : \"—\"}\n {openSessions[0].sessionExpectedEndTime\n ? ` → ${formatDateTime(openSessions[0].sessionExpectedEndTime)}`\n : \"\"}\n </Typography>\n {openSessions[0].sessionDescription ? (\n <Typography\n variant=\"caption\"\n color=\"text.secondary\"\n sx={{ display: \"block\", mt: 0.5, whiteSpace: \"pre-wrap\" }}\n >\n {openSessions[0].sessionDescription}\n </Typography>\n ) : null}\n </Box>\n ) : null}\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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"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { lazy as e } from "react";
2
2
  import { jsx as t } from "react/jsx-runtime";
3
3
  //#region routes/routes.jsx
4
- var n = e(() => import("@/views/feature-components/VerifyRoute.jsx")), r = e(() => import("./DashboardPage-CqaquOs2.js")), i = e(() => import("./CategoriesPage-BrspzkJL.js")), a = e(() => import("./BrandsPage-CSA3meke.js")), o = e(() => import("./ProductsPage-C7_r9cKn.js")), s = e(() => import("./ProductEditPage-B8qFTCW9.js")), c = e(() => import("./StorageUnitsPage-B9Hr_RkW.js")), l = e(() => import("./InventoryPage-CPbzfDMR.js")), u = e(() => import("./PurchasesPage-CvaZouVy.js")), d = e(() => import("./PurchaseCreatePage-Dcsg4uoB.js")), f = e(() => import("./PurchaseRequestsPage-BwCkbpaX.js")), p = e(() => import("./PurchaseRequestDetailPage-C7aAwEqw.js")), m = e(() => import("./PickupsPage-DCEr0LHK.js")), h = e(() => import("./PickupCreatePage-CE-oCXD_.js")), g = e(() => import("./TransfersPage-COIyouL4.js")), _ = e(() => import("./TransferCreatePage-DMuZqQ3c.js")), v = e(() => import("./SalesPage-CO3cdYX5.js")), y = e(() => import("./SaleCreatePage-DP1Qmltu.js")), b = e(() => import("./PaymentsPage-BXPvKon-.js")), x = e(() => import("./PaymentCreatePage-BYmDZAIB.js")), S = e(() => import("./VialsPage-CcbY4v6H.js")), C = e(() => import("./TransactionsPage-HKIGwEZN.js")), w = e(() => import("./SettingsPage-DvVRwSFw.js")), T = "Product Management";
4
+ var n = e(() => import("@/views/feature-components/VerifyRoute.jsx")), r = e(() => import("./DashboardPage-CqaquOs2.js")), i = e(() => import("./CategoriesPage-BrspzkJL.js")), a = e(() => import("./BrandsPage-CSA3meke.js")), o = e(() => import("./ProductsPage-C7_r9cKn.js")), s = e(() => import("./ProductEditPage-B8qFTCW9.js")), c = e(() => import("./StorageUnitsPage-B9Hr_RkW.js")), l = e(() => import("./InventoryPage-CPbzfDMR.js")), u = e(() => import("./PurchasesPage-CvaZouVy.js")), d = e(() => import("./PurchaseCreatePage-CDfNDcKG.js")), f = e(() => import("./PurchaseRequestsPage-BwCkbpaX.js")), p = e(() => import("./PurchaseRequestDetailPage-C7aAwEqw.js")), m = e(() => import("./PickupsPage-D66_Wta4.js")), h = e(() => import("./PickupCreatePage-CMGwoAXj.js")), g = e(() => import("./TransfersPage-COIyouL4.js")), _ = e(() => import("./TransferCreatePage-DMuZqQ3c.js")), v = e(() => import("./SalesPage-CO3cdYX5.js")), y = e(() => import("./SaleCreatePage-DP1Qmltu.js")), b = e(() => import("./PaymentsPage-BXPvKon-.js")), x = e(() => import("./PaymentCreatePage-BYmDZAIB.js")), S = e(() => import("./VialsPage-BNPUwGCU.js")), C = e(() => import("./TransactionsPage-HKIGwEZN.js")), w = e(() => import("./SettingsPage-DvVRwSFw.js")), T = "Product Management";
5
5
  function E(e, r, i = "General") {
6
6
  return {
7
7
  path: e,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@argusoft/medplat-product-management",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "license": "MIT",
5
5
  "description": "MEDplat Product Management",
6
6
  "type": "module",
@@ -1,310 +0,0 @@
1
- import { F as e, L as t, R as n, et as r, i, n as a, o, r as ee } from "./currency-ClRLIEg2.js";
2
- import { r as s } from "./PmTable-B9970kPY.js";
3
- import { t as c } from "./format-UOyOu75i.js";
4
- import { useMemo as l, useState as u } from "react";
5
- import { jsx as d, jsxs as f } from "react/jsx-runtime";
6
- import { v4 as p } from "uuid";
7
- import { Alert as m, Autocomplete as h, Box as g, Button as _, Card as v, CardContent as y, Chip as b, FormControl as te, FormHelperText as x, Grid as S, InputLabel as C, MenuItem as w, Select as T, Stack as E, TextField as D, Typography as O } from "@mui/material";
8
- import { showToast as k } from "@/common/toaster/toaster";
9
- import { useNavigate as A } from "react-router-dom";
10
- import j from "@mui/icons-material/SaveRounded";
11
- //#region src/views/PickupCreatePage.jsx
12
- function M(e) {
13
- return !(e.ownerType !== "FACILITY" || Number(e.qtyRemaining ?? 0) <= 0 || e.status === "EXPIRED" || e.status === "EXHAUSTED" || e.status === "QUARANTINED");
14
- }
15
- function N() {
16
- let N = A(), [P, F] = u([]), [I, L] = u([]), [R, ne] = u([]), [re, z] = u(!0), [B, V] = u(!1), [H, U] = u(""), [W, G] = u({
17
- id: p(),
18
- personalBatchId: p(),
19
- facilityId: "",
20
- sourceBatchId: "",
21
- pickedQty: 1,
22
- notes: ""
23
- });
24
- i("update.manage.productManagement.pickup", () => {
25
- async function r() {
26
- try {
27
- let [r, i, a] = await Promise.all([
28
- t(),
29
- e(),
30
- n().catch(() => [])
31
- ]);
32
- F(r), L(i), ne(a);
33
- } catch (e) {
34
- U(e?.response?.data?.message ?? e?.message ?? "Failed to load reference data");
35
- } finally {
36
- z(!1);
37
- }
38
- }
39
- r();
40
- }, []);
41
- let K = R.length > 0, q = l(() => W.facilityId ? I.filter(M).filter((e) => e.ownerId === W.facilityId) : [], [I, W.facilityId]), J = l(() => I.find((e) => e.id === W.sourceBatchId) ?? null, [I, W.sourceBatchId]);
42
- function Y(e, t) {
43
- G((n) => ({
44
- ...n,
45
- [e]: t
46
- }));
47
- }
48
- function ie(e) {
49
- G((t) => ({
50
- ...t,
51
- facilityId: e,
52
- sourceBatchId: ""
53
- }));
54
- }
55
- let X = Number(W.pickedQty), Z = Number(J?.qtyRemaining ?? 0), Q = J ? !Number.isInteger(X) || X <= 0 ? "Enter a whole number greater than 0." : X > Z ? `Only ${Z} available in this batch.` : "" : "", $ = !!W.facilityId && !!W.sourceBatchId && !Q && !K;
56
- async function ae() {
57
- if ($) {
58
- V(!0), U("");
59
- try {
60
- let e = await r({
61
- id: W.id,
62
- personalBatchId: W.personalBatchId,
63
- sourceBatchId: W.sourceBatchId,
64
- pickedQty: X,
65
- notes: W.notes || null
66
- });
67
- k({
68
- message: `Picked up ${e.pickedQty} unit${e.pickedQty === 1 ? "" : "s"}.`,
69
- type: "success"
70
- }), N("/ui/medplat/manage/pm/pickups");
71
- } catch (e) {
72
- U(e?.response?.data?.message ?? e?.message ?? "Failed to record pickup");
73
- } finally {
74
- V(!1);
75
- }
76
- }
77
- }
78
- return /* @__PURE__ */ f(g, { children: [/* @__PURE__ */ d(ee, {}), /* @__PURE__ */ d(a, {
79
- perm: "update.manage.productManagement.pickup",
80
- title: "You don’t have permission to record pickups",
81
- children: /* @__PURE__ */ f(o, {
82
- title: "Record Pickup",
83
- subtitle: "Check out stock from a facility for your field work. Record returns and wastage when you bring stock back.",
84
- actions: /* @__PURE__ */ f(E, {
85
- direction: "row",
86
- spacing: 1,
87
- children: [/* @__PURE__ */ d(_, {
88
- variant: "outlined",
89
- onClick: () => N("/ui/medplat/manage/pm/pickups"),
90
- children: "Cancel"
91
- }), /* @__PURE__ */ d(_, {
92
- variant: "contained",
93
- startIcon: /* @__PURE__ */ d(j, {}),
94
- disabled: !$ || B,
95
- onClick: () => void ae(),
96
- children: B ? "Recording…" : "Record Pickup"
97
- })]
98
- }),
99
- children: [
100
- H ? /* @__PURE__ */ d(m, {
101
- severity: "error",
102
- sx: { mb: 2 },
103
- children: H
104
- }) : null,
105
- K ? /* @__PURE__ */ f(m, {
106
- severity: "warning",
107
- sx: { mb: 2 },
108
- action: /* @__PURE__ */ d(_, {
109
- color: "inherit",
110
- size: "small",
111
- onClick: () => N("/ui/medplat/manage/pm/pickups"),
112
- children: "Go to Pickups"
113
- }),
114
- children: [
115
- "You already have ",
116
- /* @__PURE__ */ d("strong", { children: R.length }),
117
- " open outreach session",
118
- R.length === 1 ? "" : "s",
119
- ". End the active session",
120
- R.length === 1 ? "" : "s",
121
- " before starting a new pickup, or use ",
122
- /* @__PURE__ */ d("strong", { children: "Top Up" }),
123
- " on the Pickups page to add more stock to an active session."
124
- ]
125
- }) : null,
126
- /* @__PURE__ */ d(v, {
127
- sx: {
128
- borderRadius: 4,
129
- mb: 2,
130
- border: "1px solid",
131
- borderColor: "divider",
132
- boxShadow: "0 12px 32px rgba(15, 23, 42, 0.045)"
133
- },
134
- children: /* @__PURE__ */ f(y, {
135
- sx: { p: 2.5 },
136
- children: [/* @__PURE__ */ d(s, {
137
- eyebrow: "Step 1",
138
- title: "Source",
139
- hint: "Select a facility and then the batch to pick up.",
140
- sx: { mb: 2 }
141
- }), /* @__PURE__ */ f(S, {
142
- container: !0,
143
- spacing: 2,
144
- children: [/* @__PURE__ */ d(S, {
145
- item: !0,
146
- xs: 12,
147
- md: 5,
148
- children: /* @__PURE__ */ d(h, {
149
- size: "small",
150
- options: P,
151
- getOptionLabel: (e) => e?.name ?? "",
152
- isOptionEqualToValue: (e, t) => e?.id === t?.id,
153
- value: P.find((e) => e.id === W.facilityId) ?? null,
154
- onChange: (e, t) => ie(t?.id ?? ""),
155
- loading: re,
156
- renderInput: (e) => /* @__PURE__ */ d(D, {
157
- ...e,
158
- required: !0,
159
- label: "Source Facility",
160
- placeholder: "Pick a facility you're assigned to"
161
- })
162
- })
163
- }), /* @__PURE__ */ d(S, {
164
- item: !0,
165
- xs: 12,
166
- md: 7,
167
- children: /* @__PURE__ */ f(te, {
168
- required: !0,
169
- fullWidth: !0,
170
- size: "small",
171
- disabled: !W.facilityId,
172
- children: [
173
- /* @__PURE__ */ d(C, { children: "Source Batch" }),
174
- /* @__PURE__ */ d(T, {
175
- label: "Source Batch",
176
- value: W.sourceBatchId,
177
- onChange: (e) => Y("sourceBatchId", e.target.value),
178
- children: q.length === 0 ? /* @__PURE__ */ d(w, {
179
- disabled: !0,
180
- value: "",
181
- children: /* @__PURE__ */ d("em", { children: "No pickable stock in this facility" })
182
- }) : q.map((e) => /* @__PURE__ */ f(w, {
183
- value: e.id,
184
- children: [
185
- /* @__PURE__ */ d(g, {
186
- component: "span",
187
- sx: {
188
- fontWeight: 700,
189
- mr: 1
190
- },
191
- children: e.productName
192
- }),
193
- /* @__PURE__ */ f(O, {
194
- variant: "caption",
195
- color: "text.secondary",
196
- sx: { mr: 1 },
197
- children: ["qty ", e.qtyRemaining]
198
- }),
199
- e.lotNumber ? /* @__PURE__ */ d(O, {
200
- variant: "caption",
201
- sx: {
202
- fontFamily: "monospace",
203
- mr: 1
204
- },
205
- children: e.lotNumber
206
- }) : null,
207
- e.expiryDate ? /* @__PURE__ */ f(O, {
208
- variant: "caption",
209
- color: "text.secondary",
210
- children: ["exp ", c(e.expiryDate)]
211
- }) : null
212
- ]
213
- }, e.id))
214
- }),
215
- /* @__PURE__ */ d(x, { children: W.facilityId ? q.length === 0 ? "This facility has no in-stock batches you can pick up right now." : "Active facility batches only — quarantined / expired / exhausted stock is hidden." : "Pick a facility first." })
216
- ]
217
- })
218
- })]
219
- })]
220
- })
221
- }),
222
- J ? /* @__PURE__ */ d(v, {
223
- sx: {
224
- borderRadius: 4,
225
- mb: 2,
226
- border: "1px solid",
227
- borderColor: "divider",
228
- boxShadow: "0 12px 32px rgba(15, 23, 42, 0.045)"
229
- },
230
- children: /* @__PURE__ */ f(y, {
231
- sx: { p: 2.5 },
232
- children: [
233
- /* @__PURE__ */ d(s, {
234
- eyebrow: "Step 2",
235
- title: "Quantity",
236
- hint: `Available: ${Z}. You can pick up to this amount.`,
237
- sx: { mb: 2 }
238
- }),
239
- /* @__PURE__ */ f(S, {
240
- container: !0,
241
- spacing: 2,
242
- children: [/* @__PURE__ */ d(S, {
243
- item: !0,
244
- xs: 12,
245
- md: 4,
246
- children: /* @__PURE__ */ d(D, {
247
- required: !0,
248
- fullWidth: !0,
249
- size: "small",
250
- type: "number",
251
- label: "Pick Quantity",
252
- inputProps: {
253
- min: 1,
254
- max: Z
255
- },
256
- value: W.pickedQty,
257
- onChange: (e) => Y("pickedQty", e.target.value),
258
- error: !!Q,
259
- helperText: Q || `Out of ${Z} available`
260
- })
261
- }), /* @__PURE__ */ d(S, {
262
- item: !0,
263
- xs: 12,
264
- md: 8,
265
- children: /* @__PURE__ */ d(D, {
266
- fullWidth: !0,
267
- size: "small",
268
- label: "Notes (optional)",
269
- placeholder: "Anything worth recording about this pickup",
270
- value: W.notes,
271
- onChange: (e) => Y("notes", e.target.value)
272
- })
273
- })]
274
- }),
275
- /* @__PURE__ */ f(E, {
276
- direction: "row",
277
- spacing: 1,
278
- sx: { mt: 2 },
279
- flexWrap: "wrap",
280
- useFlexGap: !0,
281
- children: [
282
- /* @__PURE__ */ d(b, {
283
- size: "small",
284
- label: `Product · ${J.productName}`
285
- }),
286
- J.lotNumber ? /* @__PURE__ */ d(b, {
287
- size: "small",
288
- label: `Lot · ${J.lotNumber}`
289
- }) : null,
290
- J.expiryDate ? /* @__PURE__ */ d(b, {
291
- size: "small",
292
- label: `Expiry · ${c(J.expiryDate)}`
293
- }) : null,
294
- J.storageUnitName ? /* @__PURE__ */ d(b, {
295
- size: "small",
296
- label: `From · ${J.storageUnitName}`
297
- }) : null
298
- ]
299
- })
300
- ]
301
- })
302
- }) : null
303
- ]
304
- })
305
- })] });
306
- }
307
- //#endregion
308
- export { N as default };
309
-
310
- //# sourceMappingURL=PickupCreatePage-CE-oCXD_.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PickupCreatePage-CE-oCXD_.js","names":[],"sources":["../src/views/PickupCreatePage.jsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n Alert,\n Autocomplete,\n Box,\n Button,\n Card,\n CardContent,\n Chip,\n FormControl,\n FormHelperText,\n Grid,\n InputLabel,\n MenuItem,\n Select,\n Stack,\n TextField,\n Typography,\n} from '@mui/material';\nimport SaveRoundedIcon from '@mui/icons-material/SaveRounded';\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 } from '@pm/utils/permissions';\nimport { PmFormSection } from '@pm/components/PmTable';\nimport {\n listBatches,\n listFacilities,\n listMyOpenPickups,\n recordPickup,\n} from '@pm/services/pmApi';\nimport { formatDate } from '@pm/utils/format';\n\n// Only facility-owned, in-stock, non-quarantined, non-terminal batches are\n// candidates for pickup. The backend enforces the same rules; filtering here\n// keeps the dropdown free of unactionable rows.\nfunction isPickable(batch) {\n if (batch.ownerType !== 'FACILITY') return false;\n if (Number(batch.qtyRemaining ?? 0) <= 0) return false;\n if (batch.status === 'EXPIRED' || batch.status === 'EXHAUSTED' || batch.status === 'QUARANTINED') return false;\n return true;\n}\n\nexport default function PickupCreatePage() {\n const navigate = useNavigate();\n const [facilities, setFacilities] = useState([]);\n const [batches, setBatches] = useState([]);\n // OPEN pickups already on this user — one-session-per-user rule means\n // any open session blocks a new pickup. The user has to end the session\n // or top it up instead.\n const [openSessions, setOpenSessions] = useState([]);\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState('');\n const [form, setForm] = useState({\n id: uuidv4(),\n personalBatchId: uuidv4(),\n facilityId: '',\n sourceBatchId: '',\n pickedQty: 1,\n notes: '',\n });\n\n usePermissionedEffect('update.manage.productManagement.pickup', () => {\n async function load() {\n try {\n const [f, b, open] = await Promise.all([\n listFacilities(),\n listBatches(),\n listMyOpenPickups().catch(() => []),\n ]);\n setFacilities(f);\n setBatches(b);\n setOpenSessions(open);\n } catch (err) {\n setError(err?.response?.data?.message ?? err?.message ?? 'Failed to load reference data');\n } finally {\n setLoading(false);\n }\n }\n void load();\n }, []);\n\n const hasOpenSession = openSessions.length > 0;\n\n // Batches limited to the picked facility (when one is selected). Reset\n // when the facility changes so the user can't carry over a stale batch.\n const eligibleBatches = useMemo(() => {\n if (!form.facilityId) return [];\n return batches.filter(isPickable).filter((b) => b.ownerId === form.facilityId);\n }, [batches, form.facilityId]);\n\n const selectedBatch = useMemo(\n () => batches.find((b) => b.id === form.sourceBatchId) ?? null,\n [batches, form.sourceBatchId],\n );\n\n function patch(k, v) {\n setForm((f) => ({ ...f, [k]: v }));\n }\n\n function patchFacility(id) {\n setForm((f) => ({ ...f, facilityId: id, sourceBatchId: '' }));\n }\n\n const qty = Number(form.pickedQty);\n const remaining = Number(selectedBatch?.qtyRemaining ?? 0);\n const qtyError = !selectedBatch\n ? ''\n : !Number.isInteger(qty) || qty <= 0\n ? 'Enter a whole number greater than 0.'\n : qty > remaining\n ? `Only ${remaining} available in this batch.`\n : '';\n const formIsValid = !!form.facilityId && !!form.sourceBatchId && !qtyError && !hasOpenSession;\n\n async function save() {\n if (!formIsValid) return;\n setSubmitting(true);\n setError('');\n try {\n const created = await recordPickup({\n id: form.id,\n personalBatchId: form.personalBatchId,\n sourceBatchId: form.sourceBatchId,\n pickedQty: qty,\n notes: form.notes || null,\n });\n showToast({ message: `Picked up ${created.pickedQty} unit${created.pickedQty === 1 ? '' : 's'}.`, type: 'success' });\n navigate('/ui/medplat/manage/pm/pickups');\n } catch (err) {\n setError(err?.response?.data?.message ?? err?.message ?? 'Failed to record pickup');\n } finally {\n setSubmitting(false);\n }\n }\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'update.manage.productManagement.pickup'} title=\"You don’t have permission to record pickups\">\n <PmPageShell\n title=\"Record Pickup\"\n subtitle=\"Check out stock from a facility for your field work. Record returns and wastage when you bring stock back.\"\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" onClick={() => navigate('/ui/medplat/manage/pm/pickups')}>Cancel</Button>\n <Button variant=\"contained\" startIcon={<SaveRoundedIcon />}\n disabled={!formIsValid || submitting}\n onClick={() => void save()}>\n {submitting ? 'Recording…' : 'Record Pickup'}\n </Button>\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n {hasOpenSession ? (\n <Alert\n severity=\"warning\"\n sx={{ mb: 2 }}\n action={\n <Button color=\"inherit\" size=\"small\"\n onClick={() => navigate('/ui/medplat/manage/pm/pickups')}>\n Go to Pickups\n </Button>\n }\n >\n You already have <strong>{openSessions.length}</strong> open outreach session{openSessions.length === 1 ? '' : 's'}.\n End the active session{openSessions.length === 1 ? '' : 's'} before starting a new pickup,\n or use <strong>Top Up</strong> on the Pickups page to add more stock to an active session.\n </Alert>\n ) : null}\n\n <Card sx={{ borderRadius: 4, mb: 2, border: '1px solid', borderColor: 'divider', boxShadow: '0 12px 32px rgba(15, 23, 42, 0.045)' }}>\n <CardContent sx={{ p: 2.5 }}>\n <PmFormSection\n eyebrow=\"Step 1\"\n title=\"Source\"\n hint=\"Select a facility and then the batch to pick up.\"\n sx={{ mb: 2 }}\n />\n <Grid container spacing={2}>\n <Grid item xs={12} md={5}>\n <Autocomplete\n size=\"small\"\n options={facilities}\n getOptionLabel={(f) => f?.name ?? ''}\n isOptionEqualToValue={(a, b) => a?.id === b?.id}\n value={facilities.find((f) => f.id === form.facilityId) ?? null}\n onChange={(_, next) => patchFacility(next?.id ?? '')}\n loading={loading}\n renderInput={(params) => (\n <TextField {...params} required label=\"Source Facility\" placeholder=\"Pick a facility you're assigned to\" />\n )}\n />\n </Grid>\n <Grid item xs={12} md={7}>\n <FormControl required fullWidth size=\"small\" disabled={!form.facilityId}>\n <InputLabel>Source Batch</InputLabel>\n <Select\n label=\"Source Batch\"\n value={form.sourceBatchId}\n onChange={(e) => patch('sourceBatchId', e.target.value)}\n >\n {eligibleBatches.length === 0 ? (\n <MenuItem disabled value=\"\">\n <em>No pickable stock in this facility</em>\n </MenuItem>\n ) : (\n eligibleBatches.map((b) => (\n <MenuItem key={b.id} value={b.id}>\n <Box component=\"span\" sx={{ fontWeight: 700, mr: 1 }}>{b.productName}</Box>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ mr: 1 }}>\n qty {b.qtyRemaining}\n </Typography>\n {b.lotNumber ? (\n <Typography variant=\"caption\" sx={{ fontFamily: 'monospace', mr: 1 }}>\n {b.lotNumber}\n </Typography>\n ) : null}\n {b.expiryDate ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n exp {formatDate(b.expiryDate)}\n </Typography>\n ) : null}\n </MenuItem>\n ))\n )}\n </Select>\n <FormHelperText>\n {!form.facilityId\n ? 'Pick a facility first.'\n : eligibleBatches.length === 0\n ? 'This facility has no in-stock batches you can pick up right now.'\n : 'Active facility batches only — quarantined / expired / exhausted stock is hidden.'}\n </FormHelperText>\n </FormControl>\n </Grid>\n </Grid>\n </CardContent>\n </Card>\n\n {selectedBatch ? (\n <Card sx={{ borderRadius: 4, mb: 2, border: '1px solid', borderColor: 'divider', boxShadow: '0 12px 32px rgba(15, 23, 42, 0.045)' }}>\n <CardContent sx={{ p: 2.5 }}>\n <PmFormSection\n eyebrow=\"Step 2\"\n title=\"Quantity\"\n hint={`Available: ${remaining}. You can pick up to this amount.`}\n sx={{ mb: 2 }}\n />\n <Grid container spacing={2}>\n <Grid item xs={12} md={4}>\n <TextField\n required fullWidth size=\"small\" type=\"number\"\n label=\"Pick Quantity\"\n inputProps={{ min: 1, max: remaining }}\n value={form.pickedQty}\n onChange={(e) => patch('pickedQty', e.target.value)}\n error={!!qtyError}\n helperText={qtyError || `Out of ${remaining} available`}\n />\n </Grid>\n <Grid item xs={12} md={8}>\n <TextField\n fullWidth size=\"small\"\n label=\"Notes (optional)\"\n placeholder=\"Anything worth recording about this pickup\"\n value={form.notes}\n onChange={(e) => patch('notes', e.target.value)}\n />\n </Grid>\n </Grid>\n <Stack direction=\"row\" spacing={1} sx={{ mt: 2 }} flexWrap=\"wrap\" useFlexGap>\n <Chip size=\"small\" label={`Product · ${selectedBatch.productName}`} />\n {selectedBatch.lotNumber ? <Chip size=\"small\" label={`Lot · ${selectedBatch.lotNumber}`} /> : null}\n {selectedBatch.expiryDate ? <Chip size=\"small\" label={`Expiry · ${formatDate(selectedBatch.expiryDate)}`} /> : null}\n {selectedBatch.storageUnitName ? <Chip size=\"small\" label={`From · ${selectedBatch.storageUnitName}`} /> : null}\n </Stack>\n </CardContent>\n </Card>\n ) : null}\n </PmPageShell>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}