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 @@
include getenv("DOCUMENT_ROOT")."/include/session_include.php";
+require_once getenv("DOCUMENT_ROOT")."/assets/api/customer.php";
//echo "1111OKKKKKKKKKKKKKKKKKK";exit;
@@ -32,15 +33,22 @@ $c_fullcycle = trim($_POST["c_fullcycle"]);
if ($c_uid != "" && $c_fullcycle !== "") {
- $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");
-
- $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) {