// 한약 재고관리 시스템 - Frontend JavaScript $(document).ready(function() { // 페이지 네비게이션 $('.sidebar .nav-link').on('click', function(e) { e.preventDefault(); const page = $(this).data('page'); // Active 상태 변경 $('.sidebar .nav-link').removeClass('active'); $(this).addClass('active'); // 페이지 전환 $('.main-content').removeClass('active'); $(`#${page}`).addClass('active'); // 페이지별 데이터 로드 loadPageData(page); }); // 초기 데이터 로드 loadPageData('dashboard'); // 페이지별 데이터 로드 함수 function loadPageData(page) { switch(page) { case 'dashboard': loadDashboard(); break; case 'patients': loadPatients(); break; case 'formulas': loadFormulas(); break; case 'compound': loadCompounds(); loadPatientsForSelect(); loadFormulasForSelect(); break; case 'inventory': loadInventory(); break; case 'herbs': loadHerbs(); break; } } // 대시보드 데이터 로드 function loadDashboard() { // 환자 수 $.get('/api/patients', function(response) { if (response.success) { $('#totalPatients').text(response.data.length); } }); // 재고 현황 $.get('/api/inventory/summary', function(response) { if (response.success) { $('#totalHerbs').text(response.data.length); $('#inventoryValue').text(formatCurrency(response.summary.total_value)); } }); // TODO: 오늘 조제 수, 최근 조제 내역 } // 환자 목록 로드 function loadPatients() { $.get('/api/patients', function(response) { if (response.success) { const tbody = $('#patientsList'); tbody.empty(); response.data.forEach(patient => { tbody.append(` ${patient.name} ${patient.phone} ${patient.gender === 'M' ? '남' : patient.gender === 'F' ? '여' : '-'} ${patient.birth_date || '-'} ${patient.notes || '-'} `); }); } }); } // 환자 등록 $('#savePatientBtn').on('click', function() { const patientData = { name: $('#patientName').val(), phone: $('#patientPhone').val(), jumin_no: $('#patientJumin').val(), gender: $('#patientGender').val(), birth_date: $('#patientBirth').val(), address: $('#patientAddress').val(), notes: $('#patientNotes').val() }; $.ajax({ url: '/api/patients', method: 'POST', contentType: 'application/json', data: JSON.stringify(patientData), success: function(response) { if (response.success) { alert('환자가 등록되었습니다.'); $('#patientModal').modal('hide'); $('#patientForm')[0].reset(); loadPatients(); } }, error: function(xhr) { alert('오류: ' + xhr.responseJSON.error); } }); }); // 처방 목록 로드 function loadFormulas() { $.get('/api/formulas', function(response) { if (response.success) { const tbody = $('#formulasList'); tbody.empty(); response.data.forEach(formula => { tbody.append(` ${formula.formula_code || '-'} ${formula.formula_name} ${formula.base_cheop}첩 ${formula.base_pouches}파우치 `); }); // 구성 약재 보기 $('.view-ingredients').on('click', function() { const formulaId = $(this).data('id'); $.get(`/api/formulas/${formulaId}/ingredients`, function(response) { if (response.success) { let ingredientsList = response.data.map(ing => `${ing.herb_name}: ${ing.grams_per_cheop}g` ).join(', '); alert('구성 약재:\n' + ingredientsList); } }); }); } }); } // 처방 구성 약재 추가 (모달) let formulaIngredientCount = 0; $('#addFormulaIngredientBtn').on('click', function() { formulaIngredientCount++; $('#formulaIngredients').append(` `); // 약재 목록 로드 const selectElement = $(`#formulaIngredients tr[data-row="${formulaIngredientCount}"] .herb-select`); loadHerbsForSelect(selectElement); // 삭제 버튼 이벤트 $(`#formulaIngredients tr[data-row="${formulaIngredientCount}"] .remove-ingredient`).on('click', function() { $(this).closest('tr').remove(); }); }); // 처방 저장 $('#saveFormulaBtn').on('click', function() { const ingredients = []; $('#formulaIngredients tr').each(function() { const herbId = $(this).find('.herb-select').val(); const grams = $(this).find('.grams-input').val(); if (herbId && grams) { ingredients.push({ herb_item_id: parseInt(herbId), grams_per_cheop: parseFloat(grams), notes: $(this).find('.notes-input').val() }); } }); const formulaData = { formula_code: $('#formulaCode').val(), formula_name: $('#formulaName').val(), formula_type: $('#formulaType').val(), base_cheop: parseInt($('#baseCheop').val()), base_pouches: parseInt($('#basePouches').val()), description: $('#formulaDescription').val(), ingredients: ingredients }; $.ajax({ url: '/api/formulas', method: 'POST', contentType: 'application/json', data: JSON.stringify(formulaData), success: function(response) { if (response.success) { alert('처방이 등록되었습니다.'); $('#formulaModal').modal('hide'); $('#formulaForm')[0].reset(); $('#formulaIngredients').empty(); loadFormulas(); } }, error: function(xhr) { alert('오류: ' + xhr.responseJSON.error); } }); }); // 조제 관리 $('#newCompoundBtn').on('click', function() { $('#compoundForm').show(); $('#compoundEntryForm')[0].reset(); $('#compoundIngredients').empty(); }); $('#cancelCompoundBtn').on('click', function() { $('#compoundForm').hide(); }); // 제수 변경 시 첩수 자동 계산 $('#jeCount').on('input', function() { const jeCount = parseFloat($(this).val()) || 0; const cheopTotal = jeCount * 20; const pouchTotal = jeCount * 30; $('#cheopTotal').val(cheopTotal); $('#pouchTotal').val(pouchTotal); // 약재별 총 용량 재계산 updateIngredientTotals(); }); // 처방 선택 시 구성 약재 로드 $('#compoundFormula').on('change', function() { const formulaId = $(this).val(); if (!formulaId) { $('#compoundIngredients').empty(); return; } $.get(`/api/formulas/${formulaId}/ingredients`, function(response) { if (response.success) { $('#compoundIngredients').empty(); response.data.forEach(ing => { const cheopTotal = parseFloat($('#cheopTotal').val()) || 0; const totalGrams = ing.grams_per_cheop * cheopTotal; $('#compoundIngredients').append(` ${ing.herb_name} ${totalGrams.toFixed(1)} 확인중... `); }); // 재고 확인 checkStockForCompound(); // 용량 변경 이벤트 $('.grams-per-cheop').on('input', updateIngredientTotals); // 삭제 버튼 이벤트 $('.remove-compound-ingredient').on('click', function() { $(this).closest('tr').remove(); }); } }); }); // 약재별 총 용량 업데이트 function updateIngredientTotals() { const cheopTotal = parseFloat($('#cheopTotal').val()) || 0; $('#compoundIngredients tr').each(function() { const gramsPerCheop = parseFloat($(this).find('.grams-per-cheop').val()) || 0; const totalGrams = gramsPerCheop * cheopTotal; $(this).find('.total-grams').text(totalGrams.toFixed(1)); }); checkStockForCompound(); } // 재고 확인 function checkStockForCompound() { $('#compoundIngredients tr').each(function() { const herbId = $(this).data('herb-id'); const totalGrams = parseFloat($(this).find('.total-grams').text()) || 0; const $stockStatus = $(this).find('.stock-status'); // TODO: API 호출로 실제 재고 확인 $stockStatus.text('재고 확인 필요'); }); } // 조제 약재 추가 $('#addIngredientBtn').on('click', function() { const newRow = $(` 0.0 - `); $('#compoundIngredients').append(newRow); // 약재 목록 로드 loadHerbsForSelect(newRow.find('.herb-select-compound')); // 이벤트 바인딩 newRow.find('.grams-per-cheop').on('input', updateIngredientTotals); newRow.find('.remove-compound-ingredient').on('click', function() { $(this).closest('tr').remove(); }); newRow.find('.herb-select-compound').on('change', function() { const herbId = $(this).val(); $(this).closest('tr').attr('data-herb-id', herbId); updateIngredientTotals(); }); }); // 조제 실행 $('#compoundEntryForm').on('submit', function(e) { e.preventDefault(); const ingredients = []; $('#compoundIngredients tr').each(function() { const herbId = $(this).data('herb-id'); const gramsPerCheop = parseFloat($(this).find('.grams-per-cheop').val()); const totalGrams = parseFloat($(this).find('.total-grams').text()); if (herbId && gramsPerCheop) { ingredients.push({ herb_item_id: parseInt(herbId), grams_per_cheop: gramsPerCheop, total_grams: totalGrams }); } }); const compoundData = { patient_id: $('#compoundPatient').val() ? parseInt($('#compoundPatient').val()) : null, formula_id: $('#compoundFormula').val() ? parseInt($('#compoundFormula').val()) : null, je_count: parseFloat($('#jeCount').val()), cheop_total: parseFloat($('#cheopTotal').val()), pouch_total: parseFloat($('#pouchTotal').val()), ingredients: ingredients }; $.ajax({ url: '/api/compounds', method: 'POST', contentType: 'application/json', data: JSON.stringify(compoundData), success: function(response) { if (response.success) { alert(`조제가 완료되었습니다.\n원가: ${formatCurrency(response.total_cost)}`); $('#compoundForm').hide(); loadCompounds(); } }, error: function(xhr) { alert('오류: ' + xhr.responseJSON.error); } }); }); // 조제 내역 로드 function loadCompounds() { // TODO: 조제 내역 API 구현 필요 $('#compoundsList').html('조제 내역이 없습니다.'); } // 재고 현황 로드 function loadInventory() { $.get('/api/inventory/summary', function(response) { if (response.success) { const tbody = $('#inventoryList'); tbody.empty(); response.data.forEach(item => { tbody.append(` ${item.insurance_code || '-'} ${item.herb_name} ${item.total_quantity.toFixed(1)} ${item.lot_count} ${item.avg_price ? formatCurrency(item.avg_price) : '-'} ${formatCurrency(item.total_value)} `); }); } }); } // 약재 목록 로드 function loadHerbs() { $.get('/api/herbs', function(response) { if (response.success) { const tbody = $('#herbsList'); tbody.empty(); response.data.forEach(herb => { tbody.append(` ${herb.insurance_code || '-'} ${herb.herb_name} ${herb.specification || '-'} ${herb.current_stock ? herb.current_stock.toFixed(1) + 'g' : '0g'} `); }); } }); } // 입고장 업로드 $('#purchaseUploadForm').on('submit', function(e) { e.preventDefault(); const formData = new FormData(); const fileInput = $('#purchaseFile')[0]; if (fileInput.files.length === 0) { alert('파일을 선택해주세요.'); return; } formData.append('file', fileInput.files[0]); $('#uploadResult').html('
업로드 중...
'); $.ajax({ url: '/api/upload/purchase', method: 'POST', data: formData, processData: false, contentType: false, success: function(response) { if (response.success) { $('#uploadResult').html( `
${response.message}
` ); $('#purchaseUploadForm')[0].reset(); } }, error: function(xhr) { $('#uploadResult').html( `
오류: ${xhr.responseJSON.error}
` ); } }); }); // 검색 기능 $('#patientSearch').on('keyup', function() { const value = $(this).val().toLowerCase(); $('#patientsList tr').filter(function() { $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1); }); }); $('#inventorySearch').on('keyup', function() { const value = $(this).val().toLowerCase(); $('#inventoryList tr').filter(function() { $(this).toggle($(this).text().toLowerCase().indexOf(value) > -1); }); }); // 헬퍼 함수들 function loadPatientsForSelect() { $.get('/api/patients', function(response) { if (response.success) { const select = $('#compoundPatient'); select.empty().append(''); response.data.forEach(patient => { select.append(``); }); } }); } function loadFormulasForSelect() { $.get('/api/formulas', function(response) { if (response.success) { const select = $('#compoundFormula'); select.empty().append(''); response.data.forEach(formula => { select.append(``); }); } }); } function loadHerbsForSelect(selectElement) { $.get('/api/herbs', function(response) { if (response.success) { selectElement.empty().append(''); response.data.forEach(herb => { selectElement.append(``); }); } }); } function formatCurrency(amount) { if (amount === null || amount === undefined) return '0원'; return new Intl.NumberFormat('ko-KR', { style: 'currency', currency: 'KRW' }).format(amount); } });