import React from 'react'; import { useTranslation } from 'react-i18next'; import { ComboBox, InlineLoading, InlineNotification, Layer } from '@carbon/react'; import { formatDate, useConfig } from '@openmrs/esm-framework'; import { type MedicationDispense, type InventoryItem } from '../../types'; import { type PharmacyConfig } from '../../config-schema'; import { useDispenseStock } from './stock.resource'; type StockDispenseProps = { medicationDispense: MedicationDispense; updateInventoryItem: (inventoryItem: InventoryItem) => void; inventoryItem: InventoryItem; }; const StockDispense: React.FC = ({ medicationDispense, updateInventoryItem }) => { const { t } = useTranslation(); const config = useConfig(); const drugUuid = medicationDispense?.medicationReference?.reference?.split('/')[1]; const { inventoryItems, error, isLoading } = useDispenseStock(drugUuid); const validInventoryItems = inventoryItems .filter((item) => isValidBatch(medicationDispense, item)) .sort((a, b) => new Date(a.expiration).getTime() - new Date(b.expiration).getTime()); function parseDate(dateString) { return new Date(dateString); } //check whether the drug will expire before the medication period ends function isValidBatch(medicationToDispense, inventoryItem) { if (typeof config !== 'undefined' && !config.validateBatch) { return true; } if (medicationToDispense?.dosageInstruction && medicationToDispense?.dosageInstruction.length > 0) { return medicationToDispense.dosageInstruction.some((instruction) => { if ( instruction.timing?.repeat?.duration && instruction.timing?.repeat?.durationUnit && inventoryItem.quantity > 0 ) { const durationUnit = instruction.timing.repeat.durationUnit; const durationValue = instruction.timing.repeat.duration; const lastMedicationDate = new Date(); switch (durationUnit) { case 's': lastMedicationDate.setSeconds(lastMedicationDate.getSeconds() + durationValue); break; case 'min': lastMedicationDate.setMinutes(lastMedicationDate.getMinutes() + durationValue); break; case 'h': lastMedicationDate.setHours(lastMedicationDate.getHours() + durationValue); break; case 'd': lastMedicationDate.setDate(lastMedicationDate.getDate() + durationValue); break; case 'wk': lastMedicationDate.setDate(lastMedicationDate.getDate() + durationValue * 7); break; case 'mo': lastMedicationDate.setMonth(lastMedicationDate.getMonth() + durationValue); break; case 'y': lastMedicationDate.setFullYear(lastMedicationDate.getFullYear() + durationValue); break; default: return false; } const expiryDate = parseDate(inventoryItem.expiration); return expiryDate > lastMedicationDate; } return false; }); } return false; } const toStockDispense = (inventoryItems) => { return t( 'stockDispenseDetails', 'Batch: {{batchNumber}} - Quantity: {{quantity}} ({{quantityUoM}}) - Expiry: {{expiration}}', { batchNumber: inventoryItems.batchNumber, quantity: Math.floor(inventoryItems.quantity), quantityUoM: inventoryItems.quantityUoM, expiration: formatDate(new Date(inventoryItems.expiration)), }, ); }; if (error) { return ( ); } if (isLoading) { return ; } return ( { updateInventoryItem(selectedItem); }} itemToString={(item) => (item ? toStockDispense(item) : '')} titleText={t('stockDispense', 'Stock Dispense')} placeholder={t('selectStockDispense', 'Select stock to dispense from')} /> ); }; export default StockDispense;