From 168f1e06f3d419d2e052505a46210db8427320fa Mon Sep 17 00:00:00 2001 From: Hyojin Ahn Date: Sun, 14 Jun 2026 01:02:26 -0400 Subject: [PATCH] =?UTF-8?q?v1.3.0=20-=20[CUSTOMER]=20ERP=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=EC=99=80=20=EB=8F=99=EA=B8=B0=ED=99=94=20=EC=8B=9C?= =?UTF-8?q?=EC=9E=91.=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=A4=91=EC=8B=AC?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=EC=9C=BC=EB=A1=9C=20=ED=86=B5=ED=95=A9.?= =?UTF-8?q?=20-=20[ORDER]=20ERP=20=EC=84=9C=EB=B2=84=EC=99=80=20=EB=8F=99?= =?UTF-8?q?=EA=B8=B0=ED=99=94=20=EC=8B=9C=EC=9E=91.=2010=20=EB=AF=B8?= =?UTF-8?q?=EB=A7=8C=20=EC=88=98=EA=B1=B0=ED=95=B4=EB=8F=84=20=EC=B5=9C?= =?UTF-8?q?=EA=B7=BC=20=EC=88=98=EA=B1=B0=EC=A0=95=EB=B3=B4=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public_html/assets/api/customer.php | 956 ++++++++++++++++++ public_html/assets/api/daily.php | 593 +++++++---- public_html/assets/api/install.php | 181 ++-- public_html/assets/internal_api.php | 140 +-- public_html/doc/customer_process.php | 445 ++++---- public_html/doc/forecast_list.php | 4 +- public_html/lib/lib_updatecycle.php | 27 +- public_html/lib/mapper/erpCustomerMapper.php | 201 ++++ .../lib/mapper/erpDailyOrderMapper.php | 69 ++ public_html/lib/order_lib_process.php | 4 +- public_html/lib/receiptNote_lib_process.php | 50 +- public_html/lib/runErpOutbox.php | 338 +++++++ public_html/lib/shortInfo_lib_process.php | 105 +- public_html/lib/user_process.php | 183 ++-- 14 files changed, 2503 insertions(+), 793 deletions(-) create mode 100644 public_html/assets/api/customer.php create mode 100644 public_html/lib/mapper/erpCustomerMapper.php create mode 100644 public_html/lib/mapper/erpDailyOrderMapper.php create mode 100644 public_html/lib/runErpOutbox.php diff --git a/public_html/assets/api/customer.php b/public_html/assets/api/customer.php new file mode 100644 index 0000000..79c465f --- /dev/null +++ b/public_html/assets/api/customer.php @@ -0,0 +1,956 @@ +normalizeCustomerPayload($data, $beforeData); + + // ===================================== + // HYDRATE + // ===================================== + $data = $this->hydrateCustomerSnapshot($data, $beforeData); + + // ===================================== + // CREATE + // ===================================== + if (!$isUpdate) { + + $columns = []; + $values = []; + + foreach ($data as $k => $v) { + $columns[] = $k; + $values[] = "'" . mysqli_real_escape_string($connect, (string)$v) . "'"; + } + + $sql = " + INSERT INTO tbl_customer + ( + " . implode(',', $columns) . " + ) + VALUES + ( + " . implode(',', $values) . " + ) + "; + + if (!mysqli_query($connect, $sql)) { + throw new Exception(mysqli_error($connect)); + } + + $c_uid = mysqli_insert_id($connect); + } + + // ===================================== + // UPDATE + // ===================================== + else { + + $setParts = []; + + foreach ($data as $k => $v) { + + $vEsc = mysqli_real_escape_string( + $connect, + (string)$v + ); + + $setParts[] = "{$k}='{$vEsc}'"; + } + + $sql = " + UPDATE tbl_customer + SET + " . implode(',', $setParts) . " + WHERE c_uid='{$beforeData['c_uid']}' + LIMIT 1 + "; + + if (!mysqli_query($connect, $sql)) { + throw new Exception(mysqli_error($connect)); + } + + $c_uid = (int)$beforeData['c_uid']; + } + + // ===================================== + // AFTER RELOAD + // ===================================== + $res = mysqli_query($connect, " + SELECT * + FROM tbl_customer + WHERE c_uid='{$c_uid}' + LIMIT 1 + "); + + if (!$res) { + throw new Exception(mysqli_error($connect)); + } + + $afterData = mysqli_fetch_assoc($res); + + // ===================================== + // OUTBOX + // ===================================== + $actionType = $isUpdate + ? 'UPDATED' + : 'CREATED'; + + if (!$isUpdate|| $this->hasCustomerChanges($beforeData, $afterData)) { + $this->enqueueOutbox( + $actionType, + $beforeData, + $afterData + ); + } + + // ===================================== + // AFTER WORK + // ===================================== + if (empty($opt['skip_after'])) { + $this->runAfterChange( + $beforeData, + $afterData, + $data, + $opt + ); + } + + // ===================================== + // COMMIT + // ===================================== + if (!$inTx) { + mysqli_query($connect, "COMMIT"); + } + + return $afterData; + + } catch (Exception $e) { + + if (!$inTx) { + mysqli_query($connect, "ROLLBACK"); + } + + throw $e; + } + } + + /* ===================================================== + * PATCH CUSTOMER + * ===================================================== */ + + public function patchCustomer( + int $customerUid, + array $fields, + array $opt = [] + ): array { + + $connect = $GLOBALS['conn'] ?? null; + if (!$connect) { + throw new Exception("DB connection not found"); + } + + $inTx = !empty($opt['in_tx']); + if (!$inTx) { + mysqli_query($connect, "START TRANSACTION"); + } + + try { + + $customerUid = (int)$customerUid; + if ($customerUid <= 0) { + throw new Exception("invalid customer uid"); + } + + // ===================================== + // BEFORE + // ===================================== + $res = mysqli_query($connect, "SELECT * FROM tbl_customer WHERE c_uid='{$customerUid}' LIMIT 1"); + if (!$res) { + throw new Exception(mysqli_error($connect)); + } + + $beforeData = mysqli_fetch_assoc($res); + if (!$beforeData) { + throw new Exception("customer not found"); + } + + // ===================================== + // normalize + // ===================================== + $fields = $this->normalizeCustomerPayload( + $fields, + $beforeData + ); + if (empty($fields)) { + return $beforeData; + } + $fields['c_updateddate'] = date("YmdHis"); + + // ===================================== + // GEO RESET + // ===================================== + $this->handleGeoReset( + $beforeData, + $fields + ); + + // ===================================== + // 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}'"; + } + + $sql = " + UPDATE tbl_customer + SET + " . implode(',', $setParts) . " + WHERE c_uid='{$customerUid}' + LIMIT 1 + "; + + if (!mysqli_query($connect, $sql)) { + throw new Exception(mysqli_error($connect)); + } + + // ===================================== + // AFTER + // ===================================== + $res = mysqli_query($connect, " + SELECT * + FROM tbl_customer + WHERE c_uid='{$customerUid}' + LIMIT 1 + "); + + if (!$res) { + throw new Exception(mysqli_error($connect)); + } + + $afterData = mysqli_fetch_assoc($res); + + // ===================================== + // OUTBOX + // ===================================== + if ($this->hasCustomerChanges($beforeData, $afterData)) { + $this->enqueueOutbox( + 'UPDATED', + $beforeData, + $afterData + ); + } + + // ===================================== + // AFTER WORK + // ===================================== + if (empty($opt['skip_after'])) { + $this->runAfterChange( + $beforeData, + $afterData, + $fields, + $opt + ); + } + + if (!$inTx) { + mysqli_query($connect, "COMMIT"); + } + + return $afterData; + + } catch (Exception $e) { + + if (!$inTx) { + mysqli_query($connect, "ROLLBACK"); + } + + throw $e; + } + } + + /* ===================================================== + * DELETE CUSTOMER (사용 안함) + * ===================================================== */ + + public function deleteCustomer( + int $customerUid, + array $opt = [] + ): bool { + + $connect = $GLOBALS['conn'] ?? null; + if (!$connect) { + throw new Exception("DB connection not found"); + } + + $customerUid = (int)$customerUid; + + if ($customerUid <= 0) { + throw new Exception("invalid customer uid"); + } + + $inTx = !empty($opt['in_tx']); + + if (!$inTx) { + mysqli_query($connect, "START TRANSACTION"); + } + + try { + + $res = mysqli_query($connect, " + SELECT * + FROM tbl_customer + WHERE c_uid='{$customerUid}' + LIMIT 1 + "); + + if (!$res) { + throw new Exception(mysqli_error($connect)); + } + + $beforeData = mysqli_fetch_assoc($res); + + if (!$beforeData) { + throw new Exception("customer not found"); + } + + $sql = " + UPDATE tbl_customer + SET + c_status='D' + WHERE c_uid='{$customerUid}' + LIMIT 1 + "; + + if (!mysqli_query($connect, $sql)) { + throw new Exception(mysqli_error($connect)); + } + + $res = mysqli_query($connect, " + SELECT * + FROM tbl_customer + WHERE c_uid='{$customerUid}' + LIMIT 1 + "); + + $afterData = mysqli_fetch_assoc($res); + + $this->enqueueOutbox( + 'DELETED', + $beforeData, + $afterData + ); + + if (!$inTx) { + mysqli_query($connect, "COMMIT"); + } + + return true; + + } catch (Exception $e) { + + if (!$inTx) { + mysqli_query($connect, "ROLLBACK"); + } + + throw $e; + } + } + + /* ===================================================== + * OUTBOX + * ===================================================== */ + private function enqueueOutbox( + string $actionType, + ?array $beforeData, + ?array $afterData + ): void { + + $connect = $GLOBALS['conn'] ?? null; + if (!$connect) { + throw new Exception("DB connection not found"); + } + + $key1 = $afterData['c_accountno'] + ?? $beforeData['c_accountno'] + ?? ''; + + $payload = mysqli_real_escape_string( + $connect, + json_encode([ + + 'entity' => 'CUSTOMER', + 'action' => $actionType, + + 'key' => [ + 'c_accountno' => $key1 + ], + + 'before' => $beforeData, + 'after' => $afterData + + ], JSON_UNESCAPED_UNICODE) + ); + + $sql = " + INSERT INTO tbl_erp_outbox + ( + eo_entity_type, + eo_action_type, + eo_key1, + eo_payload, + eo_status, + eo_created_at + ) + VALUES + ( + 'CUSTOMER', + '{$actionType}', + '{$key1}', + '{$payload}', + 'PENDING', + NOW() + ) + "; + + if (!mysqli_query($connect, $sql)) { + throw new Exception(mysqli_error($connect)); + } + } + + /* ===================================================== + * AFTER SAVE + * ===================================================== */ + + private function runAfterChange( + ?array $before, + array $after, + array $changedFields = [], + array $opt = [] + ): void { + + // ========================= + // DAILY pricing sync + // ========================= + $pricingFields = [ + 'c_rate', + 'c_paymentcycle', + 'c_paymenttype' + ]; + + $hasPricingChange = false; + + foreach ($pricingFields as $f) { + + if ( + array_key_exists($f, $changedFields) + || + (($before[$f] ?? null) != ($after[$f] ?? null)) + ) { + $hasPricingChange = true; + break; + } + } + + if ($hasPricingChange) { + + $this->syncFutureDailyPricing( + $before, + $after + ); + } + + // ========================= + // DRIVER sync + // ========================= + if ( + array_key_exists('c_driveruid', $changedFields) + || + (($before['c_driveruid'] ?? null) != ($after['c_driveruid'] ?? null)) + ) { + + $this->syncFutureDriver( + $before, + $after + ); + } + } + + /* ===================================================== + * DRIVER SYNC + * ===================================================== */ + + private function syncFutureDriver( + ?array $before, + array $after + ): void { + + if (!$before) { + return; + } + + $oldDriver = $before['c_driveruid'] ?? ''; + $newDriver = $after['c_driveruid'] ?? ''; + + if ($oldDriver == $newDriver) { + return; + } + + $customerUid = (int)$after['c_uid']; + $today = date("Ymd"); + + $dailyService = new DailyService(); + $connect = $GLOBALS['conn'] ?? null; + if (!$connect) { + throw new Exception("DB connection not found"); + } + + // FUTURE DAILY + $qry = " + SELECT + d_uid, + d_orderdate, + d_accountno + FROM tbl_daily + WHERE d_customeruid = '{$customerUid}' + AND d_orderdate >= '{$today}' + "; + + $result = mysqli_query($connect, $qry); + while ($row = mysqli_fetch_assoc($result)) { + $dailyService->saveDaily( + [ + 'd_orderdate' => $row['d_orderdate'], + 'd_accountno' => $row['d_accountno'], + 'd_driveruid' => $newDriver, + 'd_updateruid' => $after['c_updatedby'] + ?? $after['c_createdby'] + ?? null + ], + [ + 'match_uid' => $row['d_uid'], + 'allow_update' => true + ] + ); + } + + // FUTURE REQUEST + mysqli_query($connect, " + UPDATE tbl_request + SET r_driveruid='{$newDriver}' + WHERE r_customeruid='{$customerUid}' + AND r_requestdate >= '{$today}' + "); + } + + /* ===================================================== + * FUTURE DAILY PRICING (위에거 포함한 bulk update 로직 만드는 거 추후에 작업) + * ===================================================== */ + private function syncFutureDailyPricing( + ?array $before, + array $after + ): void { + + if (!$before) { + return; + } + + $rateChanged = (string)($before['c_rate'] ?? '') !== (string)($after['c_rate'] ?? ''); + $cycleChanged = (string)($before['c_paymentcycle'] ?? '') !== (string)($after['c_paymentcycle'] ?? ''); + $paymentChanged = (string)($before['c_paymenttype'] ?? '') !== (string)($after['c_paymenttype'] ?? ''); + + if ( + !$rateChanged + && !$cycleChanged + && !$paymentChanged + ) { + return; + } + + $customerUid = (int)$after['c_uid']; + $today = date("Ymd"); + + $dailyService = new DailyService(); + $connect = $GLOBALS['conn'] ?? null; + if (!$connect) { + throw new Exception("DB connection not found"); + } + + $qry = " + SELECT + d_uid, + d_orderdate, + d_accountno + FROM tbl_daily + WHERE d_customeruid = '{$customerUid}' + AND d_orderdate > '{$today}' + "; + + $result = mysqli_query($connect, $qry); + while ($row = mysqli_fetch_assoc($result)) { + + $payload = [ + 'd_orderdate' => $row['d_orderdate'], + 'd_accountno' => $row['d_accountno'], + 'd_updateruid' => + $after['c_updatedby'] + ?? $after['c_createdby'] + ?? null + ]; + + if ($rateChanged) { + $payload['d_rate'] = $after['c_rate']; + } + + if ($cycleChanged) { + $payload['d_cycle'] = $after['c_paymentcycle']; + } + + if ($paymentChanged) { + $payload['d_paymenttype'] = $after['c_paymenttype']; + } + + $dailyService->saveDaily( + $payload, + [ + 'match_uid' => $row['d_uid'], + 'allow_update' => true + ] + ); + } + } + + + /* ===================================================== + * GEO RESET + * ===================================================== */ + + private function handleGeoReset( + array $before, + array &$fields + ): void { + + $beforeAddress = trim( + (string)($before['c_address'] ?? '') + ); + + $beforePostal = trim( + (string)($before['c_postal'] ?? '') + ); + + $newAddress = trim( + (string)( + $fields['c_address'] + ?? $beforeAddress + ) + ); + + $newPostal = trim( + (string)( + $fields['c_postal'] + ?? $beforePostal + ) + ); + + if ( + $beforeAddress !== $newAddress + || + $beforePostal !== $newPostal + ) { + $fields['c_geolat'] = null; + $fields['c_geolon'] = null; + } + } + + /* ===================================================== + * NORMALIZE + * ===================================================== */ + + private function normalizeCustomerPayload( + array $data, + ?array $existing = null + ): array { + + $dateFields = [ + 'c_contractdate', + 'c_installdate', + 'c_salescommissiondate', + 'c_removaldate', + 'c_inactivedate', + 'c_exchangedate', + 'c_switchformdate', + 'c_forceddate' + ]; + + foreach ($dateFields as $f) { + + if (!isset($data[$f])) { + continue; + } + + $data[$f] = preg_replace( + '/[^0-9]/', + '', + (string)$data[$f] + ); + } + + $strFields = [ + 'c_name', + 'c_address', + 'c_city', + 'c_postal', + 'c_location', + 'c_comment_ri', + 'c_comment_ci', + 'c_email', + 'c_phone', + 'c_phoneext', + 'c_cell', + 'c_createdby', + 'c_updatedby' + ]; + + foreach ($strFields as $f) { + + if (!isset($data[$f])) { + continue; + } + + $data[$f] = trim( + str_replace( + "\\", + '', + (string)$data[$f] + ) + ); + } + + if (isset($data['c_phone'])) { + $data['c_phone'] = str_replace( + '-', + '', + $data['c_phone'] + ); + } + + return $data; + } + + /* ===================================================== + * HYDRATE + * ===================================================== */ + + private function hydrateCustomerSnapshot( + array $data, + ?array $existing = null + ): array { + + $connect = $GLOBALS['conn'] ?? null; + if (!$connect) { + throw new Exception("DB connection not found"); + } + + // driver -> region snapshot + if (!empty($data['c_driveruid'])) { + + $driveruid = mysqli_real_escape_string( + $connect, + (string)$data['c_driveruid'] + ); + + $res = mysqli_query($connect, " + SELECT + m_regionuid, + m_region + FROM tbl_member + WHERE m_uid='{$driveruid}' + LIMIT 1 + "); + + if ($res) { + + $driver = mysqli_fetch_assoc($res); + + if ($driver) { + + $data['c_regionuid'] = $driver['m_regionuid']; + $data['c_region'] = $driver['m_region']; + } + } + } + + // created date + if (empty($existing)) { + if (empty($data['c_createddate'])) { + $data['c_createddate'] = date("YmdHis"); + } + } + $data['c_updateddate'] = date("YmdHis"); + + return $data; + } + + private function hasCustomerChanges( + ?array $before, + ?array $after + ): bool { + + if (!$before || !$after) { + return true; + } + + $businessFields = [ + // 기본 + 'c_accountno', + 'c_name', + 'c_status', + 'c_form_eu', + 'c_form_corsia', + 'c_rate', + 'c_paymenttype', + 'c_hstno', + 'c_driveruid', + + // 지역 + 'c_regionuid', + 'c_area', + 'c_address', + 'c_mailingaddr', + 'c_postal', + 'c_city', + 'c_province', + 'c_geolat', + 'c_geolon', + + // 연락처 + 'c_email', + 'c_phone', + 'c_phoneext', + + // 계약 + 'c_contractdate', + 'c_contractby', + 'c_installdate', + 'c_salesperson', + 'c_salescommissiondate', + 'c_salesmethod', + + // Full Cycle (erp 에서 의미없는 변화) + // 'c_fullcycle', + // 'c_fullquantity', + // 'c_fullcycleflag', + // 'c_fullcycleforced', + // 'c_forceddate', + // 'c_crondate', + + // Schedule + 'c_schedule', + 'c_scheduleday', + + // Location + 'c_location', + + // Pickup + 'c_lastpickupdate', + 'c_lastpickupquantity', + 'c_sludge', + + // Comment + 'c_comment_ri', + 'c_comment_ci' + ]; + + foreach ($businessFields as $field) { + + $beforeVal = trim((string)($before[$field] ?? '')); + $afterVal = trim((string)($after[$field] ?? '')); + + if ($beforeVal !== $afterVal) { + return true; + } + } + + return false; + } +} \ No newline at end of file diff --git a/public_html/assets/api/daily.php b/public_html/assets/api/daily.php index ab027ea..3e35548 100644 --- a/public_html/assets/api/daily.php +++ b/public_html/assets/api/daily.php @@ -2,6 +2,7 @@ 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 { @@ -147,6 +148,7 @@ class DailyService extends CONF { if (in_array($k, [ 'd_orderdate', 'd_accountno', + 'd_customeruid', 'd_jobtype', 'd_inputdate', 'd_estquantity', @@ -245,33 +247,53 @@ class DailyService extends CONF { // ========================= // ERP OUTBOX // ========================= - $event_type = $isUpdate ? 'DAILY_UPDATED' : 'DAILY_CREATED'; - + $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'] + 'd_orderdate' => $afterData['d_orderdate'], + 'd_accountno' => $afterData['d_accountno'], + 'd_jobtype' => $afterData['d_jobtype'] ], - 'before'=>$beforeData, - 'after'=>$afterData + + 'before' => $beforeData, + 'after' => $afterData + ], JSON_UNESCAPED_UNICODE) ); - mysqli_query($connect, " + $qry_outbox = " INSERT INTO tbl_erp_outbox - (eo_event_type, eo_key_date, eo_key_accountno, eo_key_jobtype, eo_payload, eo_status, eo_created_at) + ( + eo_entity_type, + eo_action_type, + eo_key1, + eo_key2, + eo_key3, + eo_payload, + eo_status, + eo_created_at + ) VALUES - ('{$event_type}', - '{$afterData['d_orderdate']}', - '{$afterData['d_accountno']}', - '{$afterData['d_jobtype']}', - '{$payload}', - 'PENDING', - NOW()) - "); + ( + '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 @@ -544,6 +566,7 @@ class DailyService extends CONF { 'd_payamount', 'd_payeename', 'd_paystatus', + 'd_paynote', // customer snapshot 'd_name', @@ -576,14 +599,14 @@ class DailyService extends CONF { // audit 'd_createruid', + 'd_updateruid', 'd_createddate', 'd_inputdate', 'd_modifydate', 'd_ruid', // misc - 'd_payeesign', - 'd_is_transfer' + 'd_payeesign' ]; } @@ -619,11 +642,23 @@ class DailyService extends CONF { private function runAfterSave(?array $before, array $after, array $opt = []): void { - $this->updateCustomerFromDaily($before, $after); + // 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); - $this->handlePickupReset($before, $after); } private function runAfterDelete(array $before, array $opt = []): void @@ -665,126 +700,96 @@ class DailyService extends CONF { "); } - private function updateCustomerFromDaily($before, $after) + private function buildCustomerPatchFromDaily( + ?array $before, + array $after + ): array { $connect = $GLOBALS['conn']; + $customerFields = []; + if (empty($after['d_customeruid'])) { + return $customerFields; + } - if (empty($after['d_customeruid'])) return; - - $customer_uid = mysqli_real_escape_string($connect, $after['d_customeruid']); - - // 고객 현재 상태 조회 + // Customer Current State + $customerUid = (int)$after['d_customeruid']; $qr = mysqli_query($connect, " - SELECT + SELECT c_paymenttype, c_is_top, c_fpickup, c_schedule, c_scheduleday FROM tbl_customer - WHERE c_uid = '{$customer_uid}' + WHERE c_uid = '{$customerUid}' LIMIT 1 "); $customer = mysqli_fetch_assoc($qr); - if (!$customer) return; + if (!$customer) { + return $customerFields; + } - $updateFields = []; - - $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); - $paystatus = $after['d_paystatus'] ?? ''; - $paymenttype = $after['d_paymenttype'] ?? ''; - - $isTop = $customer['c_is_top'] ?? ''; - - // [추가된 로직] d_sludge 업데이트 판단 - // 화면에서 넘어온 d_sludge가 빈칸이 아니면 c_sludge를 갱신 + // 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'] !== '') { - $val = (int)$after['d_sludge']; - $updateFields[] = "c_sludge = '{$val}'"; + $customerFields['c_sludge'] = (int)$after['d_sludge']; } - - // -------------------------------------------------- - // 0) Ghost Check - // -------------------------------------------------- + // Ghost Check if ( - $thisQuantity > 0 && - $lastQuantity > 0 && - $thisQuantity < 10 && - $lastQuantity < 10 && - $isTop !== 'G' + $thisQuantity > 0 + && $lastQuantity > 0 + && $thisQuantity < 10 + && $lastQuantity < 10 + && $isTop !== 'G' ) { - $updateFields[] = "c_is_top = 'G'"; + $customerFields['c_is_top'] = 'G'; } - if ($isTop === 'G' && $thisQuantity >= 10) { - $updateFields[] = "c_is_top = ''"; + $customerFields['c_is_top'] = ''; } - - // -------------------------------------------------- - // 1) c_fpickup 처리 - // -------------------------------------------------- + // First Pickup if ( - empty($customer['c_fpickup']) && - !empty($orderdate) && - $thisQuantity >= 10 + empty($customer['c_fpickup']) + && !empty($orderdate) + && $thisQuantity >= 10 ) { - $updateFields[] = "c_fpickup = '{$orderdate}'"; + $customerFields['c_fpickup'] = $orderdate; } - // -------------------------------------------------- - // 2) orderflag 처리 - // -------------------------------------------------- - if (!empty($after['d_visit']) && $after['d_visit'] === 'Y') { - $updateFields[] = "c_orderdate = ''"; - $updateFields[] = "c_orderflag = 0"; + // Order Flag + if ($status === 'F') { + $customerFields['c_orderdate'] = ''; + $customerFields['c_orderflag'] = 0; } else { - $updateFields[] = "c_orderdate = '{$orderdate}'"; - $updateFields[] = "c_orderflag = 1"; + $customerFields['c_orderdate'] = $orderdate; + $customerFields['c_orderflag'] = 1; } - // -------------------------------------------------- - // 3) Scheduled 처리 (d_ordertype == 'S') - // -> c_schedulebasic 를 시작 기준일로 고정해서 업데이트 필요없음. - // -------------------------------------------------- - // if ($ordertype === 'S' && !empty($visitdate)) { - - // $schedule = $customer['c_schedule'] ?? ''; - // $scheduleDay = $customer['c_scheduleday'] ?? ''; - - // if ($schedule > '1W' && $schedule <= '6W') { - - // $weekCount = (int)substr($schedule, 0, 1); - - // if ($weekCount > 0 && !empty($scheduleDay)) { - - // $dayParts = explode('|', $scheduleDay); - // $dayOfWeek = $dayParts[0] ?? ''; - - // $calcStr = "+{$weekCount} week {$dayOfWeek}"; - // $nextDate = date('Ymd', strtotime($calcStr, strtotime($visitdate))); - - // $updateFields[] = "c_schedulebasic = '{$nextDate}'"; - // } - // } - // } - - // -------------------------------------------------- - // UPDATE 실행 - // -------------------------------------------------- - if (!empty($updateFields)) { - - mysqli_query($connect, " - UPDATE tbl_customer - SET " . implode(",", $updateFields) . " - WHERE c_uid = '{$customer_uid}' - LIMIT 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 @@ -960,39 +965,6 @@ class DailyService extends CONF { error_log("[PickupCleanup] ERP-safe delete completed for customer={$accountno}"); } - private function handlePickupReset(?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'] ?? ''; - - $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']); - $orderdate = mysqli_real_escape_string($connect, $after['d_orderdate']); - - $sql = " - UPDATE tbl_customer - SET - c_fullquantity = 0, - c_lastpickupdate = '{$orderdate}', - c_lastpickupquantity = '{$afterQty}' - WHERE c_uid = '{$customerUid}' - "; - - mysqli_query($connect, $sql); - - error_log("[PickupReset] customer={$accountno} reset fullquantity + lastpickupdate={$orderdate}"); - } - public function deleteDaily(string $orderdate, string $accountno, string $jobtype, array $opt = []) { $connect = $GLOBALS['conn'] ?? null; @@ -1051,21 +1023,47 @@ class DailyService extends CONF { $payload = mysqli_real_escape_string( $connect, json_encode([ - 'key'=>[ - 'd_orderdate'=>$orderdate, - 'd_accountno'=>$accountno, - 'd_jobtype' =>$jobtype + 'entity' => 'DAILY', + 'action' => 'DELETED', + + 'key' => [ + 'd_orderdate' => $orderdate, + 'd_accountno' => $accountno, + 'd_jobtype' => $jobtype ], - 'before'=>$existing + + 'before' => $existing, + 'after' => null + ], JSON_UNESCAPED_UNICODE) ); - if (!mysqli_query($connect, " + $qry_outbox = " INSERT INTO tbl_erp_outbox - (eo_event_type, eo_key_date, eo_key_accountno, eo_key_jobtype, eo_payload, eo_status, eo_created_at) + ( + 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()) - ")) { + ( + 'DAILY', + 'DELETED', + '{$orderdate}', + '{$accountno}', + '{$jobtype}', + '{$payload}', + 'PENDING', + NOW() + ) + "; + + if (!mysqli_query($connect, $qry_outbox)) { throw new Exception(mysqli_error($connect)); } @@ -1115,43 +1113,86 @@ class DailyService extends CONF { $connect = $GLOBALS['conn']; $res = mysqli_query($connect, " - SELECT d_quantity, d_lastpickupquantity - FROM tbl_daily - WHERE d_customeruid = '{$customerUid}' - AND d_status = 'F' - ORDER BY d_orderdate DESC + 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) { - // 데이터 없으면 ghost 였던 것 해제 - mysqli_query($connect, " - UPDATE tbl_customer - SET c_is_top = '' - WHERE c_uid = '{$customerUid}' - and c_is_top = 'G' - "); return; } - $thisQuantity = (int)$row['d_quantity']; - $lastQuantity = (int)$row['d_lastpickupquantity']; + $currentTop = trim( + (string)($row['c_is_top'] ?? '') + ); - if ($thisQuantity < 10 && $lastQuantity < 10) { - mysqli_query($connect, " - UPDATE tbl_customer - SET c_is_top = 'G' - WHERE c_uid = '{$customerUid}' - "); - } else { - mysqli_query($connect, " - UPDATE tbl_customer - SET c_is_top = '' - WHERE c_uid = '{$customerUid}' - and c_is_top = 'G' - "); + $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 + ] + ); } } @@ -1183,7 +1224,8 @@ class DailyService extends CONF { d_quantity, d_sludge, d_paymenttype, - d_paystatus + d_paystatus, + d_updateruid FROM tbl_daily WHERE d_customeruid = '{$customerUidEsc}' AND d_status = 'F' @@ -1234,31 +1276,188 @@ class DailyService extends CONF { } } - // 3) UPDATE 구성 - $setParts = []; - $setParts[] = "c_lastpickupdate=" . ($lastPickupDate ? "'{$lastPickupDate}'" : "''"); - $setParts[] = "c_lastpickupquantity='{$lastPickupQty}'"; - $setParts[] = "c_lastpaiddate=" . ($lastPaidDate ? "'{$lastPaidDate}'" : "''"); - $setParts[] = "c_sludge='" . mysqli_real_escape_string($connect, $lastSludge) . "'"; + // 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) { - $setParts[] = "c_orderdate=''"; - $setParts[] = "c_orderflag=0"; + $customerFields['c_orderdate'] = ''; + $customerFields['c_orderflag'] = 0; } - $sql = " - UPDATE tbl_customer - SET " . implode(",", $setParts) . " - WHERE c_uid = '{$customerUidEsc}' - LIMIT 1 - "; + $customerFields['c_updatedby'] = $last['d_updateruid'] ?? null; - if (!mysqli_query($connect, $sql)) { - throw new Exception(mysqli_error($connect)); + // 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 + ] + ); } /* =============================== diff --git a/public_html/assets/api/install.php b/public_html/assets/api/install.php index 80936a6..7a4896d 100644 --- a/public_html/assets/api/install.php +++ b/public_html/assets/api/install.php @@ -1,10 +1,26 @@ dailyService = new DailyService(); + if (!$svc) { + $svc = new DailyService(); + } + + return $svc; + } + + protected function customerService(): CustomerService + { + static $svc = null; + + if (!$svc) { + $svc = new CustomerService(); + } + + return $svc; } public function search_customer() { @@ -1643,6 +1659,7 @@ trait InstallAPI { 'd_inputdate' => $now14, 'd_level' => $_SESSION['ss_LEVEL'] ?? '', 'd_createruid' => $_SESSION['ss_UID'] ?? '', + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', 'd_createddate' => $now14, ]; @@ -1658,7 +1675,7 @@ trait InstallAPI { ] ]; - $this->dailyService->saveDaily($payload, $opt); + $this->dailyService()->saveDaily($payload, $opt); } private function handleWaitlistAfterInstall(array $di, string $newStatus, int $member_uid, string $note) @@ -2106,21 +2123,32 @@ trait InstallAPI { $current_installdate = $cus['c_installdate']; if (!$current_installdate || $current_installdate === 'N/A' || $install_yyyymmdd < $current_installdate) { - qry(" - UPDATE tbl_customer - SET c_installdate='{$install_yyyymmdd}' - WHERE c_uid='{$customer_uid}' - "); + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_installdate' => $install_yyyymmdd, + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); } // exchange date (최근 install 작업) $current_exchangedate = $cus['c_exchangedate']; if ($current_exchangedate < $install_yyyymmdd) { - qry(" - UPDATE tbl_customer - SET c_exchangedate='{$install_yyyymmdd}' - WHERE c_uid='{$customer_uid}' - "); + + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_exchangedate' => $install_yyyymmdd, + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); } // removal date @@ -2134,19 +2162,30 @@ trait InstallAPI { $row_activeCount = mysqli_fetch_assoc($q_activeCount); $activeCnt = (int)($row_activeCount['active_cnt'] ?? 0); if ($activeCnt === 0) { - qry(" - UPDATE tbl_customer - SET c_removaldate = '{$install_yyyymmdd}' - WHERE c_uid = '{$customer_uid}' - "); + + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_removaldate' => $install_yyyymmdd, + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); + } else { // 치웠다가 다시 설치 - qry(" - UPDATE tbl_customer - SET c_removaldate = '' - WHERE c_uid = '{$customer_uid}' - AND c_removaldate <> '' - "); + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_removaldate' => '', + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); } } @@ -2183,14 +2222,17 @@ trait InstallAPI { // ========================================= if (!count($containers)) { - qry(" - UPDATE tbl_customer - SET - c_mainvolume = 0, - c_maincontainer = '' - WHERE c_uid = '{$customer_uid}' - LIMIT 1 - "); + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_mainvolume' => 0, + 'c_maincontainer' => '', + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); return; } @@ -2253,14 +2295,17 @@ trait InstallAPI { $this->adjustFullCycle($customer_uid, $cus, $oldVolume, $newVolume); // main volume - qry(" - UPDATE tbl_customer - SET - c_mainvolume = '{$maxCapacity}', - c_maincontainer = '{$maxType}' - WHERE c_uid = '{$customer_uid}' - LIMIT 1 - "); + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_mainvolume' => $maxCapacity, + 'c_maincontainer' => $maxType, + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); return; } @@ -2283,14 +2328,17 @@ trait InstallAPI { $this->adjustFullCycle($customer_uid, $cus, $oldVolume, $newVolume); // main volume - qry(" - UPDATE tbl_customer - SET - c_mainvolume = '{$volume}', - c_maincontainer = 'D' - WHERE c_uid = '{$customer_uid}' - LIMIT 1 - "); + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_mainvolume' => $volume, + 'c_maincontainer' => 'D', + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); return; } @@ -2298,14 +2346,17 @@ trait InstallAPI { // ========================================= // 7) fallback (이상 케이스) // ========================================= - qry(" - UPDATE tbl_customer - SET - c_mainvolume = 0, - c_maincontainer = '' - WHERE c_uid = '{$customer_uid}' - LIMIT 1 - "); + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_mainvolume' => 0, + 'c_maincontainer' => '', + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); } private function adjustFullCycle($customer_uid, $cus, $oldVolume, $newVolume) @@ -2330,12 +2381,16 @@ trait InstallAPI { $newForced = $forced * $ratio; } - qry(" - UPDATE tbl_customer - SET c_fullcycleforced = '{$newForced}' - WHERE c_uid = '{$customer_uid}' - LIMIT 1 - "); + $this->customerService()->patchCustomer( + (int)$customer_uid, + [ + 'c_fullcycleforced' => $newForced, + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ], + [ + 'skip_after' => true + ] + ); } private function reorder_daily_install_sequence($driver_uid, $install_date) { diff --git a/public_html/assets/internal_api.php b/public_html/assets/internal_api.php index b9a3ddc..e55e3c2 100644 --- a/public_html/assets/internal_api.php +++ b/public_html/assets/internal_api.php @@ -9,6 +9,7 @@ include getenv("DOCUMENT_ROOT")."/include/session_include.php"; include_once getenv("DOCUMENT_ROOT")."/lib/erp_api.php"; include_once getenv("DOCUMENT_ROOT")."/assets/api/install.php"; include_once getenv("DOCUMENT_ROOT")."/assets/api/daily.php"; +include_once getenv("DOCUMENT_ROOT")."/assets/api/customer.php"; error_reporting(E_ALL); ini_set('display_errors', '1'); @@ -435,80 +436,68 @@ class API extends CONF { } } - public function updtPoint(){ - try { - qry("UPDATE tbl_customer SET c_geolat=".$_POST['lat'].", c_geolon=".$_POST['lon'].", c_is_transfer='N' WHERE c_uid=".(int)$_POST['id']); - - // ==================== - // Integration to ERP - // ==================== - $erp = new ErpApi(); - + public function updtPoint() + { try { - $columns = array(); - $values = array(); - $columns[] = "c_accountno"; - $columns[] = "c_geolat"; - $columns[] = "c_geolon"; - $values[] = $_POST['accountno']; - $values[] = $_POST['lat']; - $values[] = $_POST['lon']; - $lguserid = $_SESSION['ss_UID']; - $erp->updateCustomerFromMis($columns, $values, $lguserid); + $svc = new CustomerService(); + $svc->patchCustomer( + (int)$_POST['id'], + [ + 'c_geolat' => $_POST['lat'], + 'c_geolon' => $_POST['lon'], + 'c_updatedby' => $_SESSION['ss_UID'] + ] + ); - // 성공 시 c_is_transfer='Y' - qry("UPDATE tbl_customer SET c_is_transfer = 'Y' WHERE c_uid = ".(int)$_POST['id']); + $this->response( + $this->json([ + "markerIndex" => $_POST['marker_index'], + "lat" => $_POST['lat'], + "lon" => $_POST['lon'], + "name" => $_POST['name'], + "qty" => $_POST['qty'], + "property" => $_POST['property'] + ]), + 200 + ); } catch (Exception $e) { - // 여기서는 아무것도 안함. + $error = array($e->getMessage()); + $this->response( + $this->json($error), + 417 + ); } - - $this->response($this->json(array("markerIndex"=>$_POST['marker_index'], "lat"=>$_POST['lat'], "lon"=>$_POST['lon'], "name"=>$_POST['name'], "qty"=>$_POST['qty'], "property"=>$_POST['property'])), 200); - } catch(Exception $e) { - $error = array($e->getMessage()); - $this->response($this->json($error), 417); - } - } - - public function updtShortInfo(){ - try { - qry("UPDATE tbl_customer - SET c_location='".addslashes($_POST['location'])."', - c_comment_ri='".addslashes($_POST['comment'])."', - c_is_transfer='N' - WHERE c_uid=".(int)$_POST['id']); - - // ==================== - // Integration to ERP - // ==================== - $erp = new ErpApi(); + } + public function updtShortInfo() + { try { - $columns = array(); - $values = array(); - $columns[] = "c_accountno"; - $columns[] = "c_location"; - $columns[] = "c_comment_ri"; - $values[] = $_POST['accountno']; - $values[] = addslashes($_POST['location']); - $values[] = addslashes($_POST['comment']); - $lguserid = $_SESSION['ss_UID']; - $erp->updateCustomerFromMis($columns, $values, $lguserid); + $svc = new CustomerService(); + $svc->patchCustomer( + (int)$_POST['id'], + [ + 'c_location' => trim($_POST['location']), + 'c_comment_ri' => trim($_POST['comment']), + 'c_updatedby' => $_SESSION['ss_UID'] + ] + ); - // 성공 시 c_is_transfer='Y' - qry("UPDATE tbl_customer SET c_is_transfer = 'Y' WHERE c_uid = ".(int)$_POST['id']); + $this->response( + $this->json([ + "result" => "success" + ]), + 200 + ); } catch (Exception $e) { - // 여기서는 아무것도 안함. + $error = array($e->getMessage()); + $this->response( + $this->json($error), + 417 + ); } - - $this->response($this->json(array("result"=>"success")), 200); - } catch(Exception $e) { - $error = array($e->getMessage()); - $this->response($this->json($error), 417); - } - } - + } public function inqDriverGeo(){ try { @@ -1252,6 +1241,7 @@ class API extends CONF { 'd_druid' => $driveruid, // 실제 driver 'd_status' => 'A', 'd_createruid' => $_SESSION['ss_UID'] ?? '', + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', 'd_createddate' => $now14, 'n_level' => $_SESSION['ss_LEVEL'], ]; @@ -1344,6 +1334,7 @@ class API extends CONF { 'd_ordertype' => 'N', 'd_jobtype' => 'UCO', 'd_createruid' => $creatoruid, + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', 'd_createddate' => $now14, 'n_level' => $_SESSION['ss_LEVEL'], ]; @@ -1611,6 +1602,27 @@ class API extends CONF { } } + // ========================= + // SAFETY CHECK + // ========================= + if ($existing) { + // row 와 넘어온 customer 가 다르면 중단 + if ( + (int)$existing['d_customeruid'] !== $customerUid + || $existing['d_accountno'] !== $customer['c_accountno'] + ) { + + throw new Exception( + "Daily key mismatch. " + . "UID={$uid}, " + . "Existing Customer={$existing['d_customeruid']}, " + . "Input Customer={$customerUid}, " + . "Existing Account={$existing['d_accountno']}, " + . "Input Account={$customer['c_accountno']}" + ); + } + } + $now14 = date('YmdHis'); // ========================= @@ -1638,7 +1650,7 @@ class API extends CONF { 'd_paystatus' => $paystatusSTR, 'd_inputdate' => $now14, - 'd_is_transfer' => 'N', + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', 'd_level' => $_SESSION['ss_LEVEL'], ]; diff --git a/public_html/doc/customer_process.php b/public_html/doc/customer_process.php index fd47e04..2d98541 100644 --- a/public_html/doc/customer_process.php +++ b/public_html/doc/customer_process.php @@ -3,6 +3,7 @@ include getenv("DOCUMENT_ROOT")."/include/session_include.php"; @include getenv("DOCUMENT_ROOT")."/config/config_shopInfo.php"; include_once getenv("DOCUMENT_ROOT") . "/lib/erp_api.php"; +include_once getenv("DOCUMENT_ROOT")."/assets/api/customer.php"; $goStr = "switched=$switched&page=$page&key_word=$key_word&column=$column&sorting_type=$sorting_type&switch=$switch&cstatus=$cstatus"; @@ -50,13 +51,23 @@ if ($actionStr == "CUSTOMERINFO" && $mode == "delete") { exit(); } - - $jdb->nQuery("UPDATE tbl_customer SET c_status='D', c_is_transfer = 'N' WHERE c_uid = '$c_uid'", "delete error"); - - // ==================== - // Integration to ERP - // ==================== - // 화면에서 기능이 없음 + try { + $svc = new CustomerService(); + $svc->patchCustomer( + (int)$c_uid, + [ + 'c_status' => 'D', + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ] + ); + } catch (Exception $e) { + $msg = $e->getMessage(); + $func->modalMsg( + $msg, + "/index_intranet.php" + ); + exit(); + } $msg = "Deleted successfully."; $urlSTR = "/index_intranet.php?view=customer_list&$goStr"; @@ -75,298 +86,180 @@ if ($actionStr == "CUSTOMERINFO" && $mode == "delete") { if ($actionStr == "CUSTOMERINFO") { - if($mode == "update") { - if($c_uid == "") { - $msg = "Invalid data. Please try again."; - $func -> modalMsg ($msg, ""); - exit(); - } - } + if ($mode == "update") { + if ($c_uid == "") { + $msg = "Invalid data. Please try again."; + $func->modalMsg($msg, ""); + exit(); + } + } - $columns = array(); - $values = array(); - - if($mode == "create") { - //$columns[] = "c_uid"; - $columns[] = "c_createddate"; - } - $columns[] = "c_accountno"; - //$columns[] = "c_gid"; - $columns[] = "c_form_us"; - $columns[] = "c_form_eu"; - $columns[] = "c_form_corsia"; - $columns[] = "c_form_new"; - $columns[] = "c_driveruid"; - $columns[] = "c_name"; - $columns[] = "c_paymenttype"; - $columns[] = "c_payableto"; - $columns[] = "c_paymentcycle"; - $columns[] = "c_mailingaddr"; - $columns[] = "c_rate"; - $columns[] = "c_mainvolume"; - $columns[] = "c_maincontainer"; - $columns[] = "c_container"; - $columns[] = "c_location"; - $columns[] = "c_phone"; - $columns[] = "c_phoneext"; - $columns[] = "c_cell"; - $columns[] = "c_email"; - $columns[] = "c_address"; - $columns[] = "c_city"; - $columns[] = "c_postal"; - //$columns[] = "c_area"; - $columns[] = "c_province"; - $columns[] = "c_contractdate"; - $columns[] = "c_contractby"; - $columns[] = "c_installdate"; - $columns[] = "c_schedule"; - $columns[] = "c_scheduleday"; - $columns[] = "c_schedulebasic"; - $columns[] = "c_fpickup"; - $columns[] = "c_salesperson"; - $columns[] = "c_salescommissiondate"; - $columns[] = "c_salesmethod"; - $columns[] = "c_status"; + try { + $data = []; - $columns[] = "c_comment_ri"; - $columns[] = "c_comment_ci"; - $columns[] = "c_fullcycle"; - $columns[] = "c_fullcycleforced"; - $columns[] = "c_fullcycleflag"; - $columns[] = "c_forceddate"; - $columns[] = "c_sludge"; - - $columns[] = "c_removaldate"; - $columns[] = "c_inactivedate"; - $columns[] = "c_exchangedate"; - $columns[] = "c_switchformdate"; + // ========================= + // MODE + // ========================= + $data['mode'] = $mode; + if ($mode == "update") { + $data['c_uid'] = $c_uid; + } - $columns[] = "c_expoilmonth"; - $columns[] = "c_hstno"; - $columns[] = "c_identcode"; - - $columns[] = "c_regionuid"; - $columns[] = "c_region"; + // ========================= + // BASIC + // ========================= + $data['c_accountno'] = $c_accountno; + $data['c_form_us'] = $c_form_us; + $data['c_form_eu'] = str_replace("-", "", trim($c_form_eu)); + $data['c_form_corsia'] = str_replace("-", "", trim($c_form_corsia)); + $data['c_form_new'] = $c_form_new; + $data['c_driveruid'] = $c_driveruid; + $data['c_name'] = str_replace("\\", "", trim($c_name)); + $data['c_status'] = $c_status; + $data['c_comment_ri'] = str_replace("\\","",trim($c_comment_ri)); - $columns[] = "c_manualvolume"; - - //////////// - // data - //////////// - if($mode == "create") { - //$values[] = $c_uid; - $values[] = date("YmdHis"); - } - $values[] = $c_accountno; - //$values[] = $c_gid; - $values[] = $c_form_us; - $values[] = str_replace("-", "", trim($c_form_eu)); - $values[] = str_replace("-", "", trim($c_form_corsia)); - $values[] = $c_form_new; - $values[] = $c_driveruid; - $values[] = str_replace("\\", "", trim($c_name)); - $values[] = $c_paymenttype; - $values[] = str_replace("\\", "", trim($c_payableto)); - $values[] = $c_paymentcycle; - $values[] = str_replace("\\", "", trim($c_mailingaddr)); - $values[] = $c_rate; - $values[] = $c_mainvolume; - $values[] = str_replace("\\", "", trim($c_maincontainer)); - $values[] = str_replace("\\", "", trim($c_container)); - $values[] = str_replace("\\", "", trim($c_location)); - - $c_phone = str_replace("-", "", trim($c_phone)); - - $values[] = str_replace("\\", "", trim($c_phone)); - $values[] = str_replace("\\", "", trim($c_phoneext)); - $values[] = str_replace("\\", "", trim($c_cell)); - $values[] = str_replace("\\", "", trim($c_email)); - $values[] = str_replace("\\", "", trim($c_address)); - $values[] = str_replace("\\", "", trim($c_city)); - $values[] = str_replace("\\", "", trim($c_postal)); - //$values[] = $c_area; - $values[] = "ON"; - $values[] = str_replace("-", "", trim($c_contractdate)); - $values[] = str_replace("\\", "", trim($c_contractby)); - $values[] = str_replace("-", "", trim($c_installdate)); - $values[] = $c_schedule; + // ========================= + // PAYMENT + // ========================= + $data['c_rate'] = $c_rate; + $data['c_paymenttype'] = $c_paymenttype; + $data['c_payableto'] = str_replace("\\","",trim($c_payableto)); + $data['c_paymentcycle'] = $c_paymentcycle; + $data['c_mailingaddr'] = str_replace("\\","",trim($c_mailingaddr)); - if(isset($_POST["c_scheduleday"])){ - $c_scheduleday_vals =""; - foreach($_POST["c_scheduleday"] as $key => $text_field){ - $c_scheduleday_vals .= $text_field ."|"; - } - } - - $values[] = $c_scheduleday_vals; - $values[] = str_replace("-", "", trim($c_schedulebasic)); - $values[] = str_replace("-", "", trim($c_fpickup)); - $values[] = str_replace("\\", "", trim($c_salesperson)); - $values[] = str_replace("-", "", trim($c_salescommissiondate)); - $values[] = str_replace("\\", "", trim($c_salesmethod)); - $values[] = $c_status; - $values[] = str_replace("\\", "", trim($c_comment_ri)); - $values[] = str_replace("\\", "", trim($c_comment_ci)); - $values[] = $c_fullcycle; - $values[] = $c_fullcycleforced; - - if ($c_fullcycleforced != "" && (float)$c_fullcycleforced != 0) $c_fullcycleflag = 1; - else $c_fullcycleflag = 0; - $values[] = $c_fullcycleflag; - + // ========================= + // CONTAINER + // ========================= + $data['c_mainvolume'] = $c_mainvolume; + $data['c_maincontainer'] = str_replace("\\","",trim($c_maincontainer)); + $data['c_container'] = str_replace("\\","",trim($c_container)); + $data['c_location'] = str_replace("\\","",trim($c_location)); + $data['c_removaldate'] = str_replace("-","",trim($c_removaldate)); + $data['c_inactivedate'] = str_replace("-","",trim($c_inactivedate)); + $data['c_exchangedate'] = str_replace("-","",trim($c_exchangedate)); - if ($mode == "update" && $c_fullcycleflag == 1) { - $qry_n = "SELECT c_fullcycleforced FROM tbl_customer WHERE c_uid = '$c_uid' "; - $rt_n = $jdb->fQuery($qry_n, "list error"); - } - - $values[] = $c_forceddate; - - $values[] = $c_sludge; + // ========================= + // CONTACT + // ========================= + $c_phone = str_replace("-", "", trim($c_phone)); + $data['c_phone'] = str_replace("\\","",trim($c_phone)); + $data['c_phoneext'] = str_replace("\\","",trim($c_phoneext)); + $data['c_cell'] = str_replace("\\","",trim($c_cell)); + $data['c_email'] = str_replace("\\","",trim($c_email)); + $data['c_address'] = str_replace("\\","",trim($c_address)); + $data['c_city'] = str_replace("\\","",trim($c_city)); + $data['c_postal'] = str_replace("\\","",trim($c_postal)); + $data['c_province'] = "ON"; - $values[] = str_replace("-", "", trim($c_removaldate)); - $values[] = str_replace("-", "", trim($c_inactivedate)); - $values[] = str_replace("-", "", trim($c_exchangedate)); - $values[] = str_replace("-", "", trim($c_switchformdate)); + // ========================= + // CONTRACT + // ========================= + $data['c_contractdate'] = str_replace("-","",trim($c_contractdate)); + $data['c_contractby'] = str_replace("\\","",trim($c_contractby)); + $data['c_installdate'] = str_replace("-","",trim($c_installdate)); + $data['c_salesperson'] = str_replace("\\","",trim($c_salesperson)); + $data['c_salescommissiondate'] = str_replace("-","",trim($c_salescommissiondate)); + $data['c_salesmethod'] = str_replace("\\","",trim($c_salesmethod)); + $data['c_switchformdate'] = str_replace("-","",trim($c_switchformdate)); + $data['c_comment_ci'] = str_replace("\\","",trim($c_comment_ci)); - $values[] = $c_expoilmonth; - $values[] = str_replace("\\", "", trim($c_hstno)); - $values[] = str_replace("\\", "", trim($c_identcode)); - - $qry_dvr = "SELECT m_regionuid, m_region FROM tbl_member WHERE m_uid = '".$c_driveruid."' "; - $rt_dvr = $jdb->fQuery($qry_dvr, "fetch query error"); - - $values[] = $rt_dvr['m_regionuid']; - $values[] = str_replace("\\", "", trim($rt_dvr['m_region'])); - - $values[] = isset($_POST['isManual']) ? 'Y' : 'N'; + // ========================= + // SCHEDULE + // ========================= + $data['c_schedule'] = $c_schedule; + $c_scheduleday_vals = ""; + if (isset($_POST["c_scheduleday"])) { + foreach ($_POST["c_scheduleday"] as $key => $text_field) { + $c_scheduleday_vals .= $text_field . "|"; + } + } + $data['c_scheduleday'] = $c_scheduleday_vals; + $data['c_schedulebasic'] = str_replace("-","",trim($c_schedulebasic)); + $data['c_fpickup'] = str_replace("-","",trim($c_fpickup)); - //for ($i=0; $i < count($columns); $i++) - //echo "[$columns[$i]][$values[$i]]
"; - //echo "[UID=$uid][ID=$userid][MAXUID=$maxuid]"; - //exit; - - if($mode == "create") { - $jdb->iQuery("tbl_customer", $columns, $values); - $msg = "Created successfully."; + // ========================= + // FULL CYCLE + // ========================= + $data['c_fullcycle'] = $c_fullcycle; + $data['c_fullcycleforced'] = $c_fullcycleforced; + if ($c_fullcycleforced != "" && (float)$c_fullcycleforced != 0) { + $c_fullcycleflag = 1; + } else { + $c_fullcycleflag = 0; + } + $data['c_fullcycleflag'] = $c_fullcycleflag; + $data['c_forceddate'] = $c_forceddate; - $query = "SELECT max(c_uid) FROM tbl_customer "; - $rt=$jdb->fQuery($query, "fetch query error"); - - $c_uid = $rt[0]; + // ========================= + // ETC + // ========================= + $data['c_sludge'] = $c_sludge; + $data['c_expoilmonth'] = $c_expoilmonth; + $data['c_hstno'] = str_replace("\\","",trim($c_hstno)); + $data['c_identcode'] = str_replace("\\","",trim($c_identcode)); + $data['c_manualvolume'] = isset($_POST['isManual'])? 'Y': 'N'; + $data['c_createdby'] = $_SESSION['ss_UID'] ?? null; + $data['c_updatedby'] = $_SESSION['ss_UID'] ?? null; - addLog ("add", "CUSTOMER DETAIL", "CREATE", $lguserid, "", $c_uid); - - //$query = "select max(uid) from tbl_members "; - //$user_id = $jdb->rQuery($query, "max query error"); - } - - else if($mode == "update") { - - $query = "SELECT c_uid, c_driveruid, c_address, c_postal, c_fullcycleforced FROM tbl_customer WHERE c_uid = '$c_uid' "; - $rt=$jdb->fQuery($query, "fetch query error"); - - $c_uid = $rt[0]; - $c_driveruid_old = $rt[1]; - - if ($c_fullcycleflag == 1) { - $c_fullcycleforcedSTR = "Org: ".$rt[4].", New: ".$c_fullcycleforced; - addLog ("add", "FORCED CYCLE - CUSTOMER", "UPDATE", $lguserid, $c_fullcycleforcedSTR, $c_uid); - } + // ========================= + // SAVE + // ========================= + $svc = new CustomerService(); + $result = $svc->saveCustomer( + $data + ); - // c_address, c_postal 변경시 geo 값 초기화 (2024.06.05) - if (str_replace("\\", "", trim($c_address)) != str_replace("\\", "", $rt['c_address']) || - str_replace("\\", "", trim($c_postal)) != str_replace("\\", "", $rt['c_postal'] )) { - - $qry_geo = "UPDATE tbl_customer SET c_geolat=NULL, c_geolon=NULL WHERE c_uid = '".$c_uid."'"; - $jdb->nQuery($qry_geo, "Update error"); - - addLog ("add", "CUSTOMER DETAIL - GEO RESET", "UPDATE", $lguserid, $qry_geo, $c_uid); - } + // ========================= + // LOG + // ========================= + if ($mode == "create") { + addLog( + "add", + "CUSTOMER DETAIL", + "CREATE", + $lguserid, + "", + $result['c_uid'] + ); + $msg = "Created successfully."; - $jdb->uQuery("tbl_customer", $columns, $values, " where c_uid = '$c_uid' "); - $msg = "Updated successfully."; + } else { - addLog ("add", "CUSTOMER DETAIL", "UPDATE", $lguserid, "", $c_uid); + addLog( + "add", + "CUSTOMER DETAIL", + "UPDATE", + $lguserid, + "", + $result['c_uid'] + ); - - // Sludge, rate, paymentcycle Update - 오늘 이후 오더장에만 적용한다. by 이강 2025-12-09 - $today = date("Ymd"); - $qry_sludge = "UPDATE tbl_daily - SET - d_rate='".$c_rate."', - d_cycle='".$c_paymentcycle."', - d_paymenttype='".$c_paymenttype."' - WHERE d_customeruid = '".$c_uid."' - and d_orderdate > '".$today."' - "; - $jdb->nQuery($qry_sludge, "Update error"); - - addLog ("add", "CUSTOMER DETAIL - SLUDGE, RATE, PAYMENTCYCLE, PAYMENTTYPE", "UPDATE", $lguserid, $qry_sludge, $c_uid); + $msg = "Updated successfully."; + } - // 모든 테이블의 드라이버 정보 업데이트 - // customer page 에서 driver 정보 업데이트시 현재일을 포함한 그 이후의 오더장이 존재하는 경우 - // 오더장의 driver를 변경된 driver로 업데이트. (2024.04.05) - // Request 도 현재일을 포함한 그 이후의 데이터가 존재하는 경우 변경된 driver 로 업데이트. (2024.04.05) - if ($c_driveruid != $c_driveruid_old) { - - $addqry_daily = " AND d_orderdate >= '".date("Ymd")."'"; - - $qry_driverd = "UPDATE tbl_daily SET d_driveruid='".$c_driveruid."' WHERE d_customeruid = '".$c_uid."'". $addqry_daily; - $jdb->nQuery($qry_driverd, "Update error"); + // ========================= + // SUCCESS + // ========================= + $func->modalMsg( + $msg, + "/index_intranet.php?view=customer_detail&mode=update&c_uid=".$result['c_uid']."&$goStr" + ); - addLog ("add", "CUSTOMER DETAIL - SLUDGE, RATE, PAYMENTCYCLE, PAYMENTTYPE", "UPDATE", $lguserid, $qry_driverd, $c_uid); - - $addqry_req = " AND r_requestdate >= '".date("Ymd")."'"; - - $qry_driverr = "UPDATE tbl_request SET r_driveruid='".$c_driveruid."' - WHERE r_driveruid = '".$c_driveruid_old."' AND r_customeruid = '".$c_uid."'". $addqry_req; - $jdb->nQuery($qry_driverr, "Update error"); - - addLog ("add", "CUSTOMER DETAIL - SLUDGE, RATE, PAYMENTCYCLE, PAYMENTTYPE", "UPDATE", $lguserid, $qry_driverr, $c_uid); - - } - } - // ==================== - // Integration to ERP - // ==================== - $erp = new ErpApi(); + exit(); - try { + } catch (Exception $e) { - if ($mode == "create") { - // MIS → ERP CREATE (payload 매핑은 ErpApi 내부에서 자동 처리) - $erp->createCustomerFromMis($columns, $values, $lguserid); - } - else if ($mode == "update") { - // MIS → ERP UPDATE - $erp->updateCustomerFromMis($columns, $values, $lguserid); - } + $msg = $e->getMessage(); - // 성공 시 c_is_transfer='Y' - $jdb->uQuery("tbl_customer", ["c_is_transfer"], ["Y"], " WHERE c_uid = '$c_uid'"); + $func->modalMsg( + $msg, + "/index_intranet.php" + ); - // - $func->modalMsg($msg, "/index_intranet.php?view=customer_detail&mode=update&c_uid=$c_uid&$goStr"); - exit(); - - } catch (Exception $e) { - $msg = "Check Integration Log."; - $func->modalMsg($msg, "/index_intranet.php"); - exit(); - } - - $msg = "Invalid data. Please try again."; - $func -> modalMsg ($msg, ""); - exit(); - - -} else { - $msg = "Invalid data. Please try again."; - $func -> modalMsg ($msg, "/index_intranet.php"); - exit(); + exit(); + } } diff --git a/public_html/doc/forecast_list.php b/public_html/doc/forecast_list.php index 9051a4b..3cde2f7 100644 --- a/public_html/doc/forecast_list.php +++ b/public_html/doc/forecast_list.php @@ -741,7 +741,9 @@ if ($c_type_p == 'P') { } else { // 몇 주마다? $weekNum = intval(str_replace('W', '', $c_schedule)); - if (!empty($c_schedulebasic)) { + + if($weekNum == 1) $isScheduleMatch = true; + else if (!empty($c_schedulebasic)) { $baseDate = strtotime($c_schedulebasic); $targetDate = strtotime($orderdate); // 날짜 차이 diff --git a/public_html/lib/lib_updatecycle.php b/public_html/lib/lib_updatecycle.php index fa17333..9d0d849 100644 --- a/public_html/lib/lib_updatecycle.php +++ b/public_html/lib/lib_updatecycle.php @@ -1,6 +1,7 @@ fQuery($qry_org, "query error"); - - $qry_cycle = "UPDATE tbl_customer - SET c_fullcycleforced = $c_fullcycle, c_fullcycleflag = 1, c_forceddate = '".date("Ymd")."' - WHERE c_uid = '$c_uid' "; - $jdb->nQuery($qry_cycle, "update error"); + $qry_org = "SELECT c_fullcycle, c_fullcycleforced, c_fullcycleflag, c_mainvolume + FROM tbl_customer WHERE c_uid = '$c_uid' "; + $rt_org = $jdb->fQuery($qry_org, "query error"); + try { + $svc = new CustomerService(); + $svc->patchCustomer( + (int)$c_uid, + [ + 'c_fullcycleforced' => $c_fullcycle, + 'c_fullcycleflag' => 1, + 'c_forceddate' => date("Ymd"), + 'c_updatedby' => $_SESSION['ss_UID'] ?? null + ] + ); + addLog ("add", "FORCED CYCLE", "UPDATE", $lguserid, $qry_cycle, $c_uid); $qry = "SELECT c_fullcycleforced, c_fullcycleflag FROM tbl_customer WHERE c_uid = '$c_uid' "; @@ -52,6 +60,9 @@ if ($c_uid != "" && $c_fullcycle !== "") { if ($rt_org['c_fullcycleflag'] == 1) echo "ERROR1|".$rt_org['c_fullcycleforced']."|".$rt_org['c_fullcycleforced']; else echo "ERROR1|".$rt_org['c_fullcycle']."|0"; } + } catch (Exception $e) { + echo "ERROR3"; + } } else echo "ERROR2"; diff --git a/public_html/lib/mapper/erpCustomerMapper.php b/public_html/lib/mapper/erpCustomerMapper.php new file mode 100644 index 0000000..1645446 --- /dev/null +++ b/public_html/lib/mapper/erpCustomerMapper.php @@ -0,0 +1,201 @@ + $cfg) { + + $dtoField = $cfg['dto']; + + $mapped[$dtoField] = self::transformValue( + $after[$misField] ?? null, + $cfg['type'] + ); + } + + // audit + $mapped['cusSourceType'] = 'MIS'; + + + return $mapped; + } + + private static function mapPatch($payload) + { + $before = $payload['before'] ?? []; + $after = $payload['after'] ?? []; + + $patch = []; + + foreach (self::fieldMap() as $misField => $cfg) { + + $beforeVal = $before[$misField] ?? null; + $afterVal = $after[$misField] ?? null; + + if (!self::isDifferent($beforeVal, $afterVal)) { + continue; + } + + $patch[$cfg['dto']] = self::transformValue( + $afterVal, + $cfg['type'] + ); + } + + // NO CHANGE + if (count($patch) <= 0) { + return null; + } + + // REQUIRED + $patch['cusSourceType'] = 'MIS'; + $patch['cusNo'] = $after['c_accountno'] ?? null; + $patch['cusExternalUpdatedBy'] = $after['c_updatedby'] ?? null; + + return $patch; + } + + // FIELD MAP + private static function fieldMap(): array + { + return [ + 'c_accountno' => ['dto' => 'cusNo' , 'type' => 'string'], + 'c_name' => ['dto' => 'cusName' , 'type' => 'string'], + 'c_status' => ['dto' => 'cusStatus' , 'type' => 'string'], + 'c_regionuid' => ['dto' => 'cusRegionId' , 'type' => 'int'], + 'c_area' => ['dto' => 'cusAreaId' , 'type' => 'int'], + 'c_address' => ['dto' => 'cusAddress1' , 'type' => 'string'], + 'c_location' => ['dto' => 'cusAddress2' , 'type' => 'string'], + 'c_postal' => ['dto' => 'cusPostalCode' , 'type' => 'string'], + 'c_city' => ['dto' => 'cusCity' , 'type' => 'string'], + 'c_province' => ['dto' => 'cusProvince' , 'type' => 'string'], + 'c_geolat' => ['dto' => 'cusGeoLat' , 'type' => 'float'], + 'c_geolon' => ['dto' => 'cusGeoLon' , 'type' => 'float'], + 'c_email' => ['dto' => 'cusEmail' , 'type' => 'string'], + 'c_phone' => ['dto' => 'cusPhone' , 'type' => 'string'], + 'c_phoneext' => ['dto' => 'cusPhoneExt' , 'type' => 'string'], + 'c_contractdate' => ['dto' => 'cusContractDate' , 'type' => 'date'], + 'c_contractby' => ['dto' => 'cusContractedBy' , 'type' => 'string'], + 'c_installdate' => ['dto' => 'cusInstallDate' , 'type' => 'date'], + // 'c_fullcycle' => ['dto' => 'cusFullCycle' , 'type' => 'decimal'], + // 'c_fullcycleflag' => ['dto' => 'cusFullCycleFlag' , 'type' => 'bool'], + // 'c_fullcycleforced' => ['dto' => 'cusFullCycleForced' , 'type' => 'decimal'], + // 'c_forceddate' => ['dto' => 'cusFullCycleForcedDate' , 'type' => 'date'], + 'c_schedule' => ['dto' => 'cusSchedule' , 'type' => 'string'], + 'c_scheduleday' => ['dto' => 'cusScheduledays' , 'type' => 'string'], + 'c_lastpaiddate' => ['dto' => 'cusLastPaidDate' , 'type' => 'date'], + 'c_rate' => ['dto' => 'cusRate' , 'type' => 'float'], + 'c_paymenttype' => ['dto' => 'cusPayMethod' , 'type' => 'string'], + 'c_form_eu' => ['dto' => 'cusIsccDate' , 'type' => 'date'], + 'c_form_corsia' => ['dto' => 'cusCorsiaDate' , 'type' => 'date'], + 'c_hstno' => ['dto' => 'cusHstNo' , 'type' => 'string'], + 'c_inactivedate' => ['dto' => 'cusTerminatedDate' , 'type' => 'date'], + 'c_lastpickupdate' => ['dto' => 'cusLastPickupDate' , 'type' => 'date'], + 'c_lastpickupquantity' => ['dto' => 'cusLastPickupQty' , 'type' => 'int'], + 'c_sludge' => ['dto' => 'cusLastSludge' , 'type' => 'int'], + 'c_comment_ri' => ['dto' => 'cusComment' , 'type' => 'string'], + 'c_comment_ci' => ['dto' => 'cusContactComment' , 'type' => 'string'], + 'c_createdby' => ['dto' => 'cusExternalCreatedBy' , 'type' => 'string'], + 'c_updatedby' => ['dto' => 'cusExternalUpdatedBy' , 'type' => 'string'], + 'c_salesperson' => ['dto' => 'cusSalesperson' , 'type' => 'string'], + 'c_salescommissiondate' => ['dto' => 'cusSalesCommissionDate' , 'type' => 'string'], + 'c_salesmethod' => ['dto' => 'cusSalesMethod' , 'type' => 'string'], + // 어차피 무시당함 + // 'c_createddate' => ['dto' => 'cusCreatedAt' , 'type' => 'datetime'], + // 'c_updateddate' => ['dto' => 'cusUpdatedAt' , 'type' => 'datetime'], + ]; + } + + // VALUE TRANSFORM + private static function transformValue( + $value, + string $type + ) { + + switch ($type) { + + case 'int': + return ($value === ''||$value === null) ? null : (int)$value; + + case 'float': + return ($value === ''||$value === null) ? null : (float)$value; + + case 'decimal': + return ($value === ''||$value === null) ? null : (float)$value; + + case 'bool': + return ($value == '1'||$value === 1||$value === true); + + case 'date': + return self::date($value); + + case 'datetime': + return self::datetime($value); + + default: + return $value; + } + } + + private static function isDifferent($a, $b): bool + { + if (is_numeric($a) && is_numeric($b)) { + return (float)$a != (float)$b; + } + + return $a !== $b; + } + + private static function date($value) + { + $value = trim((string)$value); + if ($value == '') { + return null; + } + + $value = preg_replace('/[^0-9]/','',$value); + if (strlen($value) != 8) { + return null; + } + + return + substr($value, 0, 4) + . '-' + . substr($value, 4, 2) + . '-' + . substr($value, 6, 2); + } + + private static function datetime($yyyymmddhhmiss) + { + if ( + empty($yyyymmddhhmiss) + || strlen($yyyymmddhhmiss) != 14 + ) { + return null; + } + + return substr($yyyymmddhhmiss,0,4)."-". + substr($yyyymmddhhmiss,4,2)."-". + substr($yyyymmddhhmiss,6,2)."T". + substr($yyyymmddhhmiss,8,2).":". + substr($yyyymmddhhmiss,10,2).":". + substr($yyyymmddhhmiss,12,2); + } +} + diff --git a/public_html/lib/mapper/erpDailyOrderMapper.php b/public_html/lib/mapper/erpDailyOrderMapper.php new file mode 100644 index 0000000..bd1d88a --- /dev/null +++ b/public_html/lib/mapper/erpDailyOrderMapper.php @@ -0,0 +1,69 @@ + self::date($after['d_orderdate']), + "cdoJobType" => $after['d_jobtype'] ?? null, + "cdoOrderType" => $after['d_ordertype'] ?? null, + "cdoRegionId" => !empty($after['d_regionuid']) ? (int)$after['d_regionuid'] : null, + "cdoExternalDriverId" => $after['d_druid'] ?? null, + "cdoExternalCreatedBy" => $after['d_createruid'] ?? null, + "cdoExternalUpdatedBy" => $after['d_driveruid'] ?? null, + "cdoCustomerNo" => $after['d_accountno'] ?? null, + "cdoPaymentType" => $after['d_paymenttype'] ?? null, + "cdoCycle" => $after['d_cycle'] ?? null, + "cdoRate" => isset($after['d_rate']) ? (float)$after['d_rate'] : null, + "cdoStatus" => $after['d_status'] ?? 'A', + "cdoVisitFlag" => $after['d_visit'] ?? 'N', + "cdoEstimatedQty" => isset($after['d_estquantity']) ? (float)$after['d_estquantity'] : null, + "cdoPickupAt" => ($after['d_status'] ?? '') === 'F' ? self::datetime($after['d_modifydate'] ?? null) : null, + "cdoQuantity" => isset($after['d_quantity']) ? (float)$after['d_quantity'] : null, + "cdoSludge" => isset($after['d_sludge']) ? (int)$after['d_sludge'] : null, + "cdoPayStatus" => self::nullable($after['d_paystatus'] ?? null), + "cdoPayAmount" => isset($after['d_payamount']) ? (float)$after['d_payamount'] : null, + "cdoPayeeName" => self::nullable($after['d_payeename'] ?? null), + "cdoPayeeSign" => $after['d_payeesign'] ?? null, + // "cdoPickupNote" => $after['d_location'] ?? null, + ]; + } + + private static function nullable($value) + { + if ($value === null) { + return null; + } + + $value = trim((string)$value); + + return ($value === '') ? null : $value; + } + + private static function date($yyyymmdd) + { + return substr($yyyymmdd,0,4)."-". + substr($yyyymmdd,4,2)."-". + substr($yyyymmdd,6,2); + } + + private static function datetime($yyyymmddhhmiss) + { + if ( + empty($yyyymmddhhmiss) + || strlen($yyyymmddhhmiss) != 14 + ) { + return null; + } + + return substr($yyyymmddhhmiss,0,4)."-". + substr($yyyymmddhhmiss,4,2)."-". + substr($yyyymmddhhmiss,6,2)."T". + substr($yyyymmddhhmiss,8,2).":". + substr($yyyymmddhhmiss,10,2).":". + substr($yyyymmddhhmiss,12,2); + } +} diff --git a/public_html/lib/order_lib_process.php b/public_html/lib/order_lib_process.php index 92a701e..77df013 100644 --- a/public_html/lib/order_lib_process.php +++ b/public_html/lib/order_lib_process.php @@ -32,6 +32,7 @@ try { 'd_note' => str_replace("\\", "", trim($d_note)), 'd_inputdate' => date("YmdHis"), 'd_jobtype' => $d_jobtype ?? 'UCO', + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', ]; // 기존 record 기준 update @@ -64,7 +65,8 @@ try { 'd_orderdate' => $d_visitdate, 'd_accountno' => $_POST['d_customerno'], 'd_jobtype' => 'UCO', - 'd_payeesign' => $filename + 'd_payeesign' => $filename, + 'd_updateruid' => $_SESSION['ss_UID'] ?? '' ], [ 'match_uid' => $d_uid, 'allow_update' => true diff --git a/public_html/lib/receiptNote_lib_process.php b/public_html/lib/receiptNote_lib_process.php index 142a8d4..652806d 100644 --- a/public_html/lib/receiptNote_lib_process.php +++ b/public_html/lib/receiptNote_lib_process.php @@ -1,6 +1,7 @@ checkAdmin("index.php"); @@ -32,18 +33,55 @@ if($d_uid == "") { } -$d_paynoteSTR = str_replace("\\", "", trim($d_paynote)); +try { + $qry = " + SELECT + d_uid, + d_orderdate, + d_accountno + FROM tbl_daily + WHERE d_uid = '$d_uid' + "; -$qry_daily = "UPDATE tbl_daily SET d_paynote = '".addslashes($d_paynoteSTR)."' WHERE d_uid = '$d_uid' "; + $daily = $jdb->fQuery($qry, "query error"); -//echo "[$qry_customer]
"; + if (!$daily) { + throw new Exception("Daily record not found"); + } -$jdb->nQuery($qry_daily, "update error"); + $d_paynoteSTR = str_replace("\\", "", trim($d_paynote)); -addLog ("add", "RECEIPT NOTE", "UPDATE", $lguserid, $qry_daily, $d_uid); + $dailyApi = new DailyService(); + $dailyApi->saveDaily( + [ + 'd_orderdate' => $daily['d_orderdate'], + 'd_accountno' => $daily['d_accountno'], + 'd_paynote' => $d_paynoteSTR, + 'd_updateruid' => $_SESSION['ss_UID'] ?? '' + ], + [ + 'match_uid' => $d_uid, + 'allow_update' => true + ] + ); + + addLog( + "add", + "RECEIPT NOTE", + "UPDATE", + $lguserid, + "saveDaily()", + $d_uid + ); + + echo 1; + +} catch (Exception $e) { + + echo 0; +} -echo 1; exit(); diff --git a/public_html/lib/runErpOutbox.php b/public_html/lib/runErpOutbox.php new file mode 100644 index 0000000..91dbc98 --- /dev/null +++ b/public_html/lib/runErpOutbox.php @@ -0,0 +1,338 @@ +"; +} + +echo "####[START ERP OUTBOX]####{$ENT}"; + +include_once $GETDIR . "/include/function_class.php"; +include_once $GETDIR . "/include/arrayinfo.php"; +include_once $GETDIR . "/include/mysql_class_v7.php"; +include_once $GETDIR . "/lib/mapper/erpDailyOrderMapper.php"; +include_once $GETDIR . "/lib/mapper/erpCustomerMapper.php"; + +$func = new Func(); +$jdb = new JDB(); + +/////////////////////////////////////////////////// +// CONFIG +/////////////////////////////////////////////////// + +$qry_cfg = "SELECT cfg_erp_api_url, cfg_erp_api_token FROM tbl_config LIMIT 1"; +$cfg = $jdb->fQuery($qry_cfg, "config query error"); + +$serverUrl = rtrim($cfg['cfg_erp_api_url'], '/'); +$token = trim($cfg['cfg_erp_api_token']); + +/////////////////////////////////////////////////// +// GET OUTBOX +/////////////////////////////////////////////////// + +$qry = " +SELECT * +FROM tbl_erp_outbox +WHERE eo_status IN ('PENDING', 'FAILED') + AND eo_retry_count < 5 +ORDER BY eo_id ASC +LIMIT 1000 +"; + +echo "[OUTBOX QUERY][$qry]{$ENT}"; + +$result = $jdb->nQuery($qry, "outbox query error"); + +while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { + + $eo_id = $row['eo_id']; + + echo "[$entity:$eo_id] [$method:$url] - "; + + /////////////////////////////////////////////////// + // LOCK + /////////////////////////////////////////////////// + + $qry_lock = " + UPDATE tbl_erp_outbox + SET eo_status = 'PROCESSING' + WHERE eo_id = '{$eo_id}' + AND eo_status IN ('PENDING', 'FAILED') + "; + + $jdb->nQuery($qry_lock, "lock error"); + + if (mysqli_affected_rows($jdb->DBConn) <= 0) { + + echo "[SKIP LOCK FAIL][$eo_id]{$ENT}"; + continue; + } + + try { + + /////////////////////////////////////////////////// + // PAYLOAD + /////////////////////////////////////////////////// + $payload = json_decode($row['eo_payload'], true); + $entity = strtoupper(trim($row['eo_entity_type'] ?? '')); + if ($entity == '') { + throw new Exception("Missing entity"); + } + if (!$payload) { + throw new Exception("Invalid eo_payload json"); + } + + /////////////////////////////////////////////////// + // MAPPER & URL + /////////////////////////////////////////////////// + switch ($entity) { + // DAILY + case 'DAILY': + $body = erpDailyOrderMapper::map($payload); + $method = 'POST'; + $url = $serverUrl . "/crm-rest-api/customer-daily-order"; + break; + + // CUSTOMER + case 'CUSTOMER': + $action = strtoupper(trim($payload['action'] ?? '')); + $body = erpCustomerMapper::map($payload); + if ($body === null) { + echo "[SKIP EMPTY PATCH][$eo_id]{$ENT}"; + $qry_skip = " + UPDATE tbl_erp_outbox + SET + eo_status = 'SUCCESS', + eo_last_error = NULL, + eo_processed_at = NOW() + WHERE eo_id = '{$eo_id}' + "; + + $jdb->nQuery($qry_skip, "skip update error"); + continue; + } + + // PATCH + if ($action === 'UPDATED') { + $method = 'PATCH'; + $url = $serverUrl . "/crm-rest-api/customer/no/" . urlencode($payload['key']['c_accountno']); + } + // CREATE + else { + $method = 'POST'; + $url = $serverUrl . "/crm-rest-api/customer"; + } + + break; + + // UNKNOWN + default: + throw new Exception( + "Unsupported entity: ".$entity + ); + } + + /////////////////////////////////////////////////// + // SAVE REQUEST JSON + /////////////////////////////////////////////////// + $requestJson = addslashes( + json_encode( + $body, + JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES + ) + ); + + /////////////////////////////////////////////////// + // API CALL + /////////////////////////////////////////////////// + $response = callErpApi($url, $body, $token, $method); + + /////////////////////////////////////////////////// + // RESPONSE JSON + /////////////////////////////////////////////////// + $responseJson = addslashes( + json_encode( + $response, + JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES + ) + ); + + /////////////////////////////////////////////////// + // SUCCESS + /////////////////////////////////////////////////// + if ($response['success']) { + + $qry_success = " + UPDATE tbl_erp_outbox + SET + eo_status = 'SUCCESS', + eo_request_json = '{$requestJson}', + eo_response_json = '{$responseJson}', + eo_last_error = NULL, + eo_processed_at = NOW() + WHERE eo_id = '{$eo_id}' + "; + + $jdb->nQuery($qry_success, "success update error"); + + echo "[SUCCESS]{$ENT}"; + } + + /////////////////////////////////////////////////// + // FAILED + /////////////////////////////////////////////////// + else { + + $errorMsg = addslashes( + substr( + $response['message'] ?? 'Unknown Error', + 0, + 5000 + ) + ); + + $qry_fail = " + UPDATE tbl_erp_outbox + SET + eo_status = 'FAILED', + eo_retry_count = eo_retry_count + 1, + eo_request_json = '{$requestJson}', + eo_response_json = '{$responseJson}', + eo_last_error = '{$errorMsg}', + eo_processed_at = NOW() + WHERE eo_id = '{$eo_id}' + "; + + $jdb->nQuery($qry_fail, "fail update error"); + + echo "[FAILED][{$errorMsg}]{$ENT}"; + } + + } catch (Exception $e) { + + $errorMsg = addslashes( + substr($e->getMessage(), 0, 5000) + ); + + $qry_exception = " + UPDATE tbl_erp_outbox + SET + eo_status = 'FAILED', + eo_retry_count = eo_retry_count + 1, + eo_last_error = '{$errorMsg}', + eo_processed_at = NOW() + WHERE eo_id = '{$eo_id}' + "; + + $jdb->nQuery($qry_exception, "exception update error"); + + echo "[EXCEPTION][$eo_id][{$errorMsg}]{$ENT}"; + } +} + +/////////////////////////////////////////////////// +// END +/////////////////////////////////////////////////// + +$time_end = microtime(true); + +$timeStr = "Running Time: ".($time_end - $time_start); + +echo "####[END ERP OUTBOX][$timeStr]####"; + +/////////////////////////////////////////////////// +// FUNCTIONS +/////////////////////////////////////////////////// + +function callErpApi($url, $body, $token, $method = 'POST') +{ + $requestJson = json_encode( + $body, + JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES + ); + + $ch = curl_init($url); + + curl_setopt_array($ch, array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CUSTOMREQUEST => $method, + CURLOPT_HTTPHEADER => array( + "Content-Type: application/json", + "Authorization: Bearer ".$token, + "Expect:" + ), + CURLOPT_POSTFIELDS => $requestJson, + CURLOPT_TIMEOUT => 30, + )); + + $result = curl_exec($ch); + + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + $curlError = curl_error($ch); + + curl_close($ch); + + /////////////////////////////////////////////////// + // CURL ERROR + /////////////////////////////////////////////////// + + if ($curlError != "") { + + return array( + "success" => false, + "http_code" => 0, + "message" => $curlError, + "request" => $body, + "response" => null + ); + } + + /////////////////////////////////////////////////// + // SUCCESS + /////////////////////////////////////////////////// + + if ($httpCode >= 200 && $httpCode < 300) { + + return array( + "success" => true, + "http_code" => $httpCode, + "message" => "SUCCESS", + "request" => $body, + "response" => json_decode($result, true) + ); + } + + /////////////////////////////////////////////////// + // FAIL + /////////////////////////////////////////////////// + + return array( + "success" => false, + "http_code" => $httpCode, + "message" => $result, + "request" => $body, + "response" => json_decode($result, true) + ); +} \ No newline at end of file diff --git a/public_html/lib/shortInfo_lib_process.php b/public_html/lib/shortInfo_lib_process.php index 40e4fb1..2aa526c 100644 --- a/public_html/lib/shortInfo_lib_process.php +++ b/public_html/lib/shortInfo_lib_process.php @@ -2,30 +2,7 @@ include getenv("DOCUMENT_ROOT")."/include/session_include.php"; include_once getenv("DOCUMENT_ROOT")."/lib/erp_api.php"; - -//$func->checkAdmin("index.php"); - -//echo "[$mode]";exit(); - - -/* -for($i=0; $i"; - } - } - else echo "[$key][$value]
"; - //print_r($_POST); -} - -exit; -*/ +include_once getenv("DOCUMENT_ROOT")."/assets/api/customer.php"; if($c_uid == "") { echo 0; @@ -37,50 +14,48 @@ if ($_SESSION['ss_LEVEL'] == 10) { exit(); } - -$c_comment_riSTR = str_replace("\\", "", trim($c_comment_ri)); -$c_locationSTR = str_replace("\\", "", trim($c_location)); - - -$qry_customer = "UPDATE tbl_customer - SET - c_comment_ri = '".addslashes($c_comment_riSTR)."', - c_location = '".addslashes($c_locationSTR)."', - c_is_transfer = 'N' - WHERE c_uid = '$c_uid' "; - -//echo "[$qry_customer]
"; - -$jdb->nQuery($qry_customer, "update error"); - -// ==================== -// Integration to ERP -// ==================== -$erp = new ErpApi(); - try { - $columns = array(); - $values = array(); - $columns[] = "c_accountno"; - $columns[] = "c_comment_ri"; - $columns[] = "c_location"; - $values[] = $c_accountno; - $values[] = addslashes($c_comment_riSTR); - $values[] = addslashes($c_locationSTR); - $lguserid = $_SESSION['ss_UID']; - $erp->updateCustomerFromMis($columns, $values, $lguserid); + $c_comment_riSTR = str_replace("\\","",trim($c_comment_ri)); + $c_locationSTR = str_replace("\\","",trim($c_location)); - // 성공 시 c_is_transfer='Y' - $jdb->uQuery("tbl_customer", ["c_is_transfer"], ["Y"], " WHERE c_uid = ".(int)$_POST['id']); + // ==================== + // CUSTOMER PATCH + // ==================== + $svc = new CustomerService(); + $result = $svc->patchCustomer( + (int)$c_uid, + [ + 'c_comment_ri' => $c_comment_riSTR, + 'c_location' => $c_locationSTR, + 'c_updatedby' => $_SESSION['ss_UID'] + ] + ); + + // ==================== + // LOG + // ==================== + $logText = json_encode([ + 'c_comment_ri' => $c_comment_riSTR, + 'c_location' => $c_locationSTR + ], JSON_UNESCAPED_UNICODE); + + addLog( + "add", + "SHORT INFO", + "UPDATE", + $_SESSION['ss_UID'], + $logText, + $c_uid + ); + + echo 1; + exit(); } catch (Exception $e) { - // 여기서는 아무것도 안함. + + error_log($e->getMessage()); + + echo 0; + exit(); } - -addLog ("add", "SHORT INFO", "UPDATE", $lguserid, $qry_customer, $c_uid); - -echo 1; -exit(); - - ?> \ No newline at end of file diff --git a/public_html/lib/user_process.php b/public_html/lib/user_process.php index 4f12192..28b23df 100644 --- a/public_html/lib/user_process.php +++ b/public_html/lib/user_process.php @@ -6,6 +6,7 @@ include_once getenv("DOCUMENT_ROOT") . "/lib/erp_api.php"; require_once getenv("DOCUMENT_ROOT")."/assets/conf.inc.php"; require_once getenv("DOCUMENT_ROOT")."/assets/dbCon.php"; include_once getenv("DOCUMENT_ROOT")."/assets/api/daily.php"; +include_once getenv("DOCUMENT_ROOT")."/assets/api/customer.php"; $dailyApi = new DailyService(); if ($goStr == "") $goStr = "switched=$switched&page=$page&key_word=$key_word&column=$column&sorting_type=$sorting_type&switch=$switch"; @@ -55,6 +56,7 @@ if ($actionStr == "PICKUPORDERCUSTOMER") { 'd_payeename' => $d_payeename, 'd_note' => str_replace("\\", "", trim($d_note)), 'd_createruid' => $_SESSION['ss_UID'], + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', 'd_inputdate' => date("YmdHis"), 'd_jobtype' => $d_jobtype ?? 'UCO', ]; @@ -95,6 +97,7 @@ if ($actionStr == "PICKUPORDERCUSTOMER") { 'd_accountno' => $cus['c_accountno'], 'd_payeesign' => $filename, 'd_jobtype' => $d_jobtype ?? 'UCO', + 'd_updateruid'=> $_SESSION['ss_UID'] ?? '', ], [ 'match_uid' => $d_uid, 'allow_update' => true @@ -209,6 +212,7 @@ if ($actionStr == "ORDEROIL" && $mode == "insert") { 'd_ordertype' => $valueSTR[0], 'd_ruid' => $valueSTR[2], 'd_createruid' => $_SESSION['ss_UID'], + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', 'd_createddate' => date("YmdHis"), 'd_status' => 'A', 'd_jobtype' => 'UCO' @@ -235,49 +239,6 @@ if ($actionStr == "ORDEROIL" && $mode == "insert") { exit(); } -////////////////////////////////////////////// -// DELETE CUSTOMER INFO (c_status 만 D 로 변경) -////////////////////////////////////////////// - -if ($actionStr == "CUSTOMERINFO" && $mode == "delete") { - - // Delete 기능 제한 (Admin : 1, Manager : 3, Staff : 5 만 가능) - $permit = array("1", "3", "5"); - if (in_array($_SESSION['ss_LEVEL'], $permit)) { - $setTag = ""; - } - else { - $msg = "Sorry, You don't have permission. Please contact Administrator."; - $func -> modalMsg ($msg, ""); - exit(); - } - - if($c_uid == "") { - $msg = "Invalid data. Please try again."; - $func -> modalMsg ($msg, ""); - exit(); - } - - $qry_delete = "UPDATE tbl_customer SET c_status='D' WHERE c_uid = '$c_uid' "; - - $jdb->nQuery($qry_delete, "delete error"); - $jdb->CLOSE(); - - addLog ("add", "CUSTOMER DELETE", "DELETE", $lguserid, $qry_delete, $c_uid); - - // ==================== - // Integration to ERP - // ==================== - // 화면에서 기능이 없음 - - $msg = "Deleted successfully."; - $urlSTR = "/index_intranet.php?view=customer_list&$goStr"; - //$func -> alertBack($msg); - $func -> modalMsg ($msg, $urlSTR); - exit(); -} - - ////////////////////////////////////////////// // DELETE MEMBER INFO (m_status 만 D 로 변경) @@ -829,6 +790,7 @@ if ($actionStr == "ADDREQUEST" && $mode == "create") { 'd_ruid' => $r_uidMAX, 'd_druid' => $r_druid, 'd_createruid' => $_SESSION['ss_UID'], + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', 'd_createddate' => date("YmdHis"), 'd_status' => 'A', 'd_jobtype' => 'UCO' @@ -1103,86 +1065,83 @@ if ($actionStr == "USERHISFAV" && $mode == "delete") { if ($actionStr == "SIGNATURE") { - if($customeruid == "" || $orderdate == "") { - $msg = "Invalid data. Please try again."; - $func -> modalMsg ($msg, ""); - exit(); - } + try { - // Signiture - if ($signednew == 1) $putSignFlag = 1; - else { - if ($d_payeesign == "" && $_POST['signed'] != "") $putSignFlag = 1; - else $putSignFlag = 0; - } + if ($customeruid == "" || $orderdate == "") { + throw new Exception("Invalid data. Please try again."); + } - //echo "[$signednew][$putSignFlag]"; + // SIGNATURE CHECK + if ($signednew == 1) { + $putSignFlag = 1; + } else { + if ($d_payeesign == "" && $_POST['signed'] != "") { + $putSignFlag = 1; + } else { + $putSignFlag = 0; + } + } - if ($putSignFlag == 1) { + // SAVE SIGNATURE FILE + if ($putSignFlag == 1) { + $folderPath = getenv("DOCUMENT_ROOT")."/upload_sign/".$customeruid; + if (!is_dir($folderPath)) { + mkdir($folderPath, 0755, true); + } - $folderPath = getenv("DOCUMENT_ROOT")."/upload_sign/".$customeruid; - if (!is_dir($folderPath)) mkdir($folderPath, 0755, true); + $image_parts = explode(";base64,", $_POST['signed']); + $image_type_aux = explode("image/", $image_parts[0]); + $image_type = $image_type_aux[1]; + $image_base64 = base64_decode($image_parts[1]); + $uniquevalue = uniqid(); - $image_parts = explode(";base64,", $_POST['signed']); - $image_type_aux = explode("image/", $image_parts[0]); - $image_type = $image_type_aux[1]; - $image_base64 = base64_decode($image_parts[1]); - $uniquevalue = uniqid(); + // DAILY EXISTS + $qry_cnt = "SELECT COUNT(*) FROM tbl_daily WHERE d_uid = '".$uid."'"; + $total_count = $jdb->rQuery($qry_cnt, "record query error"); - $qry_cnt = "SELECT COUNT(*) FROM tbl_daily WHERE d_uid = '".$uid."' "; - $total_count=$jdb->rQuery($qry_cnt, "record query error"); - - if ($total_count > 0) { - $file = $folderPath ."/". $orderdate. "_". $uniquevalue . '.'.$image_type; - $d_payeesignSTR = $orderdate. "_". $uniquevalue . '.'.$image_type; - $qry_customer = "UPDATE tbl_daily - SET d_payeesign='$d_payeesignSTR', d_is_transfer='N' - WHERE d_uid = '$uid'"; - - $jdb->nQuery($qry_customer, "update error"); + if ($total_count > 0) { + $filename = $orderdate . "_" . $uniquevalue . "." . $image_type; + } else { + $filename = "T_" . $orderdate . "_" . $uniquevalue . "." . $image_type; + } - // ==================== - // Integration to ERP - // ==================== - $columns = array(); - $values = array(); - $columns[] = "d_accountno"; - $columns[] = "d_orderdate"; - $columns[] = "d_payeesign"; - - $values[] = $customerno; - $values[] = $orderdate; - $values[] = $d_payeesignSTR; - - $erp = new ErpApi(); + $file = $folderPath . "/" . $filename; + file_put_contents($file, $image_base64); - try { - // ERP로 전송 (payload 내부에서 자동 매핑) - $erp->updateDailyOrderFromMis($columns, $values, $lguserid); + // SAVE DAILY + if ($total_count > 0) { + $dailyApi = new DailyService(); + $payload = [ + 'd_orderdate' => $orderdate, + 'd_accountno' => $customerno, + 'd_payeesign' => $filename, + 'd_updateruid' => $_SESSION['ss_UID'] ?? '', + ]; - // 성공 시 플래그 & 로그 - $jdb->uQuery("tbl_daily", ["d_is_transfer"], ["Y"], " WHERE d_uid = '$d_uid'"); - } catch (Exception $e) { - // 여기서는 아무것도 안함 - } - } - else { - $file = $folderPath ."/". "T_". $orderdate. "_". $uniquevalue . '.'.$image_type; - $d_payeesignSTR = "T_".$orderdate. "_". $uniquevalue . '.'.$image_type; - } + $dailyApi->saveDaily( + $payload, + [ + 'match_uid' => $uid, + 'allow_update' => true + ] + ); + } + } - file_put_contents($file, $image_base64); - - } + // DONE + $msg = "Saved successfully."; + echo " + "; - $msg = "Saved successfully."; - //$func -> modalMsg ($msg, ""); - echo " - "; - exit(); + } catch (Exception $e) { + + $func->modalMsg($e->getMessage(), ""); + } + + exit(); } function compressAndResizeImage($srcPath, $destPath, $ext, $maxWidth = 1200, $quality = 75) {