2026-04-23 15:53:33 +09:00
|
|
|
<?php
|
|
|
|
|
$editDefaults = is_array($editDefaults ?? null) ? $editDefaults : [];
|
|
|
|
|
$editMode = (bool) ($editMode ?? false);
|
|
|
|
|
$oldBagCodes = old('item_bag_code', $editDefaults['item_bag_code'] ?? []);
|
|
|
|
|
$oldQtySheets = old('item_qty_sheet', $editDefaults['item_qty_sheet'] ?? []);
|
|
|
|
|
$oldQtyBoxes = old('item_qty_box', $editDefaults['item_qty_box'] ?? []);
|
|
|
|
|
$oldBagCodes = is_array($oldBagCodes) ? $oldBagCodes : [];
|
|
|
|
|
$oldQtySheets = is_array($oldQtySheets) ? $oldQtySheets : [];
|
|
|
|
|
$oldQtyBoxes = is_array($oldQtyBoxes) ? $oldQtyBoxes : [];
|
|
|
|
|
$itemRowCount = max(8, count($oldBagCodes), count($oldQtySheets), count($oldQtyBoxes));
|
|
|
|
|
$defaultOrderDate = old('bo_order_date', $editDefaults['bo_order_date'] ?? date('Y-m-d'));
|
|
|
|
|
$defaultOrderMonth = old('bo_order_month_ui', substr($defaultOrderDate, 0, 7));
|
|
|
|
|
$defaultOrderYear = (int) substr($defaultOrderMonth, 0, 4);
|
|
|
|
|
$monthOptionValues = [];
|
|
|
|
|
for ($year = $defaultOrderYear - 2; $year <= $defaultOrderYear + 2; $year++) {
|
|
|
|
|
for ($month = 1; $month <= 12; $month++) {
|
|
|
|
|
$monthValue = sprintf('%04d-%02d', $year, $month);
|
|
|
|
|
$monthLabel = $year . '년 ' . $month . '월';
|
|
|
|
|
$monthOptionValues[] = ['value' => $monthValue, 'label' => $monthLabel];
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-26 16:13:07 +09:00
|
|
|
|
2026-04-23 15:53:33 +09:00
|
|
|
$bagMeta = [];
|
|
|
|
|
foreach (($bagReferenceRows ?? []) as $row) {
|
|
|
|
|
$bagMeta[$row['code']] = [
|
|
|
|
|
'name' => $row['name'],
|
|
|
|
|
'orderPrice' => (float) $row['orderPrice'],
|
|
|
|
|
'boxPerPack' => (int) $row['boxPerPack'],
|
|
|
|
|
'packPerSheet' => (int) $row['packPerSheet'],
|
|
|
|
|
'totalPerBox' => max(1, (int) $row['totalPerBox']),
|
|
|
|
|
];
|
|
|
|
|
}
|
2026-03-26 16:13:07 +09:00
|
|
|
|
2026-04-23 15:53:33 +09:00
|
|
|
$initialSelectedItems = [];
|
|
|
|
|
$maxOldCount = max(count($oldBagCodes), count($oldQtySheets), count($oldQtyBoxes));
|
|
|
|
|
for ($i = 0; $i < $maxOldCount; $i++) {
|
|
|
|
|
$code = trim((string) ($oldBagCodes[$i] ?? ''));
|
|
|
|
|
if ($code === '' || !isset($bagMeta[$code])) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
$fallbackQtyBox = (int) ($oldQtyBoxes[$i] ?? 0);
|
|
|
|
|
$rawQtySheet = (int) ($oldQtySheets[$i] ?? 0);
|
|
|
|
|
$fallbackTotalPerBox = (int) ($bagMeta[$code]['totalPerBox'] ?? 1);
|
|
|
|
|
if ($fallbackQtyBox <= 0 && $rawQtySheet > 0) {
|
|
|
|
|
$fallbackQtyBox = intdiv($rawQtySheet, max(1, $fallbackTotalPerBox));
|
|
|
|
|
}
|
|
|
|
|
$initialSelectedItems[] = [
|
|
|
|
|
'code' => $code,
|
|
|
|
|
'qtyBox' => max(0, $fallbackQtyBox),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$statusMap = ['normal' => '정상', 'cancelled' => '취소', 'deleted' => '삭제'];
|
2026-03-26 16:13:07 +09:00
|
|
|
|
2026-04-23 15:53:33 +09:00
|
|
|
$hubReturn = (bool) ($hubReturn ?? false);
|
|
|
|
|
$changeMode = $editMode ? (string) ($changeMode ?? 'meta') : 'meta';
|
|
|
|
|
if (! in_array($changeMode, ['price', 'meta', 'delete'], true)) {
|
|
|
|
|
$changeMode = 'meta';
|
|
|
|
|
}
|
|
|
|
|
$orderLotNo = (string) ($orderLotNo ?? '');
|
|
|
|
|
$orderReturnMonth = (string) ($orderReturnMonth ?? '');
|
|
|
|
|
$deleteMode = $editMode && $changeMode === 'delete';
|
|
|
|
|
$defaultDeleteBoIdx = (int) ($editDefaults['bo_source_idx'] ?? 0);
|
|
|
|
|
$firstNormalBoIdx = null;
|
|
|
|
|
foreach (($recentOrders ?? []) as $_h) {
|
|
|
|
|
if ((string) ($_h->bo_status ?? '') === 'normal') {
|
|
|
|
|
$firstNormalBoIdx = (int) $_h->bo_idx;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$defaultDeleteOk = false;
|
|
|
|
|
foreach (($recentOrders ?? []) as $_h) {
|
|
|
|
|
if ((int) $_h->bo_idx === $defaultDeleteBoIdx && (string) ($_h->bo_status ?? '') === 'normal') {
|
|
|
|
|
$defaultDeleteOk = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$selectedDeleteBoIdx = $defaultDeleteOk ? $defaultDeleteBoIdx : (int) ($firstNormalBoIdx ?? 0);
|
|
|
|
|
?>
|
|
|
|
|
|
|
|
|
|
<section class="border-b border-gray-300 p-2 shrink-0 bg-control-panel flex flex-wrap items-center justify-between gap-2">
|
|
|
|
|
<span class="text-sm font-bold text-gray-700"><?= $editMode ? '발주 변경' : '발주 등록' ?></span>
|
|
|
|
|
<?php if ($hubReturn && $orderReturnMonth !== ''): ?>
|
|
|
|
|
<a href="<?= base_url('bag/order/change?month=' . rawurlencode($orderReturnMonth) . '&hub_mode=' . rawurlencode($changeMode)) ?>" class="text-sm text-blue-600 hover:underline">발주 변경 목록</a>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<?php if ($deleteMode): ?>
|
|
|
|
|
<form action="<?= base_url('bag/order/delete') ?>" method="post" class="mt-2 space-y-2">
|
|
|
|
|
<?= csrf_field() ?>
|
|
|
|
|
<div class="border border-gray-300 bg-white p-2 text-sm">
|
|
|
|
|
<span class="font-bold text-gray-700">발주월</span>
|
|
|
|
|
<span class="ml-2"><?= esc($defaultOrderMonth) ?></span>
|
|
|
|
|
<span class="text-gray-600 ml-2">왼쪽 목록에서 삭제할 발주를 선택한 뒤 「삭제 실행」을 누르세요.</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="grid grid-cols-1 xl:grid-cols-12 gap-2">
|
|
|
|
|
<section class="xl:col-span-5 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-[410px]">
|
|
|
|
|
<table class="w-full data-table text-sm">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="w-10">선택</th>
|
|
|
|
|
<th class="w-28">발주일</th>
|
|
|
|
|
<th>제작업체</th>
|
|
|
|
|
<th>입고처</th>
|
|
|
|
|
<th class="w-16">상태</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<?php $deleteRadioFirst = true; ?>
|
|
|
|
|
<?php foreach (($recentOrders ?? []) as $history): ?>
|
|
|
|
|
<?php $rowNormal = (string) ($history->bo_status ?? '') === 'normal'; ?>
|
|
|
|
|
<tr class="<?= $rowNormal ? '' : 'opacity-60' ?>">
|
|
|
|
|
<td class="text-center align-middle">
|
|
|
|
|
<?php if ($rowNormal): ?>
|
|
|
|
|
<input type="radio" name="bo_idx" value="<?= (int) $history->bo_idx ?>" class="accent-red-600" <?= (int) $history->bo_idx === $selectedDeleteBoIdx ? 'checked' : '' ?> <?= $deleteRadioFirst ? 'required' : '' ?> />
|
|
|
|
|
<?php $deleteRadioFirst = false; ?>
|
|
|
|
|
<?php else: ?>
|
|
|
|
|
<span class="text-gray-400" title="삭제할 수 없는 상태">—</span>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
</td>
|
|
|
|
|
<td class="text-center"><?= esc((string) $history->bo_order_date) ?></td>
|
|
|
|
|
<td class="text-left pl-2"><?= esc((string) ($companyMap[(int) $history->bo_company_idx] ?? '-')) ?></td>
|
|
|
|
|
<td class="text-left pl-2"><?= esc((string) ($agencyMap[(int) $history->bo_agency_idx] ?? '-')) ?></td>
|
|
|
|
|
<td class="text-center"><?= esc((string) ($statusMap[(string) $history->bo_status] ?? $history->bo_status)) ?></td>
|
|
|
|
|
</tr>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
<?php if (empty($recentOrders)): ?>
|
|
|
|
|
<tr><td colspan="5" class="text-center text-gray-400 py-4">발주 이력이 없습니다.</td></tr>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
<section class="xl:col-span-7 border border-red-200 bg-red-50 p-4">
|
|
|
|
|
<p class="text-sm font-bold text-red-800 mb-2">발주 삭제</p>
|
|
|
|
|
<p class="text-sm text-gray-700 mb-4">목록에서 선택한 발주를 삭제 처리합니다. 계속하시겠습니까?</p>
|
|
|
|
|
<div class="flex flex-wrap gap-2 items-center">
|
|
|
|
|
<button type="submit" class="bg-red-600 text-white px-6 py-1.5 rounded-sm text-sm shadow hover:opacity-90" <?= $firstNormalBoIdx === null ? 'disabled' : '' ?>>삭제 실행</button>
|
|
|
|
|
<a href="<?= base_url('bag/order/change?month=' . rawurlencode($orderReturnMonth !== '' ? $orderReturnMonth : substr($defaultOrderDate, 0, 7))) ?>" class="bg-gray-200 text-gray-800 px-6 py-1.5 rounded-sm text-sm">취소</a>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
<?php else: ?>
|
|
|
|
|
|
|
|
|
|
<form action="<?= base_url('bag/order/store') ?>" method="POST" class="mt-2 space-y-2" id="bag-order-store-form">
|
|
|
|
|
<?= csrf_field() ?>
|
|
|
|
|
<?php if ($editMode): ?>
|
|
|
|
|
<input type="hidden" name="bo_source_idx" value="<?= esc((string) ($editDefaults['bo_source_idx'] ?? 0)) ?>" />
|
|
|
|
|
<fieldset class="border border-gray-200 rounded px-3 py-2 mb-1 text-sm bg-white">
|
|
|
|
|
<legend class="text-xs font-bold text-gray-600 px-1">변경 구분</legend>
|
|
|
|
|
<div class="flex flex-wrap gap-x-4 gap-y-1">
|
|
|
|
|
<label class="inline-flex items-center gap-1 cursor-pointer">
|
|
|
|
|
<input type="radio" name="bo_change_mode" value="price" <?= $changeMode === 'price' ? 'checked' : '' ?> />
|
|
|
|
|
<span>발주·도매·판매 단가</span>
|
|
|
|
|
</label>
|
|
|
|
|
<label class="inline-flex items-center gap-1 cursor-pointer">
|
|
|
|
|
<input type="radio" name="bo_change_mode" value="meta" <?= $changeMode === 'meta' ? 'checked' : '' ?> />
|
|
|
|
|
<span>업체·수수료·협회·발주</span>
|
|
|
|
|
</label>
|
2026-03-26 16:13:07 +09:00
|
|
|
</div>
|
2026-04-23 15:53:33 +09:00
|
|
|
<p class="text-xs text-gray-500 mt-1">
|
|
|
|
|
발주 삭제는 <a class="text-blue-600 hover:underline" href="<?= base_url('bag/order/revise/' . (int) ($editDefaults['bo_source_idx'] ?? 0) . '?change_mode=delete') ?>">발주 삭제 화면</a>으로 이동합니다.
|
|
|
|
|
</p>
|
|
|
|
|
</fieldset>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
<?php if ($hubReturn && $orderReturnMonth !== ''): ?>
|
|
|
|
|
<input type="hidden" name="order_return_hub" value="1" />
|
|
|
|
|
<input type="hidden" name="order_return_month" value="<?= esc($orderReturnMonth) ?>" />
|
|
|
|
|
<?php endif; ?>
|
2026-03-26 16:13:07 +09:00
|
|
|
|
2026-04-23 15:53:33 +09:00
|
|
|
<div class="border border-gray-300 bg-white p-2">
|
|
|
|
|
<div class="flex flex-wrap items-center gap-4 text-sm">
|
|
|
|
|
<div class="flex items-center gap-2">
|
|
|
|
|
<label for="bo_order_month_ui" class="font-bold text-gray-700">발주월</label>
|
|
|
|
|
<select id="bo_order_month_ui" name="bo_order_month_ui" class="border border-gray-300 rounded px-2 py-1 w-40">
|
|
|
|
|
<?php foreach ($monthOptionValues as $monthOption): ?>
|
|
|
|
|
<option value="<?= esc($monthOption['value']) ?>" <?= $monthOption['value'] === $defaultOrderMonth ? 'selected' : '' ?>>
|
|
|
|
|
<?= esc($monthOption['label']) ?>
|
|
|
|
|
</option>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
</select>
|
|
|
|
|
<span id="bo_order_month_ko" class="text-sm text-gray-700"></span>
|
|
|
|
|
</div>
|
|
|
|
|
<p class="text-blue-600 font-bold">※ 발주수량을 박스단위로 떨어지게 입력해 주세요.</p>
|
2026-03-26 16:13:07 +09:00
|
|
|
</div>
|
2026-04-23 15:53:33 +09:00
|
|
|
</div>
|
2026-03-26 16:13:07 +09:00
|
|
|
|
2026-04-23 15:53:33 +09:00
|
|
|
<div class="grid grid-cols-1 xl:grid-cols-12 gap-2">
|
|
|
|
|
<section class="xl:col-span-5 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-[410px]">
|
|
|
|
|
<table class="w-full data-table text-sm">
|
2026-03-26 16:13:07 +09:00
|
|
|
<thead>
|
|
|
|
|
<tr>
|
2026-04-23 15:53:33 +09:00
|
|
|
<th class="w-28">발주일</th>
|
|
|
|
|
<th>제작업체</th>
|
|
|
|
|
<th>입고처</th>
|
|
|
|
|
<th class="w-16">상태</th>
|
2026-03-26 16:13:07 +09:00
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
2026-04-23 15:53:33 +09:00
|
|
|
<?php foreach (($recentOrders ?? []) as $history): ?>
|
2026-03-26 16:13:07 +09:00
|
|
|
<tr>
|
2026-04-23 15:53:33 +09:00
|
|
|
<td class="text-center">
|
|
|
|
|
<a href="<?= base_url('bag/order/revise/' . (int) $history->bo_idx) ?>" class="text-blue-600 hover:underline">
|
|
|
|
|
<?= esc((string) $history->bo_order_date) ?>
|
|
|
|
|
</a>
|
2026-03-26 16:13:07 +09:00
|
|
|
</td>
|
2026-04-23 15:53:33 +09:00
|
|
|
<td class="text-left pl-2"><?= esc((string) ($companyMap[(int) $history->bo_company_idx] ?? '-')) ?></td>
|
|
|
|
|
<td class="text-left pl-2"><?= esc((string) ($agencyMap[(int) $history->bo_agency_idx] ?? '-')) ?></td>
|
|
|
|
|
<td class="text-center"><?= esc((string) ($statusMap[(string) $history->bo_status] ?? $history->bo_status)) ?></td>
|
2026-03-26 16:13:07 +09:00
|
|
|
</tr>
|
2026-04-23 15:53:33 +09:00
|
|
|
<?php endforeach; ?>
|
|
|
|
|
<?php if (empty($recentOrders)): ?>
|
|
|
|
|
<tr><td colspan="4" class="text-center text-gray-400 py-4">발주 이력이 없습니다.</td></tr>
|
|
|
|
|
<?php endif; ?>
|
2026-03-26 16:13:07 +09:00
|
|
|
</tbody>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
2026-04-23 15:53:33 +09:00
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<section class="xl:col-span-7 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"><?= $editMode ? '발주 변경 수정' : '발주 Form' ?></div>
|
|
|
|
|
<div class="p-2 space-y-2">
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-2">
|
|
|
|
|
<div class="flex items-center gap-2 text-sm">
|
|
|
|
|
<label for="bo_order_date" class="w-20 font-bold text-gray-700">발주일 <span class="text-red-500">*</span></label>
|
|
|
|
|
<input id="bo_order_date" name="bo_order_date" type="date" value="<?= esc($defaultOrderDate) ?>" required class="border border-gray-300 rounded px-2 py-1 w-full" />
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center gap-2 text-sm">
|
|
|
|
|
<label for="bo_association_idx" class="w-20 font-bold text-gray-700">협회</label>
|
|
|
|
|
<select id="bo_association_idx" name="bo_association_idx" class="border border-gray-300 rounded px-2 py-1 w-full">
|
|
|
|
|
<option value="">선택</option>
|
|
|
|
|
<?php foreach (($associations ?? []) as $association): ?>
|
|
|
|
|
<option value="<?= esc((string) $association->cp_idx) ?>" <?= (int) old('bo_association_idx', $editDefaults['bo_association_idx'] ?? 0) === (int) $association->cp_idx ? 'selected' : '' ?>>
|
|
|
|
|
<?= esc((string) $association->cp_name) ?>
|
|
|
|
|
</option>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center gap-2 text-sm">
|
|
|
|
|
<label for="bo_company_idx" class="w-20 font-bold text-gray-700">제작업체</label>
|
|
|
|
|
<select id="bo_company_idx" name="bo_company_idx" class="border border-gray-300 rounded px-2 py-1 w-full">
|
|
|
|
|
<option value="">선택</option>
|
|
|
|
|
<?php foreach (($companies ?? []) as $company): ?>
|
|
|
|
|
<option value="<?= esc((string) $company->cp_idx) ?>" <?= (int) old('bo_company_idx', $editDefaults['bo_company_idx'] ?? 0) === (int) $company->cp_idx ? 'selected' : '' ?>>
|
|
|
|
|
<?= esc((string) $company->cp_name) ?>
|
|
|
|
|
</option>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center gap-2 text-sm">
|
|
|
|
|
<label for="bo_agency_idx" class="w-20 font-bold text-gray-700">입고처</label>
|
|
|
|
|
<select id="bo_agency_idx" name="bo_agency_idx" class="border border-gray-300 rounded px-2 py-1 w-full">
|
|
|
|
|
<option value="">선택</option>
|
|
|
|
|
<?php foreach (($agencies ?? []) as $agency): ?>
|
|
|
|
|
<option value="<?= esc((string) $agency->sa_idx) ?>" <?= (int) old('bo_agency_idx', $editDefaults['bo_agency_idx'] ?? 0) === (int) $agency->sa_idx ? 'selected' : '' ?>>
|
|
|
|
|
[<?= esc((string) ($agency->sa_kind ?? '')) ?>] <?= esc((string) ($agency->sa_code ?? '')) ?> — <?= esc((string) $agency->sa_name) ?>
|
|
|
|
|
</option>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="border border-gray-300 overflow-auto">
|
|
|
|
|
<table class="w-full data-table text-sm order-input-table" id="order-item-table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="w-12">번호</th>
|
|
|
|
|
<th class="w-16">선택</th>
|
|
|
|
|
<th>품명</th>
|
|
|
|
|
<th class="w-24">수량</th>
|
|
|
|
|
<th class="w-24">단가</th>
|
|
|
|
|
<th class="w-24">낱장환산</th>
|
|
|
|
|
<?php if ($editMode): ?>
|
|
|
|
|
<th class="w-24">선정수량</th>
|
|
|
|
|
<th class="w-20">LOT</th>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
<th class="w-28">금액</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody id="selected-order-items-body"></tbody>
|
|
|
|
|
<tfoot>
|
|
|
|
|
<tr>
|
|
|
|
|
<th colspan="3" class="text-center">계</th>
|
|
|
|
|
<th class="text-right pr-2" id="sum-box-qty">0</th>
|
|
|
|
|
<th></th>
|
|
|
|
|
<th class="text-right pr-2" id="sum-sheet-qty">0</th>
|
|
|
|
|
<?php if ($editMode): ?>
|
|
|
|
|
<th></th>
|
|
|
|
|
<th></th>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
<th class="text-right pr-2" id="sum-amount">0</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</tfoot>
|
|
|
|
|
</table>
|
|
|
|
|
</div>
|
2026-03-26 16:13:07 +09:00
|
|
|
|
2026-04-23 15:53:33 +09:00
|
|
|
<div class="border border-gray-300 bg-gray-50 p-2 text-sm">
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-1">
|
|
|
|
|
<div class="flex items-center justify-between">
|
|
|
|
|
<span class="text-gray-700">품목 금액 합계</span>
|
|
|
|
|
<strong id="sum-item-amount">0</strong>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center justify-between">
|
|
|
|
|
<span class="text-gray-700">조달수수료</span>
|
|
|
|
|
<span class="flex items-center gap-1">
|
|
|
|
|
<input id="bo_fee_rate_summary" name="bo_fee_rate" type="number" step="0.01" value="<?= esc(old('bo_fee_rate', $editDefaults['bo_fee_rate'] ?? '0')) ?>" class="border border-gray-300 rounded px-2 py-0.5 w-20 text-right" />
|
|
|
|
|
<strong>%</strong>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center justify-between">
|
|
|
|
|
<span class="text-gray-700">조달수수료액</span>
|
|
|
|
|
<strong id="sum-fee-amount">0</strong>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex items-center justify-between border-t border-red-300 pt-1">
|
|
|
|
|
<span class="font-bold text-gray-800">품목 + 수수료 합계</span>
|
|
|
|
|
<strong id="sum-grand-amount" class="text-red-700">0</strong>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="flex gap-2 pt-1">
|
|
|
|
|
<button type="submit" class="bg-btn-search text-white px-6 py-1.5 rounded-sm text-sm shadow hover:opacity-90 transition"><?= $editMode ? '변경 저장' : '발주' ?></button>
|
|
|
|
|
<a href="<?= base_url('bag/purchase-inbound') ?>" class="bg-gray-200 text-gray-700 px-6 py-1.5 rounded-sm text-sm hover:bg-gray-300 transition">취소</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<section 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">
|
|
|
|
|
<table class="w-full data-table text-sm order-reference-table">
|
|
|
|
|
<thead>
|
|
|
|
|
<tr>
|
|
|
|
|
<th class="w-12">번호</th>
|
|
|
|
|
<th class="w-20">선택</th>
|
|
|
|
|
<th>봉투 종류</th>
|
|
|
|
|
<th class="w-24">발주단가</th>
|
|
|
|
|
<th class="w-24">Box당 팩</th>
|
|
|
|
|
<th class="w-24">팩당 낱장</th>
|
|
|
|
|
<th class="w-28">1박스 총 낱장</th>
|
|
|
|
|
</tr>
|
|
|
|
|
</thead>
|
|
|
|
|
<tbody>
|
|
|
|
|
<?php foreach (($bagReferenceRows ?? []) as $idx => $row): ?>
|
|
|
|
|
<tr data-reference-row data-code="<?= esc((string) $row['code']) ?>" class="cursor-pointer">
|
|
|
|
|
<td class="text-center"><?= $idx + 1 ?></td>
|
|
|
|
|
<td class="text-center">
|
|
|
|
|
<button type="button" class="js-toggle-bag border border-gray-300 rounded px-2 py-0.5 text-xs hover:bg-gray-100" data-code="<?= esc((string) $row['code']) ?>">선택</button>
|
|
|
|
|
</td>
|
|
|
|
|
<td class="text-left pl-2"><?= esc((string) $row['name']) ?></td>
|
|
|
|
|
<td class="text-right pr-2"><?= number_format((float) $row['orderPrice'], 2) ?></td>
|
|
|
|
|
<td class="text-right pr-2"><?= number_format((int) $row['boxPerPack']) ?></td>
|
|
|
|
|
<td class="text-right pr-2"><?= number_format((int) $row['packPerSheet']) ?></td>
|
|
|
|
|
<td class="text-right pr-2"><?= number_format((int) $row['totalPerBox']) ?></td>
|
|
|
|
|
</tr>
|
|
|
|
|
<?php endforeach; ?>
|
|
|
|
|
<?php if (empty($bagReferenceRows)): ?>
|
|
|
|
|
<tr><td colspan="6" class="text-center text-gray-400 py-4">표시할 봉투 기준 데이터가 없습니다.</td></tr>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
</tbody>
|
|
|
|
|
</table>
|
2026-03-26 16:13:07 +09:00
|
|
|
</div>
|
2026-04-23 15:53:33 +09:00
|
|
|
</section>
|
|
|
|
|
</form>
|
|
|
|
|
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
<?php if (! $deleteMode): ?>
|
|
|
|
|
<style>
|
|
|
|
|
.order-input-table tbody tr,
|
|
|
|
|
.order-reference-table tbody tr {
|
|
|
|
|
height: 34px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.order-input-table tbody td,
|
|
|
|
|
.order-reference-table tbody td {
|
|
|
|
|
padding-top: 4px;
|
|
|
|
|
padding-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
(() => {
|
|
|
|
|
const bagMeta = <?= json_encode($bagMeta, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
|
|
|
const initialSelectedItems = <?= json_encode($initialSelectedItems, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
|
|
|
const selectedBody = document.getElementById('selected-order-items-body');
|
|
|
|
|
const referenceRows = Array.from(document.querySelectorAll('[data-reference-row]'));
|
|
|
|
|
const sumBoxQtyEl = document.getElementById('sum-box-qty');
|
|
|
|
|
const sumSheetQtyEl = document.getElementById('sum-sheet-qty');
|
|
|
|
|
const sumAmountEl = document.getElementById('sum-amount');
|
|
|
|
|
const sumItemAmountEl = document.getElementById('sum-item-amount');
|
|
|
|
|
const sumFeeAmountEl = document.getElementById('sum-fee-amount');
|
|
|
|
|
const sumGrandAmountEl = document.getElementById('sum-grand-amount');
|
|
|
|
|
const monthInput = document.getElementById('bo_order_month_ui');
|
|
|
|
|
const monthKoLabel = document.getElementById('bo_order_month_ko');
|
|
|
|
|
const orderDateInput = document.getElementById('bo_order_date');
|
|
|
|
|
const feeRateSummaryInput = document.getElementById('bo_fee_rate_summary');
|
|
|
|
|
const orderForm = document.querySelector('form[action*="bag/order/store"]');
|
|
|
|
|
const selectedItems = new Map();
|
|
|
|
|
let activeCode = null;
|
|
|
|
|
const editMode = <?= $editMode ? 'true' : 'false' ?>;
|
|
|
|
|
const changeMode = <?= json_encode($changeMode, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
|
|
|
const orderLotNo = <?= json_encode($orderLotNo, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
|
|
|
|
|
const colEmpty = editMode ? 9 : 7;
|
|
|
|
|
|
|
|
|
|
const formatNumber = (value) => new Intl.NumberFormat('ko-KR').format(Number.isFinite(value) ? value : 0);
|
|
|
|
|
const escapeHtml = (value) => String(value ?? '')
|
|
|
|
|
.replaceAll('&', '&')
|
|
|
|
|
.replaceAll('<', '<')
|
|
|
|
|
.replaceAll('>', '>')
|
|
|
|
|
.replaceAll('"', '"')
|
|
|
|
|
.replaceAll("'", ''');
|
|
|
|
|
|
|
|
|
|
const ensureMonthOption = (monthValue) => {
|
|
|
|
|
if (!monthInput || !monthValue) return;
|
|
|
|
|
const hasOption = Array.from(monthInput.options || []).some((option) => option.value === monthValue);
|
|
|
|
|
if (hasOption) return;
|
|
|
|
|
const [year, month] = monthValue.split('-');
|
|
|
|
|
const label = `${Number(year)}년 ${Number(month)}월`;
|
|
|
|
|
const option = new Option(label, monthValue, false, false);
|
|
|
|
|
monthInput.add(option);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const syncMonthFromDate = () => {
|
|
|
|
|
if (!orderDateInput || !monthInput || !orderDateInput.value) return;
|
|
|
|
|
const monthValue = orderDateInput.value.substring(0, 7);
|
|
|
|
|
ensureMonthOption(monthValue);
|
|
|
|
|
monthInput.value = monthValue;
|
|
|
|
|
updateMonthKoLabel();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const syncDateFromMonth = () => {
|
|
|
|
|
if (!orderDateInput || !monthInput || !monthInput.value) return;
|
|
|
|
|
const parts = monthInput.value.split('-');
|
|
|
|
|
if (parts.length !== 2) return;
|
|
|
|
|
const year = Number(parts[0]);
|
|
|
|
|
const month = Number(parts[1]);
|
|
|
|
|
if (!Number.isFinite(year) || !Number.isFinite(month)) return;
|
|
|
|
|
|
|
|
|
|
const currentDay = orderDateInput.value ? Number(orderDateInput.value.split('-')[2]) : 1;
|
|
|
|
|
const lastDay = new Date(year, month, 0).getDate();
|
|
|
|
|
const day = String(Math.min(Math.max(currentDay, 1), lastDay)).padStart(2, '0');
|
|
|
|
|
orderDateInput.value = `${String(year)}-${String(month).padStart(2, '0')}-${day}`;
|
|
|
|
|
updateMonthKoLabel();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const updateMonthKoLabel = () => {
|
|
|
|
|
if (!monthKoLabel || !monthInput || !monthInput.value) {
|
|
|
|
|
if (monthKoLabel) monthKoLabel.textContent = '';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const [year, month] = monthInput.value.split('-');
|
|
|
|
|
if (!year || !month) {
|
|
|
|
|
monthKoLabel.textContent = '';
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
monthKoLabel.textContent = `${Number(year)}년 ${Number(month)}월`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const updateReferenceSelectionUi = () => {
|
|
|
|
|
referenceRows.forEach((row) => {
|
|
|
|
|
const code = row.dataset.code || '';
|
|
|
|
|
const button = row.querySelector('.js-toggle-bag');
|
|
|
|
|
const isSelected = selectedItems.has(code);
|
|
|
|
|
row.classList.toggle('bg-blue-50', isSelected);
|
|
|
|
|
if (button) {
|
|
|
|
|
button.textContent = isSelected ? '선택됨' : '선택';
|
|
|
|
|
button.classList.toggle('bg-blue-600', isSelected);
|
|
|
|
|
button.classList.toggle('text-white', isSelected);
|
|
|
|
|
button.classList.toggle('border-blue-600', isSelected);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const applyModeLock = () => {
|
|
|
|
|
if (!editMode) return;
|
|
|
|
|
const isPrice = changeMode === 'price';
|
|
|
|
|
selectedBody.querySelectorAll('.item-qty-box').forEach((el) => {
|
|
|
|
|
el.readOnly = isPrice;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const updateTotals = () => {
|
|
|
|
|
let sumBoxQty = 0;
|
|
|
|
|
let sumSheetQty = 0;
|
|
|
|
|
let sumAmount = 0;
|
|
|
|
|
|
|
|
|
|
selectedBody.querySelectorAll('tr[data-item-row]').forEach((row) => {
|
|
|
|
|
const code = row.dataset.code || '';
|
|
|
|
|
const qtyInput = row.querySelector('.item-qty-box');
|
|
|
|
|
const qtyBox = Math.max(0, parseInt(qtyInput?.value || '0', 10));
|
|
|
|
|
const meta = bagMeta[code] || { orderPrice: 0, totalPerBox: 1 };
|
|
|
|
|
const priceInput = row.querySelector('.item-unit-price-input');
|
|
|
|
|
let unitPrice = Number(meta.orderPrice || 0);
|
|
|
|
|
if (priceInput) {
|
|
|
|
|
unitPrice = Math.max(0, parseFloat(priceInput.value || '0') || 0);
|
|
|
|
|
}
|
|
|
|
|
const totalPerBox = Math.max(1, Number(meta.totalPerBox || 1));
|
|
|
|
|
const qtySheet = qtyBox * totalPerBox;
|
|
|
|
|
const amount = qtySheet * unitPrice;
|
|
|
|
|
|
|
|
|
|
const unitPriceEl = row.querySelector('.item-unit-price');
|
|
|
|
|
const qtySheetEl = row.querySelector('.item-qty-sheet');
|
|
|
|
|
const selQtyEl = row.querySelector('.item-sel-qty');
|
|
|
|
|
const sheetHelpEl = row.querySelector('.item-sheet-help');
|
|
|
|
|
const amountEl = row.querySelector('.item-amount');
|
|
|
|
|
if (unitPriceEl) unitPriceEl.textContent = formatNumber(unitPrice);
|
|
|
|
|
if (qtySheetEl) qtySheetEl.textContent = formatNumber(qtySheet);
|
|
|
|
|
if (selQtyEl) selQtyEl.textContent = formatNumber(qtySheet);
|
|
|
|
|
if (sheetHelpEl) sheetHelpEl.textContent = `낱장 ${formatNumber(qtySheet)}장`;
|
|
|
|
|
if (amountEl) amountEl.textContent = formatNumber(amount);
|
|
|
|
|
|
|
|
|
|
selectedItems.set(code, { qtyBox });
|
|
|
|
|
sumBoxQty += qtyBox;
|
|
|
|
|
sumSheetQty += qtySheet;
|
|
|
|
|
sumAmount += amount;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (sumBoxQtyEl) sumBoxQtyEl.textContent = formatNumber(sumBoxQty);
|
|
|
|
|
if (sumSheetQtyEl) sumSheetQtyEl.textContent = formatNumber(sumSheetQty);
|
|
|
|
|
if (sumAmountEl) sumAmountEl.textContent = formatNumber(sumAmount);
|
|
|
|
|
if (sumItemAmountEl) sumItemAmountEl.textContent = formatNumber(sumAmount);
|
|
|
|
|
|
|
|
|
|
const feeRateSource = feeRateSummaryInput?.value ?? '0';
|
|
|
|
|
const feeRate = Math.max(0, parseFloat(feeRateSource) || 0);
|
|
|
|
|
const feeAmount = Math.round(sumAmount * (feeRate / 100));
|
|
|
|
|
const grandAmount = sumAmount + feeAmount;
|
|
|
|
|
|
|
|
|
|
if (feeRateSummaryInput && feeRateSummaryInput.value !== feeRate.toString()) {
|
|
|
|
|
feeRateSummaryInput.value = feeRate.toString();
|
|
|
|
|
}
|
|
|
|
|
if (sumFeeAmountEl) sumFeeAmountEl.textContent = formatNumber(feeAmount);
|
|
|
|
|
if (sumGrandAmountEl) sumGrandAmountEl.textContent = formatNumber(grandAmount);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const setActiveRow = (code) => {
|
|
|
|
|
activeCode = code || null;
|
|
|
|
|
selectedBody.querySelectorAll('tr[data-item-row]').forEach((row) => {
|
|
|
|
|
row.classList.toggle('bg-amber-50', row.dataset.code === activeCode);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const renderSelectedRows = () => {
|
|
|
|
|
const codes = Object.keys(bagMeta).filter((code) => selectedItems.has(code));
|
|
|
|
|
if (codes.length === 0) {
|
|
|
|
|
selectedBody.innerHTML = `<tr><td colspan="${colEmpty}" class="text-center text-gray-400 py-4">아래 "발주 등록 종류"에서 봉투를 선택해 주세요.</td></tr>`;
|
|
|
|
|
setActiveRow(null);
|
|
|
|
|
updateTotals();
|
|
|
|
|
updateReferenceSelectionUi();
|
|
|
|
|
applyModeLock();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
selectedBody.innerHTML = codes.map((code, idx) => {
|
|
|
|
|
const meta = bagMeta[code];
|
|
|
|
|
const qtyBox = Math.max(0, parseInt(String(selectedItems.get(code)?.qtyBox ?? 0), 10));
|
|
|
|
|
const name = meta?.name || code;
|
|
|
|
|
const up = Number(meta.orderPrice || 0);
|
|
|
|
|
const priceCell = editMode && changeMode === 'price'
|
|
|
|
|
? `<td class="text-right pr-1"><input type="number" name="item_unit_price[]" step="0.01" min="0" class="item-unit-price-input border border-gray-300 rounded px-1 py-0.5 w-full text-sm text-right" value="${up}" /></td>`
|
|
|
|
|
: `<td class="text-right pr-2 item-unit-price">0</td>`;
|
|
|
|
|
const extraCols = editMode
|
|
|
|
|
? `<td class="text-right pr-2 item-sel-qty">0</td><td class="text-center text-[11px] item-lot-cell leading-tight text-gray-700">생성<br /><span class="font-mono">${escapeHtml(orderLotNo || '—')}</span></td>`
|
|
|
|
|
: '';
|
|
|
|
|
|
|
|
|
|
return `
|
|
|
|
|
<tr data-item-row data-code="${escapeHtml(code)}" class="cursor-pointer">
|
|
|
|
|
<td class="text-center">${idx + 1}</td>
|
|
|
|
|
<td class="text-center">
|
|
|
|
|
<button type="button" class="js-remove-selected text-xs text-red-600 hover:underline" data-code="${escapeHtml(code)}">해제</button>
|
|
|
|
|
</td>
|
|
|
|
|
<td class="text-left pl-2">
|
|
|
|
|
${escapeHtml(name)}
|
|
|
|
|
<input type="hidden" name="item_bag_code[]" value="${escapeHtml(code)}" />
|
|
|
|
|
</td>
|
|
|
|
|
<td>
|
|
|
|
|
<input name="item_qty_box[]" type="number" min="0" step="1" value="${qtyBox}" class="item-qty-box border border-gray-300 rounded px-2 py-1 text-sm w-full text-right leading-tight" />
|
|
|
|
|
<p class="text-[11px] text-gray-500 mt-1 item-sheet-help">낱장 0장</p>
|
|
|
|
|
</td>
|
|
|
|
|
${priceCell}
|
|
|
|
|
<td class="text-right pr-2 item-qty-sheet">0</td>
|
|
|
|
|
${extraCols}
|
|
|
|
|
<td class="text-right pr-2 item-amount">0</td>
|
|
|
|
|
</tr>
|
|
|
|
|
`;
|
|
|
|
|
}).join('');
|
|
|
|
|
|
|
|
|
|
if (!activeCode || !selectedItems.has(activeCode)) {
|
|
|
|
|
activeCode = codes[0];
|
|
|
|
|
}
|
|
|
|
|
setActiveRow(activeCode);
|
|
|
|
|
updateTotals();
|
|
|
|
|
updateReferenceSelectionUi();
|
|
|
|
|
applyModeLock();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const toggleSelection = (code) => {
|
|
|
|
|
if (!code || !bagMeta[code]) return;
|
|
|
|
|
if (selectedItems.has(code)) {
|
|
|
|
|
selectedItems.delete(code);
|
|
|
|
|
if (activeCode === code) activeCode = null;
|
|
|
|
|
} else {
|
|
|
|
|
selectedItems.set(code, { qtyBox: 0 });
|
|
|
|
|
activeCode = code;
|
|
|
|
|
}
|
|
|
|
|
renderSelectedRows();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
initialSelectedItems.forEach((item) => {
|
|
|
|
|
if (!item || !item.code || !bagMeta[item.code]) return;
|
|
|
|
|
selectedItems.set(item.code, { qtyBox: Math.max(0, parseInt(String(item.qtyBox ?? 0), 10)) });
|
|
|
|
|
activeCode = item.code;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
selectedBody.addEventListener('click', (event) => {
|
|
|
|
|
const removeButton = event.target.closest('.js-remove-selected');
|
|
|
|
|
if (removeButton) {
|
|
|
|
|
toggleSelection(removeButton.dataset.code || '');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const row = event.target.closest('tr[data-item-row]');
|
|
|
|
|
if (!row) return;
|
|
|
|
|
const code = row.dataset.code || '';
|
|
|
|
|
setActiveRow(code);
|
|
|
|
|
const qtyInput = row.querySelector('.item-qty-box');
|
|
|
|
|
if (qtyInput) qtyInput.focus();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
selectedBody.addEventListener('input', (event) => {
|
|
|
|
|
const qtyInput = event.target.closest('.item-qty-box');
|
|
|
|
|
const priceField = event.target.closest('.item-unit-price-input');
|
|
|
|
|
if (qtyInput) {
|
|
|
|
|
const row = qtyInput.closest('tr[data-item-row]');
|
|
|
|
|
if (!row) return;
|
|
|
|
|
const code = row.dataset.code || '';
|
|
|
|
|
selectedItems.set(code, { qtyBox: Math.max(0, parseInt(qtyInput.value || '0', 10)) });
|
|
|
|
|
updateTotals();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (priceField) {
|
|
|
|
|
updateTotals();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
referenceRows.forEach((row) => {
|
|
|
|
|
row.addEventListener('click', (event) => {
|
|
|
|
|
const button = event.target.closest('.js-toggle-bag');
|
|
|
|
|
if (button) {
|
|
|
|
|
toggleSelection(button.dataset.code || '');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (event.target.closest('td')) {
|
|
|
|
|
toggleSelection(row.dataset.code || '');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (monthInput) monthInput.addEventListener('change', () => { syncDateFromMonth(); updateTotals(); });
|
|
|
|
|
if (orderDateInput) orderDateInput.addEventListener('change', syncMonthFromDate);
|
|
|
|
|
if (feeRateSummaryInput) {
|
|
|
|
|
feeRateSummaryInput.addEventListener('input', () => {
|
|
|
|
|
updateTotals();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (orderForm) {
|
|
|
|
|
orderForm.addEventListener('submit', (event) => {
|
|
|
|
|
const hasValidItem = Array.from(selectedBody.querySelectorAll('tr[data-item-row]')).some((row) => {
|
|
|
|
|
const qtyInput = row.querySelector('.item-qty-box');
|
|
|
|
|
return Math.max(0, parseInt(qtyInput?.value || '0', 10)) > 0;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!hasValidItem) {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
alert('봉투를 선택하고 수량을 1 이상 입력해 주세요.');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
syncMonthFromDate();
|
|
|
|
|
updateMonthKoLabel();
|
|
|
|
|
renderSelectedRows();
|
|
|
|
|
|
|
|
|
|
if (editMode) {
|
|
|
|
|
document.querySelectorAll('input[name="bo_change_mode"]').forEach((r) => {
|
|
|
|
|
r.addEventListener('change', () => {
|
|
|
|
|
const u = new URL(window.location.href);
|
|
|
|
|
u.searchParams.set('change_mode', r.value);
|
|
|
|
|
window.location.href = u.toString();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
})();
|
|
|
|
|
</script>
|
|
|
|
|
<?php endif; ?>
|