feat: 전화접수 관리 기간조회·지정판매소 정보 패널 + 날짜 입력 월 한글화
- 전화접수 관리: 접수일 기간 조회 필터, 선택 주문의 지정판매소 정보(코드·담당자·전화·주소) + 접수 품목 내역 표시, 상단 '전화 주문 접수' 버튼 제거 - 전 화면 날짜 입력(date/month 등)에 lang=ko 지정 → 달력 월을 한글(6월)로 표시 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -7022,12 +7022,26 @@ SQL;
|
|||||||
return redirect()->to(site_url('bag/sales'))->with('error', '지자체를 선택해 주세요.');
|
return redirect()->to(site_url('bag/sales'))->with('error', '지자체를 선택해 주세요.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 일자별·기간별 조회 (접수일 so_order_date 기준)
|
||||||
|
$startDate = trim((string) ($this->request->getGet('start_date') ?? ''));
|
||||||
|
$endDate = trim((string) ($this->request->getGet('end_date') ?? ''));
|
||||||
|
$isYmd = static fn (string $d): bool => preg_match('/^\d{4}-\d{2}-\d{2}$/', $d) === 1;
|
||||||
|
if ($isYmd($startDate) && $isYmd($endDate) && $startDate > $endDate) {
|
||||||
|
[$startDate, $endDate] = [$endDate, $startDate];
|
||||||
|
}
|
||||||
|
|
||||||
$db = \Config\Database::connect();
|
$db = \Config\Database::connect();
|
||||||
$orderModel = model(ShopOrderModel::class);
|
$orderModel = model(ShopOrderModel::class);
|
||||||
$builder = $orderModel->where('so_lg_idx', $lgIdx);
|
$builder = $orderModel->where('so_lg_idx', $lgIdx);
|
||||||
if ($db->fieldExists('so_channel', 'shop_order')) {
|
if ($db->fieldExists('so_channel', 'shop_order')) {
|
||||||
$builder->where('so_channel', 'phone');
|
$builder->where('so_channel', 'phone');
|
||||||
}
|
}
|
||||||
|
if ($isYmd($startDate)) {
|
||||||
|
$builder->where('so_order_date >=', $startDate);
|
||||||
|
}
|
||||||
|
if ($isYmd($endDate)) {
|
||||||
|
$builder->where('so_order_date <=', $endDate . ' 23:59:59');
|
||||||
|
}
|
||||||
$orders = $builder->orderBy('so_idx', 'DESC')->limit(200)->findAll();
|
$orders = $builder->orderBy('so_idx', 'DESC')->limit(200)->findAll();
|
||||||
|
|
||||||
$orderIds = array_values(array_map(static fn ($o): int => (int) ($o->so_idx ?? 0), $orders));
|
$orderIds = array_values(array_map(static fn ($o): int => (int) ($o->so_idx ?? 0), $orders));
|
||||||
@@ -7056,6 +7070,25 @@ SQL;
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 주문의 지정판매소 상세(코드·담당자·전화·주소) — 우측 '지정판매소 정보' 표시용
|
||||||
|
$shopMap = [];
|
||||||
|
$dsIdxs = array_values(array_unique(array_filter(array_map(static fn ($o): int => (int) ($o->so_ds_idx ?? 0), $orders), static fn ($v): bool => $v > 0)));
|
||||||
|
if ($dsIdxs !== [] && $db->tableExists('designated_shop')) {
|
||||||
|
$shopRows = $db->table('designated_shop')
|
||||||
|
->select('ds_idx, ds_shop_no, ds_name, ds_rep_name, ds_tel, ds_addr, ds_addr_detail')
|
||||||
|
->whereIn('ds_idx', $dsIdxs)
|
||||||
|
->get()->getResultArray();
|
||||||
|
foreach ($shopRows as $s) {
|
||||||
|
$shopMap[(int) $s['ds_idx']] = [
|
||||||
|
'shop_no' => (string) ($s['ds_shop_no'] ?? ''),
|
||||||
|
'name' => (string) ($s['ds_name'] ?? ''),
|
||||||
|
'rep_name' => (string) ($s['ds_rep_name'] ?? ''),
|
||||||
|
'tel' => (string) ($s['ds_tel'] ?? ''),
|
||||||
|
'addr' => trim((string) ($s['ds_addr'] ?? '') . ' ' . (string) ($s['ds_addr_detail'] ?? '')),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$itemsByOrder = [];
|
$itemsByOrder = [];
|
||||||
foreach ($itemRows as $item) {
|
foreach ($itemRows as $item) {
|
||||||
$orderId = (int) ($item->soi_so_idx ?? 0);
|
$orderId = (int) ($item->soi_so_idx ?? 0);
|
||||||
@@ -7079,9 +7112,16 @@ SQL;
|
|||||||
$payload = [];
|
$payload = [];
|
||||||
foreach ($orders as $order) {
|
foreach ($orders as $order) {
|
||||||
$id = (int) ($order->so_idx ?? 0);
|
$id = (int) ($order->so_idx ?? 0);
|
||||||
|
$dsIdx = (int) ($order->so_ds_idx ?? 0);
|
||||||
|
$shop = $shopMap[$dsIdx] ?? ['shop_no' => '', 'name' => '', 'rep_name' => '', 'tel' => '', 'addr' => ''];
|
||||||
$payload[] = [
|
$payload[] = [
|
||||||
'so_idx' => $id,
|
'so_idx' => $id,
|
||||||
|
'so_ds_idx' => $dsIdx,
|
||||||
'so_ds_name' => (string) ($order->so_ds_name ?? ''),
|
'so_ds_name' => (string) ($order->so_ds_name ?? ''),
|
||||||
|
'ds_shop_no' => $shop['shop_no'],
|
||||||
|
'ds_rep_name' => $shop['rep_name'],
|
||||||
|
'ds_tel' => $shop['tel'],
|
||||||
|
'ds_addr' => $shop['addr'],
|
||||||
'so_order_date' => (string) ($order->so_order_date ?? ''),
|
'so_order_date' => (string) ($order->so_order_date ?? ''),
|
||||||
'so_delivery_date' => (string) ($order->so_delivery_date ?? ''),
|
'so_delivery_date' => (string) ($order->so_delivery_date ?? ''),
|
||||||
'so_payment_type' => (string) ($order->so_payment_type ?? ''),
|
'so_payment_type' => (string) ($order->so_payment_type ?? ''),
|
||||||
@@ -7094,6 +7134,8 @@ SQL;
|
|||||||
|
|
||||||
return $this->render('전화접수 관리', 'bag/order_phone_manage', [
|
return $this->render('전화접수 관리', 'bag/order_phone_manage', [
|
||||||
'orders' => $payload,
|
'orders' => $payload,
|
||||||
|
'startDate' => $isYmd($startDate) ? $startDate : '',
|
||||||
|
'endDate' => $isYmd($endDate) ? $endDate : '',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -190,6 +190,16 @@ tailwind.config = {
|
|||||||
window.addEventListener('storage', function (e) { if (e.key === FONT_KEY) applyScale(curScale()); });
|
window.addEventListener('storage', function (e) { if (e.key === FONT_KEY) applyScale(curScale()); });
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
// 네이티브 날짜 입력의 월 표기를 한글(예: 6월)로 — 요소 lang 지정(브라우저 영어 로케일 대응)
|
||||||
|
(function () {
|
||||||
|
function fixLang() {
|
||||||
|
document.querySelectorAll('input[type=date],input[type=month],input[type=datetime-local],input[type=week],input[type=time]')
|
||||||
|
.forEach(function (el) { el.setAttribute('lang', 'ko'); });
|
||||||
|
}
|
||||||
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fixLang); else fixLang();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
<?= view('components/feedback_widget') ?>
|
<?= view('components/feedback_widget') ?>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -218,6 +218,16 @@ tailwind.config = {
|
|||||||
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run, { once: true }); else run();
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', run, { once: true }); else run();
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
// 네이티브 날짜 입력의 월 표기를 한글(예: 6월)로 — 요소 lang 지정(브라우저 영어 로케일 대응)
|
||||||
|
(function () {
|
||||||
|
function fixLang() {
|
||||||
|
document.querySelectorAll('input[type=date],input[type=month],input[type=datetime-local],input[type=week],input[type=time]')
|
||||||
|
.forEach(function (el) { el.setAttribute('lang', 'ko'); });
|
||||||
|
}
|
||||||
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fixLang); else fixLang();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
<?= view('components/feedback_widget') ?>
|
<?= view('components/feedback_widget') ?>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -285,6 +285,16 @@ tailwind.config = {
|
|||||||
if (minus) minus.addEventListener('click', function () { applyScale(curScale() - 10); });
|
if (minus) minus.addEventListener('click', function () { applyScale(curScale() - 10); });
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
<script>
|
||||||
|
// 네이티브 날짜 입력의 월 표기를 한글(예: 6월)로 — 요소 lang 지정(브라우저 영어 로케일 대응)
|
||||||
|
(function () {
|
||||||
|
function fixLang() {
|
||||||
|
document.querySelectorAll('input[type=date],input[type=month],input[type=datetime-local],input[type=week],input[type=time]')
|
||||||
|
.forEach(function (el) { el.setAttribute('lang', 'ko'); });
|
||||||
|
}
|
||||||
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fixLang); else fixLang();
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
<?= view('components/feedback_widget') ?>
|
<?= view('components/feedback_widget') ?>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
|
<?php $startDate = (string) ($startDate ?? ''); $endDate = (string) ($endDate ?? ''); ?>
|
||||||
<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">
|
||||||
<div class="flex flex-wrap items-center justify-between gap-2">
|
<div class="flex flex-wrap items-center justify-between gap-2">
|
||||||
<span class="text-sm font-bold text-gray-700">전화 주문 접수 관리</span>
|
<span class="text-sm font-bold text-gray-700">전화 주문 접수 관리</span>
|
||||||
<a href="<?= base_url('bag/order/phone') ?>" class="bg-btn-search text-white px-4 py-1 rounded-sm text-sm shadow hover:opacity-90">전화 주문 접수</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
<form method="get" action="<?= base_url('bag/order/phone/manage') ?>" class="mt-2 flex flex-wrap items-center gap-2 text-sm">
|
||||||
|
<label class="font-bold text-gray-700">접수일</label>
|
||||||
|
<input type="date" lang="ko" name="start_date" value="<?= esc($startDate, 'attr') ?>" class="border border-gray-300 rounded px-2 py-1 text-sm"/>
|
||||||
|
<span class="text-gray-400">~</span>
|
||||||
|
<input type="date" lang="ko" name="end_date" value="<?= esc($endDate, 'attr') ?>" class="border border-gray-300 rounded px-2 py-1 text-sm"/>
|
||||||
|
<button type="submit" class="bg-btn-search text-white px-3 py-1 rounded-sm text-sm">조회</button>
|
||||||
|
<?php if ($startDate !== '' || $endDate !== ''): ?>
|
||||||
|
<a href="<?= base_url('bag/order/phone/manage') ?>" class="border border-gray-300 text-gray-600 px-3 py-1 rounded-sm text-sm hover:bg-gray-50">초기화</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 xl:grid-cols-5 gap-3 mt-2">
|
<div class="grid grid-cols-1 xl:grid-cols-5 gap-3 mt-2">
|
||||||
@@ -39,25 +49,28 @@
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="xl:col-span-3 border border-gray-300 rounded-lg bg-white overflow-hidden">
|
<section class="xl:col-span-3 border border-gray-300 rounded-lg bg-white overflow-hidden">
|
||||||
<div class="px-3 py-2 border-b border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700">상세 정보</div>
|
<div class="px-3 py-2 border-b border-gray-200 bg-gray-50 text-sm font-semibold text-gray-700">지정판매소 정보</div>
|
||||||
|
|
||||||
<form id="order-detail-form" action="<?= base_url('bag/order/phone/manage/update') ?>" method="POST" class="p-3 space-y-3">
|
<form id="order-detail-form" action="<?= base_url('bag/order/phone/manage/update') ?>" method="POST" class="p-3 space-y-3">
|
||||||
<?= csrf_field() ?>
|
<?= csrf_field() ?>
|
||||||
<input type="hidden" name="so_idx" id="detail-so-idx" value=""/>
|
<input type="hidden" name="so_idx" id="detail-so-idx" value=""/>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 text-sm">
|
<div class="border border-gray-200 rounded-lg p-3 bg-gray-50 text-sm">
|
||||||
<div class="border border-gray-200 rounded-lg p-2 bg-gray-50">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-1">
|
||||||
<div><span class="font-semibold text-gray-700">접수번호:</span> <span id="detail-so-no">-</span></div>
|
<div><span class="font-semibold text-gray-700 inline-block w-20">접수번호</span> <span id="detail-so-no">-</span></div>
|
||||||
<div><span class="font-semibold text-gray-700">판매소:</span> <span id="detail-shop-name">-</span></div>
|
<div><span class="font-semibold text-gray-700 inline-block w-20">판매소코드</span> <span id="detail-shop-code">-</span></div>
|
||||||
<div><span class="font-semibold text-gray-700">결제구분:</span> <span id="detail-payment">-</span></div>
|
<div><span class="font-semibold text-gray-700 inline-block w-20">판매소명</span> <span id="detail-shop-name">-</span></div>
|
||||||
</div>
|
<div><span class="font-semibold text-gray-700 inline-block w-20">담당자</span> <span id="detail-shop-rep">-</span></div>
|
||||||
<div class="border border-gray-200 rounded-lg p-2 bg-gray-50">
|
<div><span class="font-semibold text-gray-700 inline-block w-20">전화번호</span> <span id="detail-shop-tel">-</span></div>
|
||||||
<div><span class="font-semibold text-gray-700">접수일:</span> <span id="detail-order-date">-</span></div>
|
<div><span class="font-semibold text-gray-700 inline-block w-20">결제수단</span> <span id="detail-payment">-</span></div>
|
||||||
<div><span class="font-semibold text-gray-700">배달일:</span> <span id="detail-delivery-date">-</span></div>
|
<div class="md:col-span-2"><span class="font-semibold text-gray-700 inline-block w-20">주소</span> <span id="detail-shop-addr">-</span></div>
|
||||||
<div><span class="font-semibold text-gray-700">상태:</span> <span id="detail-status">-</span></div>
|
<div><span class="font-semibold text-gray-700 inline-block w-20">접수일</span> <span id="detail-order-date">-</span></div>
|
||||||
|
<div><span class="font-semibold text-gray-700 inline-block w-20">배달일</span> <span id="detail-delivery-date">-</span></div>
|
||||||
|
<div><span class="font-semibold text-gray-700 inline-block w-20">상태</span> <span id="detail-status">-</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="px-1 text-sm font-semibold text-gray-700">접수 품목 내역</div>
|
||||||
<div class="border border-gray-300 rounded-lg p-4 overflow-auto">
|
<div class="border border-gray-300 rounded-lg p-4 overflow-auto">
|
||||||
<table class="w-full data-table text-sm">
|
<table class="w-full data-table text-sm">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -114,12 +127,17 @@
|
|||||||
const nf = (n) => new Intl.NumberFormat('ko-KR').format(n || 0);
|
const nf = (n) => new Intl.NumberFormat('ko-KR').format(n || 0);
|
||||||
|
|
||||||
function setHeader(order) {
|
function setHeader(order) {
|
||||||
document.getElementById('detail-so-no').textContent = order ? String(order.so_idx || '-') : '-';
|
var t = function (id, v) { document.getElementById(id).textContent = (v === undefined || v === null || v === '') ? '-' : v; };
|
||||||
document.getElementById('detail-shop-name').textContent = order ? (order.so_ds_name || '-') : '-';
|
t('detail-so-no', order ? order.so_idx : '');
|
||||||
document.getElementById('detail-payment').textContent = order ? (order.so_payment_type || '-') : '-';
|
t('detail-shop-code', order ? order.ds_shop_no : '');
|
||||||
document.getElementById('detail-order-date').textContent = order ? (order.so_order_date || '-') : '-';
|
t('detail-shop-name', order ? order.so_ds_name : '');
|
||||||
document.getElementById('detail-delivery-date').textContent = order ? (order.so_delivery_date || '-') : '-';
|
t('detail-shop-rep', order ? order.ds_rep_name : '');
|
||||||
document.getElementById('detail-status').textContent = order ? ((order.so_status === 'cancelled') ? '취소' : '정상') : '-';
|
t('detail-shop-tel', order ? order.ds_tel : '');
|
||||||
|
t('detail-payment', order ? order.so_payment_type : '');
|
||||||
|
t('detail-shop-addr', order ? order.ds_addr : '');
|
||||||
|
t('detail-order-date', order ? order.so_order_date : '');
|
||||||
|
t('detail-delivery-date', order ? order.so_delivery_date : '');
|
||||||
|
t('detail-status', order ? ((order.so_status === 'cancelled') ? '취소' : '정상') : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function calcRow(tr) {
|
function calcRow(tr) {
|
||||||
|
|||||||
Reference in New Issue
Block a user