'required|string', 'templateId' => 'required|string' ]; protected $messages = [ 'messageId.required' => '*Message cannot be empty.', 'templateId.required' => '*Template cannot be empty.' ]; protected $listNonLockData = [ "MessageType", "AuditDateTime", "Message", "Status" ]; public function mount() { $this->messageTypes = MasterMessages::pluck('value', 'id')->toArray(); $this->docTypes = MasterDocTypes::pluck('name', 'code')->toArray(); $this->changeBtnColor = "bg-[#A020F0] hover:bg-[#B34FEF] text-white font-bold"; $this->lockData = false; $this->disableLockData = true; } public function render() { if ($this->messageId != '') { $this->responseTemplates = MasterResponseTemplates::where('mid', $this->messageId)->get()->mapWithKeys(function ($record) { $description = $record->description != '' ? ' ' . ' (' . $record->description . ')' : ''; return [$record->id => $record->code . ': ' . $record->name . $description]; })->toArray(); $this->docTypes = MasterDocTypes::where('mid', $this->messageId)->pluck('name', 'code')->toArray(); } return view('livewire.pages.manual-response.manual-response-index'); } public function updatedMessageId() { $this->templateId = ''; $this->responseTemplates = []; $this->docTypes = []; $this->docType = ''; $this->xmlData = []; $this->xmlContent = ''; $this->displayCustomizeDiv = false; if($this->messageId == 3 || $this->messageId == 4){ $this->disableDocType = true; }else{ $this->disableDocType = false; } $this->lockData = false; } public function updatedXmlTagInputList() { if ($this->xmlData === null) { $this->xmlContent = ''; } } public function gotoCustomize() { $this->disableLockData = false; $tmp_xmlData = $this->xmlData; $this->xmlData = []; $this->xmlContent = ''; $this->validate(); //Default documentType in case messsage is export/import if(empty($this->docType)){ if($this->messageId == 1){ $this->docType = 1; }else if($this->messageId == 2){ $this->docType = 0; } } $xmlGenerator = new GenXmlController(); $xml = $xmlGenerator->generateXML($this->templateId, $this->docType, $this->lockData); if ($xml == null) { session()->flash('templateNotFound', 'Template is not found!'); } else { $this->displayCustomizeDiv = true; $this->xmlContent = $xml['xmlContent']; $this->xmlData = $xml['xmlWithData']; //For response Export: 9904: Goods Transition Control Already Cancel Matching -> No auto-gen Declaration Number. $messageCode = MasterResponseTemplates::where('id', $this->templateId)->value('code') ?? ''; dd($messageCode); if($messageCode == '9904'){ $this->xmlData['DeclarationNumber'] = ''; } if($this->lockData){ foreach($this->xmlData as $key => $val){ if(isset($tmp_xmlData[$key]) && !in_array($key, $this->listNonLockData)){ $this->xmlData[$key] = $tmp_xmlData[$key]; } if(isset($tmp_xmlData['ReferenceNumber']) && isset($this->xmlData['ReferenceNo'])){ $this->xmlData['ReferenceNo'] = $tmp_xmlData['ReferenceNumber']; } } } $this->reGenerateXML(); } $this->changeBtnColor = "bg-slate-150 font-medium text-slate-800 hover:bg-slate-200 focus:bg-slate-200 active:bg-slate-200/80 rounded-md border border-[#e5e7eb] "; } public function reGenerateXML() { $xmlGenerator = new GenXmlController(); $xml = $xmlGenerator->updateXmlValues($this->xmlContent, $this->xmlData); $this->xmlContent = $xml; } public function mockUpXML() { $this->xmlData = $this->xmlWithData; } public function generateAndUploadXml() { $this->reGenerateXML(); $validateResult = $this->validateBeforeSend(); if(!$validateResult['success']){ $this->dispatchBrowserEvent('open-modal', [ 'name' => 'alert-modal', 'message' => $validateResult['message'], 'status' => 'failed' ]); return; } // Generate XML file from string $now = Carbon::now(); $filename = 'manual_response_' . $now->format('Ymd_His') . ".xml"; Storage::disk('local')->put($filename, $this->xmlContent); $filePath = storage_path('app/' . $filename); $currentUser = Auth::user(); $userConnect = UsersConnectSpn::where('uid', $currentUser->id)->first(); if(!isset($userConnect)){ $this->dispatchBrowserEvent('open-modal', [ 'name' => 'alert-modal', 'message' => 'SPN config is not found!', 'status' => 'failed' ]); return; } $spnConfigController = new SpnConfigController(); $spnConfig = $spnConfigController->init_connection($userConnect); if($spnConfig != null && $spnConfig['success'] == 'true'){ $uid = $spnConfig['uid']; $ucode = $spnConfig['ucode']; $ch = curl_init(); $cfile = new CURLFile($filePath, 'application/xml', $filename); $postData = [ 'UID' => $uid, 'UCODE' => $ucode, 'SERVICENAME' => 'imcoreservice', 'ACTION' => 'get_response_customs', 'profilecode' => '', 'API_PLACE_FILE' => 'Y', 'file' => $cfile ]; curl_setopt($ch, CURLOPT_URL, $userConnect->link . "/IE5DEV.shippingnet/data_defaulttemplate.php"); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($ch); $error = curl_error($ch); curl_close($ch); TabManualResponseLog::create([ 'uid' => $currentUser->id, 'title' => 'Send Manual Response', 'detail' => "Username: " . $userConnect->username . "\nLink: " . $userConnect->link, 'xml_content' => base64_encode($this->xmlContent), 'reference_number' => $this->xmlData['ReferenceNumber'] ?? $this->xmlData['ReferenceNo'] ?? '', 'declaration_number' => $this->xmlData['DeclarationNumber'] ?? $this->xmlData['DocumentNumber'] ?? '', 'link' => $userConnect->link ]); if ($error) { //Cannot send response to SPN $alertMessage = $error; $alertStatus = 'failed'; } elseif(!$this->validateAfterSend($result)) { $alertMessage = 'Unable to upload the file to SPN.
Please ensure the INBOX folder is properly set up before retrying.'; $alertStatus = 'failed'; } else { $alertMessage = 'Send response successfully'; $alertStatus = 'success'; } Storage::disk('local')->delete($filename); }else if($spnConfig != null && $spnConfig['success'] == 'false'){ $alertMessage = $spnConfig['message']; $alertStatus = 'failed'; }else{ //Cannot get UID/UCODE from SPN $alertMessage = 'Cannot connect to SPN'; $alertStatus = 'failed'; } $this->dispatchBrowserEvent('open-modal', [ 'name' => 'alert-modal', 'message' => $alertMessage, 'status' => $alertStatus ]); } private function validateBeforeSend(){ $messageType = $this->xmlData['MessageType'] ?? ''; $referenceNo = $this->xmlData['ReferenceNumber'] ?? $this->xmlData['ReferenceNo'] ?? ''; $declarationNo = $this->xmlData['DeclarationNumber'] ?? $this->xmlData['DocumentNumber'] ?? ''; $profileProds = ConfListProfile::where('type', 'PROD')->pluck('name')->toArray(); //Validate reference number format if (!preg_match('/^[A-Z]{4}[0-9]{9}$/', $referenceNo)) { return [ "success" => false, 'message' => 'Reference Number is incorrect format.' ]; } //Validate profile production if(in_array(substr($referenceNo, 0, 1), $profileProds)){ return [ "success" => false, 'message' => 'Profile production is not allowed.' ]; } //Validate profile production if(in_array($messageType, ['XCDA', 'XCDR']) && $declarationNo == ''){ return [ "success" => false, 'message' => 'Cancel template is required "Declaration Number" field.' ]; } return ['success' => true, 'message' => '']; } private function validateAfterSend($result){ if(str_starts_with($result, 'Sorry, there was an error moving the file.')){ return false; } return true; } }