goiintra/public_html/lib/customer_open_status.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]);
}