@argusoft/medplat-product-management 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/{BrandsPage-CSA3meke.js → BrandsPage-BE3kn-8b.js} +77 -75
  2. package/dist/BrandsPage-BE3kn-8b.js.map +1 -0
  3. package/dist/{CategoriesPage-BrspzkJL.js → CategoriesPage-COqi3pMi.js} +71 -70
  4. package/dist/{CategoriesPage-BrspzkJL.js.map → CategoriesPage-COqi3pMi.js.map} +1 -1
  5. package/dist/{DashboardPage-CqaquOs2.js → DashboardPage-C_H1Jrey.js} +90 -89
  6. package/dist/DashboardPage-C_H1Jrey.js.map +1 -0
  7. package/dist/{FacilityPicker-Dv_H95WW.js → FacilityPicker-Diq2hnYg.js} +2 -2
  8. package/dist/{FacilityPicker-Dv_H95WW.js.map → FacilityPicker-Diq2hnYg.js.map} +1 -1
  9. package/dist/{InventoryPage-CPbzfDMR.js → InventoryPage-Bjpw6vTz.js} +106 -115
  10. package/dist/InventoryPage-Bjpw6vTz.js.map +1 -0
  11. package/dist/{MemberProfileCard-0vjO3Gzd.js → MemberProfileCard-BLUVRILO.js} +10 -9
  12. package/dist/MemberProfileCard-BLUVRILO.js.map +1 -0
  13. package/dist/{PaymentCreatePage-BYmDZAIB.js → PaymentCreatePage-B5VOgTx9.js} +173 -177
  14. package/dist/PaymentCreatePage-B5VOgTx9.js.map +1 -0
  15. package/dist/{PaymentsPage-BXPvKon-.js → PaymentsPage-DY6BclkN.js} +24 -23
  16. package/dist/{PaymentsPage-BXPvKon-.js.map → PaymentsPage-DY6BclkN.js.map} +1 -1
  17. package/dist/PickupCreatePage-CCSiyFQF.js +706 -0
  18. package/dist/PickupCreatePage-CCSiyFQF.js.map +1 -0
  19. package/dist/{PickupsPage-D66_Wta4.js → PickupsPage-DGi6T5Of.js} +83 -90
  20. package/dist/PickupsPage-DGi6T5Of.js.map +1 -0
  21. package/dist/PmGuard-C90yhpsN.js +592 -0
  22. package/dist/PmGuard-C90yhpsN.js.map +1 -0
  23. package/dist/{PmTable-B9970kPY.js → PmTable-BkK65bJQ.js} +98 -98
  24. package/dist/PmTable-BkK65bJQ.js.map +1 -0
  25. package/dist/{ProductEditPage-B8qFTCW9.js → ProductEditPage-CQj9egzW.js} +138 -137
  26. package/dist/ProductEditPage-CQj9egzW.js.map +1 -0
  27. package/dist/{ProductsPage-C7_r9cKn.js → ProductsPage-i8QVw_Jm.js} +65 -64
  28. package/dist/{ProductsPage-C7_r9cKn.js.map → ProductsPage-i8QVw_Jm.js.map} +1 -1
  29. package/dist/PurchaseCreatePage-Bp6bl9n8.js +591 -0
  30. package/dist/PurchaseCreatePage-Bp6bl9n8.js.map +1 -0
  31. package/dist/{PurchaseRequestDetailPage-C7aAwEqw.js → PurchaseRequestDetailPage-CNAqIFef.js} +216 -215
  32. package/dist/PurchaseRequestDetailPage-CNAqIFef.js.map +1 -0
  33. package/dist/{PurchaseRequestsPage-BwCkbpaX.js → PurchaseRequestsPage-BJqDlNrc.js} +57 -56
  34. package/dist/{PurchaseRequestsPage-BwCkbpaX.js.map → PurchaseRequestsPage-BJqDlNrc.js.map} +1 -1
  35. package/dist/{PurchasesPage-CvaZouVy.js → PurchasesPage-BQEToymQ.js} +76 -75
  36. package/dist/{PurchasesPage-CvaZouVy.js.map → PurchasesPage-BQEToymQ.js.map} +1 -1
  37. package/dist/{SaleCreatePage-DP1Qmltu.js → SaleCreatePage-DbfBK4PH.js} +149 -173
  38. package/dist/SaleCreatePage-DbfBK4PH.js.map +1 -0
  39. package/dist/{SalesPage-CO3cdYX5.js → SalesPage-CTBJMxZe.js} +50 -49
  40. package/dist/SalesPage-CTBJMxZe.js.map +1 -0
  41. package/dist/SettingsPage-CiwVmzM3.js +663 -0
  42. package/dist/SettingsPage-CiwVmzM3.js.map +1 -0
  43. package/dist/{StorageUnitsPage-B9Hr_RkW.js → StorageUnitsPage-BV7nK_iE.js} +57 -56
  44. package/dist/{StorageUnitsPage-B9Hr_RkW.js.map → StorageUnitsPage-BV7nK_iE.js.map} +1 -1
  45. package/dist/{TransactionsPage-HKIGwEZN.js → TransactionsPage-Cocn4901.js} +55 -54
  46. package/dist/TransactionsPage-Cocn4901.js.map +1 -0
  47. package/dist/TransferCreatePage-DbjcjuOg.js +316 -0
  48. package/dist/TransferCreatePage-DbjcjuOg.js.map +1 -0
  49. package/dist/TransfersPage-BFVF7Xvc.js +471 -0
  50. package/dist/TransfersPage-BFVF7Xvc.js.map +1 -0
  51. package/dist/VialsPage-BNzYTLVd.js +321 -0
  52. package/dist/VialsPage-BNzYTLVd.js.map +1 -0
  53. package/dist/index.js +652 -34
  54. package/dist/index.js.map +1 -1
  55. package/dist/settingsStore-KW217unV.js +417 -0
  56. package/dist/settingsStore-KW217unV.js.map +1 -0
  57. package/package.json +1 -1
  58. package/dist/BrandsPage-CSA3meke.js.map +0 -1
  59. package/dist/DashboardPage-CqaquOs2.js.map +0 -1
  60. package/dist/InventoryPage-CPbzfDMR.js.map +0 -1
  61. package/dist/MemberProfileCard-0vjO3Gzd.js.map +0 -1
  62. package/dist/PaymentCreatePage-BYmDZAIB.js.map +0 -1
  63. package/dist/PickupCreatePage-CMGwoAXj.js +0 -426
  64. package/dist/PickupCreatePage-CMGwoAXj.js.map +0 -1
  65. package/dist/PickupsPage-D66_Wta4.js.map +0 -1
  66. package/dist/PmTable-B9970kPY.js.map +0 -1
  67. package/dist/ProductEditPage-B8qFTCW9.js.map +0 -1
  68. package/dist/PurchaseCreatePage-CDfNDcKG.js +0 -627
  69. package/dist/PurchaseCreatePage-CDfNDcKG.js.map +0 -1
  70. package/dist/PurchaseRequestDetailPage-C7aAwEqw.js.map +0 -1
  71. package/dist/SaleCreatePage-DP1Qmltu.js.map +0 -1
  72. package/dist/SalesPage-CO3cdYX5.js.map +0 -1
  73. package/dist/SettingsPage-DvVRwSFw.js +0 -711
  74. package/dist/SettingsPage-DvVRwSFw.js.map +0 -1
  75. package/dist/TransactionsPage-HKIGwEZN.js.map +0 -1
  76. package/dist/TransferCreatePage-DMuZqQ3c.js +0 -363
  77. package/dist/TransferCreatePage-DMuZqQ3c.js.map +0 -1
  78. package/dist/TransfersPage-COIyouL4.js +0 -480
  79. package/dist/TransfersPage-COIyouL4.js.map +0 -1
  80. package/dist/VialsPage-BNPUwGCU.js +0 -922
  81. package/dist/VialsPage-BNPUwGCU.js.map +0 -1
  82. package/dist/currency-ClRLIEg2.js +0 -1372
  83. package/dist/currency-ClRLIEg2.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PurchaseRequestDetailPage-CNAqIFef.js","names":[],"sources":["../src/views/PurchaseRequestDetailPage.jsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport {\n Alert,\n Box,\n Button,\n Card,\n CardContent,\n Chip,\n Divider,\n Stack,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport { alpha } from '@mui/material/styles';\nimport RefreshRoundedIcon from '@mui/icons-material/RefreshRounded';\nimport ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';\nimport CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';\nimport CancelRoundedIcon from '@mui/icons-material/CancelRounded';\nimport DoNotDisturbRoundedIcon from '@mui/icons-material/DoNotDisturbRounded';\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 { PmFormSection, PmMoney, PmRef } from '@pm/components/PmTable';\nimport { usePermissionedEffect, usePmPermissions } from '@pm/utils/permissions';\nimport {\n cancelPurchaseRequest,\n decidePurchaseRequest,\n getPurchaseRequest,\n} from '@pm/services/pmApi';\nimport { formatDate, formatDateTime } from '@pm/utils/format';\nimport { usePmSettings } from '@pm/utils/settingsStore';\n\nfunction statusChipColor(status) {\n switch (status) {\n case 'PENDING': return 'info';\n case 'APPROVED': return 'success';\n case 'PARTIALLY_APPROVED': return 'warning';\n case 'REJECTED': return 'error';\n case 'CANCELLED': return 'default';\n default: return 'default';\n }\n}\n\nfunction prettyStatus(status) {\n if (!status) return '';\n return status\n .toLowerCase()\n .split('_')\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join(' ');\n}\n\nexport default function PurchaseRequestDetailPage() {\n const navigate = useNavigate();\n const { requestId } = useParams();\n const perms = usePmPermissions();\n const canDecide = perms.has('approve.manage.productManagement.purchase');\n const settings = usePmSettings();\n const manageAmounts = settings?.managePurchaseAmounts !== false;\n\n const [request, setRequest] = useState(null);\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState('');\n // Per-line approved quantities the approver is currently editing. Keyed by\n // item.id so the controls stay decoupled from order in the source list.\n const [approvedDraft, setApprovedDraft] = useState({});\n // Per-line lot numbers the approver fills at decision time — the requester\n // doesn't have the goods yet, so they don't know what lot will be shipped.\n // The approver enters this when confirming receipt.\n const [lotDraft, setLotDraft] = useState({});\n // Same logic for expiry — the requester can't read the expiry off a vial\n // they don't have. Captured by the approver.\n const [expiryDraft, setExpiryDraft] = useState({});\n const [decisionNotes, setDecisionNotes] = useState('');\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n const data = await getPurchaseRequest(requestId);\n setRequest(data);\n // Seed the draft with full approval — the typical case is \"approve everything\".\n const draft = {};\n const lots = {};\n const expiries = {};\n (data?.items ?? []).forEach((it) => {\n draft[it.id] = String(it.approvedQuantity != null ? it.approvedQuantity : it.requestedQuantity);\n lots[it.id] = it.lotNumber ?? '';\n // Expiry from the existing item, normalized to yyyy-MM-dd for the date input.\n expiries[it.id] = it.expiryDate ? new Date(it.expiryDate).toISOString().substring(0, 10) : '';\n });\n setApprovedDraft(draft);\n setLotDraft(lots);\n setExpiryDraft(expiries);\n setDecisionNotes(data?.decisionNotes ?? '');\n } catch (err) {\n setError(err?.response?.data?.message ?? err?.message ?? 'Failed to load purchase request');\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect(\n ['view.manage.productManagement.purchase', 'approve.manage.productManagement.purchase'],\n () => { void load(); },\n [requestId],\n );\n\n const isPending = request?.status === 'PENDING';\n\n // Sum the *approved* dollars for the in-flight decision so the approver\n // can see the cost of what they're about to confirm.\n const approvedTotal = useMemo(() => {\n if (!request || !manageAmounts) return null;\n let total = 0;\n let priced = false;\n (request.items ?? []).forEach((it) => {\n const qty = Number(approvedDraft[it.id] ?? 0);\n if (!Number.isFinite(qty) || qty <= 0) return;\n if (it.buyPrice == null) return;\n total += Number(it.buyPrice) * qty;\n priced = true;\n });\n return priced ? total : null;\n }, [request, approvedDraft, manageAmounts]);\n\n function patchDraft(itemId, value) {\n setApprovedDraft((d) => ({ ...d, [itemId]: value }));\n }\n\n function patchLot(itemId, value) {\n setLotDraft((d) => ({ ...d, [itemId]: value }));\n }\n\n function patchExpiry(itemId, value) {\n setExpiryDraft((d) => ({ ...d, [itemId]: value }));\n }\n\n function setAllToRequested() {\n if (!request) return;\n const draft = {};\n request.items.forEach((it) => { draft[it.id] = String(it.requestedQuantity); });\n setApprovedDraft(draft);\n }\n\n function setAllToZero() {\n if (!request) return;\n const draft = {};\n request.items.forEach((it) => { draft[it.id] = '0'; });\n setApprovedDraft(draft);\n }\n\n // Validates each line's approved qty is an integer in [0, requestedQty].\n // Returns a per-id error map; empty means \"ready to submit\".\n const draftErrors = useMemo(() => {\n if (!request) return {};\n const errs = {};\n (request.items ?? []).forEach((it) => {\n const raw = approvedDraft[it.id];\n if (raw == null || raw === '') {\n errs[it.id] = 'Required';\n return;\n }\n const n = Number(raw);\n if (!Number.isInteger(n) || n < 0) errs[it.id] = 'Must be 0 or a positive whole number';\n else if (n > it.requestedQuantity) errs[it.id] = `At most ${it.requestedQuantity}`;\n });\n return errs;\n }, [request, approvedDraft]);\n // Lot is required on every line the approver is approving (>0). Rejected\n // lines don't need a lot since no stock lands.\n const lotErrors = useMemo(() => {\n if (!request) return {};\n const errs = {};\n (request.items ?? []).forEach((it) => {\n const qty = Number(approvedDraft[it.id] ?? 0);\n if (!Number.isFinite(qty) || qty <= 0) return;\n const lot = (lotDraft[it.id] ?? '').trim();\n if (!lot) errs[it.id] = 'Lot is required when approving this line';\n });\n return errs;\n }, [request, approvedDraft, lotDraft]);\n // Expiry mirrors lot — required for any approved line, must be in the future.\n const expiryErrors = useMemo(() => {\n if (!request) return {};\n const errs = {};\n const todayStr = new Date().toISOString().substring(0, 10);\n (request.items ?? []).forEach((it) => {\n const qty = Number(approvedDraft[it.id] ?? 0);\n if (!Number.isFinite(qty) || qty <= 0) return;\n const exp = (expiryDraft[it.id] ?? '').trim();\n if (!exp) {\n errs[it.id] = 'Expiry is required when approving this line';\n } else if (exp < todayStr) {\n errs[it.id] = 'Expiry must be today or later';\n }\n });\n return errs;\n }, [request, approvedDraft, expiryDraft]);\n const draftIsClean = Object.keys(draftErrors).length === 0\n && Object.keys(lotErrors).length === 0\n && Object.keys(expiryErrors).length === 0;\n\n async function submit() {\n if (!draftIsClean || !request) return;\n setSubmitting(true);\n setError('');\n try {\n const updated = await decidePurchaseRequest(request.id, {\n decisionNotes: decisionNotes || null,\n items: request.items.map((it) => {\n const lot = (lotDraft[it.id] ?? '').trim();\n const exp = (expiryDraft[it.id] ?? '').trim();\n return {\n itemId: it.id,\n approvedQuantity: Number(approvedDraft[it.id]),\n lotNumber: lot ? lot : null,\n expiryDate: exp ? exp : null,\n };\n }),\n });\n setRequest(updated);\n showToast({ message: `Request ${prettyStatus(updated.status).toLowerCase()}.`, type: 'success' });\n } catch (err) {\n setError(err?.response?.data?.message ?? err?.message ?? 'Failed to submit decision');\n } finally {\n setSubmitting(false);\n }\n }\n\n async function cancel() {\n if (!request) return;\n setSubmitting(true);\n setError('');\n try {\n const updated = await cancelPurchaseRequest(request.id);\n setRequest(updated);\n showToast({ message: 'Request cancelled.', type: 'success' });\n } catch (err) {\n setError(err?.response?.data?.message ?? err?.message ?? 'Failed to cancel request');\n } finally {\n setSubmitting(false);\n }\n }\n\n // Coarse-grained UI states for the approver: clean PENDING + decide perm →\n // show the editable decision form. Otherwise the same table is shown\n // read-only with the historical approved quantities.\n const showDecisionForm = isPending && canDecide;\n\n return (\n <Box>\n <PmNav />\n <PmGuard anyOf={['view.manage.productManagement.purchase', 'approve.manage.productManagement.purchase']}>\n <PmPageShell\n title={request?.serialId ? `Purchase Request #${request.serialId}` : 'Purchase Request'}\n subtitle=\"Approve or reject each item. Your decision closes the entire request.\"\n chips={request?.status ? [prettyStatus(request.status)] : []}\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<ArrowBackRoundedIcon />} onClick={() => navigate('/ui/medplat/manage/pm/purchase-requests')}>Back</Button>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n {!loading && request ? (\n <>\n {/* ---------- Summary ---------- */}\n <Card sx={{ borderRadius: 1.5, 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={{ xs: 'column', md: 'row' }} spacing={2} alignItems={{ md: 'flex-start' }}>\n <Box sx={{ flexGrow: 1, minWidth: 0 }}>\n <Stack direction=\"row\" alignItems=\"center\" spacing={1.5} sx={{ mb: 0.5 }}>\n <PmRef id={request.serialId} />\n <Chip size=\"small\" label={prettyStatus(request.status)} color={statusChipColor(request.status)} />\n <Typography variant=\"caption\" color=\"text.secondary\">{request.ownerType}</Typography>\n </Stack>\n <Typography variant=\"h6\" sx={{ fontWeight: 800 }}>\n {request.ownerName || (request.ownerType === 'USER' ? 'Personal' : 'Facility')}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block' }}>\n For purchase date {formatDate(request.purchaseDate)}\n </Typography>\n </Box>\n <Stack spacing={0.25} sx={{ minWidth: 260 }}>\n <Row label=\"Requested by\">{request.requestedByName || `#${request.requestedBy}`}</Row>\n <Row label=\"Requested on\">{formatDateTime(request.requestedOn)}</Row>\n {request.decidedBy ? (\n <>\n <Row label=\"Decided by\">{request.decidedByName || `#${request.decidedBy}`}</Row>\n <Row label=\"Decided on\">{formatDateTime(request.decidedOn)}</Row>\n </>\n ) : null}\n {request.paymentMode ? <Row label=\"Payment\">{request.paymentMode}</Row> : null}\n </Stack>\n </Stack>\n {request.notes ? (\n <>\n <Divider sx={{ my: 1.5 }} />\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mb: 0.5, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.6 }}>\n Requester notes\n </Typography>\n <Typography variant=\"body2\">{request.notes}</Typography>\n </>\n ) : null}\n {request.decisionNotes ? (\n <>\n <Divider sx={{ my: 1.5 }} />\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ display: 'block', mb: 0.5, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.6 }}>\n Decision notes\n </Typography>\n <Typography variant=\"body2\">{request.decisionNotes}</Typography>\n </>\n ) : null}\n </CardContent>\n </Card>\n\n {/* ---------- Line items ---------- */}\n <Card sx={{ borderRadius: 1.5, 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={{ xs: 'column', md: 'row' }} alignItems={{ md: 'flex-end' }} justifyContent=\"space-between\" sx={{ mb: 1.5 }}>\n <PmFormSection\n eyebrow=\"Lines\"\n title={showDecisionForm ? 'Decide per-line quantities' : 'Requested items'}\n hint={showDecisionForm\n ? 'Enter 0 to reject an item, or less than requested to partially approve.'\n : null}\n />\n {showDecisionForm ? (\n <Stack direction=\"row\" spacing={1}>\n <Button size=\"small\" variant=\"outlined\" onClick={setAllToRequested}>Approve all</Button>\n <Button size=\"small\" variant=\"outlined\" color=\"error\" onClick={setAllToZero}>Reject all</Button>\n </Stack>\n ) : null}\n </Stack>\n\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>Product</TableCell>\n <TableCell>Lot</TableCell>\n <TableCell>Expiry</TableCell>\n {manageAmounts ? <TableCell align=\"right\">Buy Price</TableCell> : null}\n <TableCell align=\"right\">Requested</TableCell>\n <TableCell align=\"right\">{showDecisionForm ? 'Approve' : 'Approved'}</TableCell>\n {request.ownerType === 'FACILITY' ? <TableCell>Storage</TableCell> : null}\n </TableRow>\n </TableHead>\n <TableBody>\n {request.items.map((it) => {\n const lineErr = draftErrors[it.id];\n const lotErr = lotErrors[it.id];\n const expiryErr = expiryErrors[it.id];\n const approveQty = Number(approvedDraft[it.id] ?? 0);\n const lotInputActive = showDecisionForm && Number.isFinite(approveQty) && approveQty > 0;\n return (\n <TableRow key={it.id}>\n <TableCell sx={{ fontWeight: 700 }}>{it.productName}</TableCell>\n <TableCell sx={{ fontFamily: 'monospace', fontSize: '0.78rem' }}>\n {showDecisionForm ? (\n <TextField\n size=\"small\"\n placeholder=\"Enter lot\"\n value={lotDraft[it.id] ?? ''}\n onChange={(e) => patchLot(it.id, e.target.value)}\n disabled={!lotInputActive}\n error={!!lotErr}\n helperText={lotErr || (lotInputActive ? '' : 'Approve qty > 0 to enter lot')}\n inputProps={{ style: { fontFamily: 'monospace', fontSize: '0.78rem' } }}\n sx={{ minWidth: 140 }}\n />\n ) : (it.lotNumber || '—')}\n </TableCell>\n <TableCell>\n {showDecisionForm ? (\n <TextField\n size=\"small\"\n type=\"date\"\n InputLabelProps={{ shrink: true }}\n value={expiryDraft[it.id] ?? ''}\n onChange={(e) => patchExpiry(it.id, e.target.value)}\n disabled={!lotInputActive}\n error={!!expiryErr}\n helperText={expiryErr || (lotInputActive ? '' : '')}\n sx={{ minWidth: 150 }}\n />\n ) : (it.expiryDate ? formatDate(it.expiryDate) : '—')}\n </TableCell>\n {manageAmounts ? (\n <TableCell align=\"right\">\n {it.buyPrice != null ? <PmMoney value={it.buyPrice} bold={false} /> : <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>}\n </TableCell>\n ) : null}\n <TableCell align=\"right\" sx={{ fontVariantNumeric: 'tabular-nums', fontWeight: 700 }}>\n {it.requestedQuantity}\n </TableCell>\n <TableCell align=\"right\">\n {showDecisionForm ? (\n <TextField\n size=\"small\"\n type=\"number\"\n inputProps={{ min: 0, max: it.requestedQuantity, style: { textAlign: 'right' } }}\n value={approvedDraft[it.id] ?? ''}\n onChange={(e) => patchDraft(it.id, e.target.value)}\n error={!!lineErr}\n helperText={lineErr || ''}\n sx={{ maxWidth: 110 }}\n />\n ) : (\n <Typography sx={{ fontVariantNumeric: 'tabular-nums', fontWeight: 700 }}>\n {it.approvedQuantity == null ? '—' : it.approvedQuantity}\n </Typography>\n )}\n </TableCell>\n {request.ownerType === 'FACILITY' ? (\n <TableCell>{it.storageUnitName || '—'}</TableCell>\n ) : null}\n </TableRow>\n );\n })}\n </TableBody>\n </Table>\n\n {showDecisionForm ? (\n <>\n <Divider sx={{ my: 2 }} />\n <Stack direction={{ xs: 'column', md: 'row' }} spacing={2} alignItems={{ md: 'flex-start' }}>\n <TextField\n fullWidth\n size=\"small\"\n label=\"Decision notes (optional)\"\n placeholder=\"Rationale shown to the requester\"\n value={decisionNotes}\n onChange={(e) => setDecisionNotes(e.target.value)}\n multiline\n minRows={2}\n />\n {manageAmounts && approvedTotal != null ? (\n <Box sx={(t) => ({\n minWidth: 220,\n p: 1.5,\n borderRadius: 1.5,\n border: '1px solid',\n borderColor: 'divider',\n bgcolor: alpha(t.palette.primary.main, 0.04),\n textAlign: 'right',\n })}>\n <Typography variant=\"caption\" color=\"text.secondary\"\n sx={{ display: 'block', fontWeight: 800, textTransform: 'uppercase', letterSpacing: 0.6 }}>\n Total if approved\n </Typography>\n <PmMoney value={Number(approvedTotal.toFixed(2))} size=\"big\" />\n </Box>\n ) : null}\n </Stack>\n <Stack direction=\"row\" spacing={1} justifyContent=\"flex-end\" sx={{ mt: 2 }}>\n <Button\n variant=\"outlined\" color=\"error\" startIcon={<CancelRoundedIcon />}\n disabled={submitting}\n onClick={() => { setAllToZero(); }}\n >\n Set all to 0\n </Button>\n <Button\n variant=\"contained\" startIcon={<CheckCircleRoundedIcon />}\n disabled={submitting || !draftIsClean}\n onClick={() => void submit()}\n >\n {submitting ? 'Submitting…' : 'Submit Decision'}\n </Button>\n </Stack>\n </>\n ) : null}\n\n {/* Requester withdrawal — only on PENDING + only when the\n current user is the original requester. The backend\n enforces this too; the UI just hides the button when it's\n not applicable. */}\n {isPending && !canDecide ? (\n <Stack direction=\"row\" spacing={1} justifyContent=\"flex-end\" sx={{ mt: 2 }}>\n <Button\n variant=\"outlined\" color=\"error\" startIcon={<DoNotDisturbRoundedIcon />}\n disabled={submitting} onClick={() => void cancel()}\n >\n {submitting ? 'Cancelling…' : 'Cancel Request'}\n </Button>\n </Stack>\n ) : null}\n\n {request.approvedPurchaseId ? (\n <Alert severity=\"success\" sx={{ mt: 2 }}>\n Stock was added to inventory under purchase id <strong>{request.approvedPurchaseId}</strong>.\n </Alert>\n ) : null}\n </CardContent>\n </Card>\n </>\n ) : null}\n </PmPageShell>\n </PmGuard>\n </Box>\n );\n}\n\nfunction Row({ label, children }) {\n return (\n <Stack direction=\"row\" spacing={1} sx={{ minWidth: 0 }}>\n <Typography variant=\"caption\" color=\"text.secondary\" sx={{ minWidth: 100, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.5 }}>\n {label}\n </Typography>\n <Typography variant=\"caption\" sx={{ minWidth: 0, fontWeight: 700 }}>\n {children}\n </Typography>\n </Stack>\n );\n}\n"],"mappings":"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"}
@@ -1,14 +1,15 @@
1
- import { H as e, a as t, i as n, n as r, o as i, r as ee, z as te } from "./currency-ClRLIEg2.js";
2
- import { a, c as o, s, t as c } from "./PmTable-B9970kPY.js";
3
- import { t as l } from "./format-UOyOu75i.js";
4
- import { useMemo as u, useState as d } from "react";
1
+ import { A as e, N as t } from "./settingsStore-KW217unV.js";
2
+ import { a as n, c as r, s as i, t as a } from "./PmTable-BkK65bJQ.js";
3
+ import { t as o } from "./format-UOyOu75i.js";
4
+ import { a as s, i as c, n as l, r as u, t as ee } from "./PmGuard-C90yhpsN.js";
5
+ import { useMemo as te, useState as d } from "react";
5
6
  import { Fragment as ne, jsx as f, jsxs as p } from "react/jsx-runtime";
6
- import { Alert as m, Box as h, Button as g, Chip as _, InputAdornment as v, Skeleton as y, Stack as b, Tab as x, TableBody as S, TableCell as C, TableHead as re, TableRow as w, Tabs as ie, TextField as ae, Typography as T } from "@mui/material";
7
- import oe from "@mui/icons-material/AddRounded";
8
- import se from "@mui/icons-material/RefreshRounded";
9
- import { showToast as E } from "@/common/toaster/toaster";
10
- import { useNavigate as D } from "react-router-dom";
11
- import { alpha as O, useTheme as k } from "@mui/material/styles";
7
+ import { Alert as m, Box as h, Button as g, Chip as _, InputAdornment as v, Skeleton as y, Stack as b, Tab as x, TableBody as re, TableCell as S, TableHead as C, TableRow as w, Tabs as ie, TextField as T, Typography as E } from "@mui/material";
8
+ import { showToast as ae } from "@/common/toaster/toaster";
9
+ import { alpha as D, useTheme as oe } from "@mui/material/styles";
10
+ import se from "@mui/icons-material/AddRounded";
11
+ import O from "@mui/icons-material/RefreshRounded";
12
+ import { useNavigate as k } from "react-router-dom";
12
13
  import A from "@mui/icons-material/FactCheckRounded";
13
14
  import j from "@mui/icons-material/SearchRounded";
14
15
  //#region src/views/PurchaseRequestsPage.jsx
@@ -27,17 +28,17 @@ function P(e) {
27
28
  return e ? e.toLowerCase().split("_").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ") : "";
28
29
  }
29
30
  function F() {
30
- let F = D(), I = k(), L = t(), R = L.has("update.manage.productManagement.purchase"), z = L.has("approve.manage.productManagement.purchase"), B = L.has("view.manage.productManagement.purchase"), [V, H] = d(z && !B ? "pending" : "mine"), [U, W] = d([]), [G, ce] = d([]), [K, q] = d(!0), [J, Y] = d(""), [X, le] = d("");
31
+ let F = k(), I = oe(), L = c(), R = L.has("update.manage.productManagement.purchase"), z = L.has("approve.manage.productManagement.purchase"), B = L.has("view.manage.productManagement.purchase"), [V, H] = d(z && !B ? "pending" : "mine"), [U, W] = d([]), [G, ce] = d([]), [K, q] = d(!0), [J, Y] = d(""), [X, le] = d("");
31
32
  async function Z() {
32
33
  q(!0), Y("");
33
34
  try {
34
- let t = [];
35
- B ? t.push(te()) : t.push(Promise.resolve([])), z ? t.push(e()) : t.push(Promise.resolve([]));
36
- let n = await Promise.all(t);
37
- W(n[0] ?? []), ce(n[1] ?? []);
35
+ let n = [];
36
+ B ? n.push(e()) : n.push(Promise.resolve([])), z ? n.push(t()) : n.push(Promise.resolve([]));
37
+ let r = await Promise.all(n);
38
+ W(r[0] ?? []), ce(r[1] ?? []);
38
39
  } catch (e) {
39
40
  let t = e?.response?.data?.message ?? e?.message ?? "Failed to load purchase requests";
40
- Y(t), E({
41
+ Y(t), ae({
41
42
  message: t,
42
43
  type: "error"
43
44
  });
@@ -45,19 +46,19 @@ function F() {
45
46
  q(!1);
46
47
  }
47
48
  }
48
- n(["view.manage.productManagement.purchase", "approve.manage.productManagement.purchase"], () => {
49
+ u(["view.manage.productManagement.purchase", "approve.manage.productManagement.purchase"], () => {
49
50
  Z();
50
51
  }, []);
51
- let Q = V === "pending" ? G : U, $ = u(() => {
52
+ let Q = V === "pending" ? G : U, $ = te(() => {
52
53
  let e = X.trim().toLowerCase();
53
54
  return e ? Q.filter((t) => {
54
55
  let n = (t.items ?? []).map((e) => e.productName ?? "").join(" ");
55
56
  return `${t.notes ?? ""} ${t.ownerName ?? ""} ${t.requestedByName ?? ""} ${n}`.toLowerCase().includes(e);
56
57
  }) : Q;
57
58
  }, [Q, X]);
58
- return /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(ee, {}), /* @__PURE__ */ f(r, {
59
+ return /* @__PURE__ */ p(h, { children: [/* @__PURE__ */ f(l, {}), /* @__PURE__ */ f(ee, {
59
60
  anyOf: ["view.manage.productManagement.purchase", "approve.manage.productManagement.purchase"],
60
- children: /* @__PURE__ */ p(i, {
61
+ children: /* @__PURE__ */ p(s, {
61
62
  title: "Purchase Requests",
62
63
  subtitle: "Purchase requests waiting for approval. A manager must confirm them before stock is added.",
63
64
  actions: /* @__PURE__ */ p(b, {
@@ -65,12 +66,12 @@ function F() {
65
66
  spacing: 1,
66
67
  children: [/* @__PURE__ */ f(g, {
67
68
  variant: "outlined",
68
- startIcon: /* @__PURE__ */ f(se, {}),
69
+ startIcon: /* @__PURE__ */ f(O, {}),
69
70
  onClick: () => void Z(),
70
71
  children: "Refresh"
71
72
  }), R ? /* @__PURE__ */ f(g, {
72
73
  variant: "contained",
73
- startIcon: /* @__PURE__ */ f(oe, {}),
74
+ startIcon: /* @__PURE__ */ f(se, {}),
74
75
  onClick: () => F("/ui/medplat/manage/pm/purchases/new"),
75
76
  children: "New Request"
76
77
  }) : null]
@@ -79,7 +80,7 @@ function F() {
79
80
  severity: "error",
80
81
  sx: { mb: 2 },
81
82
  children: J
82
- }) : null, /* @__PURE__ */ p(o, {
83
+ }) : null, /* @__PURE__ */ p(r, {
83
84
  eyebrow: "Approvals",
84
85
  title: V === "pending" ? "Pending approvals" : "My requests",
85
86
  subtitle: K ? "Loading…" : `${$.length} ${$.length === 1 ? "request" : "requests"}`,
@@ -116,7 +117,7 @@ function F() {
116
117
  }) : null]
117
118
  }),
118
119
  /* @__PURE__ */ f(h, { sx: { flexGrow: 1 } }),
119
- /* @__PURE__ */ f(ae, {
120
+ /* @__PURE__ */ f(T, {
120
121
  size: "small",
121
122
  fullWidth: !0,
122
123
  placeholder: "Search by owner, requester, item, notes…",
@@ -129,50 +130,50 @@ function F() {
129
130
  }) }
130
131
  })
131
132
  ]
132
- }), /* @__PURE__ */ p(s, {
133
+ }), /* @__PURE__ */ p(i, {
133
134
  dense: !0,
134
- children: [/* @__PURE__ */ f(re, { children: /* @__PURE__ */ p(w, { children: [
135
- /* @__PURE__ */ f(C, { children: "Ref" }),
136
- /* @__PURE__ */ f(C, { children: "Date" }),
137
- /* @__PURE__ */ f(C, { children: "Owner" }),
138
- /* @__PURE__ */ f(C, { children: "Items" }),
139
- /* @__PURE__ */ f(C, { children: "Requester" }),
140
- /* @__PURE__ */ f(C, { children: "Decision" }),
141
- /* @__PURE__ */ f(C, { children: "Status" })
142
- ] }) }), /* @__PURE__ */ f(S, { children: K ? Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */ f(w, { children: Array.from({ length: 7 }).map((e, t) => /* @__PURE__ */ f(C, { children: /* @__PURE__ */ f(y, { height: 22 }) }, t)) }, t)) : $.length === 0 ? /* @__PURE__ */ f(c, {
135
+ children: [/* @__PURE__ */ f(C, { children: /* @__PURE__ */ p(w, { children: [
136
+ /* @__PURE__ */ f(S, { children: "Ref" }),
137
+ /* @__PURE__ */ f(S, { children: "Date" }),
138
+ /* @__PURE__ */ f(S, { children: "Owner" }),
139
+ /* @__PURE__ */ f(S, { children: "Items" }),
140
+ /* @__PURE__ */ f(S, { children: "Requester" }),
141
+ /* @__PURE__ */ f(S, { children: "Decision" }),
142
+ /* @__PURE__ */ f(S, { children: "Status" })
143
+ ] }) }), /* @__PURE__ */ f(re, { children: K ? Array.from({ length: 4 }).map((e, t) => /* @__PURE__ */ f(w, { children: Array.from({ length: 7 }).map((e, t) => /* @__PURE__ */ f(S, { children: /* @__PURE__ */ f(y, { height: 22 }) }, t)) }, t)) : $.length === 0 ? /* @__PURE__ */ f(a, {
143
144
  colSpan: 7,
144
145
  icon: A,
145
146
  title: X.trim() === "" ? V === "pending" ? "No pending approvals" : "No requests yet" : "No requests match your search",
146
147
  hint: V === "pending" ? "Purchases needing your approval will appear here." : "Your submitted requests will appear here."
147
148
  }) : $.map((e) => {
148
- let t = e.items ?? [], n = t.slice(0, M), r = t.length - n.length;
149
+ let t = e.items ?? [], r = t.slice(0, M), i = t.length - r.length;
149
150
  return /* @__PURE__ */ p(w, {
150
151
  hover: !0,
151
152
  sx: { cursor: "pointer" },
152
153
  onClick: () => F(`/ui/medplat/manage/pm/purchase-requests/${e.id}`),
153
154
  children: [
154
- /* @__PURE__ */ f(C, { children: /* @__PURE__ */ f(a, { id: e.serialId }) }),
155
- /* @__PURE__ */ p(C, { children: [/* @__PURE__ */ f(T, {
155
+ /* @__PURE__ */ f(S, { children: /* @__PURE__ */ f(n, { id: e.serialId }) }),
156
+ /* @__PURE__ */ p(S, { children: [/* @__PURE__ */ f(E, {
156
157
  variant: "body2",
157
158
  sx: { fontWeight: 700 },
158
- children: l(e.purchaseDate)
159
- }), /* @__PURE__ */ p(T, {
159
+ children: o(e.purchaseDate)
160
+ }), /* @__PURE__ */ p(E, {
160
161
  variant: "caption",
161
162
  color: "text.secondary",
162
- children: ["Submitted ", l(e.requestedOn)]
163
+ children: ["Submitted ", o(e.requestedOn)]
163
164
  })] }),
164
- /* @__PURE__ */ p(C, { children: [/* @__PURE__ */ f(T, {
165
+ /* @__PURE__ */ p(S, { children: [/* @__PURE__ */ f(E, {
165
166
  variant: "body2",
166
167
  sx: { fontWeight: 700 },
167
168
  children: e.ownerName || (e.ownerType === "USER" ? "Personal" : "Facility")
168
- }), /* @__PURE__ */ f(T, {
169
+ }), /* @__PURE__ */ f(E, {
169
170
  variant: "caption",
170
171
  color: "text.secondary",
171
172
  children: e.ownerType
172
173
  })] }),
173
- /* @__PURE__ */ f(C, {
174
+ /* @__PURE__ */ f(S, {
174
175
  sx: { maxWidth: 360 },
175
- children: t.length === 0 ? /* @__PURE__ */ f(T, {
176
+ children: t.length === 0 ? /* @__PURE__ */ f(E, {
176
177
  variant: "caption",
177
178
  color: "text.disabled",
178
179
  children: "—"
@@ -181,7 +182,7 @@ function F() {
181
182
  spacing: .5,
182
183
  flexWrap: "wrap",
183
184
  useFlexGap: !0,
184
- children: [n.map((e) => /* @__PURE__ */ f(_, {
185
+ children: [r.map((e) => /* @__PURE__ */ f(_, {
185
186
  size: "small",
186
187
  label: /* @__PURE__ */ p(h, {
187
188
  component: "span",
@@ -207,14 +208,14 @@ function F() {
207
208
  sx: {
208
209
  height: 22,
209
210
  borderRadius: 1.5,
210
- bgcolor: O(I.palette.primary.main, .06),
211
+ bgcolor: D(I.palette.primary.main, .06),
211
212
  color: "text.primary",
212
- border: `1px solid ${O(I.palette.primary.main, .16)}`,
213
+ border: `1px solid ${D(I.palette.primary.main, .16)}`,
213
214
  "& .MuiChip-label": { px: .85 }
214
215
  }
215
- }, e.id)), r > 0 ? /* @__PURE__ */ f(_, {
216
+ }, e.id)), i > 0 ? /* @__PURE__ */ f(_, {
216
217
  size: "small",
217
- label: `+${r} more`,
218
+ label: `+${i} more`,
218
219
  sx: {
219
220
  height: 22,
220
221
  borderRadius: 1.5,
@@ -229,24 +230,24 @@ function F() {
229
230
  }) : null]
230
231
  })
231
232
  }),
232
- /* @__PURE__ */ f(C, { children: /* @__PURE__ */ f(T, {
233
+ /* @__PURE__ */ f(S, { children: /* @__PURE__ */ f(E, {
233
234
  variant: "body2",
234
235
  children: e.requestedByName || `#${e.requestedBy}`
235
236
  }) }),
236
- /* @__PURE__ */ f(C, { children: e.decidedOn ? /* @__PURE__ */ p(ne, { children: [/* @__PURE__ */ f(T, {
237
+ /* @__PURE__ */ f(S, { children: e.decidedOn ? /* @__PURE__ */ p(ne, { children: [/* @__PURE__ */ f(E, {
237
238
  variant: "body2",
238
239
  sx: { fontWeight: 700 },
239
240
  children: e.decidedByName || `#${e.decidedBy}`
240
- }), /* @__PURE__ */ f(T, {
241
+ }), /* @__PURE__ */ f(E, {
241
242
  variant: "caption",
242
243
  color: "text.secondary",
243
- children: l(e.decidedOn)
244
- })] }) : /* @__PURE__ */ f(T, {
244
+ children: o(e.decidedOn)
245
+ })] }) : /* @__PURE__ */ f(E, {
245
246
  variant: "caption",
246
247
  color: "text.disabled",
247
248
  children: "—"
248
249
  }) }),
249
- /* @__PURE__ */ f(C, { children: /* @__PURE__ */ f(_, {
250
+ /* @__PURE__ */ f(S, { children: /* @__PURE__ */ f(_, {
250
251
  size: "small",
251
252
  label: P(e.status),
252
253
  color: N(e.status)
@@ -262,4 +263,4 @@ function F() {
262
263
  //#endregion
263
264
  export { F as default };
264
265
 
265
- //# sourceMappingURL=PurchaseRequestsPage-BwCkbpaX.js.map
266
+ //# sourceMappingURL=PurchaseRequestsPage-BJqDlNrc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PurchaseRequestsPage-BwCkbpaX.js","names":[],"sources":["../src/views/PurchaseRequestsPage.jsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Alert,\n Box,\n Button,\n Chip,\n InputAdornment,\n Skeleton,\n Stack,\n Tab,\n Tabs,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport { alpha, useTheme } 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 FactCheckRoundedIcon from '@mui/icons-material/FactCheckRounded';\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 {\n listMyPurchaseRequests,\n listPendingPurchaseRequests,\n} from '@pm/services/pmApi';\nimport { formatDate } from '@pm/utils/format';\n\n// Compact one-liner of items + qty for the table. Up to MAX_ITEMS_INLINE\n// items render as inline pills; anything beyond gets a \"+N more\" pill so\n// the row height stays stable.\nconst MAX_ITEMS_INLINE = 3;\n\n// Visual mapping for the lifecycle states. Pending sits in info-blue while a\n// decision is awaited; approved/partial use success/warning to signal the\n// terminal verdict; rejected/cancelled drop to muted defaults.\nfunction statusChipColor(status) {\n switch (status) {\n case 'PENDING': return 'info';\n case 'APPROVED': return 'success';\n case 'PARTIALLY_APPROVED': return 'warning';\n case 'REJECTED': return 'error';\n case 'CANCELLED': return 'default';\n default: return 'default';\n }\n}\n\nfunction prettyStatus(status) {\n if (!status) return '';\n return status\n .toLowerCase()\n .split('_')\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join(' ');\n}\n\nexport default function PurchaseRequestsPage() {\n const navigate = useNavigate();\n const theme = useTheme();\n const perms = usePmPermissions();\n const canSubmit = perms.has('update.manage.productManagement.purchase');\n const canApprove = perms.has('approve.manage.productManagement.purchase');\n const canView = perms.has('view.manage.productManagement.purchase');\n // Default tab follows the user's role:\n // - Approver-only (no view perm) lands directly on Pending — they don't\n // have a \"My Requests\" tab to see anyway.\n // - Anyone else (view perm, or both) lands on My Requests.\n const [tab, setTab] = useState(canApprove && !canView ? 'pending' : 'mine');\n const [mine, setMine] = useState([]);\n const [pending, setPending] = useState([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState('');\n const [search, setSearch] = useState('');\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n // Mine fetched when the user has view perm; Pending when they have\n // approve perm. Each side is independent — an approver-only role\n // never fetches /mine, a viewer-only role never fetches /pending.\n const calls = [];\n if (canView) calls.push(listMyPurchaseRequests());\n else calls.push(Promise.resolve([]));\n if (canApprove) calls.push(listPendingPurchaseRequests());\n else calls.push(Promise.resolve([]));\n const results = await Promise.all(calls);\n setMine(results[0] ?? []);\n setPending(results[1] ?? []);\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load purchase requests';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect(\n ['view.manage.productManagement.purchase', 'approve.manage.productManagement.purchase'],\n () => { void load(); },\n [],\n );\n\n const rows = tab === 'pending' ? pending : mine;\n const filteredRows = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return rows;\n return rows.filter((r) => {\n const itemNames = (r.items ?? []).map((i) => i.productName ?? '').join(' ');\n const hay = `${r.notes ?? ''} ${r.ownerName ?? ''} ${r.requestedByName ?? ''} ${itemNames}`.toLowerCase();\n return hay.includes(q);\n });\n }, [rows, search]);\n\n return (\n <Box>\n <PmNav />\n <PmGuard anyOf={['view.manage.productManagement.purchase', 'approve.manage.productManagement.purchase']}>\n <PmPageShell\n title=\"Purchase Requests\"\n subtitle=\"Purchase requests waiting for approval. A manager must confirm them before stock is added.\"\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n {canSubmit ? (\n <Button variant=\"contained\" startIcon={<AddRoundedIcon />}\n onClick={() => navigate('/ui/medplat/manage/pm/purchases/new')}>\n New Request\n </Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Approvals\"\n title={tab === 'pending' ? 'Pending approvals' : 'My requests'}\n subtitle={loading\n ? 'Loading…'\n : `${filteredRows.length} ${filteredRows.length === 1 ? 'request' : 'requests'}`}\n >\n <Stack direction={{ xs: 'column', md: 'row' }} spacing={1.5} sx={{ mb: 2 }} alignItems={{ md: 'center' }}>\n <Tabs\n value={tab}\n onChange={(_, v) => setTab(v)}\n slotProps={{ indicator: { sx: { backgroundColor: theme.palette.primary.main } } }}\n sx={{ minHeight: 40 }}\n >\n {/* Tabs follow perms:\n - My Requests: only when the user has the view perm.\n - Pending: only when the user has the approve perm.\n An approver-only role sees just the Pending tab. */}\n {canView ? (\n <Tab value=\"mine\" label={`My requests${mine.length ? ` (${mine.length})` : ''}`} sx={{ minHeight: 40, textTransform: 'none', fontWeight: 700 }} />\n ) : null}\n {canApprove ? (\n <Tab value=\"pending\" label={`Pending${pending.length ? ` (${pending.length})` : ''}`} sx={{ minHeight: 40, textTransform: 'none', fontWeight: 700 }} />\n ) : null}\n </Tabs>\n <Box sx={{ flexGrow: 1 }} />\n <TextField\n size=\"small\"\n fullWidth\n placeholder=\"Search by owner, requester, item, notes…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n sx={{ maxWidth: { md: 360 } }}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchRoundedIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n }}\n />\n </Stack>\n\n <PmTable dense>\n <TableHead>\n <TableRow>\n <TableCell>Ref</TableCell>\n <TableCell>Date</TableCell>\n <TableCell>Owner</TableCell>\n <TableCell>Items</TableCell>\n <TableCell>Requester</TableCell>\n <TableCell>Decision</TableCell>\n <TableCell>Status</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n Array.from({ length: 4 }).map((_, i) => (\n <TableRow key={i}>\n {Array.from({ length: 7 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : filteredRows.length === 0 ? (\n <PmEmptyRow\n colSpan={7}\n icon={FactCheckRoundedIcon}\n title={search.trim() !== ''\n ? 'No requests match your search'\n : tab === 'pending'\n ? 'No pending approvals'\n : 'No requests yet'}\n hint={tab === 'pending'\n ? 'Purchases needing your approval will appear here.'\n : 'Your submitted requests will appear here.'}\n />\n ) : filteredRows.map((r) => {\n const items = r.items ?? [];\n const visibleItems = items.slice(0, MAX_ITEMS_INLINE);\n const overflow = items.length - visibleItems.length;\n return (\n <TableRow\n key={r.id}\n hover\n sx={{ cursor: 'pointer' }}\n onClick={() => navigate(`/ui/medplat/manage/pm/purchase-requests/${r.id}`)}\n >\n <TableCell><PmRef id={r.serialId} /></TableCell>\n <TableCell>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>{formatDate(r.purchaseDate)}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n Submitted {formatDate(r.requestedOn)}\n </Typography>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>\n {r.ownerName || (r.ownerType === 'USER' ? 'Personal' : 'Facility')}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {r.ownerType}\n </Typography>\n </TableCell>\n <TableCell sx={{ maxWidth: 360 }}>\n {items.length === 0 ? (\n <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>\n ) : (\n <Stack direction=\"row\" spacing={0.5} flexWrap=\"wrap\" useFlexGap>\n {visibleItems.map((it) => (\n <Chip\n key={it.id}\n size=\"small\"\n label={\n <Box component=\"span\" sx={{ display: 'inline-flex', alignItems: 'baseline', gap: 0.5 }}>\n <Box component=\"span\" sx={{ fontWeight: 700 }}>{it.productName ?? '—'}</Box>\n <Box component=\"span\" sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums', color: 'text.secondary' }}>\n ×{it.approvedQuantity != null ? it.approvedQuantity : it.requestedQuantity}\n </Box>\n </Box>\n }\n sx={{\n height: 22,\n borderRadius: 1.5,\n bgcolor: alpha(theme.palette.primary.main, 0.06),\n color: 'text.primary',\n border: `1px solid ${alpha(theme.palette.primary.main, 0.16)}`,\n '& .MuiChip-label': { px: 0.85 },\n }}\n />\n ))}\n {overflow > 0 ? (\n <Chip\n size=\"small\"\n label={`+${overflow} more`}\n sx={{\n height: 22,\n borderRadius: 1.5,\n bgcolor: 'transparent',\n color: 'text.secondary',\n border: `1px dashed ${theme.palette.divider}`,\n '& .MuiChip-label': { px: 0.85, fontWeight: 700 },\n }}\n />\n ) : null}\n </Stack>\n )}\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">{r.requestedByName || `#${r.requestedBy}`}</Typography>\n </TableCell>\n <TableCell>\n {r.decidedOn ? (\n <>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>\n {r.decidedByName || `#${r.decidedBy}`}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {formatDate(r.decidedOn)}\n </Typography>\n </>\n ) : (\n <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>\n )}\n </TableCell>\n <TableCell>\n <Chip size=\"small\" label={prettyStatus(r.status)} color={statusChipColor(r.status)} />\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PurchaseRequestsPage-BJqDlNrc.js","names":[],"sources":["../src/views/PurchaseRequestsPage.jsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Alert,\n Box,\n Button,\n Chip,\n InputAdornment,\n Skeleton,\n Stack,\n Tab,\n Tabs,\n TableBody,\n TableCell,\n TableHead,\n TableRow,\n TextField,\n Typography,\n} from '@mui/material';\nimport { alpha, useTheme } 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 FactCheckRoundedIcon from '@mui/icons-material/FactCheckRounded';\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 {\n listMyPurchaseRequests,\n listPendingPurchaseRequests,\n} from '@pm/services/pmApi';\nimport { formatDate } from '@pm/utils/format';\n\n// Compact one-liner of items + qty for the table. Up to MAX_ITEMS_INLINE\n// items render as inline pills; anything beyond gets a \"+N more\" pill so\n// the row height stays stable.\nconst MAX_ITEMS_INLINE = 3;\n\n// Visual mapping for the lifecycle states. Pending sits in info-blue while a\n// decision is awaited; approved/partial use success/warning to signal the\n// terminal verdict; rejected/cancelled drop to muted defaults.\nfunction statusChipColor(status) {\n switch (status) {\n case 'PENDING': return 'info';\n case 'APPROVED': return 'success';\n case 'PARTIALLY_APPROVED': return 'warning';\n case 'REJECTED': return 'error';\n case 'CANCELLED': return 'default';\n default: return 'default';\n }\n}\n\nfunction prettyStatus(status) {\n if (!status) return '';\n return status\n .toLowerCase()\n .split('_')\n .map((p) => p.charAt(0).toUpperCase() + p.slice(1))\n .join(' ');\n}\n\nexport default function PurchaseRequestsPage() {\n const navigate = useNavigate();\n const theme = useTheme();\n const perms = usePmPermissions();\n const canSubmit = perms.has('update.manage.productManagement.purchase');\n const canApprove = perms.has('approve.manage.productManagement.purchase');\n const canView = perms.has('view.manage.productManagement.purchase');\n // Default tab follows the user's role:\n // - Approver-only (no view perm) lands directly on Pending — they don't\n // have a \"My Requests\" tab to see anyway.\n // - Anyone else (view perm, or both) lands on My Requests.\n const [tab, setTab] = useState(canApprove && !canView ? 'pending' : 'mine');\n const [mine, setMine] = useState([]);\n const [pending, setPending] = useState([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState('');\n const [search, setSearch] = useState('');\n\n async function load() {\n setLoading(true);\n setError('');\n try {\n // Mine fetched when the user has view perm; Pending when they have\n // approve perm. Each side is independent — an approver-only role\n // never fetches /mine, a viewer-only role never fetches /pending.\n const calls = [];\n if (canView) calls.push(listMyPurchaseRequests());\n else calls.push(Promise.resolve([]));\n if (canApprove) calls.push(listPendingPurchaseRequests());\n else calls.push(Promise.resolve([]));\n const results = await Promise.all(calls);\n setMine(results[0] ?? []);\n setPending(results[1] ?? []);\n } catch (err) {\n const message = err?.response?.data?.message ?? err?.message ?? 'Failed to load purchase requests';\n setError(message);\n showToast({ message, type: 'error' });\n } finally {\n setLoading(false);\n }\n }\n\n usePermissionedEffect(\n ['view.manage.productManagement.purchase', 'approve.manage.productManagement.purchase'],\n () => { void load(); },\n [],\n );\n\n const rows = tab === 'pending' ? pending : mine;\n const filteredRows = useMemo(() => {\n const q = search.trim().toLowerCase();\n if (!q) return rows;\n return rows.filter((r) => {\n const itemNames = (r.items ?? []).map((i) => i.productName ?? '').join(' ');\n const hay = `${r.notes ?? ''} ${r.ownerName ?? ''} ${r.requestedByName ?? ''} ${itemNames}`.toLowerCase();\n return hay.includes(q);\n });\n }, [rows, search]);\n\n return (\n <Box>\n <PmNav />\n <PmGuard anyOf={['view.manage.productManagement.purchase', 'approve.manage.productManagement.purchase']}>\n <PmPageShell\n title=\"Purchase Requests\"\n subtitle=\"Purchase requests waiting for approval. A manager must confirm them before stock is added.\"\n actions={\n <Stack direction=\"row\" spacing={1}>\n <Button variant=\"outlined\" startIcon={<RefreshRoundedIcon />} onClick={() => void load()}>Refresh</Button>\n {canSubmit ? (\n <Button variant=\"contained\" startIcon={<AddRoundedIcon />}\n onClick={() => navigate('/ui/medplat/manage/pm/purchases/new')}>\n New Request\n </Button>\n ) : null}\n </Stack>\n }\n >\n {error ? <Alert severity=\"error\" sx={{ mb: 2 }}>{error}</Alert> : null}\n\n <PmTableCard\n eyebrow=\"Approvals\"\n title={tab === 'pending' ? 'Pending approvals' : 'My requests'}\n subtitle={loading\n ? 'Loading…'\n : `${filteredRows.length} ${filteredRows.length === 1 ? 'request' : 'requests'}`}\n >\n <Stack direction={{ xs: 'column', md: 'row' }} spacing={1.5} sx={{ mb: 2 }} alignItems={{ md: 'center' }}>\n <Tabs\n value={tab}\n onChange={(_, v) => setTab(v)}\n slotProps={{ indicator: { sx: { backgroundColor: theme.palette.primary.main } } }}\n sx={{ minHeight: 40 }}\n >\n {/* Tabs follow perms:\n - My Requests: only when the user has the view perm.\n - Pending: only when the user has the approve perm.\n An approver-only role sees just the Pending tab. */}\n {canView ? (\n <Tab value=\"mine\" label={`My requests${mine.length ? ` (${mine.length})` : ''}`} sx={{ minHeight: 40, textTransform: 'none', fontWeight: 700 }} />\n ) : null}\n {canApprove ? (\n <Tab value=\"pending\" label={`Pending${pending.length ? ` (${pending.length})` : ''}`} sx={{ minHeight: 40, textTransform: 'none', fontWeight: 700 }} />\n ) : null}\n </Tabs>\n <Box sx={{ flexGrow: 1 }} />\n <TextField\n size=\"small\"\n fullWidth\n placeholder=\"Search by owner, requester, item, notes…\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n sx={{ maxWidth: { md: 360 } }}\n InputProps={{\n startAdornment: (\n <InputAdornment position=\"start\">\n <SearchRoundedIcon fontSize=\"small\" />\n </InputAdornment>\n ),\n }}\n />\n </Stack>\n\n <PmTable dense>\n <TableHead>\n <TableRow>\n <TableCell>Ref</TableCell>\n <TableCell>Date</TableCell>\n <TableCell>Owner</TableCell>\n <TableCell>Items</TableCell>\n <TableCell>Requester</TableCell>\n <TableCell>Decision</TableCell>\n <TableCell>Status</TableCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {loading ? (\n Array.from({ length: 4 }).map((_, i) => (\n <TableRow key={i}>\n {Array.from({ length: 7 }).map((__, j) => (\n <TableCell key={j}><Skeleton height={22} /></TableCell>\n ))}\n </TableRow>\n ))\n ) : filteredRows.length === 0 ? (\n <PmEmptyRow\n colSpan={7}\n icon={FactCheckRoundedIcon}\n title={search.trim() !== ''\n ? 'No requests match your search'\n : tab === 'pending'\n ? 'No pending approvals'\n : 'No requests yet'}\n hint={tab === 'pending'\n ? 'Purchases needing your approval will appear here.'\n : 'Your submitted requests will appear here.'}\n />\n ) : filteredRows.map((r) => {\n const items = r.items ?? [];\n const visibleItems = items.slice(0, MAX_ITEMS_INLINE);\n const overflow = items.length - visibleItems.length;\n return (\n <TableRow\n key={r.id}\n hover\n sx={{ cursor: 'pointer' }}\n onClick={() => navigate(`/ui/medplat/manage/pm/purchase-requests/${r.id}`)}\n >\n <TableCell><PmRef id={r.serialId} /></TableCell>\n <TableCell>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>{formatDate(r.purchaseDate)}</Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n Submitted {formatDate(r.requestedOn)}\n </Typography>\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>\n {r.ownerName || (r.ownerType === 'USER' ? 'Personal' : 'Facility')}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {r.ownerType}\n </Typography>\n </TableCell>\n <TableCell sx={{ maxWidth: 360 }}>\n {items.length === 0 ? (\n <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>\n ) : (\n <Stack direction=\"row\" spacing={0.5} flexWrap=\"wrap\" useFlexGap>\n {visibleItems.map((it) => (\n <Chip\n key={it.id}\n size=\"small\"\n label={\n <Box component=\"span\" sx={{ display: 'inline-flex', alignItems: 'baseline', gap: 0.5 }}>\n <Box component=\"span\" sx={{ fontWeight: 700 }}>{it.productName ?? '—'}</Box>\n <Box component=\"span\" sx={{ fontWeight: 700, fontVariantNumeric: 'tabular-nums', color: 'text.secondary' }}>\n ×{it.approvedQuantity != null ? it.approvedQuantity : it.requestedQuantity}\n </Box>\n </Box>\n }\n sx={{\n height: 22,\n borderRadius: 1.5,\n bgcolor: alpha(theme.palette.primary.main, 0.06),\n color: 'text.primary',\n border: `1px solid ${alpha(theme.palette.primary.main, 0.16)}`,\n '& .MuiChip-label': { px: 0.85 },\n }}\n />\n ))}\n {overflow > 0 ? (\n <Chip\n size=\"small\"\n label={`+${overflow} more`}\n sx={{\n height: 22,\n borderRadius: 1.5,\n bgcolor: 'transparent',\n color: 'text.secondary',\n border: `1px dashed ${theme.palette.divider}`,\n '& .MuiChip-label': { px: 0.85, fontWeight: 700 },\n }}\n />\n ) : null}\n </Stack>\n )}\n </TableCell>\n <TableCell>\n <Typography variant=\"body2\">{r.requestedByName || `#${r.requestedBy}`}</Typography>\n </TableCell>\n <TableCell>\n {r.decidedOn ? (\n <>\n <Typography variant=\"body2\" sx={{ fontWeight: 700 }}>\n {r.decidedByName || `#${r.decidedBy}`}\n </Typography>\n <Typography variant=\"caption\" color=\"text.secondary\">\n {formatDate(r.decidedOn)}\n </Typography>\n </>\n ) : (\n <Typography variant=\"caption\" color=\"text.disabled\">—</Typography>\n )}\n </TableCell>\n <TableCell>\n <Chip size=\"small\" label={prettyStatus(r.status)} color={statusChipColor(r.status)} />\n </TableCell>\n </TableRow>\n );\n })}\n </TableBody>\n </PmTable>\n </PmTableCard>\n </PmPageShell>\n </PmGuard>\n </Box>\n );\n}\n"],"mappings":"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"}