diff --git a/static/app.js b/static/app.js index e77b38b..bd1ca0c 100644 --- a/static/app.js +++ b/static/app.js @@ -1207,10 +1207,16 @@ $(document).ready(function() { $('#compoundForm').show(); $('#compoundEntryForm')[0].reset(); $('#compoundIngredients').empty(); + $('#costPreview').hide(); + // 제수 기본값(1)으로 첩수/파우치 초기화 + $('#jeCount').val(1); + $('#cheopTotal').val(20); + $('#pouchTotal').val(30); }); $('#cancelCompoundBtn').on('click', function() { $('#compoundForm').hide(); + $('#costPreview').hide(); }); // 제수 변경 시 첩수 자동 계산 @@ -1230,12 +1236,20 @@ $(document).ready(function() { $('#compoundFormula').on('change', function() { const formulaId = $(this).val(); + // 제수 기반 첩수/파우치 자동 계산 (초기값 반영) + const jeCount = parseFloat($('#jeCount').val()) || 0; + if (jeCount > 0 && !$('#cheopTotal').val()) { + $('#cheopTotal').val(jeCount * 20); + $('#pouchTotal').val(jeCount * 30); + } + // 원래 처방 구성 초기화 originalFormulaIngredients = {}; $('#customPrescriptionBadge').remove(); // 커스텀 뱃지 제거 if (!formulaId) { $('#compoundIngredients').empty(); + $('#costPreview').hide(); return; } @@ -1364,6 +1378,7 @@ $(document).ready(function() { }); // 약재별 총 용량 업데이트 + let _stockCheckTimer = null; function updateIngredientTotals() { const cheopTotal = parseFloat($('#cheopTotal').val()) || 0; @@ -1373,9 +1388,88 @@ $(document).ready(function() { $(this).find('.total-grams').text(totalGrams.toFixed(1)); }); - checkStockForCompound(); // 커스텀 처방 감지 호출 checkCustomPrescription(); + // 원가 미리보기 갱신 (즉시) + updateCostPreview(); + // 재고 상태 갱신 (디바운스 300ms) + clearTimeout(_stockCheckTimer); + _stockCheckTimer = setTimeout(() => checkStockForCompound(), 300); + } + + // 원가 미리보기 계산 + function updateCostPreview() { + const rows = $('#compoundIngredients tr'); + if (rows.length === 0) { + $('#costPreview').hide(); + return; + } + + const items = []; + let totalCost = 0; + let allHavePrice = true; + + rows.each(function() { + // 약재명: 처방에서 로드된 행은 텍스트, 추가된 행은 select의 선택값 + const firstTd = $(this).find('td:first'); + const herbSelect = firstTd.find('.herb-select-compound'); + const herbName = herbSelect.length > 0 + ? (herbSelect.find('option:selected').text().trim() || '미선택') + : firstTd.text().trim().split('(')[0].trim(); + const totalGrams = parseFloat($(this).find('.total-grams').text()) || 0; + const originSelect = $(this).find('.origin-select'); + const selectedOption = originSelect.find('option:selected'); + const unitPrice = parseFloat(selectedOption.attr('data-price')) || 0; + + // 수동 배분인 경우 data-lot-assignments에서 계산 + const lotAssignmentsStr = $(this).attr('data-lot-assignments'); + let itemCost = 0; + + if (lotAssignmentsStr) { + try { + const assignments = JSON.parse(lotAssignmentsStr); + assignments.forEach(a => { + itemCost += (a.quantity || 0) * (a.unit_price || 0); + }); + } catch(e) { + itemCost = totalGrams * unitPrice; + } + } else if (unitPrice > 0) { + itemCost = totalGrams * unitPrice; + } else { + allHavePrice = false; + } + + totalCost += itemCost; + items.push({ name: herbName, grams: totalGrams, unitPrice, cost: itemCost }); + }); + + // UI 렌더링 + const tbody = $('#costPreviewItems'); + tbody.empty(); + items.forEach(item => { + const costText = item.cost > 0 + ? formatCurrency(Math.round(item.cost)) + : '-'; + const priceText = item.unitPrice > 0 + ? `${item.grams.toFixed(1)}g × ₩${item.unitPrice.toFixed(1)}` + : `${item.grams.toFixed(1)}g`; + tbody.append(` +