goiintra/public_html/lib/erp_api.php

551 lines
18 KiB
PHP

<?php
// /common/erp_api.php
include getenv("DOCUMENT_ROOT")."/include/session_include.php";
class ErpApi {
private $baseUrl;
private $token;
private $enabled = false;
public function __construct() {
global $jdb;
$row = $jdb->fQuery("SELECT cfg_erp_api_url, cfg_erp_api_token FROM tbl_config LIMIT 1", "config fetch error");
$url = isset($row['cfg_erp_api_url']) ? trim($row['cfg_erp_api_url']) : '';
$token = isset($row['cfg_erp_api_token']) ? trim($row['cfg_erp_api_token']) : '';
// URL 없으면 바로 예외 (서버 아직 준비 안됨)
if ($url === '' || $url === null) {
$this->enabled = false;
$this->baseUrl = '';
$this->token = '';
return;
}
$this->enabled = true;
$this->baseUrl = rtrim($url, '/');
$this->token = $token;
}
/**
* 공통 HTTP 요청 처리
*/
private function request($method, $endpoint, $data = null) {
// ERP 비활성화면 아무것도 하지 않고 조용히 반환
if (!$this->enabled) {
return [
"disabled" => true,
"skipped" => true,
"endpoint" => $endpoint,
];
}
$url = $this->baseUrl . $endpoint;
$headers = [
"Authorization: Bearer {$this->token}",
"Content-Type: application/json"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($data !== null) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($response === false) {
$err = curl_error($ch);
curl_close($ch);
throw new Exception("cURL Error: $err");
}
curl_close($ch);
$result = json_decode($response, true);
if ($result === null && json_last_error() !== JSON_ERROR_NONE) {
throw new Exception("JSON Decode Error: " . json_last_error_msg() . " - Response: $response");
}
if ($httpCode >= 400) {
$msg = isset($result['message']) ? $result['message'] : $response;
throw new Exception("HTTP $httpCode Error: $msg");
}
return $result;
}
// -------------------------------------------------------
// 기본 Customer API
// -------------------------------------------------------
public function createCustomer($data) {
return $this->request("POST", "/customer", $data);
}
public function updateCustomer($cusNo, $data) {
return $this->request("PATCH", "/customer/no/" . $cusNo, $data);
}
public function deleteCustomer($cusNo) {
return $this->request("DELETE", "/customer/no/" . $cusNo);
}
// -------------------------------------------------------
// 공통 유틸
// -------------------------------------------------------
private function convertDate($dateStr) {
if (!$dateStr || !is_string($dateStr)) {
return null;
}
// YYYYMMDD (8)
if (strlen($dateStr) === 8) {
return substr($dateStr, 0, 4) . '-' .
substr($dateStr, 4, 2) . '-' .
substr($dateStr, 6, 2);
}
// YYYYMMDDHHIISS (14)
if (strlen($dateStr) === 14) {
return substr($dateStr,0,4)."-"
. substr($dateStr,4,2)."-"
. substr($dateStr,6,2)."T"
. substr($dateStr,8,2).":"
. substr($dateStr,10,2).":"
. substr($dateStr,12,2);
}
// 지원하지 않는 포맷
return null;
}
private function normalizeValue($value) {
if ($value === '' || $value === false) return null;
if (is_string($value) && trim($value) === '') return null;
return $value;
}
private function getValue($columns, $values, $col) {
$idx = array_search($col, $columns);
return $idx !== false ? $values[$idx] : null;
}
// -------------------------------------------------------
// MIS → ERP Customer Payload 빌드 (완전 자동 변환)
// -------------------------------------------------------
public function buildCustomerPayload($columns, $values, $loginUser) {
$payload = [];
// MIS → ERP 매핑 규칙
$map = [
"cusNo" => "c_accountno",
"cusName" => "c_name",
"cusStatus" => "c_status",
"cusAreaId" => "c_area",
"cusAddress1" => "c_address",
"cusAddress2" => "c_mailingaddr",
"cusPostalCode" => "c_postal",
"cusCity" => "c_city",
"cusProvince" => "c_province",
"cusEmail" => "c_email",
"cusPhone" => "c_phone",
"cusPhoneExt" => "c_phoneext",
"cusRate" => "c_rate",
"cusPayMethod" => "c_paymenttype",
"cusContractDate" => "c_contractdate",
"cusContractedBy" => "c_contractby",
"cusInstallDate" => "c_installdate",
// full cycle 필요하면 나중에 추가 2025-12-16
// "cusFullCycle" => "c_fullcycle",
// "cusFullCycleFlag" => "c_fullcycleflag",
// "cusFullCycleForced" => "c_fullcycleforced",
// "cusFullCycleForcedDate"=> "c_forceddate",
"cusSchedule" => "c_schedule",
"cusScheduledays" => "c_scheduleday",
"cusIsccDate" => "c_form_eu",
"cusCorsiaDate" => "c_form_corsia",
"cusHstNo" => "c_hstno",
"cusComment" => "c_comment_ri",
"cusContactComment" => "c_comment_ci",
"cusGeoLat" => "c_geolat",
"cusGeoLon" => "c_geolon",
"cusInstallLocation" => "c_location",
];
// 날짜 변환 필드 목록
$dateCols = [
"c_contractdate",
"c_installdate",
"c_forceddate",
"c_form_eu",
"c_form_corsia"
];
// 기본 필드 채우기
foreach ($map as $erpKey => $misCol) {
$value = $this->getValue($columns, $values, $misCol);
if ($value && in_array($misCol, $dateCols)) {
$value = $this->convertDate($value);
}
$payload[$erpKey] = $value;
}
// 로그인 사용자
$payload["cusLoginUser"] = $loginUser;
return $payload;
}
// -------------------------------------------------------
// MIS → ERP Customer CREATE
// -------------------------------------------------------
public function createCustomerFromMis($columns, $values, $loginUser) {
// 비활성화면 로그도 남기지 말고 바로 종료
if (!$this->enabled) {
return ["disabled" => true, "skipped" => true];
}
$payload = $this->buildCustomerPayload($columns, $values, $loginUser);
try {
// 테스트용
// addLog("add"
// , "/customer"
// , "ERP - SUCCESS"
// , $loginUser
// , json_encode($payload, JSON_PRETTY_PRINT)
// , ''
// );
return $this->createCustomer($payload);
} catch (Exception $e) {
$logBody =
"[EXCEPTION]\n" .
$e->getMessage() . "\n\n" .
"[PAYLOAD]\n" .
json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
addLog("add"
, "/customer"
, "ERP - FAILED"
, $loginUser
, $logBody
, ''
);
// 사용자에게는 아무것도 안 알려줌
return [
"success" => false,
"queued" => true
];
}
}
// -------------------------------------------------------
// MIS → ERP Customer UPDATE (cusNo 기준)
// -------------------------------------------------------
public function updateCustomerFromMis($columns, $values, $loginUser) {
// 비활성화면 로그도 남기지 말고 바로 종료
if (!$this->enabled) {
return ["disabled" => true, "skipped" => true];
}
// accountno 찾기
$cusNo = $this->getValue($columns, $values, "c_accountno");
if (!$cusNo) {
throw new Exception("updateCustomerFromMis: Missing c_accountno");
}
$payload = $this->buildCustomerPayload($columns, $values, $loginUser);
try {
// 테스트용
// addLog("add"
// , "/customer/no/" . $cusNo
// , "ERP - SUCCESS"
// , $loginUser
// , json_encode($payload, JSON_PRETTY_PRINT)
// , $cusNo
// );
return $this->updateCustomer($cusNo, $payload);
} catch (Exception $e) {
$logBody =
"[EXCEPTION]\n" .
$e->getMessage() . "\n\n" .
"[PAYLOAD]\n" .
json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
addLog("add"
, "/customer/no/" . $cusNo
, "ERP - FAILED"
, $loginUser
, $logBody
, $cusNo
);
// 사용자에게는 아무것도 안 알려줌
return [
"success" => false,
"queued" => true
];
}
}
// -------------------------------------------------------
// MIS → ERP Customer 단일필드 업데이트 (update_column.php 용)
// -------------------------------------------------------
public function updateCustomerFieldFromMis($cusNo, $field, $value, $loginUser) {
if (!$this->enabled) {
return ["disabled" => true, "skipped" => true];
}
$payload = [
"cusLoginUser" => $loginUser,
$field => $value
];
return $this->updateCustomer($cusNo, $payload);
}
// -------------------------------------------------------
// Customer Daily Order 관련 API (RAW 호출)
// -------------------------------------------------------
/**
* POST /customer-daily-order
*/
public function createOrder($data) {
return $this->request("POST", "/customer-daily-order", $data);
}
/**
* PATCH /customer-daily-order/customer/{customerNo}/{orderDate}
* - customerNo : ERP customer.cus_no
* - orderDate : yyyy-MM-dd
*/
public function updateOrder($customerNo, $orderDate, $data) {
return $this->request(
"PATCH",
"/customer-daily-order/customer/" . $customerNo . "/" . $orderDate,
$data
);
}
/**
* DELETE /customer-daily-order/{uuid}
*/
public function deleteOrder($uuid) {
return $this->request("DELETE", "/customer-daily-order/" . $uuid);
}
// -------------------------------------------------------
// Customer Daily Order - MIS 연동용 헬퍼
// (tbl_daily $columns / $values 기반으로 payload 생성)
// -------------------------------------------------------
/**
* MIS 의 tbl_daily ( $columns, $values ) 를 ERP CustomerDailyOrderRequestDto 로 변환
*
* @param array $columns tbl_daily insert 시 사용한 컬럼명 배열
* @param array $values 각 컬럼에 대한 값 배열
* @param string $loginUser MIS 로그인 사용자 ID
* @return array ERP에 보낼 payload
*/
public function buildDailyOrderPayload($columns, $values, $loginUser) {
$payload = [];
// MIS → ERP 매핑 규칙
// (필요에 따라 계속 보강 가능)
$map = [
"cdoOrderDate" => "d_orderdate",
"cdoOrderType" => "d_ordertype",
"cdoRequestNote" => "d_requestnote",
"cdoCustomerNo" => "d_accountno",
"cdoCycle" => "d_cycle",
"cdoPaymentType" => "d_paymenttype",
"cdoRate" => "d_rate",
"cdoStatus" => "d_status",
"cdoEstimatedQty" => "d_estquantity",
"cdoQuantity" => "d_quantity",
"cdoSludge" => "d_sludge",
"cdoPayStatus" => "d_paystatus",
"cdoPayAmount" => "d_payamount",
"cdoPayeeName" => "d_payeename",
"cdoPayeeSign" => "d_payeesign",
"cdoExternalDriverId" => "d_driveruid",
"cdoVisitFlag" => "d_visit",
"cdoPickupNote" => "d_pickupnote",
"cdoPickupAt" => "d_inputdate",
];
// 날짜 변환이 필요한 컬럼들
$dateColumns = [
"d_orderdate",
"d_inputdate",
];
// 로그인 사용자
$payload["cdoLoginUser"] = $loginUser;
// map 에 따라 값 채우기
foreach ($map as $erpKey => $misCol) {
$idx = array_search($misCol, $columns);
$value = ($idx !== false) ? $values[$idx] : null;
// 빈 문자열 → null
if (is_string($value)) {
$value = trim($value);
if ($value === '') {
$value = null;
}
}
// 날짜 변환
if ($value !== null && in_array($misCol, $dateColumns, true)) {
$value = $this->convertDate($value);
}
$payload[$erpKey] = $value;
}
/* Rule */
// 연결 key
if (!$payload['cdoCustomerNo']) {
throw new Exception("DailyOrder Error: Missing CustomerNo");
}
if (!$payload['cdoOrderDate']) {
throw new Exception("DailyOrder Error: Missing OrderDate");
}
// quantity 있는데 sludge 없으면 sludge = 0
if (
array_key_exists('cdoQuantity', $payload)
&& $payload['cdoQuantity'] !== null
&& $payload['cdoSludge'] === null
) {
$payload['cdoSludge'] = 0;
}
return $payload;
}
/**
* MIS → ERP : Daily Order 신규 생성 편의 함수
*
* user_process.php 에서:
* $erp = new ErpApi();
* $payload = $erp->buildDailyOrderPayload($columns, $values, $lguserid);
* $erp->createOrder($payload);
*
* 또는:
* $erp->createDailyOrderFromMis($columns, $values, $lguserid);
*/
public function createDailyOrderFromMis($columns, $values, $loginUser) {
if (!$this->enabled) {
return ["disabled" => true, "skipped" => true];
}
$payload = $this->buildDailyOrderPayload($columns, $values, $loginUser);
try {
// 테스트용
// addLog("add"
// , "/customer-daily-order"
// , "ERP - SUCCESS"
// , $loginUser
// , json_encode($payload, JSON_PRETTY_PRINT)
// , ''
// );
return $this->createOrder($payload);
} catch (Exception $e) {
$logBody =
"[EXCEPTION]\n" .
$e->getMessage() . "\n\n" .
"[PAYLOAD]\n" .
json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
addLog("add"
, "/customer-daily-order"
, "ERP - FAILED"
, $loginUser
, $logBody
, ''
);
// 사용자에게는 아무것도 안 알려줌
return [
"success" => false,
"queued" => true
];
}
}
/**
* MIS → ERP : Daily Order 업데이트 (customerNo + orderDate 기준)
*/
public function updateDailyOrderFromMis($columns, $values, $loginUser) {
// 비활성화면 로그도 남기지 말고 바로 종료
if (!$this->enabled) {
return ["disabled" => true, "skipped" => true];
}
$payload = $this->buildDailyOrderPayload($columns, $values, $loginUser);
// customerNo / orderDate 추출
$customerNo = $payload['cdoCustomerNo'];
$orderDate = $payload['cdoOrderDate'];
try {
// 테스트용
// addLog("add"
// , "/customer-daily-order/customer/" . $customerNo . "/" . $orderDate
// , "ERP - SUCCESS"
// , $loginUser
// , json_encode($payload, JSON_PRETTY_PRINT)
// , $customerNo
// );
return $this->updateOrder($customerNo, $orderDate, $payload);
} catch (Exception $e) {
$logBody =
"[EXCEPTION]\n" .
$e->getMessage() . "\n\n" .
"[PAYLOAD]\n" .
json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
addLog("add"
, "/customer-daily-order/customer/" . $customerNo . "/" . $orderDate
, "ERP - FAILED"
, $loginUser
, $logBody
, $customerNo
);
// 사용자에게는 아무것도 안 알려줌
return [
"success" => false,
"queued" => true
];
}
}
}
?>