- [FORECAST] 체크박스 선택시 open 여부 확인.
This commit is contained in:
Hyojin Ahn 2026-07-14 11:54:25 -04:00
parent 420113b642
commit bc06775246
2 changed files with 68 additions and 8 deletions

View File

@ -12,6 +12,14 @@ if($orderdate == "") {
$func -> modalMsg ($msg, "/index_intranet.php?view=forecast"); $func -> modalMsg ($msg, "/index_intranet.php?view=forecast");
exit(); exit();
} }
// 선택 날짜에 휴무인 가게 경고용 (오픈여부 판정 라이브러리 재사용)
// $orderdate 는 아래에서 str_replace 로 'YYYYMMDD' 로 변형되므로 원본 'YYYY-MM-DD' 를 먼저 보관
$orderdateForCheck = $orderdate;
require_once getenv("DOCUMENT_ROOT")."/assets/dbCon.php";
// dbCon 이 전역 mysqli 리포트 모드를 STRICT 로 바꾸므로, 이후 $jdb 쿼리에 영향 없도록 legacy(OFF)로 원복
if (function_exists('mysqli_report')) { mysqli_report(MYSQLI_REPORT_OFF); }
require_once getenv("DOCUMENT_ROOT")."/lib/customer_open_status.php";
// Forecast 기능 제한 (Admin : 1, Staff : 5, Driver : 9 만 가능) // Forecast 기능 제한 (Admin : 1, Staff : 5, Driver : 9 만 가능)
$permit = array("1", "5", "9"); $permit = array("1", "5", "9");
@ -389,6 +397,20 @@ if ($customer_uids) {
} }
} }
// === 선택 날짜(orderdate)에 휴무인 가게 판정 (일반/Request/Scheduled 전체 uid 대상) ===
// $closedSet[c_uid] = 'closing_day' | 'day_off' (닫힌 가게만 등록)
$closedSet = [];
$__allUids = array_values(array_unique(array_merge(
(array)$customer_uids, (array)$uids_R, (array)$uids_P)));
if (!empty($__allUids)) {
$__closeStat = customersOpenStatus($__allUids, strtotime($orderdateForCheck), true);
foreach ($__closeStat as $__cid => $__st) {
if (!empty($__st['restricted']) && empty($__st['open'])) {
$closedSet[(int)$__cid] = $__st['reason'];
}
}
}
$totalrowcnt = 1; $totalrowcnt = 1;
$list_number = 1; $list_number = 1;
@ -476,7 +498,7 @@ foreach ($rows as $list) {
} }
$strList .= " $strList .= "
<tr class='$classSTR' data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name> <tr class='$classSTR'".(isset($closedSet[$c_uid]) ? " data-closed=\"1\" data-closed-reason=\"".$closedSet[$c_uid]."\"" : "")." data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name>
<td> <td>
<label class='container-chk'> <label class='container-chk'>
<!--input type='checkbox' checked='checked'--> <!--input type='checkbox' checked='checked'-->
@ -660,7 +682,7 @@ if ($c_type_r == 'R') {
$driverPopup = "<a data-toggle='modal' class='customerShortInfo' data-target='#myModalcustomerShortInfo' data-id=\"$c_uid\" data-history-type='standard-access'>&#10067;</a>"; $driverPopup = "<a data-toggle='modal' class='customerShortInfo' data-target='#myModalcustomerShortInfo' data-id=\"$c_uid\" data-history-type='standard-access'>&#10067;</a>";
$strList_r .= " $strList_r .= "
<tr class='bg-request' data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name> <tr class='bg-request'".(isset($closedSet[$c_uid]) ? " data-closed=\"1\" data-closed-reason=\"".$closedSet[$c_uid]."\"" : "")." data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name>
<td> <td>
<label class='container-chk'> <label class='container-chk'>
<!--input type='checkbox' checked='checked'--> <!--input type='checkbox' checked='checked'-->
@ -800,7 +822,7 @@ if ($c_type_p == 'P') {
$driverPopup = "<a data-toggle='modal' class='customerShortInfo' data-target='#myModalcustomerShortInfo' data-id=\"$c_uid\" data-history-type='standard-access'>&#10067;</a>"; $driverPopup = "<a data-toggle='modal' class='customerShortInfo' data-target='#myModalcustomerShortInfo' data-id=\"$c_uid\" data-history-type='standard-access'>&#10067;</a>";
$strList_s .= " $strList_s .= "
<tr class='bg-period' data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name> <tr class='bg-period'".(isset($closedSet[$c_uid]) ? " data-closed=\"1\" data-closed-reason=\"".$closedSet[$c_uid]."\"" : "")." data-id=\"$c_uid\" data-name=\"".htmlspecialchars($c_nameSTR, ENT_QUOTES)."\" data-name>
<td> <td>
<label class='container-chk'> <label class='container-chk'>
<!--input type='checkbox' checked='checked'--> <!--input type='checkbox' checked='checked'-->
@ -837,8 +859,13 @@ if ($c_type_p == 'P') {
addLog ("add", "FORECAST LIST", "VIEW", $lguserid, $query, $lgno); addLog ("add", "FORECAST LIST", "VIEW", $lguserid, $query, $lgno);
// 상단 표시용: 지금 어떤 드라이버의 어느 날짜 오더장을 만드는 중인지 (m_initial + 날짜)
$driverInitialSTR = trim($rt_driver['m_initial']);
if ($driverInitialSTR == "") $driverInitialSTR = "#".$c_driveruid;
$orderdateDisp = $orderdateForCheck ? date("Y-m-d (D)", strtotime($orderdateForCheck)) : $orderdate;
?>
?>
<? include getenv("DOCUMENT_ROOT")."/include/message_js.php"; ?> <? include getenv("DOCUMENT_ROOT")."/include/message_js.php"; ?>
@ -926,6 +953,29 @@ $(document).ready(function(){
</script> </script>
<!-- 선택 날짜 휴무 경고용 독립 토스트 (Bootstrap 3/4/5 혼재 + #myModalPopup 중복 id 회피) -->
<div id="closedWarnToast" style="display:none; position:fixed; top:22%; left:50%; transform:translateX(-50%); z-index:20000; background:#F43700; color:#FFFFFF; font-size:22px; font-weight:bold; padding:16px 32px; border-radius:6px; box-shadow:0 6px 20px rgba(0,0,0,0.35); text-align:center; letter-spacing:0.5px; white-space:nowrap;"></div>
<script type="text/javascript">
// 선택 날짜에 휴무인 가게를 체크하면 경고 (개별 체크마다, 선택 자체는 유지)
// 이 페이지엔 Bootstrap 3/4/5 가 혼재하고 #myModalPopup id 가 AJAX 조각으로 중복 주입돼
// .modal() 이 화면에 안 뜨는 문제가 있어, 부트스트랩에 의존하지 않는 독립 토스트로 표시한다.
$(document).on('change', '.custom-checkbox', function () {
if (!this.checked) return;
var $tr = $(this).closest('tr');
if ($tr.attr('data-closed') !== '1') return;
var reason = $tr.attr('data-closed-reason');
var msg = (reason === 'closing_day') ? 'CLOSED (Holiday)' : 'CLOSED (Day off)';
var el = document.getElementById('closedWarnToast');
if (!el) return;
el.textContent = msg;
el.style.display = 'block';
clearTimeout(window.__closedWarnTimer);
window.__closedWarnTimer = setTimeout(function () { el.style.display = 'none'; }, 1800);
});
</script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function(){ $(document).ready(function(){
@ -1049,6 +1099,11 @@ $(document).ready(function(){
</form> </form>
<? } ?> <? } ?>
</div> </div>
<div style="text-align: center; font-weight: bold; font-size: 16px; flex: 1;">
<span style="color:#2A9B56;"><?=htmlspecialchars($driverInitialSTR)?></span>
&nbsp;/&nbsp;
<span style="color:#2A9B56;"><?=$orderdateDisp?></span>
</div>
<div style="text-align: right;"> <div style="text-align: right;">
<span class="box-will-call">Will Call</span> <span class="box-will-call">Will Call</span>
<span class="box-period">Scheduled</span> <span class="box-period">Scheduled</span>
@ -1328,7 +1383,7 @@ $(document).ready(function(){
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="modal fade" id="myModalPopup" tabindex="-1" role="dialog" aria-labelledby="myModalPopup" style="opacity: 0.5; padding-right: 0px !important;"> <div class="modal fade" id="myModalPopup" tabindex="-1" role="dialog" aria-labelledby="myModalPopup" style="padding-right: 0px !important;">
<div class="modal-dialog modal-dialog-centered modal-xl" role="document"> <div class="modal-dialog modal-dialog-centered modal-xl" role="document">
<div class="modal-content" style="background-color:#F43700 !important; max-width:240px; margin: 0 auto;"> <div class="modal-content" style="background-color:#F43700 !important; max-width:240px; margin: 0 auto;">
<div class="myModalPopup-body" style="text-align: center; border-radius: 5px; max-height:60px; font-size:18px; background-color:#F43700; color: #FFFFFF; font-weight: bold;padding:0.5em 1em; "> <div class="myModalPopup-body" style="text-align: center; border-radius: 5px; max-height:60px; font-size:18px; background-color:#F43700; color: #FFFFFF; font-weight: bold;padding:0.5em 1em; ">

View File

@ -23,7 +23,10 @@
if (!function_exists('customersOpenStatus')) { if (!function_exists('customersOpenStatus')) {
function customersOpenStatus($ids, $now = null) { function customersOpenStatus($ids, $now = null, $dateOnly = false) {
// $dateOnly=true 이면 시각(H:i:s) 비교를 건너뛰고 "그 날짜에 영업일인가"만 본다.
// → 닫힘 사유는 closing_day(휴무기간) / day_off(그 요일 영업창 없음) 만 발생.
// (미래 날짜의 하루단위 계획용. outside_hours 는 나오지 않음)
$ids = array_values(array_unique(array_filter( $ids = array_values(array_unique(array_filter(
array_map('intval', (array)$ids), array_map('intval', (array)$ids),
function ($x) { return $x > 0; }))); function ($x) { return $x > 0; })));
@ -96,6 +99,7 @@ if (!function_exists('customersOpenStatus')) {
foreach ($wins as $w) { foreach ($wins as $w) {
$o = $w[0]; $c = $w[1]; $o = $w[0]; $c = $w[1];
if ($o === null || $o === '') continue; if ($o === null || $o === '') continue;
if ($dateOnly) { $open = true; continue; } // 날짜 단위: 유효 창이 하나라도 있으면 영업일
if ($c === null || $c === '') { // 오픈엔드 if ($c === null || $c === '') { // 오픈엔드
if ($hm >= $o) { $open = true; } if ($hm >= $o) { $open = true; }
} else { } else {
@ -105,8 +109,9 @@ if (!function_exists('customersOpenStatus')) {
if ($nextOpen === null || $o < $nextOpen) $nextOpen = $o; if ($nextOpen === null || $o < $nextOpen) $nextOpen = $o;
} }
} }
$entry = ['restricted' => true, 'open' => $open, 'reason' => ($open ? '' : 'outside_hours')]; $entry = ['restricted' => true, 'open' => $open,
if (!$open && $nextOpen !== null) { 'reason' => ($open ? '' : ($dateOnly ? 'day_off' : 'outside_hours'))];
if (!$dateOnly && !$open && $nextOpen !== null) {
$entry['next_open'] = substr($nextOpen, 0, 5); // 'HH:MM' $entry['next_open'] = substr($nextOpen, 0, 5); // 'HH:MM'
$secs = strtotime("$today $nextOpen") - $now; $secs = strtotime("$today $nextOpen") - $now;
$entry['minutes_until_open'] = max(0, (int)round($secs / 60)); $entry['minutes_until_open'] = max(0, (int)round($secs / 60));