1487 lines
45 KiB
PHP
1487 lines
45 KiB
PHP
<?php
|
|
|
|
require_once getenv("DOCUMENT_ROOT")."/assets/conf.inc.php";
|
|
require_once getenv("DOCUMENT_ROOT")."/assets/dbCon.php";
|
|
require_once getenv("DOCUMENT_ROOT")."/assets/api/customer.php";
|
|
|
|
class DailyService extends CONF {
|
|
|
|
public function saveDaily(array $data = [], array $opt = [])
|
|
{
|
|
$connect = $GLOBALS['conn'] ?? null;
|
|
if (!$connect) {
|
|
throw new Exception("DB connection not found");
|
|
}
|
|
|
|
$inTx = !empty($opt['in_tx']);
|
|
|
|
if (empty($data['d_orderdate']) || empty($data['d_accountno'])) {
|
|
throw new Exception("d_orderdate, d_accountno required");
|
|
}
|
|
|
|
// =========================
|
|
// KEY NORMALIZE
|
|
// =========================
|
|
$d_orderdate = preg_replace('/[^0-9]/', '', $data['d_orderdate']);
|
|
if (strlen($d_orderdate) !== 8) {
|
|
throw new Exception("invalid d_orderdate");
|
|
}
|
|
|
|
$d_accountno = mysqli_real_escape_string($connect, trim($data['d_accountno']));
|
|
if ($d_accountno === '') {
|
|
throw new Exception("invalid d_accountno");
|
|
}
|
|
|
|
$d_jobtype = mysqli_real_escape_string($connect, trim($data['d_jobtype']));
|
|
if ($d_jobtype === '') {
|
|
$d_jobtype = 'UCO';
|
|
}
|
|
|
|
$now14 = date('YmdHis');
|
|
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "START TRANSACTION");
|
|
}
|
|
|
|
try {
|
|
|
|
// =========================
|
|
// EXISTING LOAD (개선됨)
|
|
// =========================
|
|
|
|
$existing = null;
|
|
|
|
// 1. d_uid 우선 (가장 안전)
|
|
if (!empty($opt['match_uid'])) {
|
|
$uid = (int)$opt['match_uid'];
|
|
|
|
$res = mysqli_query($connect, "
|
|
SELECT *
|
|
FROM tbl_daily
|
|
WHERE d_uid = '{$uid}'
|
|
LIMIT 1
|
|
");
|
|
if (!$res) throw new Exception(mysqli_error($connect));
|
|
|
|
$existing = mysqli_fetch_assoc($res);
|
|
}
|
|
|
|
// 2. old_key fallback (key 변경 대응)
|
|
if (!$existing && !empty($opt['old_key'])) {
|
|
|
|
$oldDate = preg_replace('/[^0-9]/', '', $opt['old_key']['d_orderdate'] ?? '');
|
|
$oldAcc = mysqli_real_escape_string($connect, $opt['old_key']['d_accountno'] ?? '');
|
|
$oldJob = mysqli_real_escape_string($connect, $opt['old_key']['d_jobtype'] ?? '');
|
|
|
|
if ($oldDate && $oldAcc) {
|
|
$res = mysqli_query($connect, "
|
|
SELECT *
|
|
FROM tbl_daily
|
|
WHERE d_orderdate = '{$oldDate}'
|
|
AND d_accountno = '{$oldAcc}'
|
|
AND d_jobtype = '{$oldJob}'
|
|
LIMIT 1
|
|
");
|
|
if (!$res) throw new Exception(mysqli_error($connect));
|
|
|
|
$existing = mysqli_fetch_assoc($res);
|
|
}
|
|
}
|
|
|
|
// 3. 기본 key 매칭
|
|
if (!$existing) {
|
|
$res = mysqli_query($connect, "
|
|
SELECT *
|
|
FROM tbl_daily
|
|
WHERE d_orderdate = '{$d_orderdate}'
|
|
AND d_accountno = '{$d_accountno}'
|
|
AND d_jobtype = '{$d_jobtype}'
|
|
LIMIT 1
|
|
");
|
|
if (!$res) throw new Exception(mysqli_error($connect));
|
|
|
|
$existing = mysqli_fetch_assoc($res);
|
|
}
|
|
|
|
$isUpdate = (bool)$existing;
|
|
$beforeData = $existing ?: null;
|
|
|
|
// =========================
|
|
// DUPLICATE POLICY (중요)
|
|
// =========================
|
|
if ($isUpdate && empty($opt['allow_update'])) {
|
|
if (!$inTx) mysqli_query($connect, "ROLLBACK");
|
|
return null; // skip
|
|
}
|
|
|
|
// =========================
|
|
// normalize + snapshot
|
|
// =========================
|
|
$data = $this->normalizeDailyPayload($data, $existing ?: null);
|
|
$data = $this->hydrateDailySnapshot($data, $existing ?: null);
|
|
|
|
// estquantity 자동 계산 (입력때만 안그러면 d_estquantity 값이 0으로 덮어 씌워짐)
|
|
if (!$existing && empty($data['d_estquantity'])) {
|
|
$data['d_estquantity'] = $this->calculateEstQuantity($data, $existing);
|
|
}
|
|
|
|
// note 백업 (tbl_note 로 전달할 값)
|
|
$noteForUpsert = $data['d_note'] ?? '';
|
|
$pickupNoteForUpsert = $data['d_pickupnote'] ?? '';
|
|
$level = $data['d_level'] ?? 9;
|
|
|
|
// =========================
|
|
// 컬럼 필터링
|
|
// =========================
|
|
$allowed = $this->getDailyColumns();
|
|
$data = array_intersect_key($data, array_flip($allowed));
|
|
|
|
// =========================
|
|
// UPDATE
|
|
// =========================
|
|
if ($isUpdate) {
|
|
|
|
$setParts = [];
|
|
|
|
foreach ($data as $k => $v) {
|
|
// 업데이트 제외 컬럼
|
|
if (in_array($k, [
|
|
'd_orderdate',
|
|
'd_accountno',
|
|
'd_customeruid',
|
|
'd_jobtype',
|
|
'd_inputdate',
|
|
'd_estquantity',
|
|
'd_lastpickupdate',
|
|
'd_lastpickupquantity',
|
|
'd_lastpaiddate',
|
|
'd_ordertype',
|
|
'd_ruid',
|
|
'd_createruid',
|
|
'd_createddate'
|
|
], true)) continue;
|
|
if (!array_key_exists($k, $existing)) continue;
|
|
|
|
$setParts[] = "{$k}='" . mysqli_real_escape_string($connect, (string)$v) . "'";
|
|
}
|
|
|
|
$setParts[] = "d_modifydate='{$now14}'";
|
|
|
|
if (!empty($setParts)) {
|
|
|
|
// update는 무조건 d_uid 기준으로
|
|
$uid = (int)$existing['d_uid'];
|
|
|
|
$sql = "
|
|
UPDATE tbl_daily
|
|
SET " . implode(",", $setParts) . "
|
|
WHERE d_uid='{$uid}'
|
|
LIMIT 1
|
|
";
|
|
|
|
if (!mysqli_query($connect, $sql)) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
}
|
|
}
|
|
|
|
// =========================
|
|
// INSERT
|
|
// =========================
|
|
else {
|
|
|
|
$cols = [];
|
|
$vals = [];
|
|
|
|
foreach ($data as $k => $v) {
|
|
$cols[] = $k;
|
|
$vals[] = "'" . mysqli_real_escape_string($connect, (string)$v) . "'";
|
|
}
|
|
|
|
if (!in_array('d_modifydate', $cols)) {
|
|
$cols[] = 'd_modifydate';
|
|
$vals[] = "'{$now14}'";
|
|
}
|
|
|
|
$sql = "
|
|
INSERT INTO tbl_daily (" . implode(",", $cols) . ")
|
|
VALUES (" . implode(",", $vals) . ")
|
|
";
|
|
|
|
if (!mysqli_query($connect, $sql)) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
}
|
|
|
|
// =========================
|
|
// AFTER RELOAD (uid 기준)
|
|
// =========================
|
|
if ($isUpdate) {
|
|
$uid = (int)$existing['d_uid'];
|
|
$res = mysqli_query($connect, "
|
|
SELECT *
|
|
FROM tbl_daily
|
|
WHERE d_uid='{$uid}'
|
|
LIMIT 1
|
|
");
|
|
} else {
|
|
$res = mysqli_query($connect, "
|
|
SELECT *
|
|
FROM tbl_daily
|
|
WHERE d_orderdate='{$d_orderdate}'
|
|
AND d_accountno='{$d_accountno}'
|
|
AND d_jobtype = '{$d_jobtype}'
|
|
ORDER BY d_uid DESC
|
|
LIMIT 1
|
|
");
|
|
}
|
|
|
|
$afterData = mysqli_fetch_assoc($res);
|
|
// note
|
|
if ($noteForUpsert !== '') {
|
|
$afterData['d_note'] = $noteForUpsert;
|
|
$afterData['d_level'] = $level;
|
|
}
|
|
|
|
if ($pickupNoteForUpsert !== '') {
|
|
$afterData['d_pickupnote'] = $pickupNoteForUpsert;
|
|
$afterData['d_level'] = $level;
|
|
}
|
|
|
|
// =========================
|
|
// ERP OUTBOX
|
|
// =========================
|
|
$actionType = $isUpdate ? 'UPDATED' : 'CREATED';
|
|
$payload = mysqli_real_escape_string(
|
|
$connect,
|
|
json_encode([
|
|
'entity' => 'DAILY',
|
|
'action' => $actionType,
|
|
|
|
'key' => [
|
|
'd_orderdate' => $afterData['d_orderdate'],
|
|
'd_accountno' => $afterData['d_accountno'],
|
|
'd_jobtype' => $afterData['d_jobtype']
|
|
],
|
|
|
|
'before' => $beforeData,
|
|
'after' => $afterData
|
|
|
|
], JSON_UNESCAPED_UNICODE)
|
|
);
|
|
|
|
$qry_outbox = "
|
|
INSERT INTO tbl_erp_outbox
|
|
(
|
|
eo_entity_type,
|
|
eo_action_type,
|
|
eo_key1,
|
|
eo_key2,
|
|
eo_key3,
|
|
eo_payload,
|
|
eo_status,
|
|
eo_created_at
|
|
)
|
|
VALUES
|
|
(
|
|
'DAILY',
|
|
'{$actionType}',
|
|
'{$afterData['d_orderdate']}',
|
|
'{$afterData['d_accountno']}',
|
|
'{$afterData['d_jobtype']}',
|
|
'{$payload}',
|
|
'PENDING',
|
|
NOW()
|
|
)
|
|
";
|
|
|
|
if (!mysqli_query($connect, $qry_outbox)) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
// =========================
|
|
// AFTER WORK
|
|
// =========================
|
|
$this->runAfterSave($beforeData, $afterData, $opt);
|
|
|
|
// =========================
|
|
// COMMIT
|
|
// =========================
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "COMMIT");
|
|
}
|
|
|
|
return $afterData;
|
|
|
|
} catch (Exception $e) {
|
|
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "ROLLBACK");
|
|
}
|
|
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
private function isDuplicate($orderdate, $accountno, $jobtype): bool
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
|
|
$res = mysqli_query($connect, "
|
|
SELECT 1
|
|
FROM tbl_daily
|
|
WHERE d_orderdate='{$orderdate}'
|
|
AND d_accountno='{$accountno}'
|
|
AND d_jobtype = '{$jobtype}'
|
|
LIMIT 1
|
|
");
|
|
|
|
return (bool)mysqli_fetch_assoc($res);
|
|
}
|
|
|
|
private function normalizeDailyPayload(array $data, ?array $existing = null): array
|
|
{
|
|
// 날짜 정리
|
|
if (isset($data['d_orderdate'])) {
|
|
$data['d_orderdate'] = preg_replace('/[^0-9]/', '', $data['d_orderdate']);
|
|
}
|
|
|
|
if (isset($data['d_visitdate'])) {
|
|
$data['d_visitdate'] = preg_replace('/[^0-9]/', '', $data['d_visitdate']);
|
|
}
|
|
|
|
// 숫자 필드 기본값
|
|
$intFields = [
|
|
'd_quantity',
|
|
//'d_sludge' 주석처리-값이 비었을 때 0이 되지 않게
|
|
];
|
|
|
|
foreach ($intFields as $f) {
|
|
if (isset($data[$f])) {
|
|
$data[$f] = ($data[$f] === '' || $data[$f] === null)
|
|
? 0
|
|
: (int)$data[$f];
|
|
}
|
|
}
|
|
|
|
// 문자열 trim
|
|
$strFields = [
|
|
'd_pickupnote',
|
|
'd_note'
|
|
];
|
|
|
|
foreach ($strFields as $f) {
|
|
if (isset($data[$f])) {
|
|
$data[$f] = trim((string)$data[$f]);
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
private function hydrateDailySnapshot(array $data, ?array $existing = null): array
|
|
{
|
|
$connect = $GLOBALS['conn'] ?? null;
|
|
if (!$connect) {
|
|
throw new Exception("DB connection not found");
|
|
}
|
|
|
|
// =========================
|
|
// DRIVER SNAPSHOT
|
|
// =========================
|
|
$druid = isset($data['d_druid'])
|
|
? (int)$data['d_druid']
|
|
: (int)($existing['d_druid'] ?? 0);
|
|
|
|
// fallback: legacy member uid -> current driver uid
|
|
if ($druid <= 0) {
|
|
$driverUid = isset($data['d_driveruid'])
|
|
? (int)$data['d_driveruid']
|
|
: (int)($existing['d_driveruid'] ?? 0);
|
|
|
|
if ($driverUid > 0) {
|
|
$sqMap = qry("
|
|
SELECT
|
|
m.m_currentdriver AS dr_uid,
|
|
d.dr_initial
|
|
FROM tbl_member m
|
|
LEFT JOIN tbl_driver d
|
|
ON d.dr_uid = m.m_currentdriver
|
|
WHERE m.m_uid = '{$driverUid}'
|
|
LIMIT 1
|
|
");
|
|
$map = fetch_array($sqMap);
|
|
|
|
if ($map && (int)$map['dr_uid'] > 0) {
|
|
$druid = (int)$map['dr_uid'];
|
|
$data['d_druid'] = $druid;
|
|
$data['d_drinitial'] = $map['dr_initial'] ?? '';
|
|
}
|
|
}
|
|
}
|
|
|
|
// druid가 있으면 driver snapshot 확정
|
|
if ($druid > 0) {
|
|
$sqDriver = qry("
|
|
SELECT dr_initial
|
|
FROM tbl_driver
|
|
WHERE dr_uid = '{$druid}'
|
|
LIMIT 1
|
|
");
|
|
$driver = fetch_array($sqDriver);
|
|
|
|
if ($driver && !empty($driver['dr_initial'])) {
|
|
$data['d_druid'] = $druid;
|
|
$data['d_drinitial'] = $driver['dr_initial'];
|
|
} elseif ($existing) {
|
|
$data['d_druid'] = $existing['d_druid'] ?? 0;
|
|
$data['d_drinitial'] = $existing['d_drinitial'] ?? '';
|
|
}
|
|
}
|
|
|
|
// =========================
|
|
// CUSTOMER SNAPSHOT (확장)
|
|
// =========================
|
|
$customerUid = isset($data['d_customeruid'])
|
|
? (int)$data['d_customeruid']
|
|
: (int)($existing['d_customeruid'] ?? 0);
|
|
|
|
if ($customerUid > 0) {
|
|
$sqCustomer = qry("
|
|
SELECT
|
|
c_regionuid,
|
|
c_region,
|
|
c_fullcycle,
|
|
c_fullcycleforced,
|
|
c_fullcycleflag,
|
|
c_lastpickupdate,
|
|
c_lastpickupquantity,
|
|
c_lastpaiddate,
|
|
c_name,
|
|
c_paymenttype,
|
|
c_paymentcycle,
|
|
c_rate,
|
|
c_form_eu,
|
|
c_form_corsia,
|
|
c_maincontainer,
|
|
c_container,
|
|
c_location,
|
|
c_phone,
|
|
c_address,
|
|
c_city,
|
|
c_postal,
|
|
c_area
|
|
|
|
FROM tbl_customer
|
|
WHERE c_uid = '{$customerUid}'
|
|
LIMIT 1
|
|
");
|
|
$customer = fetch_array($sqCustomer);
|
|
|
|
if ($customer) {
|
|
$data['d_name'] = $customer['c_name'] ?? '';
|
|
$data['d_form_eu'] = $customer['c_form_eu'] ?? '';
|
|
$data['d_form_corsia'] = $customer['c_form_corsia'] ?? '';
|
|
$data['d_maincontainer'] = $customer['c_maincontainer'] ?? '';
|
|
//$data['d_container'] = $customer['c_container'] ?? '';
|
|
$data['d_container'] = $this->buildContainerString($customerUid, $connect);
|
|
$data['d_location'] = $customer['c_location'] ?? '';
|
|
$data['d_phone'] = $customer['c_phone'] ?? '';
|
|
$data['d_address'] = $customer['c_address'] ?? '';
|
|
$data['d_city'] = $customer['c_city'] ?? '';
|
|
$data['d_postal'] = $customer['c_postal'] ?? '';
|
|
$data['d_area'] = $customer['c_area'] ?? '';
|
|
$data['d_regionuid'] = (int)($customer['c_regionuid'] ?? 0);
|
|
$data['d_region'] = $customer['c_region'] ?? '';
|
|
$data['d_fullcycle'] = $customer['c_fullcycle'] ?? 0;
|
|
$data['d_fullcycleforced'] = $customer['c_fullcycleforced'] ?? 0;
|
|
$data['d_fullcycleflag'] = $customer['c_fullcycleflag'] ?? 0;
|
|
$data['d_lastpickupdate'] = $customer['c_lastpickupdate'] ?? '';
|
|
$data['d_lastpickupquantity'] = $customer['c_lastpickupquantity'] ?? 0;
|
|
$data['d_lastpaiddate'] = $customer['c_lastpaiddate'] ?? '';
|
|
$data['d_paymenttype'] = $customer['c_paymenttype'] ?? '';
|
|
$data['d_cycle'] = $customer['c_paymentcycle'] ?? '';
|
|
$data['d_rate'] = $customer['c_rate'] ?? '';
|
|
if (!isset($data['d_oil_2y'])) $data['d_oil_2y'] = 0;
|
|
if (!isset($data['d_oil_1y'])) $data['d_oil_1y'] = 0;
|
|
if (!isset($data['d_oil_0y'])) $data['d_oil_0y'] = 0;
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
function buildContainerString($c_uid, $connect) {
|
|
$sql = "
|
|
SELECT cc_type, COUNT(*) as cnt
|
|
FROM tbl_customer_container
|
|
WHERE cc_customer_uid = '{$c_uid}'
|
|
AND cc_status = 'A'
|
|
GROUP BY cc_type
|
|
ORDER BY cc_type
|
|
";
|
|
|
|
$res = mysqli_query($connect, $sql);
|
|
|
|
$parts = [];
|
|
|
|
while ($row = mysqli_fetch_assoc($res)) {
|
|
$type = $row['cc_type'];
|
|
$cnt = (int)$row['cnt'];
|
|
|
|
if ($cnt > 1) {
|
|
$parts[] = "{$type}x{$cnt}";
|
|
} else {
|
|
$parts[] = $type;
|
|
}
|
|
}
|
|
|
|
return implode(', ', $parts);
|
|
}
|
|
|
|
private function getDailyColumns(): array
|
|
{
|
|
return [
|
|
'd_uid',
|
|
|
|
// key
|
|
'd_orderdate',
|
|
'd_accountno',
|
|
'd_customeruid',
|
|
'd_jobtype',
|
|
|
|
// driver / region
|
|
'd_driveruid',
|
|
'd_druid',
|
|
'd_drinitial',
|
|
'd_regionuid',
|
|
'd_region',
|
|
|
|
// basic status
|
|
'd_ordertype',
|
|
'd_visitdate',
|
|
'd_visit',
|
|
'd_status',
|
|
|
|
// qty / sludge / payment
|
|
'd_quantity',
|
|
'd_sludge',
|
|
'd_paymenttype',
|
|
'd_payamount',
|
|
'd_payeename',
|
|
'd_paystatus',
|
|
'd_paynote',
|
|
|
|
// customer snapshot
|
|
'd_name',
|
|
'd_form_eu',
|
|
'd_form_corsia',
|
|
'd_maincontainer',
|
|
'd_container',
|
|
'd_location',
|
|
'd_phone',
|
|
'd_address',
|
|
'd_city',
|
|
'd_postal',
|
|
'd_area',
|
|
|
|
// oil / cycle history snapshot
|
|
'd_oil_2y',
|
|
'd_oil_1y',
|
|
'd_oil_0y',
|
|
'd_fullcycle',
|
|
'd_fullcycleforced',
|
|
'd_fullcycleflag',
|
|
'd_lastpickupdate',
|
|
'd_lastpickupquantity',
|
|
'd_lastpaiddate',
|
|
|
|
// pricing / estimate
|
|
'd_cycle',
|
|
'd_rate',
|
|
'd_estquantity',
|
|
|
|
// audit
|
|
'd_createruid',
|
|
'd_updateruid',
|
|
'd_createddate',
|
|
'd_inputdate',
|
|
'd_modifydate',
|
|
'd_ruid',
|
|
|
|
// misc
|
|
'd_payeesign'
|
|
];
|
|
}
|
|
|
|
private function calculateEstQuantity(array $data, ?array $existing = null): int
|
|
{
|
|
$customerUid = $data['d_customeruid'] ?? ($existing['d_customeruid'] ?? 0);
|
|
$orderdate = $data['d_orderdate'] ?? ($existing['d_orderdate'] ?? '');
|
|
|
|
if (!$customerUid || !$orderdate) return 0;
|
|
|
|
$sqCus = qry("
|
|
SELECT c_fullquantity, c_fullquantitydaily
|
|
FROM tbl_customer
|
|
WHERE c_uid = '{$customerUid}'
|
|
LIMIT 1
|
|
");
|
|
$customer = fetch_array($sqCus);
|
|
|
|
if (!$customer) return 0;
|
|
|
|
$today = new DateTime(date("Y-m-d"));
|
|
$searchDate = new DateTime(substr($orderdate,0,4)."-".substr($orderdate,4,2)."-".substr($orderdate,6,2));
|
|
|
|
$interval = $today->diff($searchDate);
|
|
$days = (int)$interval->days;
|
|
|
|
return max(
|
|
0,
|
|
($customer['c_fullquantity'] - $customer['c_fullquantitydaily']) +
|
|
($days * $customer['c_fullquantitydaily'])
|
|
);
|
|
}
|
|
|
|
private function runAfterSave(?array $before, array $after, array $opt = []): void
|
|
{
|
|
// order장과 customer 상태 동기화 + 픽업 정보 갱신
|
|
$customerFields = $this->buildCustomerPatchFromDaily($before, $after);
|
|
if (!empty($customerFields) && !empty($after['d_customeruid'])){
|
|
|
|
$customerFields['c_updatedby'] = $after['d_updateruid'] ?? $after['d_createruid'] ?? null;
|
|
// patch
|
|
$this->patchCustomerFromDaily(
|
|
(int)$after['d_customeruid'],
|
|
$customerFields
|
|
);
|
|
}
|
|
// request 처리 완료
|
|
$this->updateRequestFromDaily($after);
|
|
// note 처리
|
|
$this->upsertDailyNote($after);
|
|
// 픽업 발생 시 미래 오더 자동 정리
|
|
$this->handlePickupCleanup($before, $after);
|
|
}
|
|
|
|
private function runAfterDelete(array $before, array $opt = []): void
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
|
|
if (empty($before['d_customeruid'])) {
|
|
return;
|
|
}
|
|
|
|
$customerUid = mysqli_real_escape_string($connect, $before['d_customeruid']);
|
|
$orderdate = mysqli_real_escape_string($connect, $before['d_orderdate'] ?? '');
|
|
|
|
// 1) REQUEST 삭제
|
|
$this->deleteRequestByDaily($before);
|
|
|
|
// 2) CUSTOMER 재계산 (lastpick, lastpaid 등 포함)
|
|
$this->recalcCustomerFromDailyHistory($customerUid);
|
|
|
|
// 3) GHOST 재판정
|
|
$this->reEvaluateGhost($customerUid);
|
|
}
|
|
|
|
private function deleteRequestByDaily(array $before): void
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
|
|
$customerUid = (int)($before['d_customeruid'] ?? 0);
|
|
$orderdate = preg_replace('/[^0-9]/', '', $before['d_orderdate'] ?? '');
|
|
|
|
if ($customerUid <= 0 || $orderdate === '') {
|
|
return;
|
|
}
|
|
|
|
mysqli_query($connect, "
|
|
DELETE FROM tbl_request
|
|
WHERE r_customeruid = '{$customerUid}'
|
|
AND r_requestdate = '{$orderdate}'
|
|
");
|
|
}
|
|
|
|
private function buildCustomerPatchFromDaily(
|
|
?array $before,
|
|
array $after
|
|
): array
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
$customerFields = [];
|
|
if (empty($after['d_customeruid'])) {
|
|
return $customerFields;
|
|
}
|
|
|
|
// Customer Current State
|
|
$customerUid = (int)$after['d_customeruid'];
|
|
$qr = mysqli_query($connect, "
|
|
SELECT
|
|
c_paymenttype,
|
|
c_is_top,
|
|
c_fpickup,
|
|
c_schedule,
|
|
c_scheduleday
|
|
FROM tbl_customer
|
|
WHERE c_uid = '{$customerUid}'
|
|
LIMIT 1
|
|
");
|
|
|
|
$customer = mysqli_fetch_assoc($qr);
|
|
if (!$customer) {
|
|
return $customerFields;
|
|
}
|
|
|
|
// Common Values
|
|
$ordertype = $after['d_ordertype'] ?? 'N';
|
|
$orderdate = $after['d_orderdate'] ?? '';
|
|
$visitdate = $after['d_visitdate'] ?? '';
|
|
$thisQuantity = (int)($after['d_quantity'] ?? 0);
|
|
$lastQuantity = (int)($after['d_lastpickupquantity'] ?? 0);
|
|
$status = $after['d_status'] ?? '';
|
|
$visit = $after['d_visit'] ?? '';
|
|
$isTop = trim($customer['c_is_top'] ?? '');
|
|
// Sludge
|
|
if (isset($after['d_sludge']) && (string)$after['d_sludge'] !== '') {
|
|
$customerFields['c_sludge'] = (int)$after['d_sludge'];
|
|
}
|
|
// Ghost Check
|
|
if (
|
|
$thisQuantity > 0
|
|
&& $lastQuantity > 0
|
|
&& $thisQuantity < 10
|
|
&& $lastQuantity < 10
|
|
&& $isTop !== 'G'
|
|
) {
|
|
$customerFields['c_is_top'] = 'G';
|
|
}
|
|
if ($isTop === 'G' && $thisQuantity >= 10) {
|
|
$customerFields['c_is_top'] = '';
|
|
}
|
|
// First Pickup
|
|
if (
|
|
empty($customer['c_fpickup'])
|
|
&& !empty($orderdate)
|
|
&& $thisQuantity >= 10
|
|
) {
|
|
$customerFields['c_fpickup'] = $orderdate;
|
|
}
|
|
|
|
// Order Flag
|
|
if ($status === 'F') {
|
|
$customerFields['c_orderdate'] = '';
|
|
$customerFields['c_orderflag'] = 0;
|
|
} else {
|
|
$customerFields['c_orderdate'] = $orderdate;
|
|
$customerFields['c_orderflag'] = 1;
|
|
}
|
|
|
|
// =========================
|
|
// Last Pickup
|
|
//
|
|
// 변경된 정책 (20260601):
|
|
// 수량 상관없이 완료 방문이면 기록
|
|
// =========================
|
|
if ($status === 'F') {
|
|
$customerFields['c_lastpickupdate'] = $orderdate;
|
|
$customerFields['c_lastpickupquantity'] = $thisQuantity;
|
|
// Full Quantity Reset 10L 이상일 때만
|
|
if ($thisQuantity >= 10) {
|
|
$customerFields['c_fullquantity'] = 0;
|
|
}
|
|
}
|
|
|
|
return $customerFields;
|
|
}
|
|
|
|
private function updateRequestFromDaily(array $after): void
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
|
|
if (empty($after['d_ordertype']) || $after['d_ordertype'] !== 'R') {
|
|
return;
|
|
}
|
|
|
|
if (empty($after['d_ruid'])) {
|
|
return;
|
|
}
|
|
|
|
// pickup 완료 조건 (방문 완료 + 상태 F)
|
|
if (
|
|
empty($after['d_visit']) ||
|
|
$after['d_visit'] !== 'Y' ||
|
|
empty($after['d_status']) ||
|
|
$after['d_status'] !== 'F'
|
|
) {
|
|
return;
|
|
}
|
|
|
|
$r_uid = mysqli_real_escape_string($connect, $after['d_ruid']);
|
|
|
|
mysqli_query($connect, "
|
|
UPDATE tbl_request
|
|
SET r_status = 'F'
|
|
WHERE r_uid = '{$r_uid}'
|
|
LIMIT 1
|
|
");
|
|
}
|
|
|
|
private function upsertDailyNote(array $after): void
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
|
|
if (empty($after['d_uid'])) return;
|
|
|
|
// note는 saveDaily payload에 포함되어 있어야 함
|
|
// if (empty($after['d_pickupnote']) && empty($after['d_note'])) {
|
|
// return;
|
|
// }
|
|
|
|
$noteText = trim($after['d_pickupnote'] ?? $after['d_note'] ?? '');
|
|
|
|
// if (strlen($noteText) <= 1) return;
|
|
|
|
$dailyuid = mysqli_real_escape_string($connect, $after['d_uid']);
|
|
$customeruid = mysqli_real_escape_string($connect, $after['d_customeruid'] ?? '');
|
|
$memberuid = mysqli_real_escape_string($connect, $after['d_driveruid'] ?? '');
|
|
$noteEsc = mysqli_real_escape_string($connect, $noteText);
|
|
$now14 = date('YmdHis');
|
|
$level = mysqli_real_escape_string($connect, $after['d_level'] ?? 9);
|
|
|
|
if ($noteText === '') {
|
|
mysqli_query($connect, "
|
|
DELETE FROM tbl_note
|
|
WHERE n_dailyuid = '{$dailyuid}'
|
|
LIMIT 1
|
|
");
|
|
return;
|
|
}
|
|
|
|
// 기존 note 존재 여부 확인
|
|
$qr = mysqli_query($connect, "
|
|
SELECT n_uid
|
|
FROM tbl_note
|
|
WHERE n_dailyuid = '{$dailyuid}'
|
|
LIMIT 1
|
|
");
|
|
|
|
$existing = mysqli_fetch_assoc($qr);
|
|
|
|
if ($existing) {
|
|
// UPDATE
|
|
mysqli_query($connect, "
|
|
UPDATE tbl_note
|
|
SET
|
|
n_memberuid = '{$memberuid}',
|
|
n_customeruid = '{$customeruid}',
|
|
n_type = 'D',
|
|
n_level = {$level},
|
|
n_view = 1,
|
|
n_note = '{$noteEsc}',
|
|
n_createddate = '{$now14}'
|
|
WHERE n_dailyuid = '{$dailyuid}'
|
|
LIMIT 1
|
|
");
|
|
} else {
|
|
// INSERT
|
|
mysqli_query($connect, "
|
|
INSERT INTO tbl_note (
|
|
n_memberuid,
|
|
n_customeruid,
|
|
n_dailyuid,
|
|
n_type,
|
|
n_level,
|
|
n_view,
|
|
n_note,
|
|
n_createddate
|
|
) VALUES (
|
|
'{$memberuid}',
|
|
'{$customeruid}',
|
|
'{$dailyuid}',
|
|
'D',
|
|
{$level},
|
|
1,
|
|
'{$noteEsc}',
|
|
'{$now14}'
|
|
)
|
|
");
|
|
}
|
|
}
|
|
|
|
private function handlePickupCleanup(?array $before, array $after): void
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
|
|
$beforeQty = (int)($before['d_quantity'] ?? 0);
|
|
$afterQty = (int)($after['d_quantity'] ?? 0);
|
|
|
|
$status = $after['d_status'] ?? '';
|
|
$visit = $after['d_visit'] ?? '';
|
|
|
|
// 최초 pickup
|
|
$isFirstPickup = ($beforeQty < 10 && $afterQty >= 10);
|
|
|
|
if (!$isFirstPickup) return;
|
|
if ($status !== 'F' || $visit !== 'Y') return;
|
|
|
|
$customerUid = mysqli_real_escape_string($connect, $after['d_customeruid']);
|
|
$accountno = mysqli_real_escape_string($connect, $after['d_accountno']);
|
|
$today = date('Ymd');
|
|
$jobtype = mysqli_real_escape_string($connect, $after['d_jobtype'] ?? 'UCO');
|
|
|
|
// =========================
|
|
// 삭제 대상 조회
|
|
// =========================
|
|
$res = mysqli_query($connect, "
|
|
SELECT d_orderdate, d_accountno, d_jobtype
|
|
FROM tbl_daily
|
|
WHERE d_customeruid = '{$customerUid}'
|
|
AND d_orderdate > '{$today}'
|
|
AND d_status = 'A'
|
|
AND d_jobtype = '{$jobtype}'
|
|
");
|
|
|
|
if (!$res) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
// =========================
|
|
// 하나씩 deleteDaily 호출
|
|
// =========================
|
|
while ($row = mysqli_fetch_assoc($res)) {
|
|
|
|
try {
|
|
$this->deleteDaily(
|
|
$row['d_orderdate'],
|
|
$row['d_accountno'],
|
|
$row['d_jobtype'],
|
|
['in_tx' => true]
|
|
);
|
|
|
|
} catch (Exception $e) {
|
|
// 여기서 실패하면 전체 rollback 유도
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
error_log("[PickupCleanup] ERP-safe delete completed for customer={$accountno}");
|
|
}
|
|
|
|
public function deleteDaily(string $orderdate, string $accountno, string $jobtype, array $opt = [])
|
|
{
|
|
$connect = $GLOBALS['conn'] ?? null;
|
|
if (!$connect) {
|
|
throw new Exception("DB connection not found");
|
|
}
|
|
|
|
$inTx = !empty($opt['in_tx']);
|
|
|
|
// =========================
|
|
// KEY NORMALIZE
|
|
// =========================
|
|
$orderdate = preg_replace('/[^0-9]/', '', $orderdate);
|
|
if (strlen($orderdate) !== 8) {
|
|
throw new Exception("invalid orderdate");
|
|
}
|
|
|
|
$accountno = mysqli_real_escape_string($connect, trim($accountno));
|
|
if ($accountno === '') {
|
|
throw new Exception("invalid accountno");
|
|
}
|
|
|
|
$jobtype = mysqli_real_escape_string($connect, trim($jobtype));
|
|
if ($jobtype === '') {
|
|
$jobtype = 'UCO';
|
|
}
|
|
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "START TRANSACTION");
|
|
}
|
|
|
|
try {
|
|
|
|
// =========================
|
|
// 1. 기존 데이터 조회
|
|
// =========================
|
|
$res = mysqli_query($connect, "
|
|
SELECT *
|
|
FROM tbl_daily
|
|
WHERE d_orderdate='{$orderdate}'
|
|
AND d_accountno='{$accountno}'
|
|
AND d_jobtype = '{$jobtype}'
|
|
LIMIT 1
|
|
");
|
|
if (!$res) throw new Exception(mysqli_error($connect));
|
|
|
|
$existing = mysqli_fetch_assoc($res);
|
|
|
|
if (!$existing) {
|
|
throw new Exception("Daily record not found");
|
|
}
|
|
|
|
// =========================
|
|
// 2. ERP OUTBOX 기록
|
|
// =========================
|
|
$payload = mysqli_real_escape_string(
|
|
$connect,
|
|
json_encode([
|
|
'entity' => 'DAILY',
|
|
'action' => 'DELETED',
|
|
|
|
'key' => [
|
|
'd_orderdate' => $orderdate,
|
|
'd_accountno' => $accountno,
|
|
'd_jobtype' => $jobtype
|
|
],
|
|
|
|
'before' => $existing,
|
|
'after' => null
|
|
|
|
], JSON_UNESCAPED_UNICODE)
|
|
);
|
|
|
|
$qry_outbox = "
|
|
INSERT INTO tbl_erp_outbox
|
|
(
|
|
eo_entity_type,
|
|
eo_action_type,
|
|
eo_key1,
|
|
eo_key2,
|
|
eo_key3,
|
|
eo_payload,
|
|
eo_status,
|
|
eo_created_at
|
|
)
|
|
VALUES
|
|
(
|
|
'DAILY',
|
|
'DELETED',
|
|
'{$orderdate}',
|
|
'{$accountno}',
|
|
'{$jobtype}',
|
|
'{$payload}',
|
|
'PENDING',
|
|
NOW()
|
|
)
|
|
";
|
|
|
|
if (!mysqli_query($connect, $qry_outbox)) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
// =========================
|
|
// 3. 물리 삭제
|
|
// =========================
|
|
if (!mysqli_query($connect, "
|
|
DELETE FROM tbl_daily
|
|
WHERE d_orderdate='{$orderdate}'
|
|
AND d_accountno='{$accountno}'
|
|
AND d_jobtype = '{$jobtype}'
|
|
LIMIT 1
|
|
")) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
if (mysqli_affected_rows($connect) === 0) {
|
|
throw new Exception("Delete failed");
|
|
}
|
|
|
|
// =========================
|
|
// AFTER WORK 중앙화
|
|
// =========================
|
|
$this->runAfterDelete($existing, $opt);
|
|
|
|
// =========================
|
|
// COMMIT
|
|
// =========================
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "COMMIT");
|
|
}
|
|
|
|
return true;
|
|
|
|
} catch (Exception $e) {
|
|
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "ROLLBACK");
|
|
}
|
|
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
private function reEvaluateGhost(int $customerUid): void
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
|
|
$res = mysqli_query($connect, "
|
|
SELECT
|
|
c.c_is_top,
|
|
d.d_quantity,
|
|
d.d_lastpickupquantity,
|
|
d.d_updateruid
|
|
FROM tbl_customer c
|
|
LEFT JOIN tbl_daily d
|
|
ON d.d_customeruid = c.c_uid
|
|
AND d.d_status = 'F'
|
|
WHERE c.c_uid = '{$customerUid}'
|
|
ORDER BY d.d_orderdate DESC
|
|
LIMIT 1
|
|
");
|
|
|
|
if (!$res) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
$row = mysqli_fetch_assoc($res);
|
|
|
|
if (!$row) {
|
|
return;
|
|
}
|
|
|
|
$currentTop = trim(
|
|
(string)($row['c_is_top'] ?? '')
|
|
);
|
|
|
|
$thisQuantity = (int)($row['d_quantity'] ?? 0);
|
|
$lastQuantity = (int)($row['d_lastpickupquantity'] ?? 0);
|
|
|
|
// =========================
|
|
// NO DAILY HISTORY
|
|
// =========================
|
|
if (empty($row['d_quantity']) && empty($row['d_lastpickupquantity'])) {
|
|
// 현재 ghost 인 경우만 해제
|
|
if ($currentTop === 'G') {
|
|
$this->patchCustomerFromDaily(
|
|
$customerUid,
|
|
[
|
|
'c_is_top' => '',
|
|
'c_updatedby' => $row['d_updateruid'] ?? null
|
|
]
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// =========================
|
|
// SHOULD BE GHOST
|
|
// =========================
|
|
$shouldGhost = ($thisQuantity < 10) && ($lastQuantity < 10);
|
|
|
|
// ghost 추가
|
|
if ($shouldGhost) {
|
|
// 이미 G 면 skip
|
|
if ($currentTop !== 'G') {
|
|
$this->patchCustomerFromDaily(
|
|
$customerUid,
|
|
[
|
|
'c_is_top' => 'G',
|
|
'c_updatedby' => $row['d_updateruid'] ?? null
|
|
]
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// =========================
|
|
// REMOVE GHOST
|
|
// =========================
|
|
if ($currentTop === 'G') {
|
|
// $shouldGhost 는 이미 false;
|
|
$this->patchCustomerFromDaily(
|
|
$customerUid,
|
|
[
|
|
'c_is_top' => '',
|
|
'c_updatedby' => $row['d_updateruid'] ?? null
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
private function recalcCustomerFromDailyHistory(string $customerUid): void
|
|
{
|
|
$connect = $GLOBALS['conn'];
|
|
$customerUidEsc = mysqli_real_escape_string($connect, $customerUid);
|
|
|
|
// 0) "오늘 포함 이후" 오더장 존재 여부 체크 (남아있으면 리셋 금지)
|
|
$today = date('Ymd');
|
|
|
|
$resFuture = mysqli_query($connect, "
|
|
SELECT 1
|
|
FROM tbl_daily
|
|
WHERE d_customeruid = '{$customerUidEsc}'
|
|
AND d_orderdate >= '{$today}'
|
|
AND d_status = 'A'
|
|
LIMIT 1
|
|
");
|
|
if (!$resFuture) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
$hasFutureOrder = (bool)mysqli_fetch_assoc($resFuture);
|
|
|
|
// 1) 마지막 완료 주문(F) 기준으로 last pickup 재계산
|
|
$res = mysqli_query($connect, "
|
|
SELECT
|
|
d_orderdate,
|
|
d_quantity,
|
|
d_sludge,
|
|
d_paymenttype,
|
|
d_paystatus,
|
|
d_updateruid
|
|
FROM tbl_daily
|
|
WHERE d_customeruid = '{$customerUidEsc}'
|
|
AND d_status = 'F'
|
|
ORDER BY d_orderdate DESC
|
|
LIMIT 1
|
|
");
|
|
if (!$res) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
$last = mysqli_fetch_assoc($res);
|
|
|
|
$lastPickupDate = '';
|
|
$lastPickupQty = 0;
|
|
$lastSludge = '';
|
|
$lastPaidDate = '';
|
|
|
|
if ($last) {
|
|
$lastPickupDate = $last['d_orderdate'];
|
|
$lastPickupQty = (int)$last['d_quantity'];
|
|
$lastSludge = (string)$last['d_sludge'];
|
|
|
|
if ($last['d_paymenttype'] === 'CA' && $last['d_paystatus'] === 'P') {
|
|
$lastPaidDate = $last['d_orderdate'];
|
|
}
|
|
}
|
|
|
|
// 2) 마지막 주문이 cash paid가 아니면, cash paid 마지막을 다시 찾음
|
|
if ($lastPaidDate === '') {
|
|
|
|
$res2 = mysqli_query($connect, "
|
|
SELECT d_orderdate
|
|
FROM tbl_daily
|
|
WHERE d_customeruid = '{$customerUidEsc}'
|
|
AND d_status = 'F'
|
|
AND d_paymenttype = 'CA'
|
|
AND d_paystatus = 'P'
|
|
ORDER BY d_orderdate DESC
|
|
LIMIT 1
|
|
");
|
|
if (!$res2) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
$paid = mysqli_fetch_assoc($res2);
|
|
if ($paid) {
|
|
$lastPaidDate = $paid['d_orderdate'];
|
|
}
|
|
}
|
|
|
|
// 3) CUSTOMER PATCH 구성
|
|
$customerFields = [];
|
|
$customerFields['c_lastpickupdate'] = $lastPickupDate;
|
|
$customerFields['c_lastpickupquantity'] = $lastPickupQty;
|
|
$customerFields['c_lastpaiddate'] = $lastPaidDate;
|
|
$customerFields['c_sludge'] = $lastSludge;
|
|
|
|
// 4) orderflag/orderdate 리셋 정책 반영
|
|
// - 오늘 포함 이후 오더장이 남아있으면 유지 (아무것도 안함)
|
|
// - 없으면 리셋
|
|
if (!$hasFutureOrder) {
|
|
$customerFields['c_orderdate'] = '';
|
|
$customerFields['c_orderflag'] = 0;
|
|
}
|
|
|
|
$customerFields['c_updatedby'] = $last['d_updateruid'] ?? null;
|
|
|
|
// 5) PATCH CUSTOMER
|
|
$this->patchCustomerFromDaily(
|
|
(int)$customerUid,
|
|
$customerFields
|
|
);
|
|
}
|
|
|
|
/* =====================================================
|
|
* PATCH DAILY
|
|
* ===================================================== */
|
|
|
|
public function patchDaily(
|
|
int $dailyUid,
|
|
array $fields = [],
|
|
array $opt = []
|
|
): array {
|
|
|
|
$connect = $GLOBALS['conn'] ?? null;
|
|
if (!$connect) {
|
|
throw new Exception("DB connection not found");
|
|
}
|
|
|
|
$dailyUid = (int)$dailyUid;
|
|
if ($dailyUid <= 0) {
|
|
throw new Exception("invalid daily uid");
|
|
}
|
|
|
|
if (empty($fields)) {
|
|
throw new Exception("empty patch fields");
|
|
}
|
|
|
|
$inTx = !empty($opt['in_tx']);
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "START TRANSACTION");
|
|
}
|
|
|
|
try {
|
|
// BEFORE
|
|
$res = mysqli_query($connect, "
|
|
SELECT *
|
|
FROM tbl_daily
|
|
WHERE d_uid = '{$dailyUid}'
|
|
LIMIT 1
|
|
");
|
|
|
|
if (!$res) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
$beforeData = mysqli_fetch_assoc($res);
|
|
if (!$beforeData) {
|
|
throw new Exception("daily not found");
|
|
}
|
|
|
|
// NORMALIZE
|
|
$fields = $this->normalizeDailyPayload(
|
|
$fields,
|
|
$beforeData
|
|
);
|
|
|
|
// MODIFY DATE
|
|
$fields['d_modifydate'] = date("YmdHis");
|
|
|
|
// UPDATE
|
|
$setParts = [];
|
|
|
|
foreach ($fields as $k => $v) {
|
|
if ($v === null) {
|
|
$setParts[] = "{$k}=NULL";
|
|
continue;
|
|
}
|
|
|
|
$vEsc = mysqli_real_escape_string(
|
|
$connect,
|
|
(string)$v
|
|
);
|
|
|
|
$setParts[] = "{$k}='{$vEsc}'";
|
|
}
|
|
|
|
if (empty($setParts)) {
|
|
throw new Exception("nothing to update");
|
|
}
|
|
|
|
$sql = "
|
|
UPDATE tbl_daily
|
|
SET
|
|
" . implode(',', $setParts) . "
|
|
WHERE d_uid='{$dailyUid}'
|
|
LIMIT 1
|
|
";
|
|
|
|
if (!mysqli_query($connect, $sql)) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
// AFTER
|
|
$res = mysqli_query($connect, "
|
|
SELECT *
|
|
FROM tbl_daily
|
|
WHERE d_uid='{$dailyUid}'
|
|
LIMIT 1
|
|
");
|
|
if (!$res) {
|
|
throw new Exception(mysqli_error($connect));
|
|
}
|
|
|
|
$afterData = mysqli_fetch_assoc($res);
|
|
|
|
// OUTBOX
|
|
$this->enqueueOutbox(
|
|
'UPDATED',
|
|
$beforeData,
|
|
$afterData
|
|
);
|
|
|
|
// AFTER WORK
|
|
if (empty($opt['skip_after'])) {
|
|
$this->runAfterSave(
|
|
$beforeData,
|
|
$afterData,
|
|
$opt
|
|
);
|
|
}
|
|
|
|
// COMMIT
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "COMMIT");
|
|
}
|
|
|
|
return $afterData;
|
|
|
|
} catch (Exception $e) {
|
|
|
|
if (!$inTx) {
|
|
mysqli_query($connect, "ROLLBACK");
|
|
}
|
|
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
private function patchCustomerFromDaily(
|
|
int $customerUid,
|
|
array $fields = []
|
|
): void {
|
|
|
|
if ($customerUid <= 0) {
|
|
return;
|
|
}
|
|
|
|
if (empty($fields)) {
|
|
return;
|
|
}
|
|
|
|
$customerSvc = new CustomerService();
|
|
|
|
$customerSvc->patchCustomer(
|
|
$customerUid,
|
|
$fields,
|
|
[
|
|
'in_tx' => true,
|
|
'skip_after' => true
|
|
]
|
|
);
|
|
}
|
|
|
|
/* ===============================
|
|
* 공통 JSON 응답
|
|
* =============================== */
|
|
|
|
private function jsonSuccess($data = [])
|
|
{
|
|
return json_encode([
|
|
'result' => 'success',
|
|
'data' => $data
|
|
]);
|
|
}
|
|
|
|
private function jsonError($msg)
|
|
{
|
|
return json_encode([
|
|
'result' => 'error',
|
|
'message'=> $msg
|
|
]);
|
|
}
|
|
|
|
} |