153 lines
6.8 KiB
PHP
153 lines
6.8 KiB
PHP
<?php
|
|
/* =====================================================================
|
|
* /lib/customer_open_status.php
|
|
* "지금 이 고객이 오픈인가?" 판정 — 라이브러리 + 엔드포인트 겸용
|
|
*
|
|
* [라이브러리로 쓸 때] 다른 파일에서 include/require 하면 함수만 제공됨
|
|
* require_once getenv("DOCUMENT_ROOT")."/lib/customer_open_status.php";
|
|
* $st = customerIsOpenNow($c_uid); // 단일
|
|
* $map = customersOpenStatus([13013,13014]); // 배치
|
|
* (호출 전에 dbCon.php(qry/fetch_array) 가 로드돼 있어야 함)
|
|
*
|
|
* [엔드포인트로 쓸 때] 이 파일을 직접 호출하면 JSON 반환
|
|
* POST/GET ids=13013,13014,... → { "closed":[...], "detail":{...} }
|
|
*
|
|
* 판정 규칙:
|
|
* · c_time_restricted != 'Y' → open=true (경고 없음)
|
|
* · tbl_customer_accesstime 데이터 없음 → open=true (항상 열림)
|
|
* · 오늘이 휴무(closing day) → open=false (closing_day)
|
|
* · 오늘 요일에 창이 하나도 없음 → open=false (day_off)
|
|
* · 현재 시각이 어떤 창(open~close)에 포함 → open=true (close=NULL 이면 오픈엔드)
|
|
* · 그 외 → open=false (outside_hours)
|
|
* ===================================================================== */
|
|
|
|
if (!function_exists('customersOpenStatus')) {
|
|
|
|
function customersOpenStatus($ids, $now = null) {
|
|
$ids = array_values(array_unique(array_filter(
|
|
array_map('intval', (array)$ids),
|
|
function ($x) { return $x > 0; })));
|
|
$out = [];
|
|
if (empty($ids)) return $out;
|
|
|
|
if ($now === null) $now = time();
|
|
$dow = (int)date('w', $now); // 0=Sun .. 6=Sat
|
|
$today = date('Y-m-d', $now);
|
|
$hm = date('H:i:s', $now);
|
|
$inList = implode(',', $ids);
|
|
|
|
// 기본값: 제한 없음(열림)
|
|
foreach ($ids as $id) {
|
|
$out[$id] = ['restricted' => false, 'open' => true, 'reason' => 'no_restriction'];
|
|
}
|
|
|
|
// c_time_restricted='Y' 인 고객만 대상 (1차 게이트)
|
|
$restrictedFlag = [];
|
|
$r = qry("SELECT c_uid AS id FROM tbl_customer
|
|
WHERE c_uid IN ($inList) AND c_time_restricted = 'Y'");
|
|
while ($row = fetch_array($r)) { $restrictedFlag[(int)$row['id']] = true; }
|
|
|
|
// 액세스타임 사용 여부
|
|
$usesAT = [];
|
|
$r = qry("SELECT DISTINCT ca_customer_uid AS id
|
|
FROM tbl_customer_accesstime
|
|
WHERE ca_customer_uid IN ($inList) AND ca_status = 'A'");
|
|
while ($row = fetch_array($r)) { $usesAT[(int)$row['id']] = true; }
|
|
|
|
// 오늘 휴무인 고객
|
|
$closedToday = [];
|
|
$r = qry("SELECT DISTINCT ccd_customer_uid AS id
|
|
FROM tbl_customer_closing_days
|
|
WHERE ccd_customer_uid IN ($inList)
|
|
AND '$today' BETWEEN ccd_start_date AND ccd_end_date");
|
|
while ($row = fetch_array($r)) { $closedToday[(int)$row['id']] = true; }
|
|
|
|
// 오늘 요일의 창
|
|
$windows = []; // id => [ [open, close], ... ]
|
|
$r = qry("SELECT ca_customer_uid AS id, ca_open_time AS o, ca_close_time AS c
|
|
FROM tbl_customer_accesstime
|
|
WHERE ca_customer_uid IN ($inList) AND ca_status = 'A' AND ca_day_of_week = $dow");
|
|
while ($row = fetch_array($r)) { $windows[(int)$row['id']][] = [$row['o'], $row['c']]; }
|
|
|
|
foreach ($ids as $id) {
|
|
// (1) c_time_restricted='Y' 아니면 신경 안 씀 → 항상 열림
|
|
if (empty($restrictedFlag[$id])) {
|
|
$out[$id] = ['restricted' => false, 'open' => true, 'reason' => 'not_restricted'];
|
|
continue;
|
|
}
|
|
// (2) 액세스타임 데이터가 없으면 항상 열림
|
|
if (empty($usesAT[$id])) {
|
|
$out[$id] = ['restricted' => false, 'open' => true, 'reason' => 'no_accesstime'];
|
|
continue;
|
|
}
|
|
// 오늘 휴무
|
|
if (!empty($closedToday[$id])) {
|
|
$out[$id] = ['restricted' => true, 'open' => false, 'reason' => 'closing_day'];
|
|
continue;
|
|
}
|
|
// 오늘 요일 창 없음 → 휴무
|
|
$wins = isset($windows[$id]) ? $windows[$id] : [];
|
|
if (empty($wins)) {
|
|
$out[$id] = ['restricted' => true, 'open' => false, 'reason' => 'day_off'];
|
|
continue;
|
|
}
|
|
$open = false;
|
|
$nextOpen = null; // 오늘 아직 안 열린(현재보다 늦은) 창의 오픈시간 중 가장 이른 것
|
|
foreach ($wins as $w) {
|
|
$o = $w[0]; $c = $w[1];
|
|
if ($o === null || $o === '') continue;
|
|
if ($c === null || $c === '') { // 오픈엔드
|
|
if ($hm >= $o) { $open = true; }
|
|
} else {
|
|
if ($hm >= $o && $hm <= $c) { $open = true; }
|
|
}
|
|
if ($o > $hm) { // 오늘 이따 여는 창
|
|
if ($nextOpen === null || $o < $nextOpen) $nextOpen = $o;
|
|
}
|
|
}
|
|
$entry = ['restricted' => true, 'open' => $open, 'reason' => ($open ? '' : 'outside_hours')];
|
|
if (!$open && $nextOpen !== null) {
|
|
$entry['next_open'] = substr($nextOpen, 0, 5); // 'HH:MM'
|
|
$secs = strtotime("$today $nextOpen") - $now;
|
|
$entry['minutes_until_open'] = max(0, (int)round($secs / 60));
|
|
}
|
|
$out[$id] = $entry;
|
|
}
|
|
|
|
return $out;
|
|
}
|
|
|
|
// 단일 고객
|
|
function customerIsOpenNow($id, $now = null) {
|
|
$r = customersOpenStatus([$id], $now);
|
|
$id = intval($id);
|
|
return isset($r[$id]) ? $r[$id]
|
|
: ['restricted' => false, 'open' => true, 'reason' => 'no_restriction'];
|
|
}
|
|
}
|
|
|
|
/* ---------------------------------------------------------------------
|
|
* 이 파일을 "직접 호출"했을 때만 엔드포인트로 동작.
|
|
* (다른 파일에서 include/require 될 땐 위 함수만 제공하고 여기는 건너뜀)
|
|
* ------------------------------------------------------------------- */
|
|
$__self = basename(__FILE__);
|
|
$__script = isset($_SERVER['SCRIPT_FILENAME']) ? basename($_SERVER['SCRIPT_FILENAME']) : '';
|
|
if ($__script === $__self) {
|
|
|
|
include getenv("DOCUMENT_ROOT")."/include/session_include.php";
|
|
require_once getenv("DOCUMENT_ROOT")."/assets/dbCon.php";
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
$idsRaw = isset($_POST['ids']) ? $_POST['ids'] : (isset($_GET['ids']) ? $_GET['ids'] : '');
|
|
$ids = is_array($idsRaw) ? $idsRaw : array_filter(explode(',', (string)$idsRaw), 'strlen');
|
|
|
|
$detail = customersOpenStatus($ids);
|
|
|
|
$closed = [];
|
|
foreach ($detail as $id => $st) {
|
|
if (!empty($st['restricted']) && empty($st['open'])) $closed[] = $id;
|
|
}
|
|
|
|
echo json_encode(['closed' => $closed, 'detail' => $detail]);
|
|
} |