m3 Security Fixes

This commit is contained in:
Mark Gregory
2026-09-17 10:37:56 +01:00
parent a094477840
commit 1644efed9c
5 changed files with 356 additions and 821 deletions
+66 -60
View File
@@ -159,74 +159,80 @@ class Helper
// Read M3 JSON and Analyse it for Errors
public static function checkM3Errors($responseResult)
{
// dd($responseResult);
// M3 Response Types
$M3TypesResponse = ['CloseShipment', 'Move', 'COCharge', 'Replenish', 'MoveDock'];
// CloseShipment Types And Contents
$M3CloseShipmentResp = ['AddPackage', 'PickingListClose', 'TrailerNo', 'TrackingNo', 'ContentLabel', 'DeliveryNote', 'ShipLabel'];
// 'ContentLabel', 'DeliveryNote','ShipLabel'
$ErrorMessages = '';
if (! is_object($responseResult)) {
return 'Invalid M3 response ';
}
$typesErrors = 0;
$messages = [];
$inactiveTypes = 0;
$closeShipmentInactive = self::collectCloseShipmentErrors($responseResult, $messages);
foreach ($M3TypesResponse as $key => $Type) {
// dump($responseResult->$Type);
if ($Type == 'CloseShipment') {
// dump($Type);
$CloseShipmentErr = 0;
$M3RespClose = $responseResult->$Type;
foreach ($M3CloseShipmentResp as $key => $closeType) {
$ErrorMessage = $M3RespClose->$closeType->ErrorMessage;
$ErrorMessage = $ErrorMessage == '' ? '' : $ErrorMessage;
$Result = $M3RespClose->$closeType->Result;
$ResultT = $M3RespClose->$closeType->Result;
$Result = $Result == 'N/A' || $Result == 'OK' ? '' : $Result;
if ($ErrorMessage != '' || $Result != '') {
$ErrorMessages .= $closeType . '-' . $Result . '-' . $ErrorMessage . ' ';
}
// dump($closeType);// dump($ErrorMessage);// dump($Result);
foreach (['Move', 'COCharge', 'Replenish', 'MoveDock'] as $type) {
$result = self::extractM3Result($responseResult, $type);
self::appendM3Error($messages, $type, $result);
if ($ResultT == 'N/A') {
$CloseShipmentErr++;
}
}
} elseif ($Type == 'MoveDock') {
$MoveDockRes = isset($responseResult->$Type->Move) ? $responseResult->$Type->Move : '';
$ErrorMessage = isset($MoveDockRes->ErrorMessage) ? $MoveDockRes->ErrorMessage : '';
$ErrorMessage = $ErrorMessage == '' ? '' : $ErrorMessage;
$Result = isset($MoveDockRes->Result) ? $MoveDockRes->Result : '';
$ResultT = $Result;
$Result = $Result == 'N/A' || $Result == 'OK' ? '' : $Result;
if ($ErrorMessage != '' || $Result != '') {
$ErrorMessages .= $Type . '-' . $Result . '-' . $ErrorMessage . ' ';
}
// dump($Type);// dump($ErrorMessage);// dump($Result);// dump($responseResult->$Type);
if ($ResultT == 'N/A') {
$typesErrors++;
}
} else {
$ErrorMessage = isset($responseResult->$Type->ErrorMessage) ? $responseResult->$Type->ErrorMessage : '';
$ErrorMessage = $ErrorMessage == '' ? '' : $ErrorMessage;
$Result = isset($responseResult->$Type->Result) ? $responseResult->$Type->Result : '';
$ResultT = $Result;
$Result = $Result == 'N/A' || $Result == 'OK' ? '' : $Result;
if ($ErrorMessage != '' || $Result != '') {
$ErrorMessages .= $Type . '-' . $Result . '-' . $ErrorMessage . ' ';
}
// dump($Type); // dump($ErrorMessage); // dump($Result); // dump($responseResult->$Type);
if ($ResultT == 'N/A') {
$typesErrors++;
}
if ($result['rawResult'] === 'N/A') {
$inactiveTypes++;
}
}
// dd($ErrorMessages);
if ($CloseShipmentErr == count($M3CloseShipmentResp) && $typesErrors == count($M3TypesResponse) - 1) {
$ErrorMessages .= '-M3 did not call any method or type ';
if ($closeShipmentInactive === 7 && $inactiveTypes === 4) {
$messages[] = '-M3 did not call any method or type';
}
return $ErrorMessages;
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
@@ -1,484 +0,0 @@
<?php
namespace Modules\M3\Http\Controllers\API;
use Config;
use DB;
use Http;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Json;
use Log;
use Modules\M3\Helpers\Helper;
use Modules\M3\Http\Controllers\Controller;
use Str;
class M3InventoryReport extends Controller
{
private const ZERO_PAD = '000000';
private const JSON_CONTENT_TYPE = 'application/json';
private const NO_M3_RESPONSE = 'Error: No Response from M3';
// M3InventoryReport for Single Part
public function M3InventoryReport(Request $request)
{
ini_set('max_execution_time', Config::get('arrays.PHPTimeOut'));
ini_set('max_input_time', Config::get('arrays.PHPTimeOut'));
ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut'));
$user = Str::upper(trim((string) m3_user())) ?: 'WEBUSER';
$source = 'M3InventoryReport';
$warehouse = '';
$payload = [];
try {
$input = $request->json()->all();
$warehouse = trim((string) ($input['WHS'] ?? ''));
$payload = [
'WHS' => $warehouse,
'PART' => trim((string) ($input['PART'] ?? '')),
'LOT' => trim((string) ($input['LOT'] ?? '')),
];
$tokenResponse = Helper::checkReceiveTokenV2();
$tokenData = $tokenResponse->getData();
if ((string) ($tokenData->code ?? '') !== '200') {
self::logInventoryResponse(
self::ZERO_PAD,
(string) ($tokenData->message ?? ''),
$user,
$source,
$warehouse
);
return $tokenResponse;
}
return self::sendInventoryRequest(
(string) ($tokenData->token ?? ''),
$payload,
$user,
$source,
$warehouse
);
} catch (\Throwable $exception) {
return self::inventoryExceptionResponse($exception, $payload, $user, $source, $warehouse);
}
}
private static function sendInventoryRequest(
string $token,
array $payload,
string $user,
string $source,
string $warehouse
) {
if ($token === '') {
return response()->json([
'code' => '401',
'status' => 'error',
'message' => 'M3 authentication token was not returned.',
], 401);
}
$response = Http::withHeaders([
'accept' => self::JSON_CONTENT_TYPE,
'Content-Type' => self::JSON_CONTENT_TYPE,
])
->withToken($token)
->timeout(Config::get('arrays.curlTimeOut'))
->post(env('ENDPOINTURL') . 'APIFLOWS/Sentinel/M3InventoryReport?ionapiRespStyle=sync', $payload);
$statusCode = $response->getStatusCode();
$sessionId = $response->hasHeader('x-transaction-id')
? '-sessionID:' . $response->header('x-transaction-id')
: '-sessionID';
if ($statusCode !== Response::HTTP_OK) {
self::logInventoryResponse(
self::ZERO_PAD,
$statusCode . self::NO_M3_RESPONSE . $sessionId,
$user,
$source,
$warehouse,
true
);
return response()->json([
'code' => '405',
'status' => 'error',
'message' => self::NO_M3_RESPONSE,
], 502);
}
$sanitized = Helper::sanityzeString($response->body());
self::logInventoryResponse(
self::ZERO_PAD,
$statusCode . $sanitized . '-' . json_encode($payload) . $sessionId,
$user,
$source,
$warehouse
);
return response()->json([
'code' => $statusCode,
'status' => 'Success',
'message' => json_decode($sanitized),
]);
}
private static function inventoryExceptionResponse(
\Throwable $exception,
array $payload,
string $user,
string $source,
string $warehouse
) {
$isCurlError = str_contains($exception->getMessage(), 'cURL error');
$message = $isCurlError
? 'Curl Error: Communication with M3 Timed Out.'
: 'M3 inventory request failed.';
self::logInventoryResponse(
self::ZERO_PAD,
$isCurlError ? $message : mb_substr($exception->getMessage(), 0, 300),
$user,
$source,
$warehouse,
true
);
Log::error('M3 inventory request failed.', [
'exception' => $exception,
'payload' => $payload,
]);
return response()->json([
'code' => '405',
'status' => 'error',
'message' => $message,
], 502);
}
private static function logInventoryResponse(
string $deliveryNumber,
string $message,
string $user,
string $source,
string $warehouse,
bool $isError = false
): void {
Helper::logToICM699M([
'SHMACPKR' => $deliveryNumber,
'SHDT' => date('Y-m-d'),
'SHTIME' => date('H:i:s'),
'SHERROR' => $isError ? 'X' : '',
'SHINTBOX' => '',
'SHTYPE' => 'M3-Res-out',
'SHDATA' => $message,
'SHUSER' => $user,
'SHSOURCE' => $source,
'SHCO' => '',
'SHWHS' => $warehouse,
]);
}
// End M3InventoryReport
// M3InventoryReportList with URL Params
public function M3InventoryReportListURL(Request $request)
{
ini_set('max_execution_time', Config::get('arrays.PHPTimeOut'));
ini_set('max_input_time', Config::get('arrays.PHPTimeOut'));
ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut'));
// Set API Name
$SHSOURCE = 'M3InventoryReportListURL';
// Get The Calling User
$SHUSER = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser';
$M3Errors = '';
try {
// Get Json Contents
$urlParams = count($request->all()) > 0 ? $request->all() : '';
$REQPKWS = isset($urlParams['REQPKWS']) ? $urlParams['REQPKWS'] : '';
$REQKPKUS = isset($urlParams['REQKPKUS']) ? $urlParams['REQKPKUS'] : 'WebUser';
$CO = isset($urlParams['CO']) ? $urlParams['CO'] : '';
$WHS = isset($urlParams['WHS']) ? $urlParams['WHS'] : '';
$MACPKR = isset($urlParams['MACPKR']) ? $urlParams['MACPKR'] : self::ZERO_PAD; // Delivery Number
$PKLN = isset($urlParams['PKLN']) ? $urlParams['PKLN'] : '';
if ($urlParams != '') {
$IncomingParams = ['CO' => $CO, 'WHS' => $WHS, 'MACPKR' => $MACPKR, 'PKLN' => $PKLN, 'REQPKWS' => $REQPKWS, 'REQKPKUS' => $REQKPKUS];
$IncomingParams = json_encode($IncomingParams);
// Write to Logs : Params In
$data = ['SHMACPKR' => $MACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => '', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Req-out',
'SHDATA' => $IncomingParams, 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $CO, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
// Get Parts And Lots from ICM688M2
$ICM688M2SLTMP = DB::connection(config('m3.connection', 'pgsql'))->table('icm688m2')
->select('A5WHS', 'A5PART', 'A5LOTNUM', 'A5SENTPKR')
->distinct()
->where('A5CO', $CO)
->where('A5WHS', $WHS)
->where('A5MACPKR', $MACPKR);
// Get Pack Lines
if ($PKLN != '') {
$ICM688M2SLTMP->where('A5PKLN', $PKLN);
}
$ICM688M2SL = $ICM688M2SLTMP->get();
// dd($ICM688M2SL);
if (count($ICM688M2SL) > 0) {
// Update ICM688M1 : Add Timestamp
$ICM688M1TS = now();
DB::connection(config('m3.connection', 'pgsql'))->table('icm688m1')
->where('A4MACPKR', $MACPKR)
->update(['A4INRFSHTS' => $ICM688M1TS]);
$PICKERARR = [];
foreach ($ICM688M2SL as $key => $ICM688M2) {
$PART = trim($ICM688M2->A5PART);
$LOT = trim($ICM688M2->A5LOTNUM);
$PARTS[] = ['PART' => $PART, 'LOT' => $LOT];
$PICKERARR[$PART] = $ICM688M2->A5SENTPKR;
}
// Log::info($PARTS);
// dump($PARTS);
$JSON = json_encode(['WHS' => $WHS, 'PARTS' => $PARTS]);
// Log::info($JSON);
// Get Token
$tokenResponse = Helper::checkReceiveTokenV2();
$tokenData = $tokenResponse->getData();
if ($tokenData->code == '200') {
$IonToken = isset($tokenData->token) ? $tokenData->token : '';
} else {
$SHDATA = isset($tokenData->message) ? $tokenData->message : '';
// Write to Logs : Error
$data = ['SHMACPKR' => $MACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => $SHDATA, 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $CO, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
return $tokenResponse;
}
// Call ionapi with Params
$endPointURL = env('ENDPOINTURL') . 'APIFLOWS/Sentinel/M3InventoryReportList?ionapiRespStyle=sync';
$token = $IonToken;
$response = Http::withHeaders([
'accept' => self::JSON_CONTENT_TYPE,
'Content-Type' => self::JSON_CONTENT_TYPE,
])
->withToken($token)
->withBody($JSON, self::JSON_CONTENT_TYPE)
->timeout(Config::get('arrays.curlTimeOut'))
->post($endPointURL);
$M3SessionId = $response->hasHeader('x-transaction-id') ? '-sessionID:' . $response->header('x-transaction-id') : '-sessionID';
$responseStatusCode = $response->getStatusCode();
if ($responseStatusCode == '200') {
// Check M3 Response for Errors
$M3Errors = '';
$responseJSON = $response->getBody()->getContents();
$JsonSanytized = Helper::sanityzeString($responseJSON);
// Array
$responseArray = json_decode($JsonSanytized, true);
$responseTMP = $responseArray['result'];
} else {
$M3Errors = self::NO_M3_RESPONSE;
}
// Validate response From M3
if ($M3Errors != '') {
// Write to Logs : Error
$data = ['SHMACPKR' => $MACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => $responseStatusCode . '-' . $M3Errors . $M3SessionId, 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $CO, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
// Send Response
return response()->json([
'code' => '405',
'status' => 'error',
'message' => self::NO_M3_RESPONSE,
]);
} else {
// Write to Logs : JSON
$data = ['SHMACPKR' => $MACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => '', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => $responseStatusCode . '-' . $JsonSanytized . $M3SessionId, 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $CO, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
}
$dataToWrite2 = [];
foreach ($responseTMP as $key => $value) {
// dump($value);
$dataToWrite = [];
foreach ($value as $key2 => $content) {
if ($key2 != 'Locations') {
$dataToWrite[$key2] = $content;
} else {
foreach ($content as $key3 => $content2) {
// dump($content2);
$dataToWrite2[] = array_merge($dataToWrite, $content2);
}
}
}
}
// LOG::info($dataToWrite2);
// Delete Old Records from IC630M
foreach ($dataToWrite2 as $key => $value) {
$ICM630MDeleteSQL = DB::connection(config('m3.connection', 'pgsql'))->table('ic630m')
->where('LLCO', $CO)
->where('LLWHNO', $WHS)
->where('LLPPN', trim($value['PartNumber']))
->delete();
}
foreach ($dataToWrite2 as $key => $value) {
// Check if Location exist in DE640M ("LVCO", "WSELOC", "VLOCID")
$DE640MSQLSEL = DB::connection(config('m3.connection', 'pgsql'))->table('de640m')
->where('LVCO', $CO)
->where('WSELOC', $value['Warehouse'])
->where('VLOCID', $value['Location'])
->first();
// dd($DE640MSQLSEL);
$LocationExist = isset($DE640MSQLSEL->VLOCID) ? trim($DE640MSQLSEL->VLOCID) : '';
$WHExist = isset($DE640MSQLSEL->WSELOC) ? trim($DE640MSQLSEL->WSELOC) : '';
$COExist = isset($DE640MSQLSEL->LVCO) ? trim($DE640MSQLSEL->LVCO) : '';
// dd($LocationExist .': '.$WHExist.': '.$COExist);
// if No records Founds insert New Record
if ($LocationExist == '' && $WHExist == '' && $COExist == '') {
$SQLInsertPrep640M['LVCO'] = $CO; // Company
$SQLInsertPrep640M['WSELOC'] = $value['Warehouse'];
// $SQLInsertPrep640M['LVDELNO'] = $MACPKR; # M3 Delivery note number DELETED
// $SQLInsertPrep640M['LVUSD3'] = $value['']; # Pallet Size : Not Found in M3 JSON
$SQLInsertPrep640M['VLOCID'] = $value['Location']; // Stock location
$SQLInsertPrep640M['LVSEQN'] = $value['LocationSeq'];
$SQLInsertPrep640M['LVUSD2'] = $value['LocationType'];
$SQLInsertPrep640M['LVZONE'] = $value['Zone']; // Warehouse zone
$SQLInsertPrep640M['LVMAINTTS'] = now(); // Last maintained time stamp
DB::connection(config('m3.connection', 'pgsql'))->table('de640m')->insert($SQLInsertPrep640M);
}
// Update
else {
$SQLUpdatePrep640M['LVSEQN'] = $value['LocationSeq'];
$SQLUpdatePrep640M['LVUSD2'] = $value['LocationType'];
$SQLUpdatePrep640M['LVZONE'] = $value['Zone'];
$SQLUpdatePrep640M['LVMAINTTS'] = now();
DB::connection(config('m3.connection', 'pgsql'))->table('de640m')
->where('LVCO', $CO)
->where('WSELOC', $value['Warehouse'])
->where('VLOCID', $value['Location'])
->update($SQLUpdatePrep640M);
}
// Insert New Records to IC630M
$SQLInsertPrep630M = [];
$SQLInsertPrep630M['LLCO'] = $CO; // Company
$SQLInsertPrep630M['LLWHNO'] = $value['Warehouse']; // Warehouse
// $SQLInsertPrep630M['LLDELNO'] = $MACPKR; # M3 Delivery note number DELETED
$SQLInsertPrep630M['LLPPN'] = $value['PartNumber']; // Part Number
$SQLInsertPrep630M['LLBALANCE'] = $value['Quantity']; // Quantity
$SQLInsertPrep630M['LLSTLC'] = $value['Location']; // Stock location
$SQLInsertPrep630M['LLLTNO'] = $value['LotNumber']; // Lot Number
$SQLInsertPrep630M['LLMAINTTS'] = now(); // Request time timestamp
$SQLInsertPrep630M['LLIZLCF'] = trim($value['LotNumber']) != '' ? '1' : ''; // Lot control flag
$SQLInsertPrep630M['LLCMDESC'] = $value['Description']; // Description
$SQLInsertPrep630M['LLSPR10A01'] = isset($value['Allocation']) ? $value['Allocation'] : ''; // Allocation
$SQLInsertPrep630M['LLSPR15A01'] = isset($value['AllocatedTo']) ? $value['AllocatedTo'] : ''; // AllocatedTo
DB::connection(config('m3.connection', 'pgsql'))->table('ic630m')->insert($SQLInsertPrep630M);
}
// dump($SQLInsertPrep);
// Send Response
return response()->json([
'code' => '200',
'status' => 'Success',
]);
} else {
// Write to Logs Out : Error
$MACPKR = isset($MACPKR) ? $MACPKR : self::ZERO_PAD;
$data = ['SHMACPKR' => $MACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => 'No Records Found in ICM688M2', 'SHUSER' => $REQKPKUS, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $CO, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
// Return Error
return response()->json([
'code' => '405',
'status' => 'Error',
'message' => 'No Records Found in ICM688M2',
]);
}
} else {
// Write to Logs Out : Error
$MACPKR = isset($MACPKR) ? $MACPKR : self::ZERO_PAD;
$data = ['SHMACPKR' => $MACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => 'No URL Parameters Sent', 'SHUSER' => $REQKPKUS, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $CO, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
// Return Error
return response()->json([
'code' => '405',
'status' => 'Error',
'message' => 'No URL Parameters Sent',
]);
}
} catch (\Throwable $th) {
// Write to Logs Out : Error
$MACPKR = isset($MACPKR) ? $MACPKR : self::ZERO_PAD;
$getCurlErrors = str_contains($th->getMessage(), 'cURL error');
if ($getCurlErrors) {
// dd($getCurlErrors);
// Write to Logs Out : Failed
$data = ['SHMACPKR' => $MACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => $th->getMessage() . ' M3-JSN-out' . $IncomingParams,
'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $CO, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
return response()->json([
'code' => '405',
'status' => 'error',
'message' => 'Curl Error: Communication with M3 Timed Out.',
]);
} else {
// Set SHERROR To Z if Duplicate Key Detected $th
// Read The substring from SHDATA after M3-JSN-out
$SHERROR = 'X';
$word = 'Duplicate key value specified';
$position = strpos($th, $word);
if ($position !== false) {
$SHERROR = 'Z';
}
$data = ['SHMACPKR' => $MACPKR, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => $SHERROR, 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => 'An Error Occured-' . substr($th, 0, 300), 'SHUSER' => $REQKPKUS, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $CO, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
Log::error($th);
return response()->json([
'code' => '405',
'status' => 'error',
'message' => 'Catched Error: ' . $th,
]);
}
}
}
// End M3InventoryReportListURL
}
+120 -131
View File
@@ -5,157 +5,146 @@ namespace Modules\M3\Http\Controllers\API;
use Cache;
use Config;
use File;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Log;
use Modules\M3\Helpers\Helper;
use Modules\M3\Http\Controllers\Controller;
use Smalot\PdfParser\Parser;
use Str;
class PdfStorage extends Controller
{
private const ZERO_PAD = '000000';
// PdfStorageAPI : PDF file read and save to Cache
public function PdfStorageAPI(Request $request)
public function PdfStorageAPI(Request $request): JsonResponse
{
ini_set('max_execution_time', Config::get('arrays.PHPTimeOut'));
ini_set('max_input_time', Config::get('arrays.PHPTimeOut'));
ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut'));
// dd($request->all());
// Get the Calling User
$SHUSER = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser';
$SHSOURCE = 'PdfStorageAPI';
// PDF File PATH
$pdfFilePath = Config::get('arrays.PdfPath');
$this->configureTimeouts();
$context = $this->requestContext($request);
if ($context === null) {
return $this->errorResponse('No URL Parameters Sent', self::ZERO_PAD, '', '', '');
}
try {
// Get URL PARAMS
$urlParams = count($request->all()) > 0 ? $request->all() : '';
// dd($urlParams);
$this->logRequest($context);
$COMPANY = isset($urlParams['COMPANY']) ? trim($urlParams['COMPANY']) : ''; // Company
$WHS = isset($urlParams['WHS']) ? trim($urlParams['WHS']) : ''; // WareHouse
$DOCTYPE = isset($urlParams['DOCTYPE']) ? trim($urlParams['DOCTYPE']) : ''; // document type (PackingList, CarrierLabel, ContentLabel)
$FILENAME = isset($urlParams['FILENAME']) ? trim($urlParams['FILENAME']) : ''; // PDF File name
$DOCNUM = isset($urlParams['DOCNUM']) ? trim($urlParams['DOCNUM']) : ''; // document number (ie the internal box number, the pick list number)
$A4MACPKR = isset($urlParams['A4MACPKR']) ? trim($urlParams['A4MACPKR']) : ''; // Delivery note number
$cacheKey = $this->buildCacheKey($context);
$pdfFileName = (string) Config::get('arrays.PdfPath') . $context['FILENAME'] . '.pdf';
$error = $this->validateStorageRequest($pdfFileName, $cacheKey);
if ($urlParams != '') {
// Key Combination : COMPANY WHS A4MACPKR DOCTYPE DOCNUM
// Document type (PackingList, CarrierLabel, ContentLabel)
$DELIVERYNO = isset($A4MACPKR) ? $A4MACPKR : self::ZERO_PAD;
$DELIVERYNO = $DELIVERYNO != '' && $DELIVERYNO != null ? $DELIVERYNO : self::ZERO_PAD;
// Write to Logs : Params In
$IncomingParams = ['COMPANY' => $COMPANY, 'WHS' => $WHS, 'DOCTYPE' => $DOCTYPE, 'FILENAME' => $FILENAME, 'A4MACPKR' => $A4MACPKR, 'DOCNUM' => $DOCNUM];
$data = ['SHMACPKR' => $DELIVERYNO, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => '', 'SHINTBOX' => $DOCNUM, 'SHTYPE' => 'M3-Req-out',
'SHDATA' => json_encode($IncomingParams), 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $COMPANY, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
// Make Key and Test Validity
if ($A4MACPKR != '' && $DOCTYPE != '' && $DOCNUM != '' && $COMPANY != '' && $WHS != '') {
$cacheKey = $A4MACPKR . $DOCTYPE . $DOCNUM . $COMPANY . $WHS;
} else {
$cacheKey = '';
}
// Read PDF File and Encode to Base64
$pdfFileName = $pdfFilePath . $FILENAME . '.pdf';
// dd($pdfFileName);
// dd(File::exists($pdfFileName));
if (File::exists($pdfFileName) && $cacheKey != '') {
// dd(File::exists($pdfFileName));
// Parse PDF file and build necessary objects.
$parser = new Parser;
// $pdf = $parser->parseFile('/www/sentm3test/htdocs/labels/E1232824-10826596.pdf');
// dump($pdf);
// $text = $pdf->getText();
// dump("Text Only");
// dump($text);
$pdfFile = File::get($pdfFileName);
// Transform content to base64
$base64PDF = base64_encode($pdfFile);
// Output base64 string
// dump($base64PDF);
// Save Cache
Cache::forever($cacheKey, $base64PDF);
// Cache::put($cacheKey, $base64PDF, now()->addMinutes(60));
// Retrieve Cache
// $cachedPdfFile = Cache::get($cacheKey);
// dump("Retrieve Base64 Encoded PDF saved in Cache:");
// dump($cachedPdfFile);
// $pdfData = substr($cachedPdfFile,0,50);
// remove File from Cache
// Cache::put(pdfFileName, 'value', -5);
// Cache::forget($pdfFileName);
// Base64 Decode and Display
// $pdf = $parser->parseContent(base64_decode($base64PDF));
// $text = $pdf->getText();
// dump($text);
// Write to Logs Out : Success
$data = ['SHMACPKR' => $DELIVERYNO, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => '', 'SHINTBOX' => $DOCNUM, 'SHTYPE' => 'M3-Res-out',
'SHDATA' => 'PDF File converted to Base64 and Saved to Cache.Key: ' . $cacheKey, 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $COMPANY, 'SHWHS' => $WHS];
// dd($data);
Helper::logToICM699M($data);
return response()->json([
'code' => '200',
'status' => 'Success',
'cacheKey' => $cacheKey,
// 'PDFData' => $pdfData
]);
} else {
$SHDATA = File::exists($pdfFileName) ? '' : 'PDF File Not Found-';
$SHDATA = $cacheKey != '' ? $SHDATA . '' : $SHDATA . 'Cache Key is missing Params';
// Write to Logs Out : Error
$data = ['SHMACPKR' => $DELIVERYNO, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => $DOCNUM, 'SHTYPE' => 'M3-Res-out',
'SHDATA' => 'An Error Occured -' . $SHDATA, 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $COMPANY, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
// Return Error
return response()->json([
'code' => '405',
'status' => 'Error',
'message' => $SHDATA,
]);
}
} else {
// Write to Logs Out : Error
$DELIVERYNO = isset($DELIVERYNO) ? $DELIVERYNO : self::ZERO_PAD;
$data = ['SHMACPKR' => $DELIVERYNO, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => 'No URL Parameters Sent.', 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $COMPANY, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
// Return Error
return response()->json([
'code' => '405',
'status' => 'Error',
'message' => 'No URL Parameters Sent',
]);
if ($error !== null) {
return $this->errorResponse($error, $context['DELIVERYNO'], $context['DOCNUM'], $context['COMPANY'], $context['WHS']);
}
} catch (\Throwable $th) {
// Log::error($th);
// Write to Logs Out : Error
$DELIVERYNO = isset($DELIVERYNO) ? $DELIVERYNO : self::ZERO_PAD;
$data = ['SHMACPKR' => $DELIVERYNO, 'SHDT' => date('Y-m-d'), 'SHTIME' => date('H:i:s'), 'SHERROR' => 'X', 'SHINTBOX' => '', 'SHTYPE' => 'M3-Res-out',
'SHDATA' => 'An Error Occured - ' . substr($th, 0, 300), 'SHUSER' => $SHUSER, 'SHSOURCE' => $SHSOURCE, 'SHCO' => $COMPANY, 'SHWHS' => $WHS];
Helper::logToICM699M($data);
Cache::forever($cacheKey, base64_encode(File::get($pdfFileName)));
$this->logResult($context, 'PDF File converted to Base64 and Saved to Cache.Key: ' . $cacheKey);
return response()->json(['code' => '200', 'status' => 'Success', 'cacheKey' => $cacheKey]);
} catch (\Throwable $exception) {
$message = 'An Error Occured - ' . substr($exception->getMessage(), 0, 300);
$this->safeLog($context, $message, true);
return response()->json([
'code' => '405',
'status' => 'error',
'message' => 'Catched Error: ' . $th,
'message' => 'Catched Error: ' . $exception->getMessage(),
]);
}
}
// End PdfStorageAPI
private function configureTimeouts(): void
{
$timeout = (string) Config::get('arrays.PHPTimeOut');
ini_set('max_execution_time', $timeout);
ini_set('max_input_time', $timeout);
ini_set('default_socket_timeout', $timeout);
}
private function requestContext(Request $request): ?array
{
if ($request->all() === []) {
return null;
}
$context = [];
foreach (['COMPANY', 'WHS', 'DOCTYPE', 'FILENAME', 'DOCNUM', 'A4MACPKR'] as $key) {
$context[$key] = trim((string) $request->input($key, ''));
}
$context['DELIVERYNO'] = $context['A4MACPKR'] !== '' ? $context['A4MACPKR'] : self::ZERO_PAD;
$context['SHUSER'] = m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser';
$context['SHSOURCE'] = 'PdfStorageAPI';
return $context;
}
private function buildCacheKey(array $context): string
{
foreach (['A4MACPKR', 'DOCTYPE', 'DOCNUM', 'COMPANY', 'WHS'] as $required) {
if ($context[$required] === '') {
return '';
}
}
return $context['A4MACPKR'] . $context['DOCTYPE'] . $context['DOCNUM'] . $context['COMPANY'] . $context['WHS'];
}
private function validateStorageRequest(string $pdfFileName, string $cacheKey): ?string
{
$messages = [];
if (! File::exists($pdfFileName)) {
$messages[] = 'PDF File Not Found-';
}
if ($cacheKey === '') {
$messages[] = 'Cache Key is missing Params';
}
return $messages === [] ? null : implode('', $messages);
}
private function logRequest(array $context): void
{
$params = array_intersect_key($context, array_flip(['COMPANY', 'WHS', 'DOCTYPE', 'FILENAME', 'A4MACPKR', 'DOCNUM']));
$this->safeLog($context, json_encode($params, JSON_THROW_ON_ERROR), false, 'M3-Req-out');
}
private function logResult(array $context, string $message): void
{
$this->safeLog($context, $message);
}
private function safeLog(array $context, string $message, bool $error = false, string $type = 'M3-Res-out'): void
{
try {
Helper::logToICM699M([
'SHMACPKR' => $context['DELIVERYNO'] ?? self::ZERO_PAD,
'SHDT' => date('Y-m-d'),
'SHTIME' => date('H:i:s'),
'SHERROR' => $error ? 'X' : '',
'SHINTBOX' => $context['DOCNUM'] ?? '',
'SHTYPE' => $type,
'SHDATA' => $message,
'SHUSER' => $context['SHUSER'] ?? (m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser'),
'SHSOURCE' => $context['SHSOURCE'] ?? 'PdfStorageAPI',
'SHCO' => $context['COMPANY'] ?? '',
'SHWHS' => $context['WHS'] ?? '',
]);
} catch (\Throwable) {
// Logging must never turn an API response into a 500 error.
}
}
private function errorResponse(string $message, string $deliveryNo, string $docNum, string $company, string $warehouse): JsonResponse
{
$context = [
'DELIVERYNO' => $deliveryNo,
'DOCNUM' => $docNum,
'COMPANY' => $company,
'WHS' => $warehouse,
'SHUSER' => m3_user() !== '' ? Str::upper(m3_user()) : 'WebUser',
'SHSOURCE' => 'PdfStorageAPI',
];
$this->safeLog($context, 'An Error Occured -' . $message, true);
return response()->json(['code' => '405', 'status' => 'Error', 'message' => $message]);
}
}
@@ -5,101 +5,108 @@ namespace Modules\M3\Http\Controllers;
use Artisan;
use Config;
use DB;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Log;
class M3CallCloseAPIController extends Controller
{
public static function index(Request $request)
public static function index(Request $request): JsonResponse
{
ini_set('max_execution_time', Config::get('arrays.PHPTimeOut'));
ini_set('max_input_time', Config::get('arrays.PHPTimeOut'));
ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut'));
self::configureTimeouts();
$params = self::validatedParams($request);
if ($params === null) {
Log::channel('dailyCron')->error('Manifest CloseAPI: Manifest, company and warehouse must be defined.');
return self::errorResponse('Manifest CloseAPI: Manifest, company and warehouse must be defined.');
}
try {
$records = self::findOpenManifestRecords($params);
if ($records->isEmpty()) {
Log::channel('dailyCron')->info('Manifest CloseAPI: No records found in ICM705M1.');
// Get the Calling User
// Get URL PARAMS
$urlParams = count($request->all()) > 0 ? $request->all() : '';
// dd($urlParams);
$SHUSER = isset($urlParams['SHUSER']) ? $urlParams['SHUSER'] : '';
$MANIFEST = isset($urlParams['MANIFEST']) ? $urlParams['MANIFEST'] : '';
$APCO = isset($urlParams['APCO']) ? $urlParams['APCO'] : '';
$APWHS = isset($urlParams['APWHS']) ? $urlParams['APWHS'] : '';
if ($MANIFEST != '' && $APCO != '' && $APWHS != '') { // $SHUSER!='' &&
// Log::channel('dailyCron')->info("Cron...Start CallCloseAPI...For user:".$SHUSER." Manifest#: ".$MANIFEST);
// Get Logged User CO & WH
// Get users from ICM428M
// $ICM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m')
// ->select('R428US','R428CO', 'R428WH')
// ->where('R428US','=',$SHUSER)
// ->first();
// $R428US = isset($ICM428M->R428US) ? $ICM428M->R428US : '';
// $USERCO = isset($ICM428M->R428CO) ? $ICM428M->R428CO : '';
// $USERWH = isset($ICM428M->R428WH) ? $ICM428M->R428WH : '';
// dump($R428US.':'.$USERCO.':'.$USERWH);
// Get Macpickers from ICM705M1
// SELECT APMANIFEST FROM ICM705M1 WHERE APSPARE2='' AND APCO='110' AND APWHS='321'
$ICM705M1 = DB::connection(config('m3.connection', 'pgsql'))->table('icm705m1')
->select('APMANIFEST', 'APCO', 'APWHS')
->where('APSPARE2', '')
->where('APCO', $APCO)
->where('APWHS', $APWHS)
->where('APMANIFEST', '=', $MANIFEST)
->whereRaw('EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - APLDCLOZ)) / 60 > 15')
->orderBy('APMANIFEST')
->get();
// dump($ICM705M1);
if (count($ICM705M1) > 0) {
// Loop the Results from $ICM705M1
foreach ($ICM705M1 as $key => $ICM705M1R) {
// Send CO and WHS to CallCloseAPI
$USERCO = isset($ICM705M1R->APCO) ? $ICM705M1R->APCO : '';
$USERWH = isset($ICM705M1R->APWHS) ? $ICM705M1R->APWHS : '';
$callCloseShipment = Artisan::call('command:CallCloseAPI', ['user' => $SHUSER, 'manifest' => $ICM705M1R->APMANIFEST,
'co' => $USERCO, 'whs' => $USERWH]);
// dump($callCloseShipment);
if ($callCloseShipment == 1) {
return response()->json([
'code' => '200',
'status' => 'Success',
'message' => 'Manifest Closing submitted',
]);
} else {
return response()->json([
'code' => '206',
'status' => 'Failure',
'message' => 'Manifest Closing Failed',
]);
}
}
} else {
Log::channel('dailyCron')->info('Manifest CloseAPI: No records found in ICM705M1...');
return response()->json([
'code' => '206',
'status' => 'Error',
'message' => 'Manifest CloseAPI: No records found in ICM705M1...',
]);
}
} else {
Log::channel('dailyCron')->error('Manifest CloseAPI: A User and Manifest must be defined...');
return response()->json([
'code' => '206',
'status' => 'Error',
'message' => 'Manifest CloseAPI: A User and Manifest must be defined...',
]);
return self::errorResponse('Manifest CloseAPI: No records found in ICM705M1.');
}
} catch (\Throwable $th) {
Log::error($th);
return self::submitManifest($records->first(), $params['SHUSER']);
} catch (\Throwable $exception) {
Log::error($exception);
return response()->json([
'code' => '500',
'status' => 'Error',
'message' => 'Manifest Closing failed unexpectedly.',
], 500);
}
}
private static function configureTimeouts(): void
{
$timeout = (string) Config::get('arrays.PHPTimeOut');
ini_set('max_execution_time', $timeout);
ini_set('max_input_time', $timeout);
ini_set('default_socket_timeout', $timeout);
}
private static function validatedParams(Request $request): ?array
{
$params = [
'SHUSER' => trim((string) $request->input('SHUSER', '')),
'MANIFEST' => trim((string) $request->input('MANIFEST', '')),
'APCO' => trim((string) $request->input('APCO', '')),
'APWHS' => trim((string) $request->input('APWHS', '')),
];
if ($params['MANIFEST'] === '' || $params['APCO'] === '' || $params['APWHS'] === '') {
return null;
}
return $params;
}
private static function findOpenManifestRecords(array $params)
{
$connection = config('m3.connection', 'pgsql');
if (! Schema::connection($connection)->hasTable('icm705m1')) {
return collect();
}
return DB::connection($connection)->table('icm705m1')
->select('APMANIFEST', 'APCO', 'APWHS')
->where('APSPARE2', '')
->where('APCO', $params['APCO'])
->where('APWHS', $params['APWHS'])
->where('APMANIFEST', $params['MANIFEST'])
->whereRaw('EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - APLDCLOZ)) / 60 > 15')
->orderBy('APMANIFEST')
->get();
}
private static function submitManifest(object $record, string $user): JsonResponse
{
$exitCode = Artisan::call('command:CallCloseAPI', [
'user' => $user,
'manifest' => $record->APMANIFEST ?? '',
'co' => $record->APCO ?? '',
'whs' => $record->APWHS ?? '',
]);
if ($exitCode === 1) {
return response()->json([
'code' => '200',
'status' => 'Success',
'message' => 'Manifest Closing submitted',
]);
}
return self::errorResponse('Manifest Closing Failed');
}
private static function errorResponse(string $message): JsonResponse
{
return response()->json(['code' => '206', 'status' => 'Error', 'message' => $message]);
}
}
@@ -42,83 +42,100 @@ class M3ErrorsDispController extends Controller
public function datatables(Request $request)
{
ini_set('max_execution_time', Config::get('arrays.PHPTimeOut'));
ini_set('max_input_time', Config::get('arrays.PHPTimeOut'));
ini_set('default_socket_timeout', Config::get('arrays.PHPTimeOut'));
$this->configureDataTableRuntime();
$filters = $this->dataTableFilters($request);
$connection = config('m3.connection', 'pgsql');
if (! Schema::connection($connection)->hasTable('icm699m')) {
return Datatables::of(collect())->addIndexColumn()->make(true);
}
$profile = $this->findM3Profile($connection, $filters['SHUSER']);
$query = $this->buildM3LogQuery($connection);
$this->applyM3LogFilters($query, $filters, $profile);
return Datatables::of($query)->addIndexColumn()->make(true);
}
private function configureDataTableRuntime(): void
{
$timeout = (string) Config::get('arrays.PHPTimeOut');
ini_set('max_execution_time', $timeout);
ini_set('max_input_time', $timeout);
ini_set('default_socket_timeout', $timeout);
ini_set('memory_limit', '1024M');
}
// dump($request->all());
$SHMACPKR = $request->SHMACPKR != null ? trim($request->SHMACPKR) : '';
$SHSOURCE = $request->SHSOURCE != null ? trim($request->SHSOURCE) : '';
$STARTDATE = $request->STARTDATE != null ? trim($request->STARTDATE) : today()->subDays(1)->format('Y-m-d');
$ENDDATE = $request->ENDDATE != null ? trim($request->ENDDATE) : today()->format('Y-m-d');
$SHOWERRORS = $request->SHOWERRORS != null ? trim($request->SHOWERRORS) : 'N';
$SHUSER = m3_user() !== '' ? Str::upper(trim(m3_user())) : '';
$SKIPDATES = $request->SKIPDATES != null ? trim($request->SKIPDATES) : 'N';
private function dataTableFilters(Request $request): array
{
return [
'SHMACPKR' => trim((string) $request->input('SHMACPKR', '')),
'SHSOURCE' => trim((string) $request->input('SHSOURCE', '')),
'STARTDATE' => trim((string) $request->input('STARTDATE', today()->subDays(1)->format('Y-m-d'))),
'ENDDATE' => trim((string) $request->input('ENDDATE', today()->format('Y-m-d'))),
'SHOWERRORS' => trim((string) $request->input('SHOWERRORS', 'N')),
'SHUSER' => m3_user() !== '' ? Str::upper(trim(m3_user())) : '',
'SKIPDATES' => trim((string) $request->input('SKIPDATES', 'N')),
];
}
// Get Logged User CO & WH
// Get users from ICM428M
$ICM428M = DB::connection(config('m3.connection', 'pgsql'))->table('icm428m')
private function findM3Profile(string $connection, string $user): ?object
{
if ($user === '' || ! Schema::connection($connection)->hasTable('icm428m')) {
return null;
}
return DB::connection($connection)->table('icm428m')
->select('R428US', 'R428CO', 'R428WH')
->where('R428US', '=', $SHUSER)
->where('R428US', $user)
->first();
}
$R428US = isset($ICM428M->R428US) ? $ICM428M->R428US : '';
$USERCO = isset($ICM428M->R428CO) ? $ICM428M->R428CO : '';
$USERWH = isset($ICM428M->R428WH) ? $ICM428M->R428WH : '';
private function buildM3LogQuery(string $connection)
{
$query = DB::connection($connection)->table('icm699m')
->select('ICM699M.*', DB::raw("ICM699M.SHDT || ' ' || ICM699M.SHTIME AS SHDATETIME"))
->distinct();
// Merge date and time fields
$mergedDateTime = DB::raw(" ICM699M.SHDT || ' ' || ICM699M.SHTIME AS SHDATETIME");
if (Schema::connection($connection)->hasTable('icm428m')) {
$query->addSelect('ICM428M.R428FIRST', 'ICM428M.R428FAMILY')
->leftJoin('ICM428M', 'ICM699M.SHUSER', '=', 'ICM428M.R428US');
}
if (Schema::connection($connection)->hasTable('icm688m1')) {
$query->addSelect('ICM688M1.A4ONO', 'ICM688M1.A4SHSHNM')
->leftJoin('ICM688M1', 'ICM699M.SHMACPKR', '=', 'ICM688M1.A4MACPKR');
}
if (Schema::connection($connection)->hasTable('icm666m')) {
$query->addSelect('ICM666M.A1ONO', 'ICM666M.A1SHSHNM')
->leftJoin('ICM666M', 'ICM699M.SHMACPKR', '=', 'ICM666M.A1DELNO');
}
$ICM699M = DB::connection(config('m3.connection', 'pgsql'))->table('icm699m')
->select(
'ICM699M.*',
'ICM699M.SHACKDATE',
'ICM699M.SHACKTIME',
'ICM699M.SHACKUSER',
$mergedDateTime,
'ICM428M.R428FIRST',
'ICM428M.R428FAMILY',
'ICM688M1.A4ONO',
'ICM688M1.A4SHSHNM',
'ICM666M.A1ONO',
'ICM666M.A1SHSHNM',
)
->distinct()
->leftJoin('ICM428M', 'ICM699M.SHUSER', '=', 'ICM428M.R428US')
->leftJoin('ICM688M1', 'ICM699M.SHMACPKR', '=', 'ICM688M1.A4MACPKR')
->leftJoin('ICM666M', 'ICM699M.SHMACPKR', '=', 'ICM666M.A1DELNO');
return $query;
}
if ($R428US != '') {
$ICM699M->whereIn('SHCO', [$USERCO, '']);
$ICM699M->whereIn('SHWHS', [$USERWH, '']);
private function applyM3LogFilters($query, array $filters, ?object $profile): void
{
if ($profile !== null) {
$query->whereIn('SHCO', [trim((string) ($profile->R428CO ?? '')), ''])
->whereIn('SHWHS', [trim((string) ($profile->R428WH ?? '')), '']);
} else {
$ICM699M->where('SHCO', null);
$ICM699M->where('SHWHS', null);
$query->whereNull('SHCO')->whereNull('SHWHS');
}
if ($SHMACPKR != '') {
$ICM699M->where('SHMACPKR', $SHMACPKR);
foreach (['SHMACPKR', 'SHSOURCE'] as $field) {
if ($filters[$field] !== '') {
$query->where($field, $filters[$field]);
}
}
if ($SHSOURCE != '') {
$ICM699M->where('SHSOURCE', $SHSOURCE);
$query->where('SHSOURCE', '!=', 'PdfStorageAPI');
if ($filters['SHMACPKR'] === '' && $filters['SKIPDATES'] === 'N') {
$query->whereBetween('SHDT', [$filters['STARTDATE'], $filters['ENDDATE']]);
}
// Disable PDFStorage Search
$ICM699M->where('SHSOURCE', '!=', 'PdfStorageAPI');
if ($SHMACPKR == '' && $SKIPDATES == 'N') {
$ICM699M->whereBetween('SHDT', [$STARTDATE, $ENDDATE]);
if ($filters['SHOWERRORS'] === 'Y') {
$query->where('SHERROR', 'X');
}
if ($SHOWERRORS == 'Y') {
$ICM699M->where('SHERROR', 'X');
}
// Get only M3 Logs
$ICM699M->where('SHTYPE', 'like', '%M3%');
return Datatables::of($ICM699M)->addIndexColumn()->make(true);
$query->where('SHTYPE', 'like', '%M3%');
}
public static function update699M(Request $request)