M3 Integration fixes

This commit is contained in:
Mark Gregory
2026-09-22 11:08:39 +01:00
parent e4213d1fd6
commit dc97598278
7 changed files with 158 additions and 136 deletions
@@ -57,9 +57,10 @@
</div>
<div class="hd-select-wrap shrink-0 md:w-72">
<label for="kanban-board-select" class="sr-only">Kanban board</label>
<select
id="kanban-board-select"
class="hd-select"
aria-label="Kanban board"
onchange="window.location.href = '{{ route('helpdesk.kanban') }}?board_id=' + encodeURIComponent(this.value)"
>
@foreach ($boards as $availableBoard)
+36 -24
View File
@@ -22,32 +22,44 @@ class ReplenAPI extends Controller
$context = $this->requestContext($request);
try {
if ($context['params'] === []) {
return $this->missingParametersResponse($context);
}
$this->logRequest($context);
$tokenResponse = Helper::checkReceiveTokenV2();
$tokenData = $tokenResponse->getData();
if ((string) ($tokenData->code ?? '') !== '200') {
$this->log($context, (string) ($tokenData->message ?? ''), 'X', 'M3-Res-out');
return $tokenResponse;
}
$result = $this->fetchInventory($context, (string) ($tokenData->token ?? ''));
if ($result['error'] !== '') {
$this->log($context, $result['status'] . '-' . $result['error'] . $result['session'], 'X', 'M3-Res-out');
return response()->json(['code' => '405', 'status' => 'error', 'message' => $result['error']]);
}
$this->log($context, $result['status'] . '-' . $result['json'] . $result['session'], '', 'M3-Res-out');
$rows = $this->flattenInventory($result['result']);
$this->replaceInventory($context, $rows);
return response()->json(['code' => '200', 'status' => 'Success']);
$response = $this->processInventoryRequest($context);
} catch (\Throwable $throwable) {
return $this->exceptionResponse($context, $throwable);
$response = $this->exceptionResponse($context, $throwable);
}
return $response;
}
private function processInventoryRequest(array $context)
{
if ($context['params'] === []) {
return $this->missingParametersResponse($context);
}
$this->logRequest($context);
$tokenResponse = Helper::checkReceiveTokenV2();
$tokenData = $tokenResponse->getData();
if ((string) ($tokenData->code ?? '') !== '200') {
$this->log($context, (string) ($tokenData->message ?? ''), 'X', 'M3-Res-out');
return $tokenResponse;
}
return $this->inventoryResponse($context, (string) ($tokenData->token ?? ''));
}
private function inventoryResponse(array $context, string $token)
{
$result = $this->fetchInventory($context, $token);
if ($result['error'] !== '') {
$this->log($context, $result['status'] . '-' . $result['error'] . $result['session'], 'X', 'M3-Res-out');
return response()->json(['code' => '405', 'status' => 'error', 'message' => $result['error']]);
}
$this->log($context, $result['status'] . '-' . $result['json'] . $result['session'], '', 'M3-Res-out');
$rows = $this->flattenInventory($result['result']);
$this->replaceInventory($context, $rows);
return response()->json(['code' => '200', 'status' => 'Success']);
}
private function configureTimeouts(): void
@@ -27,7 +27,20 @@ class FillBOL2Controller extends Controller
// # $bOL = BOL::findOrFail($request);
$bOL = $request;
$data = [
$data = $this->bolData($request, $bOL);
try {
$filledPdf = $this->bolService->fillBillOfLading($data);
return response()->download($filledPdf)->deleteFileAfterSend(true);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
private function bolData(Request $request, Request $bOL): array
{
return [
'bol_number' => $request->input('BOL_number') ?? '1234567890',
'shipper_no' => $request->input('shipper_no') ?? '1234567890',
'date' => now()->format('m/d/Y') ?? '01/01/2000',
@@ -213,14 +226,6 @@ Line 5',
'NUMDROPS' => '',
];
try {
$filledPdf = $this->bolService->fillBillOfLading($data);
return response()->download($filledPdf)->deleteFileAfterSend(true);
} catch (\Exception $e) {
return response()->json(['error' => $e->getMessage()], 500);
}
}
}
@@ -41,7 +41,22 @@ class FillBOLController extends Controller
dd($error);
}
$result = $pdf->fillForm([
$result = $pdf->fillForm(self::bolFormData($bOL))
->needAppearances() // ensures values are visible in viewer
->saveAs(Storage::disk('public')->path($newfile));
// Always check for errors
if ($result === false) {
var_dump('step 3');
$error = $pdf->getError();
dd($error);
} else {
return response()->file(Storage::disk('public')->path($newfile));
}
}
private static function bolFormData(Request $bOL): array
{
return [
'DTESHIPED.1' => date('d/m/Y'),
'invoice_number' => $bOL['BOL_number'],
'amount_due' => number_format($bOL['amount'], 2),
@@ -197,17 +212,7 @@ class FillBOLController extends Controller
'BILLTOADDR' => '',
'NUMDROPS' => '',
])
->needAppearances() // ensures values are visible in viewer
->saveAs(Storage::disk('public')->path($newfile));
// Always check for errors
if ($result === false) {
var_dump('step 3');
$error = $pdf->getError();
dd($error);
} else {
return response()->file(Storage::disk('public')->path($newfile));
}
];
}
}
@@ -41,81 +41,80 @@ class UserControlController extends Controller
//
public static function saveUserAdd(Request $request)
{
if ($request->R428EMPCDE == '') {
$request->R428EMPCDE = 0;
}
// Insert record to ICM428M
// dump($request);
// Validate user profile exists on the system
$usrprf = [(object) ['COUNT' => 0]]; // PostgreSQL/Core owns M3 profiles; no QSYS2 lookup.
// Validate employee code exists in LBPF file
// if($request->R428EMPCDE>0) {
// $empcde=DB::connection(config('m3.connection', 'pgsql'))->select("select count(*) as COUNT2 from LBPF where EMPNO='$request->R428EMPCDE'");
// if($empcde[0]->COUNT2=="0") {
// #echo "<script>alert('Employee code entered does not exist, please try again');</script>";
// return "error empcd";
// }
// }
$icm428m = DB::connection(config('m3.connection', 'pgsql'))->select("select count(*) as COUNT1 from ICM428M where R428US='$request->R428US'");
if ($icm428m[0]->COUNT1 == '1') {
$connection = DB::connection(config('m3.connection', 'pgsql'));
$existing = $connection->select("select count(*) as COUNT1 from ICM428M where R428US='$request->R428US'");
if (($existing[0]->COUNT1 ?? 0) == '1') {
return 'error exists';
} else {
if ($usrprf[0]->COUNT == '1') {
DB::connection(config('m3.connection', 'pgsql'))->insert("insert into ICM428M
(R428CO, R428PL, R428WH, R428STS, R428US, R428FIRST, R428FAMILY, R428EMAIL, R428EMPCDE, R428ADMUSR, R428PWRUSR, MENU2OPT, MENU3OPT, MENU4OPT, MENU5OPT, MENU6OPT, R42811A)
values ('$request->R428CO', '$request->R428PL', '$request->R428WH', '$request->R428STS', '$request->R428US', '$request->R428FIRST',
'$request->R428FAMILY', '$request->R428EMAIL', $request->R428EMPCDE, '$request->R428ADMUSR', '$request->R428PWRUSR',
'NN" . $request->MENU2OPT3 . 'NNN' . $request->MENU2OPT7 . $request->MENU2OPT8 . "N', '" . $request->MENU3OPT1 . $request->MENU3OPT2 . "NNNNNNN',
'" . $request->MENU4OPT1 . $request->MENU4OPT2 . $request->MENU4OPT3 . "NNNNNN',
'" . $request->MENU5OPT1 . $request->MENU5OPT2 . $request->MENU5OPT3 . 'N' . $request->MENU5OPT5 . "NNNN','" . $request->MENU6OPT1 . $request->MENU6OPT2 . $request->MENU6OPT3 . "','" . $request->R42811A . "')");
return 'success';
} else {
// CL program call here (ewobjtst.)ICMUSRPRF parms(R428US, R428FIRST, R428FAMILY)
// connect to toolkit using DB2 credentials (can also leave blank for default authority)
try {
$conn = app(PostgresProgramBridge::class);
} catch (\Throwable $e) {
// Determine reason for failure.
// Probably database authentication error or invalid or unreachable database.
return self::programBridgeConnectionError($e);
}
$conn->setOptions(['persistent' => false, 'stateless' => true, 'debug' => true, 'debugLogFile' => '/www/sentm3test/htdocs/M3/storage/logs/toolkit_debug.log']);
// Add LIB
// $result = $conn->CLCommand('ADDLIBLE LIB(MPDAT10)');
// define several input/output params
$params = [];
$params[] = $conn->AddParameterChar('in', 10, 'User profile', 'E#iUsrPrf', $request->R428US);
$params[] = $conn->AddParameterChar('in', 20, 'First name', 'FIRST', $request->R428FIRST);
$params[] = $conn->AddParameterChar('in', 30, 'Family name', 'FAMILY', $request->R428FAMILY);
// # $result = $conn->PgmCall(Config::get('eproconf.misc.PGM1'), Config::get('eproconf.misc.libname4'), $params, array(), array());
$result = $conn->PgmCall('ICMUSRPRF', 'EWOBJ', $params, [], []);
if (! $result) {
return 'error profile2';
} else {
// Successful Call : User profile created with default password
// dd($result);
// echo "<script>alert('User profile $request->R428US was created on the system with default password.');</script>";
DB::connection(config('m3.connection', 'pgsql'))->insert("insert into ICM428M
(R428CO, R428PL, R428WH, R428STS, R428US, R428FIRST, R428FAMILY, R428EMAIL, R428EMPCDE, R428ADMUSR, R428PWRUSR, MENU2OPT, MENU3OPT, MENU4OPT, MENU5OPT, MENU6OPT, R42811A,R42821A)
values ('$request->R428CO', '$request->R428PL', '$request->R428WH', '$request->R428STS', '$request->R428US', '$request->R428FIRST',
'$request->R428FAMILY', '$request->R428EMAIL', $request->R428EMPCDE, '$request->R428ADMUSR', '$request->R428PWRUSR',
'NN" . $request->MENU2OPT3 . 'NNN' . $request->MENU2OPT7 . $request->MENU2OPT8 . "N', '" . $request->MENU3OPT1 . $request->MENU3OPT2 . "NNNNNNN',
'" . $request->MENU4OPT1 . $request->MENU4OPT2 . $request->MENU4OPT3 . "NNNNNN',
'" . $request->MENU5OPT1 . $request->MENU5OPT2 . $request->MENU5OPT3 . 'N' . $request->MENU5OPT5 . "NNNN','" . $request->MENU6OPT1 . $request->MENU6OPT2 . $request->MENU6OPT3 . "','" . $request->R42811A . "','" . $request->R42821A . "')");
return 'success2';
}
// #kd return "error profile";
}
}
// PostgreSQL/Core owns M3 profiles; no QSYS2 lookup is currently available.
$profileExists = false;
if ($profileExists) {
self::insertUser($request, false);
return 'success';
}
return self::createSystemProfileAndUser($request);
}
private static function createSystemProfileAndUser(Request $request): string
{
try {
$conn = app(PostgresProgramBridge::class);
} catch (\Throwable $e) {
return self::programBridgeConnectionError($e);
}
$conn->setOptions([
'persistent' => false,
'stateless' => true,
'debug' => true,
'debugLogFile' => '/www/sentm3test/htdocs/M3/storage/logs/toolkit_debug.log',
]);
$params = [
$conn->AddParameterChar('in', 10, 'User profile', 'E#iUsrPrf', $request->R428US),
$conn->AddParameterChar('in', 20, 'First name', 'FIRST', $request->R428FIRST),
$conn->AddParameterChar('in', 30, 'Family name', 'FAMILY', $request->R428FAMILY),
];
if (! $conn->PgmCall('ICMUSRPRF', 'EWOBJ', $params, [], [])) {
return 'error profile2';
}
self::insertUser($request, true);
return 'success2';
}
private static function insertUser(Request $request, bool $includeR42821A): void
{
$values = [
'R428CO' => $request->R428CO,
'R428PL' => $request->R428PL,
'R428WH' => $request->R428WH,
'R428STS' => $request->R428STS,
'R428US' => $request->R428US,
'R428FIRST' => $request->R428FIRST,
'R428FAMILY' => $request->R428FAMILY,
'R428EMAIL' => $request->R428EMAIL,
'R428EMPCDE' => $request->R428EMPCDE,
'R428ADMUSR' => $request->R428ADMUSR,
'R428PWRUSR' => $request->R428PWRUSR,
'MENU2OPT' => 'NN' . $request->MENU2OPT3 . 'NNN' . $request->MENU2OPT7 . $request->MENU2OPT8 . 'N',
'MENU3OPT' => $request->MENU3OPT1 . $request->MENU3OPT2 . 'NNNNNNN',
'MENU4OPT' => $request->MENU4OPT1 . $request->MENU4OPT2 . $request->MENU4OPT3 . 'NNNNNN',
'MENU5OPT' => $request->MENU5OPT1 . $request->MENU5OPT2 . $request->MENU5OPT3 . 'N' . $request->MENU5OPT5 . 'NNNN',
'MENU6OPT' => $request->MENU6OPT1 . $request->MENU6OPT2 . $request->MENU6OPT3,
'R42811A' => $request->R42811A,
];
if ($includeR42821A) {
$values['R42821A'] = $request->R42821A;
}
DB::connection(config('m3.connection', 'pgsql'))->table('icm428m')->insert($values);
}
//
@@ -229,24 +229,7 @@ class UtilitiesController extends Controller
// Build GS1 18 Digits Code
$gs1_128_bc_1 = '00' . $packageType . $manufactID . $gS1SEQUENCEID;
// Calculate Check Digit
$digits = str_split($gs1_128_bc_1);
$sum = 0;
$length = count($digits);
// Loop through each digit starting from the right
for ($i = 0; $i < $length; $i++) {
$digit = $digits[$length - $i - 1];
// Assign a weight of 3 or 1 alternately
$weight = ($i % 2 == 0) ? 3 : 1;
// Add the product of the digit and its weight to the sum
$sum += $digit * $weight;
}
// Calculate the remainder when sum is divided by 10
$remainder = $sum % 10;
// If remainder is 0, check digit is 0; otherwise, subtract remainder from 10
$checkDigit = ($remainder == 0) ? 0 : 10 - $remainder;
// End Check Digit Calculation
$checkDigit = self::gs1CheckDigit($gs1_128_bc_1);
// SSCC 18 Digits Code
$gs1_128_bc = $gs1_128_bc_1 . $checkDigit;
@@ -377,6 +360,23 @@ class UtilitiesController extends Controller
}
}
private static function gs1CheckDigit(string $value): int
{
$digits = str_split($value);
$sum = 0;
$length = count($digits);
for ($i = 0; $i < $length; $i++) {
$digit = (int) $digits[$length - $i - 1];
$weight = $i % 2 === 0 ? 3 : 1;
$sum += $digit * $weight;
}
$remainder = $sum % 10;
return $remainder === 0 ? 0 : 10 - $remainder;
}
public static function generateGS128Tst(Request $request)
{
print_r('>>> Generate PDF');
+1 -1
View File
@@ -102,7 +102,7 @@
align-items: center;
background: linear-gradient(135deg, rgba(15, 118, 110, 0.14), rgba(37, 99, 235, 0.12));
border-radius: 18px;
color: #052f2c;
color: #00100f;
display: flex;
font-size: 1.35rem;
height: 56px;