feat: 조제 화면에 2단계 선택 시스템 구현
- 1단계: 제품 선택 (같은 주성분의 여러 제품 중 선택) - 2단계: 원산지/로트 선택 (선택한 제품의 원산지별 로트 중 선택) - formula_ingredients API 응답 구조 변경에 따른 프론트엔드 수정 - available_products 배열 기반 렌더링 - 제품 선택 드롭다운과 원산지 선택 드롭다운 분리 - 제품 변경 시 원산지/로트 옵션 동적 로드 예시: - 인삼 → 신흥인삼 선택 → [한국산|중국산] 선택 가능 - 인삼 → 세화인삼 선택 → [한국산|미국산] 선택 가능
This commit is contained in:
parent
9fa1f7a031
commit
55974423ea
@ -595,20 +595,39 @@ $(document).ready(function() {
|
|||||||
const cheopTotal = parseFloat($('#cheopTotal').val()) || 0;
|
const cheopTotal = parseFloat($('#cheopTotal').val()) || 0;
|
||||||
const totalGrams = ing.grams_per_cheop * cheopTotal;
|
const totalGrams = ing.grams_per_cheop * cheopTotal;
|
||||||
|
|
||||||
|
// 제품 선택 옵션 생성
|
||||||
|
let productOptions = '<option value="">제품 선택</option>';
|
||||||
|
if (ing.available_products && ing.available_products.length > 0) {
|
||||||
|
ing.available_products.forEach(product => {
|
||||||
|
const specInfo = product.specification ? ` [${product.specification}]` : '';
|
||||||
|
productOptions += `<option value="${product.herb_item_id}">${product.herb_name}${specInfo} (재고: ${product.stock.toFixed(0)}g)</option>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
$('#compoundIngredients').append(`
|
$('#compoundIngredients').append(`
|
||||||
<tr data-herb-id="${ing.herb_item_id}">
|
<tr data-ingredient-code="${ing.ingredient_code}" data-herb-id="">
|
||||||
<td>${ing.herb_name}</td>
|
<td>
|
||||||
|
${ing.herb_name}
|
||||||
|
${ing.total_available_stock > 0
|
||||||
|
? `<small class="text-success">(총 ${ing.total_available_stock.toFixed(0)}g 사용 가능)</small>`
|
||||||
|
: '<small class="text-danger">(재고 없음)</small>'}
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" class="form-control form-control-sm grams-per-cheop"
|
<input type="number" class="form-control form-control-sm grams-per-cheop"
|
||||||
value="${ing.grams_per_cheop}" min="0.1" step="0.1">
|
value="${ing.grams_per_cheop}" min="0.1" step="0.1">
|
||||||
</td>
|
</td>
|
||||||
<td class="total-grams">${totalGrams.toFixed(1)}</td>
|
<td class="total-grams">${totalGrams.toFixed(1)}</td>
|
||||||
<td class="origin-select-cell">
|
<td class="product-select-cell">
|
||||||
<select class="form-control form-control-sm origin-select" disabled>
|
<select class="form-control form-control-sm product-select" ${ing.available_products.length === 0 ? 'disabled' : ''}>
|
||||||
<option value="">로딩중...</option>
|
${productOptions}
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td class="stock-status">확인중...</td>
|
<td class="origin-select-cell">
|
||||||
|
<select class="form-control form-control-sm origin-select" disabled>
|
||||||
|
<option value="">제품 먼저 선택</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
<td class="stock-status">대기중</td>
|
||||||
<td>
|
<td>
|
||||||
<button type="button" class="btn btn-sm btn-outline-danger remove-compound-ingredient">
|
<button type="button" class="btn btn-sm btn-outline-danger remove-compound-ingredient">
|
||||||
<i class="bi bi-x"></i>
|
<i class="bi bi-x"></i>
|
||||||
@ -617,15 +636,54 @@ $(document).ready(function() {
|
|||||||
</tr>
|
</tr>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// 각 약재별로 원산지별 재고 확인
|
// 첫 번째 제품 자동 선택 및 원산지 로드
|
||||||
loadOriginOptions(ing.herb_item_id, totalGrams);
|
const tr = $(`tr[data-ingredient-code="${ing.ingredient_code}"]`);
|
||||||
|
if (ing.available_products && ing.available_products.length > 0) {
|
||||||
|
const firstProduct = ing.available_products[0];
|
||||||
|
tr.find('.product-select').val(firstProduct.herb_item_id);
|
||||||
|
tr.attr('data-herb-id', firstProduct.herb_item_id);
|
||||||
|
// 원산지/로트 옵션 로드
|
||||||
|
loadOriginOptions(firstProduct.herb_item_id, totalGrams);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 재고 확인
|
// 재고 확인
|
||||||
checkStockForCompound();
|
checkStockForCompound();
|
||||||
|
|
||||||
|
// 제품 선택 변경 이벤트
|
||||||
|
$('.product-select').on('change', function() {
|
||||||
|
const herbId = $(this).val();
|
||||||
|
const row = $(this).closest('tr');
|
||||||
|
|
||||||
|
if (herbId) {
|
||||||
|
row.attr('data-herb-id', herbId);
|
||||||
|
const cheopTotal = parseFloat($('#cheopTotal').val()) || 0;
|
||||||
|
const gramsPerCheop = parseFloat(row.find('.grams-per-cheop').val()) || 0;
|
||||||
|
const totalGrams = gramsPerCheop * cheopTotal;
|
||||||
|
|
||||||
|
// 원산지/로트 옵션 로드
|
||||||
|
loadOriginOptions(herbId, totalGrams);
|
||||||
|
} else {
|
||||||
|
row.attr('data-herb-id', '');
|
||||||
|
row.find('.origin-select').empty().append('<option value="">제품 먼저 선택</option>').prop('disabled', true);
|
||||||
|
row.find('.stock-status').text('대기중');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 용량 변경 이벤트
|
// 용량 변경 이벤트
|
||||||
$('.grams-per-cheop').on('input', updateIngredientTotals);
|
$('.grams-per-cheop').on('input', function() {
|
||||||
|
updateIngredientTotals();
|
||||||
|
|
||||||
|
// 원산지 옵션 다시 로드
|
||||||
|
const row = $(this).closest('tr');
|
||||||
|
const herbId = row.attr('data-herb-id');
|
||||||
|
if (herbId) {
|
||||||
|
const cheopTotal = parseFloat($('#cheopTotal').val()) || 0;
|
||||||
|
const gramsPerCheop = parseFloat($(this).val()) || 0;
|
||||||
|
const totalGrams = gramsPerCheop * cheopTotal;
|
||||||
|
loadOriginOptions(herbId, totalGrams);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 삭제 버튼 이벤트
|
// 삭제 버튼 이벤트
|
||||||
$('.remove-compound-ingredient').on('click', function() {
|
$('.remove-compound-ingredient').on('click', function() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user