@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.
- package/dist/PickupCreatePage-CMGwoAXj.js +426 -0
- package/dist/PickupCreatePage-CMGwoAXj.js.map +1 -0
- package/dist/{PickupsPage-DCEr0LHK.js → PickupsPage-D66_Wta4.js} +144 -108
- package/dist/PickupsPage-D66_Wta4.js.map +1 -0
- package/dist/{PurchaseCreatePage-Dcsg4uoB.js → PurchaseCreatePage-CDfNDcKG.js} +138 -137
- package/dist/PurchaseCreatePage-CDfNDcKG.js.map +1 -0
- package/dist/{VialsPage-CcbY4v6H.js → VialsPage-BNPUwGCU.js} +291 -224
- package/dist/VialsPage-BNPUwGCU.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/PickupCreatePage-CE-oCXD_.js +0 -310
- package/dist/PickupCreatePage-CE-oCXD_.js.map +0 -1
- package/dist/PickupsPage-DCEr0LHK.js.map +0 -1
- package/dist/PurchaseCreatePage-Dcsg4uoB.js.map +0 -1
- package/dist/VialsPage-CcbY4v6H.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PickupsPage-DCEr0LHK.js","names":[],"sources":["../src/views/PickupsPage.jsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Alert,\n Box,\n Button,\n Chip,\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n FormControl,\n FormHelperText,\n InputAdornment,\n InputLabel,\n MenuItem,\n Select,\n Skeleton,\n Stack,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport { alpha } from '@mui/material/styles';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\nimport SearchRoundedIcon from '@mui/icons-material/SearchRounded';\nimport MoveDownRoundedIcon from '@mui/icons-material/MoveDownRounded';\nimport AssignmentReturnRoundedIcon from '@mui/icons-material/AssignmentReturnRounded';\nimport { showToast } from '@/common/toaster/toaster';\nimport PmPageShell from '@pm/components/PmPageShell';\nimport PmNav from '@pm/components/PmNav';\nimport PmGuard from '@pm/components/PmGuard';\nimport { usePermissionedEffect, usePmPermissions } from '@pm/utils/permissions';\nimport {\n PmEmptyRow,\n PmRef,\n PmTable,\n PmTableCard,\n} from '@pm/components/PmTable';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n listPickups,\n recordPickupReturn,\n recordPickupTopup,\n} from '@pm/services/pmApi';\nimport { formatDate, formatDateTime } from '@pm/utils/format';\nimport { PICKUP_STATUSES, WASTAGE_REASONS, labelOf } from '@pm/utils/constants';\n\nfunction statusChipColor(status) {\n switch (status) {\n case 'OPEN': return 'info';\n case 'RETURNED': return 'success';\n case 'CANCELLED': return 'default';\n default: return 'default';\n }\n}\n\nexport default function PickupsPage() {\n const navigate = useNavigate();\n const perms = usePmPermissions();\n const canCreate = perms.has('update.manage.productManagement.pickup');\n const [rows, setRows] = useState([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState('');\n const [search, setSearch] = useState('');\n const [returnDialog, setReturnDialog] = useState({ open: false, pickup: null });\n const [returnForm, setReturnForm] = useState({ returnedQty: '', wastageReason: '', notes: '' });\n const [topupDialog, setTopupDialog] = useState({ open: false, pickup: null });\n const [topupForm, setTopupForm] = useState({ additionalQty: '', notes: '' });\n const [submitting, setSubmitting] = useState(false);\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n setRows(await listPickups());\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load pickups';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect('view.manage.productManagement.pickup', () => { void load(); }, []);\n\n const filtered = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return rows;\n return rows.filter((r) => {\n const hay = `${r.productName ?? ''} ${r.facilityName ?? ''} ${r.userName ?? ''} ${r.lotNumber ?? ''} ${r.notes ?? ''}`.toLowerCase();\n return hay.includes(q);\n });\n }, [rows, search]);\n\n function openReturn(p) {\n const expected = p.expectedRemainingQty ?? 0;\n setReturnForm({\n // Default to \"return everything that's expected to remain\" — no wastage.\n returnedQty: String(expected),\n wastageReason: '',\n notes: '',\n });\n setReturnDialog({ open: true, pickup: p });\n }\n\n function closeReturn() {\n if (submitting) return;\n setReturnDialog({ open: false, pickup: null });\n }\n\n function openTopup(p) {\n setTopupForm({ additionalQty: '1', notes: '' });\n setTopupDialog({ open: true, pickup: p });\n }\n\n function closeTopup() {\n if (submitting) return;\n setTopupDialog({ open: false, pickup: null });\n }\n\n // Ceiling for a top-up is whatever the source (facility) batch still has —\n // the backend rejects more than this, so cap it here for a friendly UX.\n const topupSourceAvailable = topupDialog.pickup?.sourceBatchQtyRemaining ?? null;\n const topupAdditionalQty = Number(topupForm.additionalQty);\n const topupQtyError = !Number.isInteger(topupAdditionalQty) || topupAdditionalQty <= 0\n ? 'Enter a whole number greater than 0.'\n : (topupSourceAvailable != null && topupAdditionalQty > topupSourceAvailable)\n ? `Only ${topupSourceAvailable} available at the source facility.`\n : '';\n\n async function submitTopup() {\n if (topupQtyError || !topupDialog.pickup) return;\n setSubmitting(true);\n try {\n await recordPickupTopup(topupDialog.pickup.id, {\n id: uuidv4(),\n additionalQty: topupAdditionalQty,\n notes: topupForm.notes || null,\n });\n showToast({\n message: `Topped up ${topupAdditionalQty} unit${topupAdditionalQty === 1 ? '' : 's'}.`,\n type: 'success',\n });\n closeTopup();\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to top up';\n showToast({ message, type: 'error' });\n } finally {\n setSubmitting(false);\n }\n }\n\n const expectedRemaining = returnDialog.pickup?.expectedRemainingQty ?? 0;\n const returnedQty = Number(returnForm.returnedQty);\n const wastedQty = Number.isFinite(returnedQty) && returnedQty >= 0 && returnedQty <= expectedRemaining\n ? expectedRemaining - returnedQty\n : null;\n const returnedQtyError = !Number.isInteger(returnedQty) || returnedQty < 0\n ? 'Enter a whole number from 0 to the expected remaining.'\n : returnedQty > expectedRemaining\n ? `At most ${expectedRemaining} can be returned.`\n : '';\n // Reason is required whenever ANY wastage will be written — either the\n // sealed-units gap is > 0, or there are open vials to close (their\n // remaining volume becomes wastage).\n const reasonRequired = (wastedQty != null && wastedQty > 0)\n || ((returnDialog.pickup?.openVials ?? []).length > 0);\n const reasonError = reasonRequired && !returnForm.wastageReason\n ? 'A reason is required for the wastage being recorded.'\n : '';\n const returnFormValid = !returnedQtyError && !reasonError;\n\n async function submitReturn() {\n if (!returnFormValid || !returnDialog.pickup) return;\n setSubmitting(true);\n try {\n await recordPickupReturn(returnDialog.pickup.id, {\n returnedQty,\n wastageReason: reasonRequired ? returnForm.wastageReason : null,\n notes: returnForm.notes || null,\n });\n showToast({\n message: wastedQty > 0\n ? `Returned ${returnedQty}, wasted ${wastedQty}.`\n : `Returned ${returnedQty} unit${returnedQty === 1 ? '' : 's'}.`,\n type: 'success',\n });\n closeReturn();\n await load();\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to record return';\n showToast({ message, type: 'error' });\n } finally {\n setSubmitting(false);\n }\n }\n\n return (\n <Box>\n <PmNav />\n <PmGuard perm={'view.manage.productManagement.pickup'}>\n <PmPageShell\n title=\"Stock Pickups\"\n subtitle=\"Stock you're carrying for field work. Record returns and any items lost or used.\"\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n {canCreate ? (\n <Button variant=\"contained\" startIcon={<AddRoundedIcon />}\n onClick={() => navigate('/ui/medplat/manage/pm/pickups/new')}>\n New Pickup\n </Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Operations\"\n title=\"Pickups\"\n subtitle={loading ? 'Loading…' : `${filtered.length} ${filtered.length === 1 ? 'pickup' : 'pickups'}`}\n >\n <Stack direction={{ xs: 'column', md: 'row' }} spacing={1.5} sx={{ mb: 2 }}>\n <TextField\n size=\"small\" fullWidth\n placeholder=\"Search by product, facility, user, lot, notes…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n InputProps={{\n startAdornment: <InputAdornment position=\"start\"><SearchRoundedIcon fontSize=\"small\" /></InputAdornment>,\n }}\n />\n </Stack>\n\n <PmTable dense>\n <TableHead>\n <TableRow>\n <TableCell>Ref</TableCell>\n <TableCell>Product</TableCell>\n <TableCell>Facility</TableCell>\n <TableCell>User</TableCell>\n <TableCell align=\"right\">Qty</TableCell>\n <TableCell>Picked</TableCell>\n <TableCell>Status</TableCell>\n <TableCell align=\"right\">Action</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n Array.from({ length: 4 }).map((_, i) => (\n <TableRow key={i}>\n {Array.from({ length: 8 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : filtered.length === 0 ? (\n <PmEmptyRow\n colSpan={8}\n icon={MoveDownRoundedIcon}\n title={search.trim() !== '' ? 'No pickups match your search' : 'No pickups yet'}\n hint=\"Check out stock from a facility to use in the field.\"\n action={canCreate ? (\n <Button variant=\"contained\" size=\"small\" startIcon={<AddRoundedIcon />}\n onClick={() => navigate('/ui/medplat/manage/pm/pickups/new')}>\n Record first pickup\n </Button>\n ) : null}\n />\n ) : filtered.map((r) => (\n <TableRow key={r.id} hover>\n <TableCell><PmRef id={r.serialId} /></TableCell>\n <TableCell>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>{r.productName ?? '—'}</Typography>\n {r.lotNumber ? (\n <Typography variant=\"caption\" sx={{ fontFamily: 'monospace', color: 'text.secondary' }}>\n {r.lotNumber}\n </Typography>\n ) : null}\n </TableCell>\n <TableCell>{r.facilityName ?? '—'}</TableCell>\n <TableCell>{r.userName ?? '—'}</TableCell>\n <TableCell align=\"right\">\n <Typography sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums' }}>{r.pickedQty}</Typography>\n {r.status === 'OPEN' && r.expectedRemainingQty != null ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {r.expectedRemainingQty} left on user\n </Typography>\n ) : r.status === 'RETURNED' ? (\n <Typography variant=\"caption\" color=\"text.secondary\">\n {r.returnedQty} returned{r.wastedQty > 0 ? ` · ${r.wastedQty} wasted` : ''}\n </Typography>\n ) : null}\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">{formatDate(r.pickedOn)}</Typography>\n </TableCell>\n <TableCell>\n <Chip size=\"small\" label={labelOf(PICKUP_STATUSES, r.status)} color={statusChipColor(r.status)} />\n </TableCell>\n <TableCell align=\"right\">\n {r.status === 'OPEN' && canCreate ? (\n <Stack direction=\"row\" spacing={1} justifyContent=\"flex-end\">\n <Button size=\"small\" variant=\"outlined\" startIcon={<AddRoundedIcon />}\n onClick={() => openTopup(r)}>\n Top Up\n </Button>\n <Button size=\"small\" variant=\"outlined\" startIcon={<AssignmentReturnRoundedIcon />}\n onClick={() => openReturn(r)}>\n End Session\n </Button>\n </Stack>\n ) : (\n <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>\n )}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n </PmGuard>\n\n {/* ---------- End Outreach Session dialog ---------- */}\n <Dialog open={returnDialog.open} onClose={closeReturn} maxWidth=\"sm\" fullWidth>\n <DialogTitle>End outreach session #{returnDialog.pickup?.serialId}</DialogTitle>\n <DialogContent>\n {returnDialog.pickup ? (\n <Stack spacing={2} sx={{ mt: 1 }}>\n <Box sx={(t) => ({\n p: 1.5, borderRadius: 3,\n bgcolor: alpha(t.palette.primary.main, 0.04),\n border: `1px solid ${alpha(t.palette.primary.main, 0.12)}`,\n })}>\n <Typography variant=\"body2\"><strong>{returnDialog.pickup.productName}</strong></Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block' }}>\n Picked {returnDialog.pickup.pickedQty} on {formatDateTime(returnDialog.pickup.pickedOn)} from {returnDialog.pickup.facilityName}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mt: 0.5 }}>\n Sealed units expected on user: <strong>{expectedRemaining}</strong>\n {' '}({(returnDialog.pickup.pickedQty ?? 0) - expectedRemaining - ((returnDialog.pickup.openVials ?? []).length)} already administered / wasted during the day)\n </Typography>\n </Box>\n\n <TextField\n required size=\"small\" type=\"number\"\n label=\"Sealed Units Returned\"\n inputProps={{ min: 0, max: expectedRemaining }}\n value={returnForm.returnedQty}\n onChange={(e) => setReturnForm((f) => ({ ...f, returnedQty: e.target.value }))}\n error={!!returnedQtyError}\n helperText={returnedQtyError || `Out of ${expectedRemaining} sealed units expected to remain`}\n />\n\n {wastedQty != null && wastedQty > 0 ? (\n <Alert severity=\"warning\" variant=\"outlined\">\n <strong>{wastedQty}</strong> sealed {wastedQty === 1 ? 'unit' : 'units'} unaccounted for — will be marked as wastage.\n </Alert>\n ) : null}\n\n {/* Open-vial wastage preview. Any vial opened during outreach\n does not return to the facility — it's closed with wastage\n as part of this end-session action. Volume shown so the\n operator knows what's being written off. */}\n {(returnDialog.pickup.openVials ?? []).length > 0 ? (\n <Alert severity=\"info\" variant=\"outlined\">\n <Typography variant=\"body2\" sx={{ fontWeight: 700, mb: 0.5 }}>\n {returnDialog.pickup.openVials.length} open vial{returnDialog.pickup.openVials.length === 1 ? '' : 's'} on you will be closed with wastage\n </Typography>\n <Stack spacing={0.25} sx={{ mt: 0.5 }}>\n {returnDialog.pickup.openVials.map((v) => (\n <Typography key={v.id} variant=\"caption\" color=\"text.secondary\">\n Lot {v.lotNumber || '—'} · {Number(v.volumeRemainingMl ?? 0).toFixed(2)} ml remaining\n </Typography>\n ))}\n </Stack>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mt: 0.75 }}>\n These volumes will be recorded as wastage using the reason picked below.\n </Typography>\n </Alert>\n ) : null}\n\n <FormControl size=\"small\" disabled={!reasonRequired} error={!!reasonError}>\n <InputLabel>Wastage Reason{reasonRequired ? ' *' : ''}</InputLabel>\n <Select\n label={`Wastage Reason${reasonRequired ? ' *' : ''}`}\n value={returnForm.wastageReason}\n onChange={(e) => setReturnForm((f) => ({ ...f, wastageReason: e.target.value }))}\n >\n <MenuItem value=\"\"><em>—</em></MenuItem>\n {WASTAGE_REASONS.map((r) => (\n <MenuItem key={r.value} value={r.value}>{r.label}</MenuItem>\n ))}\n </Select>\n <FormHelperText>\n {reasonError\n || (reasonRequired\n ? 'Required — same reason covers both unaccounted sealed units and any open-vial remaining volume.'\n : 'Not needed — nothing being wasted.')}\n </FormHelperText>\n </FormControl>\n\n <TextField\n size=\"small\" multiline minRows={2}\n label=\"Notes (optional)\"\n value={returnForm.notes}\n onChange={(e) => setReturnForm((f) => ({ ...f, notes: e.target.value }))}\n />\n </Stack>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={closeReturn} disabled={submitting}>Cancel</Button>\n <Button variant=\"contained\" onClick={() => void submitReturn()}\n disabled={!returnFormValid || submitting}>\n {submitting ? 'Submitting…' : 'End Session'}\n </Button>\n </DialogActions>\n </Dialog>\n\n {/* ---------- Top Up dialog ---------- */}\n <Dialog open={topupDialog.open} onClose={closeTopup} maxWidth=\"xs\" fullWidth>\n <DialogTitle>Top up session #{topupDialog.pickup?.serialId}</DialogTitle>\n <DialogContent>\n {topupDialog.pickup ? (\n <Stack spacing={2} sx={{ mt: 1 }}>\n <Box sx={(t) => ({\n p: 1.5, borderRadius: 3,\n bgcolor: alpha(t.palette.primary.main, 0.04),\n border: `1px solid ${alpha(t.palette.primary.main, 0.12)}`,\n })}>\n <Typography variant=\"body2\"><strong>{topupDialog.pickup.productName}</strong></Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block' }}>\n Source: {topupDialog.pickup.facilityName} · Lot {topupDialog.pickup.lotNumber || '—'}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block' }}>\n Currently picked: {topupDialog.pickup.pickedQty} · remaining sealed on user: {topupDialog.pickup.expectedRemainingQty ?? 0}\n </Typography>\n {topupSourceAvailable != null ? (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block' }}>\n Available at source: <strong>{topupSourceAvailable}</strong>\n </Typography>\n ) : null}\n </Box>\n\n <Alert severity=\"info\" variant=\"outlined\">\n Top-ups come from the same source batch as the original pickup so lot / expiry stays consistent. To pick from a different batch, end this session first.\n </Alert>\n\n <TextField\n required size=\"small\" type=\"number\"\n label=\"Additional Quantity\"\n inputProps={{ min: 1, max: topupSourceAvailable ?? undefined }}\n value={topupForm.additionalQty}\n onChange={(e) => setTopupForm((f) => ({ ...f, additionalQty: e.target.value }))}\n error={!!topupQtyError}\n helperText={topupQtyError\n || (topupSourceAvailable != null\n ? `Sealed units to add. Up to ${topupSourceAvailable} available at the source.`\n : 'Sealed units to add to this session.')}\n />\n\n <TextField\n size=\"small\" multiline minRows={2}\n label=\"Notes (optional)\"\n value={topupForm.notes}\n onChange={(e) => setTopupForm((f) => ({ ...f, notes: e.target.value }))}\n />\n </Stack>\n ) : null}\n </DialogContent>\n <DialogActions>\n <Button onClick={closeTopup} disabled={submitting}>Cancel</Button>\n <Button variant=\"contained\" onClick={() => void submitTopup()}\n disabled={!!topupQtyError || submitting}>\n {submitting ? 'Submitting…' : 'Top Up'}\n </Button>\n </DialogActions>\n </Dialog>\n </Box>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PurchaseCreatePage-Dcsg4uoB.js","names":[],"sources":["../src/views/PurchaseCreatePage.jsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { v4 as uuidv4 } from 'uuid';\nimport {\n Alert,\n Box,\n Button,\n Card,\n CardContent,\n Chip,\n Divider,\n FormControl,\n FormHelperText,\n Grid,\n IconButton,\n InputLabel,\n MenuItem,\n Select,\n Stack,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport DeleteOutlineRoundedIcon from '@mui/icons-material/DeleteOutlineRounded';\nimport AddRoundedIcon from '@mui/icons-material/AddRounded';\nimport SaveRoundedIcon from '@mui/icons-material/SaveRounded';\nimport Inventory2RoundedIcon from '@mui/icons-material/Inventory2Rounded';\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 {\n createPurchase,\n getProducts,\n getStorageUnits,\n listBatches,\n submitPurchaseRequest,\n} from '@pm/services/pmApi';\nimport FacilityPicker from '@pm/components/FacilityPicker';\nimport { BATCH_STATUSES, PAYMENT_MODES, labelOf } from '@pm/utils/constants';\nimport {\n isClean,\n validateFutureDate,\n validatePastOrTodayDate,\n validatePrice,\n validateQuantity,\n validateRequired,\n} from '@pm/utils/validation';\nimport { formatDate, formatNumber, statusColor } from '@pm/utils/format';\nimport { PmFormSection } from '@pm/components/PmTable';\nimport { useFieldErrors } from '@pm/utils/useFieldErrors';\nimport { usePermissionedEffect } from '@pm/utils/permissions';\nimport { usePmSettings } from '@pm/utils/settingsStore';\n\n// Purchase type → backend owner_type mapping. \"Personal Use\" puts the stock\n// against the acting user; \"Facility Use\" puts it against a facility the user\n// has access to. The Personal option is filtered out when the deployment-level\n// allowPersonalPurchase setting is off (see PURCHASE_TYPES filter below).\nconst ALL_PURCHASE_TYPES = [\n { value: 'USER', label: 'Personal Use' },\n { value: 'FACILITY', label: 'Facility Use' },\n];\n\nfunction emptyLine() {\n return {\n key: uuidv4(),\n batchId: uuidv4(),\n productId: '',\n quantity: 1,\n buyPrice: '',\n expiryDate: '',\n lotNumber: '',\n manufactureDate: '',\n storageUnitId: '',\n };\n}\n\nexport default function PurchaseCreatePage() {\n const navigate = useNavigate();\n const settings = usePmSettings();\n const manageAmounts = settings?.managePurchaseAmounts !== false;\n const allowPersonalPurchase = settings?.allowPersonalPurchase !== false;\n // When confirmation is on, the form submits to the request endpoint and\n // the user lands on the request detail page instead of the purchases list.\n const requireConfirmation = settings?.requirePurchaseConfirmation === true;\n // Personal Use is hidden entirely when the deployment doesn't allow it; the\n // dropdown then has a single option and the form defaults to FACILITY.\n const PURCHASE_TYPES = useMemo(\n () => (allowPersonalPurchase ? ALL_PURCHASE_TYPES : ALL_PURCHASE_TYPES.filter((t) => t.value !== 'USER')),\n [allowPersonalPurchase],\n );\n const [products, setProducts] = useState([]);\n const [storageUnits, setStorageUnits] = useState([]);\n const [batches, setBatches] = useState([]);\n const [error, setError] = useState('');\n const fieldErrors = useFieldErrors();\n const today = new Date().toISOString().substring(0, 10);\n const [form, setForm] = useState({\n id: uuidv4(),\n ownerType: allowPersonalPurchase ? 'USER' : 'FACILITY',\n ownerId: '',\n purchaseDate: today,\n paymentMode: 'CASH',\n notes: '',\n items: [emptyLine()],\n });\n\n // When the deployment setting flips from allowing personal purchases to not\n // allowing them (or vice-versa) after the form has rendered, snap the\n // ownerType back to a valid choice so the user can't end up submitting USER\n // against a deployment that doesn't accept it.\n useEffect(() => {\n if (!allowPersonalPurchase && form.ownerType === 'USER') {\n setForm((f) => ({ ...f, ownerType: 'FACILITY', ownerId: '' }));\n }\n }, [allowPersonalPurchase, form.ownerType]);\n\n usePermissionedEffect('update.manage.productManagement.purchase', () => {\n async function load() {\n try {\n const [p, su, b] = await Promise.all([\n getProducts(),\n getStorageUnits({ activeOnly: true }),\n // Pulled here so the existing-inventory panel renders alongside the\n // purchase form — the operator can see what they / the facility\n // already hold before deciding what to buy.\n listBatches().catch(() => []),\n ]);\n setProducts(p);\n setStorageUnits(su);\n setBatches(b);\n } catch (err) {\n setError(err?.response?.data?.message ?? err?.message ?? 'Failed to load reference data');\n }\n }\n void load();\n }, []);\n\n // Existing-stock view for the currently-selected owner. Personal purchases\n // show the operator's USER-owned batches; facility purchases show batches\n // owned by the picked facility. Exhausted/expired rows are skipped to keep\n // the panel decision-relevant.\n const existingInventory = useMemo(() => {\n if (form.ownerType === 'USER') {\n return batches.filter((b) => b.ownerType === 'USER' && Number(b.qtyRemaining ?? 0) > 0\n && b.status !== 'EXPIRED' && b.status !== 'EXHAUSTED');\n }\n if (form.ownerType === 'FACILITY' && form.ownerId) {\n return batches.filter((b) => b.ownerType === 'FACILITY' && b.ownerId === form.ownerId\n && Number(b.qtyRemaining ?? 0) > 0\n && b.status !== 'EXPIRED' && b.status !== 'EXHAUSTED');\n }\n return [];\n }, [batches, form.ownerType, form.ownerId]);\n\n // Storage units filtered by the selected facility (when applicable).\n // Personal purchases don't reference a storage unit at all.\n const eligibleStorageUnits = useMemo(() => {\n if (form.ownerType !== 'FACILITY' || !form.ownerId) return [];\n return storageUnits.filter((u) => u.ownerId === form.ownerId);\n }, [storageUnits, form.ownerType, form.ownerId]);\n\n function patchLine(idx, k, v) {\n setForm((f) => {\n const items = f.items.slice();\n items[idx] = { ...items[idx], [k]: v };\n return { ...f, items };\n });\n }\n\n function removeLine(idx) {\n setForm((f) => ({ ...f, items: f.items.filter((_, i) => i !== idx) }));\n }\n\n function addLine() {\n setForm((f) => ({ ...f, items: [...f.items, emptyLine()] }));\n }\n\n // Sum of (qty * buy price) for lines that have a price. Used to validate\n // the optional Total Amount header field.\n const computedLineTotal = useMemo(() => {\n let priced = false;\n const sum = form.items.reduce((acc, line) => {\n if (line.buyPrice === '' || line.quantity === '' || line.quantity == null) return acc;\n const qty = Number(line.quantity);\n const price = Number(line.buyPrice);\n if (Number.isNaN(qty) || Number.isNaN(price)) return acc;\n priced = true;\n return acc + qty * price;\n }, 0);\n return { sum, priced };\n }, [form.items]);\n\n // Header + per-line errors. The total is auto-derived from the line items so it\n // never needs its own validation message.\n const headerErrors = {\n ownerType: validateRequired(form.ownerType, 'Purchase type'),\n ownerId: form.ownerType === 'FACILITY' ? validateRequired(form.ownerId, 'Facility') : '',\n purchaseDate: validateRequired(form.purchaseDate, 'Purchase date'),\n };\n const lineErrors = form.items.map((line) => {\n const product = products.find((p) => p.id === line.productId);\n const expiryRequired = product?.hasExpiry === true;\n // Storage units only apply to facility-owned stock — personal purchases keep\n // the field disabled, so the requirement is only enforced for facility flows.\n const storageRequired = product?.needsStorageUnit === true && form.ownerType === 'FACILITY';\n let storageErr = storageRequired ? validateRequired(line.storageUnitId, 'Storage unit') : '';\n // Cold-chain check: if the product has a vaccine config with a required\n // storage range, the selected storage unit's operating range must fit\n // inside it. Mirror the backend STORAGE_UNIT_TEMP_MISMATCH rule.\n if (!storageErr && line.storageUnitId && product?.vaccineConfig) {\n const cfg = product.vaccineConfig;\n const unit = storageUnits.find((u) => u.id === line.storageUnitId);\n if (cfg.storageTempMinCelsius != null && cfg.storageTempMaxCelsius != null && unit) {\n const uMin = unit.operatingTempMinCelsius;\n const uMax = unit.operatingTempMaxCelsius;\n // Unit must be able to reach every temp the vaccine tolerates: its\n // operating range must contain the vaccine's required range.\n if (uMin == null || uMax == null\n || Number(uMin) > Number(cfg.storageTempMinCelsius)\n || Number(uMax) < Number(cfg.storageTempMaxCelsius)) {\n storageErr = `Unit operates ${uMin ?? '?'}°C → ${uMax ?? '?'}°C, which cannot cover this product's required ${cfg.storageTempMinCelsius}°C → ${cfg.storageTempMaxCelsius}°C.`;\n }\n }\n }\n return {\n productId: validateRequired(line.productId, 'Product'),\n quantity: validateQuantity(line.quantity),\n buyPrice: validatePrice(line.buyPrice),\n // In request mode the approver fills expiry at confirmation, so we\n // don't require it from the requester even when the product carries\n // hasExpiry. The approver gets to enter the actual expiry off the\n // packaging on PurchaseRequestDetailPage.\n expiryDate: requireConfirmation\n ? ''\n : expiryRequired\n ? (validateRequired(line.expiryDate, 'Expiry date')\n || validateFutureDate(line.expiryDate, { label: 'Expiry' }))\n : validateFutureDate(line.expiryDate, { label: 'Expiry' }),\n manufactureDate: validatePastOrTodayDate(line.manufactureDate, { label: 'Manufacture date' }),\n storageUnitId: storageErr,\n };\n });\n const formIsValid = isClean(headerErrors) && lineErrors.every(isClean) && form.items.length > 0;\n\n async function save() {\n if (!formIsValid) {\n fieldErrors.markAllTouched();\n setError('Please fix the highlighted fields and try again.');\n return;\n }\n // Payload shape is the same for direct purchase and request submission —\n // the difference is the endpoint and what we navigate to afterwards.\n const payload = {\n id: form.id,\n ownerType: form.ownerType,\n ownerId: form.ownerType === 'FACILITY' ? form.ownerId : null,\n purchaseDate: form.purchaseDate,\n paymentMode: manageAmounts ? (form.paymentMode || null) : null,\n // Amount tracking is a per-deployment toggle. When it's off, scrub money\n // values to null so the backend's validatePurchaseTotal stays a no-op\n // and inventory rows don't carry stale prices that aren't surfaced anywhere.\n totalAmount: manageAmounts && computedLineTotal.priced ? Number(computedLineTotal.sum.toFixed(2)) : null,\n notes: form.notes || null,\n items: form.items.map((line) => ({\n batchId: line.batchId,\n productId: line.productId,\n quantity: Number(line.quantity),\n buyPrice: manageAmounts && line.buyPrice !== '' ? Number(line.buyPrice) : null,\n expiryDate: line.expiryDate || null,\n lotNumber: line.lotNumber || null,\n manufactureDate: line.manufactureDate || null,\n storageUnitId: line.storageUnitId || null,\n })),\n };\n try {\n if (requireConfirmation) {\n const submitted = await submitPurchaseRequest(payload);\n showToast({ message: 'Purchase request submitted for approval.', type: 'success' });\n navigate(`/ui/medplat/manage/pm/purchase-requests/${submitted?.id ?? form.id}`);\n } else {\n await createPurchase(payload);\n showToast({ message: 'Purchase recorded.', type: 'success' });\n navigate('/ui/medplat/manage/pm/purchases');\n }\n } catch (err) {\n setError(err?.response?.data?.message\n ?? err?.message\n ?? (requireConfirmation ? 'Failed to submit purchase request' : 'Failed to record purchase'));\n }\n }\n\n return (\n <Box>\n <PmNav />\n <PmGuard\n perm={'update.manage.productManagement.purchase'}\n title={requireConfirmation\n ? \"You don’t have permission to submit purchase requests\"\n : \"You don’t have permission to record purchases\"}>\n <PmPageShell\n title={requireConfirmation ? 'Submit Purchase Request' : 'Record Purchase'}\n subtitle={requireConfirmation\n ? 'Purchases need approval before stock is added. Submit the request and wait for a manager to confirm.'\n : 'Each item creates a batch that you can track and a record in your ledger.'}\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\"\n onClick={() => navigate(requireConfirmation\n ? '/ui/medplat/manage/pm/purchase-requests'\n : '/ui/medplat/manage/pm/purchases')}>Cancel</Button>\n <Button variant=\"contained\" startIcon={<SaveRoundedIcon />}\n disabled={!formIsValid}\n onClick={() => void save()}>{requireConfirmation ? 'Submit Request' : 'Save'}</Button>\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n {/* ---------- Ownership ---------- */}\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=\"Purchase for\"\n hint=\"Choose who will own this stock: yourself or a facility.\"\n sx={{ mb: 2 }}\n />\n <Grid container spacing={2}>\n <Grid item xs={12} md={4}>\n <FormControl required fullWidth size=\"small\"\n error={fieldErrors.show('ownerType') && !!headerErrors.ownerType}>\n <InputLabel>Purchase Type</InputLabel>\n <Select label=\"Purchase Type\" value={form.ownerType}\n onChange={(e) => setForm({ ...form, ownerType: e.target.value, ownerId: '' })}\n onBlur={fieldErrors.onBlur('ownerType')}>\n {PURCHASE_TYPES.map((t) => (\n <MenuItem key={t.value} value={t.value}>{t.label}</MenuItem>\n ))}\n </Select>\n <FormHelperText>\n {fieldErrors.show('ownerType') && headerErrors.ownerType\n ? headerErrors.ownerType\n : 'Personal stock vs. facility stock'}\n </FormHelperText>\n </FormControl>\n </Grid>\n {form.ownerType === 'FACILITY' ? (\n <Grid item xs={12} md={4}>\n <FacilityPicker\n required\n value={form.ownerId}\n onChange={(id) => setForm({ ...form, ownerId: id })}\n onBlur={fieldErrors.onBlur('ownerId')}\n error={fieldErrors.show('ownerId') && !!headerErrors.ownerId}\n helperText={\n fieldErrors.show('ownerId') && headerErrors.ownerId\n ? headerErrors.ownerId\n : 'Search for the facility.'\n }\n />\n </Grid>\n ) : null}\n </Grid>\n </CardContent>\n </Card>\n\n {/* ---------- Existing inventory for the picked owner ---------- */}\n {(form.ownerType === 'USER' || (form.ownerType === 'FACILITY' && form.ownerId)) ? (\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=\"Context\"\n title=\"Existing inventory\"\n hint={form.ownerType === 'USER'\n ? 'Your current stock.'\n : 'What this facility already has, including where it is stored.'}\n sx={{ mb: 1.5 }}\n />\n {existingInventory.length === 0 ? (\n <Stack direction=\"row\" spacing={1.25} alignItems=\"center\" sx={{ py: 1.5, color: 'text.secondary' }}>\n <Inventory2RoundedIcon fontSize=\"small\" />\n <Typography variant=\"body2\">No active stock yet for this owner.</Typography>\n </Stack>\n ) : (\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>Product</TableCell>\n <TableCell>Lot</TableCell>\n <TableCell align=\"right\">Remaining</TableCell>\n <TableCell>Expiry</TableCell>\n {form.ownerType === 'FACILITY' ? <TableCell>Storage</TableCell> : null}\n <TableCell>Status</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {existingInventory.map((b) => (\n <TableRow key={b.id}>\n <TableCell sx={{ fontWeight: 700 }}>{b.productName}</TableCell>\n <TableCell sx={{ fontFamily: 'monospace', fontSize: '0.78rem' }}>{b.lotNumber || '—'}</TableCell>\n <TableCell align=\"right\" sx={{ fontVariantNumeric: 'tabular-nums', fontWeight: 700 }}>\n {b.qtyRemaining}\n </TableCell>\n <TableCell>{b.expiryDate ? formatDate(b.expiryDate) : '—'}</TableCell>\n {form.ownerType === 'FACILITY' ? (\n <TableCell>{b.storageUnitName || '—'}</TableCell>\n ) : null}\n <TableCell>\n <Chip size=\"small\" label={labelOf(BATCH_STATUSES, b.status)} color={statusColor(b.status)} />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n )}\n </CardContent>\n </Card>\n ) : null}\n\n {/* ---------- Lines ---------- */}\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 <Stack direction=\"row\" justifyContent=\"space-between\" alignItems=\"flex-start\" sx={{ mb: 2 }}>\n <PmFormSection\n eyebrow=\"Step 2\"\n title=\"Line items\"\n hint=\"Each item creates one batch in your inventory and a receipt record.\"\n />\n <Button variant=\"outlined\" startIcon={<AddRoundedIcon />} onClick={addLine}>Add Line</Button>\n </Stack>\n <Divider sx={{ mb: 2 }} />\n <Stack spacing={2}>\n {form.items.map((line, idx) => {\n const lerr = lineErrors[idx] || {};\n const product = products.find((p) => p.id === line.productId);\n const expiryRequired = product?.hasExpiry === true;\n const storageRequired = product?.needsStorageUnit === true && form.ownerType === 'FACILITY';\n return (\n <Card key={line.key} variant=\"outlined\" sx={{ p: 2, borderRadius: 3 }}>\n <Grid container spacing={2}>\n <Grid item xs={12} md={3}>\n <FormControl required fullWidth size=\"small\"\n error={fieldErrors.show(`items.${idx}.productId`) && !!lerr.productId}>\n <InputLabel>Product</InputLabel>\n <Select label=\"Product\" value={line.productId}\n onChange={(e) => patchLine(idx, 'productId', e.target.value)}\n onBlur={fieldErrors.onBlur(`items.${idx}.productId`)}>\n {products.map((p) => <MenuItem key={p.id} value={p.id}>{p.name}</MenuItem>)}\n </Select>\n {fieldErrors.show(`items.${idx}.productId`) && lerr.productId\n ? <FormHelperText>{lerr.productId}</FormHelperText> : null}\n </FormControl>\n </Grid>\n <Grid item xs={6} md={1}>\n <TextField required fullWidth size=\"small\" type=\"number\" label=\"Qty\"\n inputProps={{ min: 1 }}\n value={line.quantity}\n onChange={(e) => patchLine(idx, 'quantity', e.target.value)}\n onBlur={fieldErrors.onBlur(`items.${idx}.quantity`)}\n error={fieldErrors.show(`items.${idx}.quantity`) && !!lerr.quantity}\n helperText={fieldErrors.show(`items.${idx}.quantity`) ? lerr.quantity : ''} />\n </Grid>\n {manageAmounts ? (\n <Grid item xs={6} md={2}>\n <TextField fullWidth size=\"small\" type=\"number\" inputProps={{ step: '0.01', min: 0 }}\n label=\"Buy Price\"\n value={line.buyPrice}\n onChange={(e) => patchLine(idx, 'buyPrice', e.target.value)}\n onBlur={fieldErrors.onBlur(`items.${idx}.buyPrice`)}\n error={fieldErrors.show(`items.${idx}.buyPrice`) && !!lerr.buyPrice}\n helperText={fieldErrors.show(`items.${idx}.buyPrice`) ? lerr.buyPrice : ''} />\n </Grid>\n ) : null}\n {/* Expiry is captured at confirmation time alongside Lot —\n the requester is asking for stock they don't yet have,\n so they can't read the expiry off the packaging. */}\n {requireConfirmation ? null : (\n <Grid item xs={6} md={2}>\n <TextField required={expiryRequired} fullWidth size=\"small\" type=\"date\" label=\"Expiry\"\n InputLabelProps={{ shrink: true }}\n inputProps={{ min: today }}\n value={line.expiryDate}\n onChange={(e) => patchLine(idx, 'expiryDate', e.target.value)}\n onBlur={fieldErrors.onBlur(`items.${idx}.expiryDate`)}\n error={fieldErrors.show(`items.${idx}.expiryDate`) && !!lerr.expiryDate}\n helperText={\n fieldErrors.show(`items.${idx}.expiryDate`) && lerr.expiryDate\n ? lerr.expiryDate\n : (expiryRequired ? 'Required for this product' : '')\n } />\n </Grid>\n )}\n {/* Lot # is captured at confirmation time by the approver,\n who physically receives the goods. Hidden when this\n form is in request-mode so the requester doesn't waste\n time guessing a lot they don't have yet. */}\n {requireConfirmation ? null : (\n <Grid item xs={6} md={2}>\n <TextField fullWidth size=\"small\" label=\"Lot #\"\n value={line.lotNumber}\n onChange={(e) => patchLine(idx, 'lotNumber', e.target.value)} />\n </Grid>\n )}\n <Grid item xs={10} md={1}>\n <FormControl fullWidth size=\"small\"\n required={storageRequired}\n disabled={form.ownerType !== 'FACILITY' || !form.ownerId}\n error={fieldErrors.show(`items.${idx}.storageUnitId`) && !!lerr.storageUnitId}>\n <InputLabel>Storage</InputLabel>\n <Select label=\"Storage\" value={line.storageUnitId || ''}\n onChange={(e) => patchLine(idx, 'storageUnitId', e.target.value)}\n onBlur={fieldErrors.onBlur(`items.${idx}.storageUnitId`)}>\n <MenuItem value=\"\"><em>—</em></MenuItem>\n {eligibleStorageUnits.map((u) => <MenuItem key={u.id} value={u.id}>{u.unitName}</MenuItem>)}\n </Select>\n {fieldErrors.show(`items.${idx}.storageUnitId`) && lerr.storageUnitId ? (\n <FormHelperText>{lerr.storageUnitId}</FormHelperText>\n ) : storageRequired ? (\n <FormHelperText>Required for this product</FormHelperText>\n ) : null}\n </FormControl>\n </Grid>\n <Grid item xs={2} md={1} sx={{ textAlign: 'right' }}>\n <IconButton color=\"error\" onClick={() => removeLine(idx)} disabled={form.items.length === 1}>\n <DeleteOutlineRoundedIcon />\n </IconButton>\n </Grid>\n </Grid>\n </Card>\n );\n })}\n </Stack>\n </CardContent>\n </Card>\n\n {/* ---------- Summary footer (like a bill) ---------- */}\n <Card sx={{\n borderRadius: 4,\n bgcolor: 'grey.50',\n border: '1px solid',\n borderColor: 'divider',\n boxShadow: '0 12px 32px rgba(15, 23, 42, 0.045)',\n }}>\n <CardContent sx={{ p: 2.5 }}>\n <PmFormSection\n eyebrow=\"Step 3\"\n title={manageAmounts ? 'Bill summary' : 'Receipt details'}\n hint={manageAmounts\n ? 'The total is calculated from items. Add payment mode and notes. The date is set automatically.'\n : 'Add notes about this receipt. The date is set automatically.'}\n sx={{ mb: 2 }}\n />\n <Grid container spacing={2}>\n {manageAmounts ? (\n <Grid item xs={12} md={6}>\n <FormControl fullWidth size=\"small\">\n <InputLabel>Payment Mode</InputLabel>\n <Select label=\"Payment Mode\" value={form.paymentMode || ''}\n onChange={(e) => setForm({ ...form, paymentMode: e.target.value })}>\n <MenuItem value=\"\"><em>—</em></MenuItem>\n {PAYMENT_MODES.map((m) => <MenuItem key={m.value} value={m.value}>{m.label}</MenuItem>)}\n </Select>\n </FormControl>\n </Grid>\n ) : null}\n <Grid item xs={12} md={manageAmounts ? 6 : 12}>\n <TextField fullWidth size=\"small\" label=\"Notes\" value={form.notes}\n onChange={(e) => setForm({ ...form, notes: e.target.value })} />\n </Grid>\n </Grid>\n\n {manageAmounts ? (\n <>\n <Divider sx={{ my: 2 }} />\n\n <Stack direction=\"row\" justifyContent=\"flex-end\" alignItems=\"baseline\" spacing={2}>\n <Typography variant=\"body2\" color=\"text.secondary\">\n Total ({form.items.length} {form.items.length === 1 ? 'line' : 'lines'})\n </Typography>\n <Typography variant=\"h4\" sx={{ fontWeight: 800, fontVariantNumeric: 'tabular-nums' }}>\n {computedLineTotal.priced ? formatNumber(computedLineTotal.sum) : '—'}\n </Typography>\n </Stack>\n {!computedLineTotal.priced ? (\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', textAlign: 'right' }}>\n Add a Buy Price on at least one line to compute the total.\n </Typography>\n ) : null}\n </>\n ) : null}\n </CardContent>\n </Card>\n </PmPageShell>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VialsPage-CcbY4v6H.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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"}
|