M3 Integration fixes
This commit is contained in:
Executable
Executable
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
// app/Helpers/USStates.php
|
||||
|
||||
namespace Modules\M3\Helpers;
|
||||
|
||||
class CAProvinces
|
||||
{
|
||||
public static function all()
|
||||
{
|
||||
return [
|
||||
'AB' => 'Alberta',
|
||||
'BC' => 'British Columbia',
|
||||
'MB' => 'Manitoba',
|
||||
'NB' => 'New Brunswick',
|
||||
'NL' => 'Newfoundland and Labrador',
|
||||
'NS' => 'Nova Scotia',
|
||||
'NT' => 'Northwest Territories',
|
||||
'NU' => 'Nunavut',
|
||||
'ON' => 'Ontario',
|
||||
'PE' => 'Prince Edward Island',
|
||||
'QC' => 'Quebec',
|
||||
'SK' => 'Saskatchewan',
|
||||
'YT' => 'Yukon',
|
||||
];
|
||||
}
|
||||
}
|
||||
Executable
+352
@@ -0,0 +1,352 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\M3\Helpers;
|
||||
|
||||
use Cache;
|
||||
use Config;
|
||||
use DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Log;
|
||||
|
||||
class Helper
|
||||
{
|
||||
// Check M3 API Token
|
||||
public static function checkReceiveToken()
|
||||
{
|
||||
ini_set('max_execution_time', Config::get('arrays.PHPTimeOut'));
|
||||
|
||||
// Clear Cache
|
||||
// Cache::forget('token');
|
||||
// Check if cached Token is still Valid
|
||||
$token = Cache::get('token');
|
||||
|
||||
if (isset($token)) {
|
||||
$ionToken = $token;
|
||||
} else {
|
||||
// ## CURL
|
||||
// ## Generate Token
|
||||
$curl = curl_init();
|
||||
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => env('ENDPOINTURLSSO') . env('URLTOKEN'),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_ENCODING => '',
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 0,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
||||
CURLOPT_POSTFIELDS => 'grant_type=' . env('GRANT_TYPE') . '&password=' . env('PASSWORD') . '&username=' . env('USERNAME') . '&client_secret=' . env('CLIENT_SECRET') .
|
||||
'&client_id=' . env('CLIENT_ID'),
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
'charset:UTF-8',
|
||||
'Accept: application/json',
|
||||
],
|
||||
]);
|
||||
|
||||
$response = curl_exec($curl);
|
||||
$responseJ = json_decode($response);
|
||||
|
||||
if ($response === false) {
|
||||
return response()->json([
|
||||
'code' => '400',
|
||||
'status' => 'Failed',
|
||||
'message' => 'Token Verification Error...' . curl_error($curl),
|
||||
]);
|
||||
} elseif (isset($responseJ->access_token)) {
|
||||
$ionToken = $responseJ->access_token;
|
||||
|
||||
Cache::put('token', $ionToken, now()->addMinutes(59));
|
||||
} else {
|
||||
return response()->json([
|
||||
'code' => '400',
|
||||
'status' => 'Failed',
|
||||
'message' => 'Token Verification Error...M3 response:' . $response,
|
||||
]);
|
||||
}
|
||||
|
||||
curl_close($curl);
|
||||
}
|
||||
|
||||
return $ionToken;
|
||||
// 'code' => '200',
|
||||
// 'token' => $ionToken
|
||||
// ]);
|
||||
}
|
||||
|
||||
// Check M3 API Token V2
|
||||
public static function checkReceiveTokenV2()
|
||||
{
|
||||
ini_set('max_execution_time', Config::get('arrays.PHPTimeOut'));
|
||||
ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut'));
|
||||
|
||||
// Clear Cache
|
||||
// Cache::forget('token');
|
||||
|
||||
// Check if cached Token is still Valid
|
||||
$token = Cache::get('token');
|
||||
|
||||
if (isset($token)) {
|
||||
$ionToken = $token;
|
||||
} else {
|
||||
// ## CURL
|
||||
// ## Generate Token
|
||||
$curl = curl_init();
|
||||
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => env('ENDPOINTURLSSO') . env('URLTOKEN'),
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_ENCODING => '',
|
||||
CURLOPT_MAXREDIRS => 10,
|
||||
CURLOPT_TIMEOUT => 0,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
|
||||
CURLOPT_CUSTOMREQUEST => 'POST',
|
||||
CURLOPT_POSTFIELDS => 'grant_type=' . env('GRANT_TYPE') . '&password=' . env('PASSWORD') . '&username=' . env('USERNAME') . '&client_secret=' . env('CLIENT_SECRET') .
|
||||
'&client_id=' . env('CLIENT_ID'),
|
||||
CURLOPT_HTTPHEADER => [
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
'charset:UTF-8',
|
||||
'Accept: application/json',
|
||||
],
|
||||
]);
|
||||
|
||||
$response = curl_exec($curl);
|
||||
$responseJ = json_decode($response);
|
||||
curl_close($curl);
|
||||
|
||||
if ($response === false) {
|
||||
// Clear Cache
|
||||
Cache::forget('token');
|
||||
|
||||
// Return Error
|
||||
return response()->json([
|
||||
'code' => '400',
|
||||
'status' => 'Failed',
|
||||
'message' => 'Token Verification Error...' . curl_error($curl),
|
||||
]);
|
||||
} elseif (isset($responseJ->access_token)) {
|
||||
$ionToken = $responseJ->access_token;
|
||||
Cache::put('token', $ionToken, now()->addMinutes(59));
|
||||
} else {
|
||||
// Clear Cache
|
||||
Cache::forget('token');
|
||||
|
||||
return response()->json([
|
||||
'code' => '400',
|
||||
'status' => 'Failed',
|
||||
'message' => 'Token Verification Error...M3 response:' . $response,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'code' => '200',
|
||||
'token' => $ionToken,
|
||||
]);
|
||||
}
|
||||
|
||||
// Read M3 JSON and Analyse it for Errors
|
||||
public static function checkM3Errors($responseResult)
|
||||
{
|
||||
if (! is_object($responseResult)) {
|
||||
return 'Invalid M3 response ';
|
||||
}
|
||||
|
||||
$messages = [];
|
||||
$inactiveTypes = 0;
|
||||
$closeShipmentInactive = self::collectCloseShipmentErrors($responseResult, $messages);
|
||||
|
||||
foreach (['Move', 'COCharge', 'Replenish', 'MoveDock'] as $type) {
|
||||
$result = self::extractM3Result($responseResult, $type);
|
||||
self::appendM3Error($messages, $type, $result);
|
||||
|
||||
if ($result['rawResult'] === 'N/A') {
|
||||
$inactiveTypes++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($closeShipmentInactive === 7 && $inactiveTypes === 4) {
|
||||
$messages[] = '-M3 did not call any method or type';
|
||||
}
|
||||
|
||||
return $messages === [] ? '' : implode(' ', $messages) . ' ';
|
||||
}
|
||||
|
||||
private static function collectCloseShipmentErrors(object $responseResult, array &$messages): int
|
||||
{
|
||||
$closeShipment = $responseResult->CloseShipment ?? null;
|
||||
if (! is_object($closeShipment)) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
$inactive = 0;
|
||||
foreach (['AddPackage', 'PickingListClose', 'TrailerNo', 'TrackingNo', 'ContentLabel', 'DeliveryNote', 'ShipLabel'] as $type) {
|
||||
$result = self::extractResultNode($closeShipment->{$type} ?? null);
|
||||
self::appendM3Error($messages, $type, $result);
|
||||
|
||||
if ($result['rawResult'] === 'N/A') {
|
||||
$inactive++;
|
||||
}
|
||||
}
|
||||
|
||||
return $inactive;
|
||||
}
|
||||
|
||||
private static function extractM3Result(object $responseResult, string $type): array
|
||||
{
|
||||
$node = $responseResult->{$type} ?? null;
|
||||
if ($type === 'MoveDock' && is_object($node)) {
|
||||
$node = $node->Move ?? null;
|
||||
}
|
||||
|
||||
return self::extractResultNode($node);
|
||||
}
|
||||
|
||||
private static function extractResultNode(mixed $node): array
|
||||
{
|
||||
if (! is_object($node)) {
|
||||
return ['error' => '', 'result' => '', 'rawResult' => 'N/A'];
|
||||
}
|
||||
|
||||
$error = trim((string) ($node->ErrorMessage ?? ''));
|
||||
$rawResult = trim((string) ($node->Result ?? ''));
|
||||
$result = in_array($rawResult, ['N/A', 'OK'], true) ? '' : $rawResult;
|
||||
|
||||
return ['error' => $error, 'result' => $result, 'rawResult' => $rawResult];
|
||||
}
|
||||
|
||||
private static function appendM3Error(array &$messages, string $type, array $result): void
|
||||
{
|
||||
if ($result['error'] === '' && $result['result'] === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
$messages[] = $type . '-' . $result['result'] . '-' . $result['error'];
|
||||
}
|
||||
|
||||
// Log All Success And Error to ICM699M
|
||||
public static function logToICM699M($data)
|
||||
{
|
||||
ini_set('max_execution_time', Config::get('arrays.PHPTimeOut'));
|
||||
|
||||
DB::connection(config('m3.connection', 'pgsql'))->table('ICM699M')->insert($data);
|
||||
}
|
||||
|
||||
// Get Substring in string between 2 Substrings
|
||||
public static function getSubstringBetween($string, $start, $end)
|
||||
{
|
||||
$startPos = strpos($string, $start);
|
||||
if ($startPos === false) {
|
||||
return '';
|
||||
}
|
||||
$endPos = strpos($string, $end, $startPos + strlen($start));
|
||||
if ($endPos === false) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return substr($string, $startPos + strlen($start), $endPos - ($startPos + strlen($start)));
|
||||
}
|
||||
|
||||
public static function checkLength($jsonFields, $dbFields, $type)
|
||||
{
|
||||
$type = $type == 'integer' || $type == 'DEC' ? 'number' : $type;
|
||||
|
||||
// Check Json Field should be < DB Field
|
||||
$lengthOK[413] = (strlen($jsonFields) <= $dbFields) ? true : false;
|
||||
// Empty Fields
|
||||
$lengthOK[411] = true; // !empty($jsonFields) ? true : false ;
|
||||
// Wrong Types
|
||||
$lengthOK[417] = true; // $jSONTypeConv == $type ? true : false ;
|
||||
// Log::info($lengthOK);
|
||||
|
||||
return $lengthOK;
|
||||
}
|
||||
|
||||
public static function sanityzeString($strToSanitize)
|
||||
{
|
||||
$badChars = Config::get('arrays.BadChars');
|
||||
|
||||
$goodString = trim($strToSanitize);
|
||||
$goodString = str_replace("'", '', $goodString);
|
||||
$goodString = str_replace("\u{f0e0}", '', $goodString);
|
||||
$goodString = preg_replace('/\\\\u201[0-9A-F]+/i', '', $goodString);
|
||||
$goodString = str_replace($badChars, '', $goodString);
|
||||
$goodString = iconv('UTF-8', 'ISO-8859-1//IGNORE', $goodString);
|
||||
$goodString = iconv('ISO-8859-1', 'UTF-8', $goodString);
|
||||
|
||||
// MAK : New Automatic Detection for encoding and conversion
|
||||
// Detect the encoding
|
||||
// $encoding = mb_detect_encoding($goodString, mb_list_encodings(), true);
|
||||
// Log::info($goodString);
|
||||
|
||||
// If encoding is detected, convert the string
|
||||
// if ($encoding !== false) {
|
||||
// // Log::info($encoding);
|
||||
// // Log::info($goodString);
|
||||
|
||||
// $goodString = mb_convert_encoding($goodString, "UTF-8", $encoding);
|
||||
// } else {
|
||||
// $goodString = "";
|
||||
// }
|
||||
|
||||
return $goodString;
|
||||
}
|
||||
|
||||
// Remove Duplicate SubString
|
||||
public static function removeDuplicateSubstrings($str)
|
||||
{
|
||||
$result = '';
|
||||
$seenPhrases = [];
|
||||
|
||||
$phrases = explode(' ', $str);
|
||||
foreach ($phrases as $phrase) {
|
||||
if (! in_array($phrase, $seenPhrases)) {
|
||||
$result .= $phrase . ' ';
|
||||
$seenPhrases[] = $phrase;
|
||||
}
|
||||
}
|
||||
|
||||
return trim($result);
|
||||
}
|
||||
|
||||
public static function getUserCOWHSPLT()
|
||||
{
|
||||
$defaults = [
|
||||
'UserCO' => '',
|
||||
'UserWHS' => '',
|
||||
'UserPL' => '',
|
||||
];
|
||||
|
||||
$loggedUser = strtoupper(trim((string) m3_user()));
|
||||
if ($loggedUser === '') {
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
try {
|
||||
if (! Schema::connection(config('m3.connection', 'pgsql'))->hasTable('icm428m')) {
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
$user = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m')
|
||||
->select('R428US', 'R428ADMUSR', 'R428PWRUSR', 'R428CO', 'R428PL', 'R428WH', 'R42811A', 'R42821A')
|
||||
->where('R428US', $loggedUser)
|
||||
->first();
|
||||
|
||||
if (! $user) {
|
||||
return $defaults;
|
||||
}
|
||||
|
||||
return [
|
||||
'UserCO' => trim((string) ($user->R428CO ?? '')),
|
||||
'UserWHS' => trim((string) ($user->R428WH ?? '')),
|
||||
'UserPL' => trim((string) ($user->R428PL ?? '')),
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
\Illuminate\Support\Facades\Log::warning('M3 user context unavailable', ['exception' => $e->getMessage()]);
|
||||
|
||||
return $defaults;
|
||||
}
|
||||
}
|
||||
}
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('m3_user')) {
|
||||
/**
|
||||
* Return the current Core username in the format expected by the legacy M3 data.
|
||||
* M3 previously depended on PHP Basic Auth and read PHP_AUTH_USER directly.
|
||||
*/
|
||||
function m3_user(): string
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$value = $user?->username
|
||||
?? $user?->user_name
|
||||
?? $user?->name
|
||||
?? $user?->email
|
||||
?? request()->server('PHP_AUTH_USER')
|
||||
?? '';
|
||||
|
||||
if (str_contains((string) $value, '@')) {
|
||||
$value = strstr((string) $value, '@', true) ?: $value;
|
||||
}
|
||||
|
||||
return strtoupper(trim((string) $value));
|
||||
}
|
||||
}
|
||||
|
||||
if (! function_exists('m3_legacy_password')) {
|
||||
/**
|
||||
* Passwords are intentionally unavailable in Core. PostgreSQL access uses
|
||||
* Laravel's configured connection and never reuses a user's login password.
|
||||
*/
|
||||
function m3_legacy_password(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('subdirAsset')) {
|
||||
function subdirAsset($path)
|
||||
{
|
||||
return asset((App::environment('production') ? env('APP_DIR') : '') . '/' . $path);
|
||||
}
|
||||
}
|
||||
if (! function_exists('subdirMix')) {
|
||||
function subdirMix($path)
|
||||
{
|
||||
return mix((App::environment('production') ? env('APP_DIR') : '') . '/' . $path);
|
||||
}
|
||||
}
|
||||
Executable
+65
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
// app/Helpers/USStates.php
|
||||
|
||||
namespace Modules\M3\Helpers;
|
||||
|
||||
class USStates
|
||||
{
|
||||
public static function all()
|
||||
{
|
||||
return [
|
||||
'AL' => 'Alabama',
|
||||
'AK' => 'Alaska',
|
||||
'AZ' => 'Arizona',
|
||||
'AR' => 'Arkansas',
|
||||
'CA' => 'California',
|
||||
'CO' => 'Colorado',
|
||||
'CT' => 'Connecticut',
|
||||
'DE' => 'Delaware',
|
||||
'FL' => 'Florida',
|
||||
'GA' => 'Georgia',
|
||||
'HI' => 'Hawaii',
|
||||
'ID' => 'Idaho',
|
||||
'IL' => 'Illinois',
|
||||
'IN' => 'Indiana',
|
||||
'IA' => 'Iowa',
|
||||
'KS' => 'Kansas',
|
||||
'KY' => 'Kentucky',
|
||||
'LA' => 'Louisiana',
|
||||
'ME' => 'Maine',
|
||||
'MD' => 'Maryland',
|
||||
'MA' => 'Massachusetts',
|
||||
'MI' => 'Michigan',
|
||||
'MN' => 'Minnesota',
|
||||
'MS' => 'Mississippi',
|
||||
'MO' => 'Missouri',
|
||||
'MT' => 'Montana',
|
||||
'NE' => 'Nebraska',
|
||||
'NV' => 'Nevada',
|
||||
'NH' => 'New Hampshire',
|
||||
'NJ' => 'New Jersey',
|
||||
'NM' => 'New Mexico',
|
||||
'NY' => 'New York',
|
||||
'NC' => 'North Carolina',
|
||||
'ND' => 'North Dakota',
|
||||
'OH' => 'Ohio',
|
||||
'OK' => 'Oklahoma',
|
||||
'OR' => 'Oregon',
|
||||
'PA' => 'Pennsylvania',
|
||||
'RI' => 'Rhode Island',
|
||||
'SC' => 'South Carolina',
|
||||
'SD' => 'South Dakota',
|
||||
'TN' => 'Tennessee',
|
||||
'TX' => 'Texas',
|
||||
'UT' => 'Utah',
|
||||
'VT' => 'Vermont',
|
||||
'VA' => 'Virginia',
|
||||
'WA' => 'Washington',
|
||||
'WV' => 'West Virginia',
|
||||
'WI' => 'Wisconsin',
|
||||
'WY' => 'Wyoming',
|
||||
'DC' => 'District of Columbia',
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user