202 lines
9.5 KiB
PHP
202 lines
9.5 KiB
PHP
<!-- SAM RULES: include=../inc/header.php; base=/tenant; width=1280; js=jQuery+BS5 -->
|
|
<?php
|
|
// 모달 내부 Ajax 본문 조각 (header/footer 없음)
|
|
$jobId = $_POST['job_id'] ?? ($_GET['job_id'] ?? '');
|
|
$cust = $_POST['cust'] ?? ($_GET['cust'] ?? '');
|
|
$orderNo = $_POST['order_no'] ?? ($_GET['order_no'] ?? '');
|
|
?>
|
|
<div class="p-3">
|
|
|
|
<!-- 0) 작업 기본정보 (텍스트 표기) -->
|
|
<div class="border rounded mb-3">
|
|
<div class="p-2 border-bottom bg-light fw-semibold">작업 기본정보</div>
|
|
<div class="p-3">
|
|
<div class="row g-2 small">
|
|
<div class="col-md-3"><span class="text-muted">작업코드</span> : <strong><?= htmlspecialchars($jobId) ?></strong></div>
|
|
<div class="col-md-3"><span class="text-muted">수주번호</span> : <strong><?= htmlspecialchars($orderNo) ?></strong></div>
|
|
<div class="col-md-3"><span class="text-muted">고객명</span> : <strong><?= htmlspecialchars($cust) ?></strong></div>
|
|
<div class="col-md-3"><span class="text-muted">현장명</span> : <strong>자동입력</strong></div>
|
|
<div class="col-md-3"><span class="text-muted">수주계약일</span> : <strong>자동입력</strong></div>
|
|
<div class="col-md-3"><span class="text-muted">제품명</span> : <strong>자동입력</strong></div>
|
|
<div class="col-md-3"><span class="text-muted">출고요청일</span> : <strong>자동입력</strong></div>
|
|
<div class="col-md-3"><span class="text-muted">비고</span> : <strong>-</strong></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 1) 작업 상세 -->
|
|
<div class="border rounded">
|
|
<!-- 상단 바: 전체 일괄 체크 -->
|
|
<div class="d-flex align-items-center justify-content-between p-2 border-bottom bg-light">
|
|
<div class="fw-semibold">작업 상세정보</div>
|
|
<button type="button" class="btn btn-sm btn-outline-dark" id="btnCheckAll">전체 일괄 체크</button>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-sm align-middle m-0" id="procTable">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th style="width:70px;">일련</th>
|
|
<th style="width:140px;">원자재 로트</th>
|
|
<th style="width:60px;">층</th>
|
|
<th style="width:90px;">부호</th>
|
|
<th style="width:120px;">자재명</th>
|
|
<th style="width:90px;">가로</th>
|
|
<th style="width:90px;">세로</th>
|
|
<th style="width:160px;">제단사항</th>
|
|
|
|
<!-- 각 공정 버튼을 해당 칼럼 라인에 정렬 -->
|
|
<th style="width:110px; text-align:center;">
|
|
<div class="mb-1">절단</div>
|
|
<button type="button" class="btn btn-xs btn-outline-primary w-100" id="btnAllCut">전체</button>
|
|
</th>
|
|
<th style="width:110px; text-align:center;">
|
|
<div class="mb-1">미싱</div>
|
|
<button type="button" class="btn btn-xs btn-outline-primary w-100" id="btnAllSew">전체</button>
|
|
</th>
|
|
<th style="width:130px; text-align:center;">
|
|
<div class="mb-1">중간검사</div>
|
|
<button type="button" class="btn btn-xs btn-outline-primary w-100" id="btnOpenMid">열기</button>
|
|
</th>
|
|
<th style="width:110px; text-align:center;">
|
|
<div class="mb-1">포장</div>
|
|
<button type="button" class="btn btn-xs btn-outline-primary w-100" id="btnAllPack">전체</button>
|
|
</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="procBody"><!-- JS 렌더 --></tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 하단 버튼 -->
|
|
<div class="d-flex justify-content-end gap-2 mt-3">
|
|
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">닫기</button>
|
|
<button type="button" class="btn btn-primary" id="btnSaveProcess">저장</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 중간검사서 모달(본문은 별도 파일로 로드) -->
|
|
<div class="modal fade" id="midInspectModal" tabindex="-1" aria-hidden="true">
|
|
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
<div class="modal-body p-0" id="midBody"><!-- /tenant/production/mid_inspection.php 로드 --></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
#procTable th, #procTable td { vertical-align: middle; }
|
|
.cell-center { text-align:center; }
|
|
.chip-pass { background:#d1e7dd; color:#0f5132; border-radius:12px; padding:.1rem .5rem; font-size:.8rem; }
|
|
.chip-fail { background:#ffdede; color:#a10000; border-radius:12px; padding:.1rem .5rem; font-size:.8rem; }
|
|
.btn-xs { --bs-btn-padding-y:.15rem; --bs-btn-padding-x:.35rem; --bs-btn-font-size:.75rem; }
|
|
</style>
|
|
|
|
<script>
|
|
(function($){
|
|
// ---- 샘플 데이터 ----
|
|
const rows = [
|
|
{ id:1, rawlot:'250729-01', floor:1, unit:'FSS-01', item:'실리카', w:6960, h:3050, cutnote:'1220*2장 800*1장',
|
|
cut:false, sew:false, mid:null, pack:false },
|
|
{ id:2, rawlot:'250729-01', floor:1, unit:'FSS-02', item:'실리카', w:5160, h:3050, cutnote:'1220*2장 800*1장',
|
|
cut:false, sew:false, mid:null, pack:false },
|
|
{ id:3, rawlot:'', floor:'', unit:'', item:'', w:'', h:'', cutnote:'',
|
|
cut:false, sew:false, mid:null, pack:false },
|
|
{ id:4, rawlot:'', floor:'', unit:'', item:'', w:'', h:'', cutnote:'',
|
|
cut:false, sew:false, mid:null, pack:false },
|
|
];
|
|
|
|
function midBadge(v){
|
|
if(v==null || v==='') return '';
|
|
return (v==='합격')
|
|
? '<span class="chip-pass">합격</span>'
|
|
: '<span class="chip-fail">불합격</span>';
|
|
}
|
|
|
|
function renderMain(){
|
|
const html = rows.map((r,i)=>`
|
|
<tr data-idx="${i}">
|
|
<td>${r.id||''}</td>
|
|
<td>${r.rawlot||''}</td>
|
|
<td>${r.floor||''}</td>
|
|
<td>${r.unit||''}</td>
|
|
<td>${r.item||''}</td>
|
|
<td>${r.w||''}</td>
|
|
<td>${r.h||''}</td>
|
|
<td>${r.cutnote||''}</td>
|
|
|
|
<td class="cell-center">
|
|
<input class="form-check-input form-check-input-sm chk-cut" type="checkbox" ${r.cut?'checked':''}>
|
|
</td>
|
|
<td class="cell-center">
|
|
<input class="form-check-input form-check-input-sm chk-sew" type="checkbox" ${r.sew?'checked':''}>
|
|
</td>
|
|
<td class="cell-center">
|
|
<div class="mid-badge">${midBadge(r.mid)}</div>
|
|
</td>
|
|
<td class="cell-center">
|
|
<input class="form-check-input form-check-input-sm chk-pack" type="checkbox" ${r.pack?'checked':''}>
|
|
</td>
|
|
</tr>
|
|
`).join('');
|
|
$('#procBody').html(html);
|
|
}
|
|
|
|
// ---- 전체 일괄 체크/해제 ----
|
|
function toggleAllProcesses(){
|
|
const anyOff = rows.some(r=>!(r.cut && r.sew && r.pack));
|
|
rows.forEach(r=>{ r.cut=anyOff; r.sew=anyOff; r.pack=anyOff; });
|
|
renderMain();
|
|
}
|
|
$('#btnCheckAll').on('click', toggleAllProcesses);
|
|
|
|
// ---- 공정별 일괄 토글 ----
|
|
function toggleColumn(key){
|
|
const anyOff = rows.some(r=>!r[key]);
|
|
rows.forEach(r=>{ r[key]=anyOff; });
|
|
renderMain();
|
|
}
|
|
$('#btnAllCut').on('click', ()=>toggleColumn('cut'));
|
|
$('#btnAllSew').on('click', ()=>toggleColumn('sew'));
|
|
$('#btnAllPack').on('click', ()=>toggleColumn('pack'));
|
|
|
|
// 개별 체크
|
|
$(document).on('change', '.chk-cut', function(){ rows[$(this).closest('tr').data('idx')].cut = this.checked; });
|
|
$(document).on('change', '.chk-sew', function(){ rows[$(this).closest('tr').data('idx')].sew = this.checked; });
|
|
$(document).on('change', '.chk-pack', function(){ rows[$(this).closest('tr').data('idx')].pack = this.checked; });
|
|
|
|
// ---- 중간검사서 열기: 별도 페이지 로드 ----
|
|
$('#btnOpenMid').on('click', function(){
|
|
$('#midBody').html('<div class="p-4 text-center text-muted">로딩 중…</div>');
|
|
$('#midBody').load('/tenant/production/mid_inspection.php', {
|
|
sheet_title: '스크린-중간 검사성적서',
|
|
rows: JSON.stringify(rows)
|
|
}, function(){
|
|
new bootstrap.Modal('#midInspectModal').show();
|
|
});
|
|
});
|
|
|
|
// ---- 중간검사서 → 결과 적용 (커스텀 이벤트 수신) ----
|
|
document.addEventListener('mid:apply', function(e){
|
|
const results = e.detail || [];
|
|
// results: [{idx:0, result:'합격'|'불합격'}, ...]
|
|
results.forEach(r=>{
|
|
if(rows[r.idx]) rows[r.idx].mid = r.result || null;
|
|
});
|
|
renderMain();
|
|
const m = bootstrap.Modal.getInstance(document.getElementById('midInspectModal'));
|
|
m && m.hide();
|
|
});
|
|
|
|
// 저장(모의)
|
|
$('#btnSaveProcess').on('click', function(){
|
|
const payload = { job_id: <?= json_encode($jobId) ?>, order_no: <?= json_encode($orderNo) ?>, rows };
|
|
console.log('[PROCESS SAVE]', payload);
|
|
alert('저장(모의). 콘솔을 확인하세요.');
|
|
});
|
|
|
|
renderMain();
|
|
})(jQuery);
|
|
</script>
|