goiintra/public_html/lib/runErpOutbox.php

338 lines
9.3 KiB
PHP

<?php
///////////////////////////////////////////////////
// ERP OUTBOX WORKER
///////////////////////////////////////////////////
//
// CRON
//
// * * * * * /usr/local/bin/php -q /home/.../lib/runErpOutbox.php
//
///////////////////////////////////////////////////
date_default_timezone_set('America/Toronto');
$time_start = microtime(true);
$mode = (PHP_SAPI === 'cli') ? "SHELL" : "WEB";
// if ($mode == "SHELL") {
// $GETDIR = "/var/www/html";
// $ENT = "\n";
if ($mode == "SHELL") {
$GETDIR = dirname(__DIR__);
$ENT = "\n";
} else {
$GETDIR = getenv("DOCUMENT_ROOT");
$ENT = "<br>";
}
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)
);
}