Files
sam-api/public/tenant/production/process_detail.php
hskwon cc206fdbed style: Laravel Pint 코드 포맷팅 적용
- PSR-12 스타일 가이드 준수
- 302개 파일 스타일 이슈 자동 수정
- 코드 로직 변경 없음 (포맷팅만)
2025-11-06 17:45:49 +09:00

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>