feat(proxy-input): 부적합 대분류/소분류 선택 추가
- 부적합 시간 > 0 → 대분류/소분류 드롭다운 표시 - issue_report_categories (nonconformity) + issue_report_items 연동 - 저장 시 work_report_defects에 category_id, item_id 포함 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -137,8 +137,8 @@ const ProxyInputController = {
|
||||
);
|
||||
if (existingDefects.length === 0) {
|
||||
await conn.query(
|
||||
`INSERT INTO work_report_defects (report_id, defect_hours, note) VALUES (?, ?, '대리입력')`,
|
||||
[reportId, defectHours]
|
||||
`INSERT INTO work_report_defects (report_id, defect_hours, category_id, item_id, note) VALUES (?, ?, ?, ?, '대리입력')`,
|
||||
[reportId, defectHours, entry.defect_category_id || null, entry.defect_item_id || null]
|
||||
);
|
||||
await conn.query(
|
||||
'UPDATE daily_work_reports SET error_hours = ?, work_status_id = 2 WHERE id = ?',
|
||||
|
||||
@@ -9,6 +9,7 @@ let allWorkers = [];
|
||||
let selectedIds = new Set();
|
||||
let projects = [];
|
||||
let workTypes = [];
|
||||
let defectCategories = []; // { category_id, category_name, items: [{ item_id, item_name }] }
|
||||
|
||||
// ===== Init =====
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
@@ -28,6 +29,18 @@ async function loadDropdownData() {
|
||||
]);
|
||||
projects = (pRes.data || pRes || []).filter(p => p.is_active !== 0);
|
||||
workTypes = (wRes.data || wRes || []).map(w => ({ id: w.id || w.work_type_id, name: w.name || w.work_type_name, ...w }));
|
||||
|
||||
// 부적합 대분류/소분류 로드
|
||||
const cRes = await window.apiCall('/work-issues/categories/type/nonconformity');
|
||||
const cats = cRes.data || cRes || [];
|
||||
for (const c of cats) {
|
||||
const iRes = await window.apiCall('/work-issues/items/category/' + c.category_id);
|
||||
defectCategories.push({
|
||||
category_id: c.category_id,
|
||||
category_name: c.category_name,
|
||||
items: (iRes.data || iRes || [])
|
||||
});
|
||||
}
|
||||
} catch (e) { console.warn('드롭다운 로드 실패:', e); }
|
||||
}
|
||||
|
||||
@@ -174,6 +187,13 @@ async function saveAll() {
|
||||
return;
|
||||
}
|
||||
|
||||
const defectCategoryId = defect > 0 ? (parseInt(document.getElementById('bulkDefectCategory').value) || null) : null;
|
||||
const defectItemId = defect > 0 ? (parseInt(document.getElementById('bulkDefectItem').value) || null) : null;
|
||||
if (defect > 0 && !defectCategoryId) {
|
||||
showToast('부적합 대분류를 선택하세요', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
const btn = document.getElementById('saveBtn');
|
||||
btn.disabled = true;
|
||||
document.getElementById('saveBtnText').textContent = '저장 중...';
|
||||
@@ -184,6 +204,8 @@ async function saveAll() {
|
||||
work_type_id: parseInt(wtypeId),
|
||||
work_hours: hours,
|
||||
defect_hours: defect,
|
||||
defect_category_id: defectCategoryId,
|
||||
defect_item_id: defectItemId,
|
||||
note: note,
|
||||
start_time: '08:00',
|
||||
end_time: '17:00',
|
||||
@@ -213,4 +235,28 @@ async function saveAll() {
|
||||
document.getElementById('saveBtnText').textContent = '전체 저장';
|
||||
}
|
||||
|
||||
// ===== Defect Category/Item =====
|
||||
function onDefectChange() {
|
||||
const val = parseFloat(document.getElementById('bulkDefect').value) || 0;
|
||||
const row = document.getElementById('defectCategoryRow');
|
||||
if (val > 0) {
|
||||
row.classList.remove('hidden');
|
||||
const catSel = document.getElementById('bulkDefectCategory');
|
||||
if (catSel.options.length <= 1) {
|
||||
catSel.innerHTML = '<option value="">부적합 대분류 *</option>' +
|
||||
defectCategories.map(c => `<option value="${c.category_id}">${esc(c.category_name)}</option>`).join('');
|
||||
}
|
||||
} else {
|
||||
row.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
function onDefectCategoryChange() {
|
||||
const catId = parseInt(document.getElementById('bulkDefectCategory').value);
|
||||
const itemSel = document.getElementById('bulkDefectItem');
|
||||
const cat = defectCategories.find(c => c.category_id === catId);
|
||||
itemSel.innerHTML = '<option value="">소분류 *</option>' +
|
||||
(cat ? cat.items.map(i => `<option value="${i.item_id}">${esc(i.item_name)}</option>`).join('') : '');
|
||||
}
|
||||
|
||||
function esc(s) { return (s || '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); }
|
||||
|
||||
@@ -80,7 +80,17 @@
|
||||
</div>
|
||||
<div class="pi-edit-row">
|
||||
<label class="pi-field"><span>시간</span><input type="number" id="bulkHours" value="8" step="0.5" min="0" max="24" class="pi-input"></label>
|
||||
<label class="pi-field"><span>부적합</span><input type="number" id="bulkDefect" value="0" step="0.5" min="0" max="24" class="pi-input"></label>
|
||||
<label class="pi-field"><span>부적합 시간</span><input type="number" id="bulkDefect" value="0" step="0.5" min="0" max="24" class="pi-input" onchange="onDefectChange()"></label>
|
||||
</div>
|
||||
<div id="defectCategoryRow" class="hidden">
|
||||
<div class="pi-edit-row">
|
||||
<select id="bulkDefectCategory" class="pi-select" onchange="onDefectCategoryChange()">
|
||||
<option value="">부적합 대분류 *</option>
|
||||
</select>
|
||||
<select id="bulkDefectItem" class="pi-select">
|
||||
<option value="">소분류 *</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" id="bulkNote" placeholder="비고 (선택)" class="pi-note-input">
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user