실사 저장값이 페이지 이동 후 원복되지 않도록 저장/조회 경로를 보강하고, 코드 범위 보정과 bis 간 동기화를 추가했다. 또한 메뉴 관리를 레벨4 이상으로 제한하고 메뉴 변경 사항을 모든 지자체에 일괄 반영하도록 동기화 로직을 도입했다. Made-with: Cursor
274 lines
12 KiB
PHP
274 lines
12 KiB
PHP
<?php
|
|
$startDate = (string) ($startDate ?? date('Y-m-01'));
|
|
$endDate = (string) ($endDate ?? date('Y-m-d'));
|
|
$workDate = (string) ($workDate ?? date('Y-m-d'));
|
|
$itemCode = (string) ($itemCode ?? '');
|
|
$viewType = (string) ($viewType ?? 'box');
|
|
$inspectionRuns = is_array($inspectionRuns ?? null) ? $inspectionRuns : [];
|
|
$items = is_array($items ?? null) ? $items : [];
|
|
$popupItems = is_array($popupItems ?? null) ? $popupItems : [];
|
|
$overviewRows = is_array($overviewRows ?? null) ? $overviewRows : [];
|
|
$boxRows = is_array($boxRows ?? null) ? $boxRows : [];
|
|
$sheetRows = is_array($sheetRows ?? null) ? $sheetRows : [];
|
|
$selectedInspectionId = (int) ($selectedInspectionId ?? 0);
|
|
$selectedInspectionItemId = (int) ($selectedInspectionItemId ?? 0);
|
|
$selectedBoxCode = (string) ($selectedBoxCode ?? '');
|
|
$selectedPackCode = (string) ($selectedPackCode ?? '');
|
|
$overviewTotalQty = 0;
|
|
foreach ($overviewRows as $row) {
|
|
$overviewTotalQty += (int) ($row['bisi_system_qty'] ?? 0);
|
|
}
|
|
$packTotalQty = 0;
|
|
foreach ($boxRows as $row) {
|
|
$packTotalQty += (int) ($row['bisp_sheet_qty'] ?? 0);
|
|
}
|
|
$sheetTotalQty = 0;
|
|
foreach ($sheetRows as $row) {
|
|
$sheetTotalQty += (int) ($row['biss_system_qty'] ?? 0);
|
|
}
|
|
?>
|
|
|
|
<div class="space-y-2">
|
|
<section class="border border-gray-300 bg-white p-2">
|
|
<form method="get" class="flex flex-wrap items-end justify-between gap-2 text-sm">
|
|
<div class="flex flex-wrap items-end gap-2">
|
|
<label class="font-bold text-gray-700">실사기간</label>
|
|
<input type="date" name="start_date" value="<?= esc($startDate) ?>" class="border border-gray-300 rounded px-2 py-1">
|
|
<span>~</span>
|
|
<input type="date" name="end_date" value="<?= esc($endDate) ?>" class="border border-gray-300 rounded px-2 py-1">
|
|
|
|
<label class="font-bold text-gray-700 ml-2">실사품목</label>
|
|
<select name="item_code" class="border border-gray-300 rounded px-2 py-1 min-w-[11rem]">
|
|
<option value="">전체</option>
|
|
<?php foreach ($items as $it): ?>
|
|
<?php $code = (string) ($it['bag_code'] ?? ''); ?>
|
|
<option value="<?= esc($code) ?>" <?= $itemCode === $code ? 'selected' : '' ?>><?= esc((string) ($it['bag_name'] ?? '')) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
|
|
<label class="font-bold text-gray-700 ml-2">조회구분</label>
|
|
<select name="view_type" class="border border-gray-300 rounded px-2 py-1 min-w-[7rem]">
|
|
<option value="box" <?= $viewType === 'box' ? 'selected' : '' ?>>박스별</option>
|
|
<option value="pack" <?= $viewType === 'pack' ? 'selected' : '' ?>>팩별</option>
|
|
</select>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<button type="submit" class="bg-btn-search text-white px-3 py-1 rounded-sm">조회</button>
|
|
<button type="button" id="open-inspection-popup" class="border border-blue-300 text-blue-700 px-3 py-1 rounded-sm hover:bg-blue-50">실사 선별</button>
|
|
</div>
|
|
</form>
|
|
<p class="mt-1 text-xs text-blue-700">※ 실사 선별 처리 결과를 조회하는 화면입니다(읽기 전용).</p>
|
|
</section>
|
|
|
|
<section class="grid grid-cols-1 xl:grid-cols-2 gap-2">
|
|
<div class="border border-gray-300 bg-white">
|
|
<div class="border-b border-gray-300 bg-gray-50 px-2 py-1 text-sm font-bold text-gray-700">실사 선별자</div>
|
|
<div class="overflow-auto max-h-[500px]">
|
|
<table class="w-full data-table text-sm">
|
|
<thead>
|
|
<tr>
|
|
<th class="w-24">실사일자</th>
|
|
<th>종류</th>
|
|
<th class="w-40">박스</th>
|
|
<th class="w-20">전산재고</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if ($overviewRows !== []): ?>
|
|
<?php $prevBagName = null; ?>
|
|
<?php foreach ($overviewRows as $row): ?>
|
|
<?php
|
|
$itemId = (int) ($row['bisi_idx'] ?? 0);
|
|
$bagName = (string) ($row['bisi_bag_name'] ?? '');
|
|
$showBagName = $prevBagName !== $bagName;
|
|
$prevBagName = $bagName;
|
|
$isSelected = $itemId === $selectedInspectionItemId;
|
|
$url = base_url('bag/inventory/inspection-select?' . http_build_query([
|
|
'start_date' => $startDate,
|
|
'end_date' => $endDate,
|
|
'bis_id' => $selectedInspectionId,
|
|
'item_code' => $itemCode,
|
|
'view_type' => $viewType,
|
|
'sel_item_id' => $itemId,
|
|
]));
|
|
?>
|
|
<tr class="<?= $isSelected ? 'bg-blue-100' : 'cursor-pointer hover:bg-blue-50' ?>" onclick="window.location.href='<?= esc($url, 'attr') ?>'">
|
|
<td class="text-center"><?= esc((string) ($row['bis_work_date'] ?? '')) ?></td>
|
|
<td class="pl-2"><?= $showBagName ? esc($bagName) : '' ?></td>
|
|
<td class="text-center"><?= esc((string) ($row['box_code'] ?? '')) ?></td>
|
|
<td class="text-right pr-2"><?= number_format((int) ($row['bisi_system_qty'] ?? 0)) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<tr><td colspan="4" class="text-center text-gray-400 py-4">조회 결과가 없습니다.</td></tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="bg-gray-100 font-semibold">
|
|
<td class="text-center" colspan="3">합계</td>
|
|
<td class="text-right pr-2"><?= number_format($overviewTotalQty) ?></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="space-y-2">
|
|
<div class="border border-gray-300 bg-white">
|
|
<div class="border-b border-gray-300 bg-gray-50 px-2 py-1 text-sm font-bold text-gray-700">실사 선별 품목(읽기 전용)</div>
|
|
<div class="overflow-auto max-h-[260px]">
|
|
<table class="w-full data-table text-sm">
|
|
<thead>
|
|
<tr>
|
|
<th>팩코드</th>
|
|
<th class="w-16">포장량</th>
|
|
<th class="w-16">재고</th>
|
|
<th>낱장(시작)</th>
|
|
<th>낱장(끝)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if ($boxRows !== []): ?>
|
|
<?php foreach ($boxRows as $row): ?>
|
|
<?php
|
|
$code = (string) ($row['bisp_box_code'] ?? '');
|
|
$packCode = (string) ($row['bisp_pack_code'] ?? '');
|
|
$systemQty = (int) ($row['bisp_sheet_qty'] ?? 0);
|
|
$url = base_url('bag/inventory/inspection-select?' . http_build_query([
|
|
'start_date' => $startDate,
|
|
'end_date' => $endDate,
|
|
'bis_id' => $selectedInspectionId,
|
|
'item_code' => $itemCode,
|
|
'view_type' => $viewType,
|
|
'sel_item_id' => $selectedInspectionItemId,
|
|
'sel_box_code' => $code,
|
|
'sel_pack_code' => $packCode,
|
|
]));
|
|
$isSelected = $selectedBoxCode === $code && $selectedPackCode === $packCode;
|
|
?>
|
|
<tr class="<?= $isSelected ? 'bg-blue-100' : 'cursor-pointer hover:bg-blue-50' ?>" onclick="window.location.href='<?= esc($url, 'attr') ?>'">
|
|
<td class="pl-2"><?= esc($packCode) ?></td>
|
|
<td class="text-center"><?= number_format($systemQty) ?></td>
|
|
<td class="text-right pr-2"><?= number_format($systemQty) ?></td>
|
|
<td class="text-center"><?= esc((string) ($row['bisp_sheet_start_code'] ?? '')) ?></td>
|
|
<td class="text-center"><?= esc((string) ($row['bisp_sheet_end_code'] ?? '')) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<tr><td colspan="5" class="text-center text-gray-400 py-4">선택된 품목이 없습니다.</td></tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="bg-gray-100 font-semibold">
|
|
<td class="text-center" colspan="2">합계</td>
|
|
<td class="text-right pr-2"><?= number_format($packTotalQty) ?></td>
|
|
<td colspan="2"></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="border border-gray-300 bg-white">
|
|
<div class="border-b border-gray-300 bg-gray-50 px-2 py-1 text-sm font-bold text-gray-700">실사 선별 내용(읽기 전용)</div>
|
|
<div class="overflow-auto max-h-[240px]">
|
|
<table class="w-full data-table text-sm">
|
|
<thead>
|
|
<tr>
|
|
<th class="w-12">No</th>
|
|
<th>낱장</th>
|
|
<th class="w-16">수량</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if ($sheetRows !== []): ?>
|
|
<?php foreach ($sheetRows as $row): ?>
|
|
<tr>
|
|
<td class="text-center"><?= esc((string) ($row['no'] ?? '')) ?></td>
|
|
<td class="pl-2"><?= esc((string) ($row['biss_sheet_code'] ?? '')) ?></td>
|
|
<td class="text-right pr-2"><?= number_format((int) ($row['biss_system_qty'] ?? 0)) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php else: ?>
|
|
<tr><td colspan="3" class="text-center text-gray-400 py-4">선택된 팩/박스가 없습니다.</td></tr>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="bg-gray-100 font-semibold">
|
|
<td class="text-center" colspan="2">합계</td>
|
|
<td class="text-right pr-2"><?= number_format($sheetTotalQty) ?></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
|
|
<div id="inspection-popup" class="fixed inset-0 bg-black/40 hidden items-center justify-center z-[999]">
|
|
<div class="bg-white border border-gray-400 w-[min(720px,95vw)] max-h-[90vh] overflow-auto p-4">
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h3 class="text-lg font-bold">실사 선별</h3>
|
|
<button type="button" id="close-inspection-popup" class="text-gray-600 hover:text-gray-900">닫기</button>
|
|
</div>
|
|
<form method="post" action="<?= base_url('bag/inventory/inspection-run') ?>" id="inspection-run-form" class="space-y-3">
|
|
<?= csrf_field() ?>
|
|
<div class="flex items-center gap-2">
|
|
<label class="font-bold text-gray-700 text-sm">작업 일자</label>
|
|
<input type="date" name="work_date" value="<?= esc($workDate) ?>" class="border border-gray-300 rounded px-2 py-1 text-sm">
|
|
</div>
|
|
<p class="text-red-600 font-semibold">바코드가 없는 봉투는 실사에서 제외 됩니다.</p>
|
|
<div class="overflow-auto border border-gray-300 max-h-[55vh]">
|
|
<table class="w-full data-table text-sm">
|
|
<thead>
|
|
<tr><th>종류</th><th class="w-20">선택구분</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($popupItems as $row): ?>
|
|
<?php $hasBarcode = (bool) ($row['has_barcode'] ?? false); ?>
|
|
<tr class="<?= $hasBarcode ? '' : 'bg-gray-50 text-gray-400' ?>">
|
|
<td class="pl-2"><?= esc((string) ($row['bag_name'] ?? '')) ?></td>
|
|
<td class="text-center">
|
|
<input type="checkbox" name="bag_codes[]" value="<?= esc((string) ($row['bag_code'] ?? ''), 'attr') ?>" <?= $hasBarcode ? '' : 'disabled' ?>>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="flex justify-end gap-2">
|
|
<button type="submit" class="bg-btn-search text-white px-5 py-1.5 rounded-sm text-sm">실행</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(() => {
|
|
const popup = document.getElementById('inspection-popup');
|
|
const openBtn = document.getElementById('open-inspection-popup');
|
|
const closeBtn = document.getElementById('close-inspection-popup');
|
|
if (openBtn && popup) {
|
|
openBtn.addEventListener('click', () => {
|
|
popup.classList.remove('hidden');
|
|
popup.classList.add('flex');
|
|
});
|
|
}
|
|
if (closeBtn && popup) {
|
|
closeBtn.addEventListener('click', () => {
|
|
popup.classList.add('hidden');
|
|
popup.classList.remove('flex');
|
|
});
|
|
}
|
|
const form = document.getElementById('inspection-run-form');
|
|
if (form) {
|
|
form.addEventListener('submit', (event) => {
|
|
if (!window.confirm('전산 선별 처리를 실행하시겠습니까?')) {
|
|
event.preventDefault();
|
|
}
|
|
});
|
|
}
|
|
})();
|
|
</script>
|