diff --git a/frontend/app.js b/frontend/app.js index 2c1b830..2ac8bf3 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -251,6 +251,7 @@ function setupEventListeners() { const cancelReceiveDeliveryBtn = document.getElementById('cancelReceiveDeliveryBtn'); const addDeliveryLineBtn = document.getElementById('addDeliveryLineBtn'); const addVariantFromDeliveryBtn = document.getElementById('addVariantFromDeliveryBtn'); + const addPackSizeFromDeliveryBtn = document.getElementById('addPackSizeFromDeliveryBtn'); const addVariantPackRowBtn = document.getElementById('addVariantPackRowBtn'); const addEditVariantPackRowBtn = document.getElementById('addEditVariantPackRowBtn'); const variantUnitSelect = document.getElementById('variantUnit'); @@ -289,6 +290,23 @@ function setupEventListeners() { if (cancelReceiveDeliveryBtn) cancelReceiveDeliveryBtn.addEventListener('click', () => closeModal(receiveDeliveryModal)); if (addDeliveryLineBtn) addDeliveryLineBtn.addEventListener('click', () => appendDeliveryLine()); if (addVariantFromDeliveryBtn) addVariantFromDeliveryBtn.addEventListener('click', handleAddVariantFromDelivery); + if (addPackSizeFromDeliveryBtn) addPackSizeFromDeliveryBtn.addEventListener('click', openAddPackSizeFromDeliveryModal); + + const addPackSizeForm = document.getElementById('addPackSizeForm'); + const cancelAddPackSizeBtn = document.getElementById('cancelAddPackSizeBtn'); + const addPackSizeModal = document.getElementById('addPackSizeModal'); + if (addPackSizeForm) addPackSizeForm.addEventListener('submit', handleAddPackSize); + if (cancelAddPackSizeBtn) cancelAddPackSizeBtn.addEventListener('click', () => closeModal(addPackSizeModal)); + + const addPackSizeVariantSelect = document.getElementById('addPackSizeVariantSelect'); + if (addPackSizeVariantSelect) { + addPackSizeVariantSelect.addEventListener('change', () => { + const variantId = parseInt(addPackSizeVariantSelect.value || '', 10); + const variant = getVariantById(variantId); + const hint = document.getElementById('addPackSizeHint'); + if (hint) hint.textContent = variant ? `Base unit: ${variant.unit}` : ''; + }); + } if (addVariantPackRowBtn) addVariantPackRowBtn.addEventListener('click', () => appendVariantPackRow()); if (addEditVariantPackRowBtn) addEditVariantPackRowBtn.addEventListener('click', () => appendEditVariantPackRow()); if (variantUnitSelect) { @@ -3166,6 +3184,103 @@ function handleAddVariantFromDelivery() { openAddVariantModal(deliveryDrugId); } +function openAddPackSizeFromDeliveryModal() { + if (!deliveryDrugId) { + showToast('Select a drug first', 'warning'); + return; + } + const drug = getActiveDeliveryDrug(); + if (!drug) { + showToast('Drug not found', 'error'); + return; + } + + const form = document.getElementById('addPackSizeForm'); + if (form) form.reset(); + + const label = document.getElementById('addPackSizeDrugLabel'); + if (label) label.textContent = `Drug: ${drug.name}`; + + // Try to pre-select variant from first delivery line that has one chosen + const deliveryContainer = document.getElementById('deliveryLinesContainer'); + const selectedDeliveryVariantId = deliveryContainer + ? (Array.from(deliveryContainer.querySelectorAll('.delivery-variant-select')) + .map(s => s.value) + .find(v => v)) || '' + : ''; + + const variantSelect = document.getElementById('addPackSizeVariantSelect'); + if (variantSelect) { + variantSelect.innerHTML = [ + '', + ...drug.variants.map(v => + `` + ) + ].join(''); + if (selectedDeliveryVariantId) { + variantSelect.value = selectedDeliveryVariantId; + } else if (drug.variants.length === 1) { + variantSelect.value = String(drug.variants[0].id); + } + } + + // Update the hint for the pre-selected variant + const selectedId = parseInt(variantSelect?.value || '', 10); + const selectedVariant = getVariantById(selectedId); + const hint = document.getElementById('addPackSizeHint'); + if (hint) hint.textContent = selectedVariant ? `Base unit: ${selectedVariant.unit}` : ''; + + // Reset pack type default to box + const packTypeSelect = document.getElementById('addPackSizeType'); + if (packTypeSelect) packTypeSelect.value = 'box'; + + openModal(document.getElementById('addPackSizeModal')); +} + +async function handleAddPackSize(e) { + e.preventDefault(); + + const variantId = parseInt(document.getElementById('addPackSizeVariantSelect')?.value || '', 10); + const packType = (document.getElementById('addPackSizeType')?.value || 'box').trim(); + const packSize = parseFloat(document.getElementById('addPackSizeCount')?.value || ''); + const packLabel = `${packType.charAt(0).toUpperCase() + packType.slice(1)} of ${packSize}`; + + if (!variantId) { + showToast('Please select a variant', 'warning'); + return; + } + if (!packSize || packSize <= 0) { + showToast('Please enter a valid pack size greater than zero', 'warning'); + return; + } + + try { + const response = await apiCall(`/variants/${variantId}/packs`, { + method: 'POST', + body: JSON.stringify({ + label: packLabel, + pack_unit_name: packType, + pack_size_in_base_units: packSize, + is_active: true + }) + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.detail || 'Failed to add pack size'); + } + + closeModal(document.getElementById('addPackSizeModal')); + await loadDrugs(); + // Refresh delivery line pack selects so the new pack is immediately available + refreshDeliveryVariantSelects(); + showToast('Pack size added successfully!', 'success'); + } catch (error) { + console.error('Error adding pack size:', error); + showToast('Failed to add pack size: ' + error.message, 'error'); + } +} + async function handleReceiveDelivery(e) { e.preventDefault(); diff --git a/frontend/index.html b/frontend/index.html index 9ae6ce3..2255b78 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -576,6 +576,41 @@ + + +