feat: '발주파일 생성'(구 LOT-No 디스켓 불출) 이름변경 + 생성 전 내용 확인
- 메뉴/화면/매뉴얼 명칭을 '발주파일 생성'으로 변경(메뉴 rename 마이그레이션 SQL 포함) - 발주파일(seed) 생성 전 '내용 확인' 미리보기 추가(암호화 전 발주 메타·품목 표시) · GET bag/order/lot-seed/preview 신설, 생성/미리보기 데이터 구성 공용화 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,7 @@ class Manual extends BaseConfig
|
|||||||
*/
|
*/
|
||||||
public array $screenHelp = [
|
public array $screenHelp = [
|
||||||
'bag/order/phone' => 'sales#전화 주문 접수',
|
'bag/order/phone' => 'sales#전화 주문 접수',
|
||||||
'bag/order/lot-seed' => 'order#LOT-No 디스켓 불출',
|
'bag/order/lot-seed' => 'order#발주파일 생성',
|
||||||
'bag/order' => 'order#발주 등록',
|
'bag/order' => 'order#발주 등록',
|
||||||
'bag/password-change' => 'account#비밀번호 변경',
|
'bag/password-change' => 'account#비밀번호 변경',
|
||||||
'bag/bag-orders' => 'order#발주 현황',
|
'bag/bag-orders' => 'order#발주 현황',
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ $routes->get('bag/order/phone/receipt/(:num)', 'Bag::phoneOrderReceipt/$1');
|
|||||||
$routes->get('bag/order/change', 'Bag::orderChange');
|
$routes->get('bag/order/change', 'Bag::orderChange');
|
||||||
$routes->get('bag/order/revise/(:num)', 'Bag::orderRevise/$1');
|
$routes->get('bag/order/revise/(:num)', 'Bag::orderRevise/$1');
|
||||||
$routes->get('bag/order/lot-seed', 'Bag::orderLotSeed');
|
$routes->get('bag/order/lot-seed', 'Bag::orderLotSeed');
|
||||||
|
$routes->get('bag/order/lot-seed/preview', 'Bag::orderLotSeedPreview');
|
||||||
$routes->post('bag/order/lot-seed/generate', 'Bag::orderLotSeedGenerate');
|
$routes->post('bag/order/lot-seed/generate', 'Bag::orderLotSeedGenerate');
|
||||||
$routes->post('bag/order/store', 'Bag::orderStore');
|
$routes->post('bag/order/store', 'Bag::orderStore');
|
||||||
$routes->post('bag/order/cancel/(:num)', 'Bag::orderCancel/$1');
|
$routes->post('bag/order/cancel/(:num)', 'Bag::orderCancel/$1');
|
||||||
|
|||||||
@@ -3953,7 +3953,7 @@ SQL);
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LOT-No 디스켓 불출: 발주 건을 선택해 암호화 seed 파일 생성/다운로드.
|
* 발주파일 생성(구 'LOT-No 디스켓 불출'): 발주 건을 선택해 암호화 seed 파일 생성/다운로드.
|
||||||
*/
|
*/
|
||||||
public function orderLotSeed(): string|RedirectResponse
|
public function orderLotSeed(): string|RedirectResponse
|
||||||
{
|
{
|
||||||
@@ -4031,7 +4031,7 @@ SQL);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('LOT-No 디스켓 불출', 'bag/order_lot_seed', [
|
return $this->render('발주파일 생성', 'bag/order_lot_seed', [
|
||||||
'orders' => $orders,
|
'orders' => $orders,
|
||||||
'pager' => $pager,
|
'pager' => $pager,
|
||||||
'startMonth' => $startMonth,
|
'startMonth' => $startMonth,
|
||||||
@@ -4044,17 +4044,16 @@ SQL);
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function orderLotSeedGenerate(): RedirectResponse|ResponseInterface
|
/**
|
||||||
|
* 발주파일(seed) 생성·미리보기가 공용으로 쓰는 데이터 구성.
|
||||||
|
* 발주 메타(order_data)와 품목(items, 팩/박스 환산 포함), 무결성 해시를 만든다.
|
||||||
|
*
|
||||||
|
* @return array{ok: bool, error?: string, order?: object, order_data?: array<string,mixed>, items?: array<int,array<string,mixed>>, lot_no?: string, uuid?: string, version?: int, order_hash?: string}
|
||||||
|
*/
|
||||||
|
private function buildLotSeedData(int $lgIdx, int $boIdx): array
|
||||||
{
|
{
|
||||||
helper('admin');
|
|
||||||
$lgIdx = $this->lgIdx();
|
|
||||||
if (! $lgIdx) {
|
|
||||||
return redirect()->to(site_url('bag/purchase-inbound'))->with('error', '지자체를 선택해 주세요.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$boIdx = (int) ($this->request->getPost('bo_idx') ?? 0);
|
|
||||||
if ($boIdx <= 0) {
|
if ($boIdx <= 0) {
|
||||||
return redirect()->back()->with('error', '발주 건을 선택해 주세요.');
|
return ['ok' => false, 'error' => '발주 건을 선택해 주세요.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$order = model(BagOrderModel::class)
|
$order = model(BagOrderModel::class)
|
||||||
@@ -4062,14 +4061,14 @@ SQL);
|
|||||||
->where('bo_idx', $boIdx)
|
->where('bo_idx', $boIdx)
|
||||||
->first();
|
->first();
|
||||||
if (! $order) {
|
if (! $order) {
|
||||||
return redirect()->back()->with('error', '발주 정보를 찾을 수 없습니다.');
|
return ['ok' => false, 'error' => '발주 정보를 찾을 수 없습니다.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$lotNo = trim((string) ($order->bo_lot_no ?? ''));
|
$lotNo = trim((string) ($order->bo_lot_no ?? ''));
|
||||||
$uuid = trim((string) ($order->bo_uuid ?? ''));
|
$uuid = trim((string) ($order->bo_uuid ?? ''));
|
||||||
$version = max(1, (int) ($order->bo_version ?? 1));
|
$version = max(1, (int) ($order->bo_version ?? 1));
|
||||||
if ($lotNo === '' || $uuid === '') {
|
if ($lotNo === '' || $uuid === '') {
|
||||||
return redirect()->back()->with('error', '발주의 LOT/UUID 정보가 없어 seed 파일을 생성할 수 없습니다.');
|
return ['ok' => false, 'error' => '발주의 LOT/UUID 정보가 없어 발주파일을 생성할 수 없습니다.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$items = model(BagOrderItemModel::class)
|
$items = model(BagOrderItemModel::class)
|
||||||
@@ -4077,7 +4076,7 @@ SQL);
|
|||||||
->orderBy('boi_idx', 'ASC')
|
->orderBy('boi_idx', 'ASC')
|
||||||
->findAll();
|
->findAll();
|
||||||
if ($items === []) {
|
if ($items === []) {
|
||||||
return redirect()->back()->with('error', '발주 품목이 없어 seed 파일을 생성할 수 없습니다.');
|
return ['ok' => false, 'error' => '발주 품목이 없어 발주파일을 생성할 수 없습니다.'];
|
||||||
}
|
}
|
||||||
|
|
||||||
$unitRows = model(PackagingUnitModel::class)
|
$unitRows = model(PackagingUnitModel::class)
|
||||||
@@ -4142,10 +4141,100 @@ SQL);
|
|||||||
$orderHash = hash('sha256', $payloadJson);
|
$orderHash = hash('sha256', $payloadJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
$seedPath = $this->generateLotSeedFile($uuid, $version, $lotNo, $orderData, $hashItems, $orderHash);
|
return [
|
||||||
|
'ok' => true,
|
||||||
|
'order' => $order,
|
||||||
|
'order_data' => $orderData,
|
||||||
|
'items' => $hashItems,
|
||||||
|
'lot_no' => $lotNo,
|
||||||
|
'uuid' => $uuid,
|
||||||
|
'version' => $version,
|
||||||
|
'order_hash' => $orderHash,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 발주파일 생성 전 '내용 확인'(미리보기): 암호화 전 평문 내용을 JSON 으로 반환.
|
||||||
|
*/
|
||||||
|
public function orderLotSeedPreview(): ResponseInterface
|
||||||
|
{
|
||||||
|
helper('admin');
|
||||||
|
$lgIdx = $this->lgIdx();
|
||||||
|
if (! $lgIdx) {
|
||||||
|
return $this->response->setJSON(['ok' => false, 'error' => '지자체를 선택해 주세요.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$boIdx = (int) ($this->request->getGet('bo_idx') ?? 0);
|
||||||
|
$data = $this->buildLotSeedData($lgIdx, $boIdx);
|
||||||
|
if (! ($data['ok'] ?? false)) {
|
||||||
|
return $this->response->setJSON(['ok' => false, 'error' => (string) ($data['error'] ?? '내용을 확인할 수 없습니다.')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$order = $data['order'];
|
||||||
|
$companyIdx = (int) ($order->bo_company_idx ?? 0);
|
||||||
|
$companyName = '';
|
||||||
|
if ($companyIdx > 0) {
|
||||||
|
$company = model(CompanyModel::class)
|
||||||
|
->where('cp_lg_idx', $lgIdx)
|
||||||
|
->where('cp_idx', $companyIdx)
|
||||||
|
->first();
|
||||||
|
$companyName = (string) ($company->cp_name ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$items = array_map(static fn (array $it): array => [
|
||||||
|
'bag_code' => (string) $it['boi_bag_code'],
|
||||||
|
'bag_name' => (string) $it['boi_bag_name'],
|
||||||
|
'unit_price' => (float) $it['boi_unit_price'],
|
||||||
|
'qty_box' => (int) $it['boi_qty_box'],
|
||||||
|
'qty_pack' => (int) $it['boi_qty_pack'],
|
||||||
|
'qty_sheet' => (int) $it['boi_qty_sheet'],
|
||||||
|
'amount' => (float) $it['boi_amount'],
|
||||||
|
], $data['items']);
|
||||||
|
|
||||||
|
return $this->response->setJSON([
|
||||||
|
'ok' => true,
|
||||||
|
'bo_idx' => $boIdx,
|
||||||
|
'lot_no' => $data['lot_no'],
|
||||||
|
'uuid' => $data['uuid'],
|
||||||
|
'version' => $data['version'],
|
||||||
|
'order_date' => (string) ($order->bo_order_date ?? ''),
|
||||||
|
'company' => $companyName,
|
||||||
|
'order_hash' => $data['order_hash'],
|
||||||
|
'items' => $items,
|
||||||
|
'totals' => [
|
||||||
|
'line_count' => count($items),
|
||||||
|
'qty_box' => array_sum(array_map(static fn ($i) => (int) $i['qty_box'], $items)),
|
||||||
|
'qty_sheet' => array_sum(array_map(static fn ($i) => (int) $i['qty_sheet'], $items)),
|
||||||
|
'amount' => array_sum(array_map(static fn ($i) => (float) $i['amount'], $items)),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function orderLotSeedGenerate(): RedirectResponse|ResponseInterface
|
||||||
|
{
|
||||||
|
helper('admin');
|
||||||
|
$lgIdx = $this->lgIdx();
|
||||||
|
if (! $lgIdx) {
|
||||||
|
return redirect()->to(site_url('bag/purchase-inbound'))->with('error', '지자체를 선택해 주세요.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$boIdx = (int) ($this->request->getPost('bo_idx') ?? 0);
|
||||||
|
$data = $this->buildLotSeedData($lgIdx, $boIdx);
|
||||||
|
if (! ($data['ok'] ?? false)) {
|
||||||
|
return redirect()->back()->with('error', (string) ($data['error'] ?? '발주파일을 생성할 수 없습니다.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$seedPath = $this->generateLotSeedFile(
|
||||||
|
$data['uuid'],
|
||||||
|
$data['version'],
|
||||||
|
$data['lot_no'],
|
||||||
|
$data['order_data'],
|
||||||
|
$data['items'],
|
||||||
|
$data['order_hash']
|
||||||
|
);
|
||||||
$seedBinary = @file_get_contents($seedPath);
|
$seedBinary = @file_get_contents($seedPath);
|
||||||
if (! is_string($seedBinary) || $seedBinary === '') {
|
if (! is_string($seedBinary) || $seedBinary === '') {
|
||||||
return redirect()->back()->with('error', 'seed 파일 생성에는 성공했으나 파일을 읽을 수 없습니다.');
|
return redirect()->back()->with('error', '발주파일 생성에는 성공했으나 파일을 읽을 수 없습니다.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->response
|
return $this->response
|
||||||
|
|||||||
@@ -67,14 +67,17 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## LOT-No 디스켓 불출 · *발주 입고 관리 › LOT-No 디스켓 불출*
|
## 발주파일 생성 · *발주 입고 관리 › 발주파일 생성*
|
||||||
|
|
||||||
발주별 **LOT 번호 시드(seed) 데이터를 파일로 생성**하는 화면입니다. (바코드·LOT 부여에 쓰는 디스켓/파일 형태 데이터)
|
선택한 발주 건의 내용을 **봉투 생산기(바코드 인쇄) 전달용 파일**로 만드는 화면입니다. (예전 이름: *LOT-No 디스켓 불출*) 생성되는 파일은 발주 정보와 품목이 담긴 **암호화된 발주파일**(`.seed.json`)이며, 봉투 생산 장비가 이 파일을 읽어 그 발주의 바코드를 인쇄합니다.
|
||||||
|
|
||||||
|
**LOT-No란?** 발주를 등록할 때 그 건에 자동 부여되는 **6자리 배치(묶음) 번호**입니다. 이후 그 발주로 인쇄되는 모든 봉투 바코드의 앞자리(예: `ZLCH2M-000006-…`)가 되어, 어느 발주에서 나온 봉투인지 구분하는 기준이 됩니다.
|
||||||
|
|
||||||
**필터**: 시작월 · 종료월 · LOT-No · 제작업체.
|
**필터**: 시작월 · 종료월 · LOT-No · 제작업체.
|
||||||
**순서**
|
**순서**
|
||||||
1. 기간·조건으로 발주 목록을 조회합니다.
|
1. 기간·조건으로 발주 목록을 조회합니다.
|
||||||
2. 해당 발주 행의 **`seed 생성`** 을 눌러 그 발주의 LOT 시드 파일을 만듭니다.
|
2. 대상 발주 행의 **`내용 확인`** 을 누르면, 파일에 담길 **발주 정보와 품목 목록(봉투코드·수량·금액 등)** 을 팝업으로 미리 볼 수 있습니다.
|
||||||
|
3. 내용을 확인한 뒤 **`발주파일 생성(다운로드)`** 을 누르면 암호화된 발주파일이 내려받아집니다.
|
||||||
|
|
||||||
**표 컬럼**: 발주일자 · LOT-No · 품명 · 수량 · 제작업체 · (생성 버튼).
|
**표 컬럼**: 발주일자 · LOT-No · 품명 · 수량 · 제작업체 · (내용 확인 버튼).
|
||||||
> 정상·취소 발주가 함께 조회되며, 시드 생성은 발주 단위로 동작합니다.
|
> 정상·취소 발주가 함께 조회되며, 파일 생성은 발주 단위로 동작합니다. 생성 전 **`내용 확인`** 단계에서 반드시 품목·수량을 검토하세요.
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ for ($year = $baseYear - 2; $year <= $baseYear + 2; $year++) {
|
|||||||
?>
|
?>
|
||||||
|
|
||||||
<section class="border-b border-gray-300 p-2 shrink-0 bg-control-panel">
|
<section class="border-b border-gray-300 p-2 shrink-0 bg-control-panel">
|
||||||
<span class="text-sm font-bold text-gray-700">LOT-No 디스켓 불출</span>
|
<span class="text-sm font-bold text-gray-700">발주파일 생성</span>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="border border-gray-300 rounded-lg p-2 mt-2 bg-white">
|
<section class="border border-gray-300 rounded-lg p-2 mt-2 bg-white">
|
||||||
@@ -92,11 +92,12 @@ for ($year = $baseYear - 2; $year <= $baseYear + 2; $year++) {
|
|||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<form method="post" action="<?= base_url('bag/order/lot-seed/generate') ?>" class="inline">
|
<button type="button"
|
||||||
<?= csrf_field() ?>
|
class="lot-preview-btn text-blue-600 hover:underline text-xs"
|
||||||
<input type="hidden" name="bo_idx" value="<?= $boIdx ?>" />
|
data-bo-idx="<?= $boIdx ?>"
|
||||||
<button type="submit" class="text-blue-600 hover:underline text-xs">seed 생성</button>
|
data-lot="<?= esc((string) ($order->bo_lot_no ?? ''), 'attr') ?>">
|
||||||
</form>
|
내용 확인
|
||||||
|
</button>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-center"><?= esc((string) ($order->bo_order_date ?? '')) ?></td>
|
<td class="text-center"><?= esc((string) ($order->bo_order_date ?? '')) ?></td>
|
||||||
<td class="text-center font-mono"><?= esc((string) ($order->bo_lot_no ?? '')) ?></td>
|
<td class="text-center font-mono"><?= esc((string) ($order->bo_lot_no ?? '')) ?></td>
|
||||||
@@ -128,3 +129,133 @@ for ($year = $baseYear - 2; $year <= $baseYear + 2; $year++) {
|
|||||||
<?php if (isset($pager)): ?>
|
<?php if (isset($pager)): ?>
|
||||||
<div class="mt-2 mb-2 no-print"><?= $pager->links() ?></div>
|
<div class="mt-2 mb-2 no-print"><?= $pager->links() ?></div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- 발주파일 생성 전 '내용 확인' 모달 -->
|
||||||
|
<div id="lot-preview-overlay" class="fixed inset-0 z-50 hidden items-center justify-center bg-black/40 p-4">
|
||||||
|
<div class="bg-white rounded-lg shadow-xl w-full max-w-3xl max-h-[85vh] flex flex-col">
|
||||||
|
<div class="flex items-center justify-between border-b border-gray-200 px-4 py-2">
|
||||||
|
<span class="text-sm font-bold text-gray-800">발주파일 내용 확인</span>
|
||||||
|
<button type="button" id="lot-preview-close" class="text-gray-400 hover:text-gray-700 text-lg leading-none">×</button>
|
||||||
|
</div>
|
||||||
|
<div class="p-4 overflow-auto text-sm">
|
||||||
|
<div id="lot-preview-loading" class="text-center text-gray-400 py-8">불러오는 중…</div>
|
||||||
|
<div id="lot-preview-error" class="hidden text-center text-red-600 py-8"></div>
|
||||||
|
<div id="lot-preview-body" class="hidden">
|
||||||
|
<p class="text-xs text-gray-500 mb-2">아래 내용으로 <b>암호화된 발주파일(.seed.json)</b>이 생성·다운로드됩니다. 생성 전 내용을 확인하세요.</p>
|
||||||
|
<dl class="grid grid-cols-[6rem_1fr] gap-y-1 text-[13px] mb-3 border border-gray-200 rounded p-2 bg-gray-50">
|
||||||
|
<dt class="font-semibold text-gray-600">LOT-No</dt><dd class="font-mono" id="lp-lot"></dd>
|
||||||
|
<dt class="font-semibold text-gray-600">발주일</dt><dd id="lp-date"></dd>
|
||||||
|
<dt class="font-semibold text-gray-600">제작업체</dt><dd id="lp-company"></dd>
|
||||||
|
<dt class="font-semibold text-gray-600">버전</dt><dd id="lp-version"></dd>
|
||||||
|
<dt class="font-semibold text-gray-600">무결성해시</dt><dd class="font-mono text-[11px] text-gray-500 break-all" id="lp-hash"></dd>
|
||||||
|
</dl>
|
||||||
|
<div class="overflow-auto border border-gray-200 rounded">
|
||||||
|
<table class="w-full data-table text-[13px]">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-left pl-2">봉투코드</th>
|
||||||
|
<th class="text-left">봉투명</th>
|
||||||
|
<th class="w-20 text-right">단가</th>
|
||||||
|
<th class="w-16 text-right">박스</th>
|
||||||
|
<th class="w-16 text-right">팩</th>
|
||||||
|
<th class="w-20 text-right">낱장</th>
|
||||||
|
<th class="w-24 text-right pr-2">금액</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="lp-items"></tbody>
|
||||||
|
<tfoot>
|
||||||
|
<tr class="font-semibold bg-gray-50">
|
||||||
|
<td class="pl-2" colspan="3">합계 (<span id="lp-line-count">0</span>품목)</td>
|
||||||
|
<td class="text-right" id="lp-sum-box">0</td>
|
||||||
|
<td class="text-right">—</td>
|
||||||
|
<td class="text-right" id="lp-sum-sheet">0</td>
|
||||||
|
<td class="text-right pr-2" id="lp-sum-amount">0</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="border-t border-gray-200 px-4 py-2 flex items-center justify-end gap-2">
|
||||||
|
<button type="button" id="lot-preview-cancel" class="border border-gray-300 text-gray-600 px-3 py-1.5 rounded-sm text-sm hover:bg-gray-50">닫기</button>
|
||||||
|
<form method="post" action="<?= base_url('bag/order/lot-seed/generate') ?>" class="inline" id="lot-generate-form">
|
||||||
|
<?= csrf_field() ?>
|
||||||
|
<input type="hidden" name="bo_idx" id="lot-generate-bo-idx" value="" />
|
||||||
|
<button type="submit" id="lot-generate-submit" class="bg-btn-search text-white px-4 py-1.5 rounded-sm text-sm shadow hover:opacity-90 disabled:opacity-50" disabled>발주파일 생성(다운로드)</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var previewUrl = '<?= base_url('bag/order/lot-seed/preview') ?>';
|
||||||
|
var overlay = document.getElementById('lot-preview-overlay');
|
||||||
|
var elLoading = document.getElementById('lot-preview-loading');
|
||||||
|
var elError = document.getElementById('lot-preview-error');
|
||||||
|
var elBody = document.getElementById('lot-preview-body');
|
||||||
|
var elSubmit = document.getElementById('lot-generate-submit');
|
||||||
|
var elBoIdx = document.getElementById('lot-generate-bo-idx');
|
||||||
|
var nf = function (n) { return new Intl.NumberFormat('ko-KR').format(n || 0); };
|
||||||
|
var esc = function (s) { return String(s == null ? '' : s).replace(/[&<>]/g, function (c) { return ({ '&': '&', '<': '<', '>': '>' })[c]; }); };
|
||||||
|
|
||||||
|
function openModal() { overlay.classList.remove('hidden'); overlay.classList.add('flex'); }
|
||||||
|
function closeModal() { overlay.classList.add('hidden'); overlay.classList.remove('flex'); }
|
||||||
|
|
||||||
|
function showState(state) {
|
||||||
|
elLoading.classList.toggle('hidden', state !== 'loading');
|
||||||
|
elError.classList.toggle('hidden', state !== 'error');
|
||||||
|
elBody.classList.toggle('hidden', state !== 'body');
|
||||||
|
elSubmit.disabled = state !== 'body';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.querySelectorAll('.lot-preview-btn').forEach(function (btn) {
|
||||||
|
btn.addEventListener('click', function () {
|
||||||
|
var boIdx = btn.getAttribute('data-bo-idx');
|
||||||
|
elBoIdx.value = boIdx;
|
||||||
|
openModal();
|
||||||
|
showState('loading');
|
||||||
|
fetch(previewUrl + '?bo_idx=' + encodeURIComponent(boIdx), { credentials: 'same-origin' })
|
||||||
|
.then(function (r) { return r.json(); })
|
||||||
|
.then(function (d) {
|
||||||
|
if (!d || !d.ok) {
|
||||||
|
elError.textContent = (d && d.error) || '내용을 불러오지 못했습니다.';
|
||||||
|
showState('error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.getElementById('lp-lot').textContent = d.lot_no || '';
|
||||||
|
document.getElementById('lp-date').textContent = d.order_date || '';
|
||||||
|
document.getElementById('lp-company').textContent = d.company || '-';
|
||||||
|
document.getElementById('lp-version').textContent = 'v' + (d.version || 1);
|
||||||
|
document.getElementById('lp-hash').textContent = d.order_hash || '';
|
||||||
|
var rows = (d.items || []).map(function (it) {
|
||||||
|
return '<tr>'
|
||||||
|
+ '<td class="pl-2 font-mono">' + esc(it.bag_code) + '</td>'
|
||||||
|
+ '<td>' + esc(it.bag_name) + '</td>'
|
||||||
|
+ '<td class="text-right">' + nf(it.unit_price) + '</td>'
|
||||||
|
+ '<td class="text-right">' + nf(it.qty_box) + '</td>'
|
||||||
|
+ '<td class="text-right">' + nf(it.qty_pack) + '</td>'
|
||||||
|
+ '<td class="text-right">' + nf(it.qty_sheet) + '</td>'
|
||||||
|
+ '<td class="text-right pr-2">' + nf(it.amount) + '</td>'
|
||||||
|
+ '</tr>';
|
||||||
|
}).join('');
|
||||||
|
document.getElementById('lp-items').innerHTML = rows || '<tr><td colspan="7" class="text-center text-gray-400 py-4">품목이 없습니다.</td></tr>';
|
||||||
|
var t = d.totals || {};
|
||||||
|
document.getElementById('lp-line-count').textContent = nf(t.line_count);
|
||||||
|
document.getElementById('lp-sum-box').textContent = nf(t.qty_box);
|
||||||
|
document.getElementById('lp-sum-sheet').textContent = nf(t.qty_sheet);
|
||||||
|
document.getElementById('lp-sum-amount').textContent = nf(t.amount);
|
||||||
|
showState('body');
|
||||||
|
})
|
||||||
|
.catch(function () {
|
||||||
|
elError.textContent = '통신 오류가 발생했습니다.';
|
||||||
|
showState('error');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('lot-preview-close').addEventListener('click', closeModal);
|
||||||
|
document.getElementById('lot-preview-cancel').addEventListener('click', closeModal);
|
||||||
|
overlay.addEventListener('click', function (e) { if (e.target === overlay) closeModal(); });
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
-- LOT-No 디스켓 불출 소메뉴 링크 보정
|
-- 발주파일 생성(구 LOT-No 디스켓 불출) 소메뉴 링크 보정
|
||||||
-- 실행:
|
-- 실행:
|
||||||
-- mysql --default-character-set=utf8mb4 -u ... -p DBNAME < writable/database/menu_link_lot_seed_issue.sql
|
-- mysql --default-character-set=utf8mb4 -u ... -p DBNAME < writable/database/menu_link_lot_seed_issue.sql
|
||||||
|
|
||||||
@@ -8,4 +8,4 @@ SET CHARACTER_SET_CLIENT = utf8mb4;
|
|||||||
UPDATE `menu` m
|
UPDATE `menu` m
|
||||||
INNER JOIN `menu_type` t ON t.mt_idx = m.mt_idx AND t.mt_code = 'site'
|
INNER JOIN `menu_type` t ON t.mt_idx = m.mt_idx AND t.mt_code = 'site'
|
||||||
SET m.mm_link = 'bag/order/lot-seed'
|
SET m.mm_link = 'bag/order/lot-seed'
|
||||||
WHERE m.mm_name = 'LOT-No 디스켓 불출';
|
WHERE m.mm_name IN ('발주파일 생성', 'LOT-No 디스켓 불출');
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ SET m.mm_link = CASE m.mm_name
|
|||||||
WHEN '지정 판매소 현황' THEN 'bag/designated-shops/district-new-cancel'
|
WHEN '지정 판매소 현황' THEN 'bag/designated-shops/district-new-cancel'
|
||||||
WHEN '발주 등록' THEN 'bag/order/create'
|
WHEN '발주 등록' THEN 'bag/order/create'
|
||||||
WHEN '발주 변경' THEN 'bag/order/change'
|
WHEN '발주 변경' THEN 'bag/order/change'
|
||||||
WHEN 'LOT-No 디스켓 불출' THEN 'bag/order/lot-seed'
|
WHEN '발주파일 생성' THEN 'bag/order/lot-seed'
|
||||||
WHEN '발주 현황' THEN 'bag/bag-orders'
|
WHEN '발주 현황' THEN 'bag/bag-orders'
|
||||||
WHEN '발주 입고[스캐너]' THEN 'bag/receiving/create'
|
WHEN '발주 입고[스캐너]' THEN 'bag/receiving/create'
|
||||||
WHEN '입고 현황' THEN 'bag/bag-receivings'
|
WHEN '입고 현황' THEN 'bag/bag-receivings'
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ SELECT @mt_site, 1, t.mm_name,
|
|||||||
CASE t.mm_name
|
CASE t.mm_name
|
||||||
WHEN '발주 등록' THEN 'bag/order/create'
|
WHEN '발주 등록' THEN 'bag/order/create'
|
||||||
WHEN '발주 변경' THEN 'bag/order/change'
|
WHEN '발주 변경' THEN 'bag/order/change'
|
||||||
WHEN 'LOT-No 디스켓 불출' THEN 'bag/order/lot-seed'
|
WHEN '발주파일 생성' THEN 'bag/order/lot-seed'
|
||||||
WHEN '발주 현황' THEN 'bag/bag-orders'
|
WHEN '발주 현황' THEN 'bag/bag-orders'
|
||||||
WHEN '발주 입고[스캐너]' THEN 'bag/receiving/create'
|
WHEN '발주 입고[스캐너]' THEN 'bag/receiving/create'
|
||||||
WHEN '입고 현황' THEN 'bag/bag-receivings'
|
WHEN '입고 현황' THEN 'bag/bag-receivings'
|
||||||
@@ -93,7 +93,7 @@ SELECT @mt_site, 1, t.mm_name,
|
|||||||
FROM (
|
FROM (
|
||||||
SELECT 0 AS mm_num, '발주 등록' AS mm_name UNION ALL
|
SELECT 0 AS mm_num, '발주 등록' AS mm_name UNION ALL
|
||||||
SELECT 1, '발주 변경' UNION ALL
|
SELECT 1, '발주 변경' UNION ALL
|
||||||
SELECT 2, 'LOT-No 디스켓 불출' UNION ALL
|
SELECT 2, '발주파일 생성' UNION ALL
|
||||||
SELECT 3, '발주 현황' UNION ALL
|
SELECT 3, '발주 현황' UNION ALL
|
||||||
SELECT 4, '발주 입고[스캐너]' UNION ALL
|
SELECT 4, '발주 입고[스캐너]' UNION ALL
|
||||||
SELECT 5, '일괄입고' UNION ALL
|
SELECT 5, '일괄입고' UNION ALL
|
||||||
|
|||||||
13
writable/database/rename_lot_seed_menu_to_order_file.sql
Normal file
13
writable/database/rename_lot_seed_menu_to_order_file.sql
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
-- 메뉴명 변경: 'LOT-No 디스켓 불출' → '발주파일 생성'
|
||||||
|
-- 링크(mm_link='bag/order/lot-seed') 기준으로, 기본 이름을 쓰는 항목만 안전하게 변경한다.
|
||||||
|
-- (지자체가 직접 다른 이름으로 바꿔 둔 항목은 건드리지 않음)
|
||||||
|
-- 실행:
|
||||||
|
-- mysql --default-character-set=utf8mb4 -u USER -p DBNAME < writable/database/rename_lot_seed_menu_to_order_file.sql
|
||||||
|
|
||||||
|
SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||||
|
SET CHARACTER_SET_CLIENT = utf8mb4;
|
||||||
|
|
||||||
|
UPDATE `menu`
|
||||||
|
SET `mm_name` = '발주파일 생성'
|
||||||
|
WHERE `mm_link` = 'bag/order/lot-seed'
|
||||||
|
AND `mm_name` = 'LOT-No 디스켓 불출';
|
||||||
Reference in New Issue
Block a user