diff --git a/app/Classes/Jobs/Commands/V2/YD/FetchByTrakingNoYdPortalV2CommandJob.php b/app/Classes/Jobs/Commands/V2/YD/FetchByTrakingNoYdPortalV2CommandJob.php new file mode 100644 index 00000000..78a4451f --- /dev/null +++ b/app/Classes/Jobs/Commands/V2/YD/FetchByTrakingNoYdPortalV2CommandJob.php @@ -0,0 +1,31 @@ +packingList = $packingList; + } + + public function handle() + { + Log::info('Processing FetchByTrakingNoYdPortalV2CommandJob'); + $processor = app(FetchByTrakingNoYdPortalV2Processor::class); + $processor->execute($this->packingList); + } +} diff --git a/app/Classes/Jobs/Commands/V3/YD/FetchContainersUpdatesYdPortalV3CommandJob.php b/app/Classes/Jobs/Commands/V3/YD/FetchContainersUpdatesYdPortalV3CommandJob.php new file mode 100644 index 00000000..59535399 --- /dev/null +++ b/app/Classes/Jobs/Commands/V3/YD/FetchContainersUpdatesYdPortalV3CommandJob.php @@ -0,0 +1,32 @@ +container = $container; + } + + public function handle() + { + Log::info('Processing FetchContainersUpdatesYdPortalV3CommandJob'); + $processor = app(FetchContainersUpdatesYdPortalV3Processor::class); + $processor->execute($this->container); + } +} diff --git a/app/Classes/Jobs/Commands/V3/YD/FetchContainersYdPortalV3CommandJob.php b/app/Classes/Jobs/Commands/V3/YD/FetchContainersYdPortalV3CommandJob.php new file mode 100644 index 00000000..f48ffd9c --- /dev/null +++ b/app/Classes/Jobs/Commands/V3/YD/FetchContainersYdPortalV3CommandJob.php @@ -0,0 +1,32 @@ +packingList = $packingList; + } + + public function handle() + { + Log::info('Processing FetchContainersYdPortalV3CommandJob'); + $processor = app(FetchContainersYdPortalV3Processor::class); + $processor->execute($this->packingList); + } +} diff --git a/app/Classes/Modules/OpenAI/Services/CreatesChatGPTResponse.php b/app/Classes/Modules/OpenAI/Services/CreatesChatGPTResponse.php new file mode 100644 index 00000000..243a3c18 --- /dev/null +++ b/app/Classes/Modules/OpenAI/Services/CreatesChatGPTResponse.php @@ -0,0 +1,49 @@ + 'gpt-4-turbo', //gpt-4-turbo, gpt-4o-mini + 'messages' => [ + [ + 'role' => 'user', + 'content' => $userPrompt + ] + ] + ]; + + $response = Http::withHeaders([ + 'Authorization' => 'Bearer ' . config('openai.api_key') + ])->post(config('openai.base_url') . '/v1/chat/completions', $data); + + if ($response->successful()) { + $data = $response->json(); + return $data; + } else { + Log::info('CreatesChatGPTResponse: ' . $response); + return null; + } + } + catch (\Illuminate\Http\Client\ConnectionException $exception) { + $error = 'Failed to connect to ChatGPT API'; + throw new ConnectionErrorException($error, $exception->getMessage(), $userPrompt, $exception->getTraceAsString()); + } + catch (\Exception $exception) { + throw new MalformedRequestException('Unable to get correct response from ChatGPT API: ' . $exception->getMessage()); + } + } +} diff --git a/app/Classes/Modules/PackingLists/Processors/V2/FetchByTrakingNoYdPortalV2Processor.php b/app/Classes/Modules/PackingLists/Processors/V2/FetchByTrakingNoYdPortalV2Processor.php new file mode 100644 index 00000000..12d8e6e4 --- /dev/null +++ b/app/Classes/Modules/PackingLists/Processors/V2/FetchByTrakingNoYdPortalV2Processor.php @@ -0,0 +1,236 @@ +fetchesDataFRomYDPortal = $fetchesDataFRomYDPortal; + $this->createsChatGPTResponse = $createsChatGPTResponse; + } + + + /** + * @param PackingList $packingList + * @return void + * @throws MalformedRequestException + */ + public function execute(PackingList $packingList) + { + Log::info('FetchByTrakingNoYdPortalV2Processor starts with packingList id ' . $packingList->id); + // return; + + $time_start = microtime(true); + + $reference = $packingList->reference; + Log::info('reference ' . $reference); + + $oneHourAgo = Carbon::now()->subHour(); + $check1 = YDOrderTracking::where('tracking_no', $reference) + ->orderBy('updated_at', 'desc') + ->first(); + + if ($check1 && $check1->updated_at >= $oneHourAgo) { + Log::info('FetchByTrakingNoYdPortalV2Processor SKIPPED: Record updated within the last hour'); + Log::info('---'); + return; + } + + $check2 = YDOrderTracking::where('tracking_no', $reference) + ->where('tracking', '第三方提货') + ->first(); + + if ($check2) { + Log::info('FetchByTrakingNoYdPortalV2Processor SKIPPED: 第三方提货'); + Log::info('---'); + return; + } + + $trackingRequest = $this->fetchesDataFRomYDPortal->clientRequest('http://www.yd-wl.com/api/ApiTracking.ashx', 'GET', [ + 'trakingno' => $reference + ]); + + $rows = $this->fetchesDataFRomYDPortal->getResponseBody($trackingRequest); + + $this->processData(json_encode($rows), $reference); + + $time_end = microtime(true); + + $execution_time = ($time_end - $time_start)/60; + + Log::info('FetchByTrakingNoYdPortalV2Processor ends with packingList id ' . $packingList->id . ' => Total Execution Time: '.$execution_time.' Mins.'); + Log::info('---'); + } + + public function processData($jsonData, $reference) + { + $data = json_decode($jsonData, true); + + if ($data['res'] == 1 && isset($data['data'])) { + Log::info('package_id: '.$data['data'][0]['package_id']); + foreach (array_reverse($data['data']) as $item) { + $existingRecord = YDOrderTracking::where('order_tracking_id', $item['Id']) + ->where('tracking_no', $reference) + ->first(); + + if (!$existingRecord) { + $etdEta = $this->parseEtdEta($item['remark'], $item['tracking'], $item['trackingtime']); + YDOrderTracking::create([ + 'order_tracking_id' => $item['Id'], + 'tracking_no' => $reference, + 'package_id' => $item['package_id'], + 'tracking' => $item['tracking'] ?? null, + 'tracking_time' => $item['trackingtime'] ?? null, + 'add_time' => $item['addtime'] ?? null, + 'remark' => $item['remark'] ?? null, + 'etd' => $etdEta['etd'], + 'eta' => $etdEta['eta'] + ]); + Log::info('FetchByTrakingNoYdPortalV2Processor RECORD CREATED'); + } + else{ + Log::info('FetchByTrakingNoYdPortalV2Processor RECORD EXIST'); + } + } + } + } + + public function parseEtdEta($remark, $tracking, $trackingtime) + { + $etd = null; + $eta = null; + $etaString = ''; + $etdString = ''; + + if($remark && $tracking != '第三方提货'){ + if (preg_match('/(?:预计|延)(\d+\.\d+)(?:号)?开/', $remark, $matches)) { + $etdString = $matches[1]; + } + + if (preg_match('/(?:预计)?(\d+\.\d+)(?:号)?到港/', $remark, $matches)) { + $etaString = $matches[1]; + } + Log::info('remark: '.$remark); + + $currentYear = Carbon::now()->year; + $trackingDate = Carbon::parse($trackingtime); + $trackingYear = $trackingDate->year; + + if($remark && preg_match('/\b\d{1,2}[-\/.]\d{1,2}\b/', $remark) && $eta === null && $etd === null){ + $existingRecord = YDOrderTracking::where('remark', $remark)->where(function ($query) { + $query->whereNotNull('eta') + ->orWhereNotNull('etd'); + }) + ->first(); + if($existingRecord){ + Log::info('FetchByTrakingNoYdPortalV2Processor SAVER'); + return [ + 'etd' => $existingRecord->etd, + 'eta' => $existingRecord->eta, + ]; + } + + $userPrompt = "Show me the answer in json string without escape, e.g. {'ETA': '', 'ETD': ''}. ".$remark." What is the ETA and ETD?"; + Log::info('prompt: '.$userPrompt); + $result = $this->createsChatGPTResponse->execute($userPrompt); + Log::info(json_encode($result)); + $content = $result['choices'][0]['message']['content'] ?? null; + Log::info('content:'. json_encode($content)); + if ($content) { + $parsedContent = json_decode(str_replace("'", '"', $content), true); + if (is_array($parsedContent) && isset($parsedContent['ETA'], $parsedContent['ETD'])) { + Log::info('parsedContent ETA:'. $parsedContent['ETA']); + Log::info('parsedContent ETD:'. $parsedContent['ETD']); + $etaString = $parsedContent['ETA']; + $etdString = $parsedContent['ETD']; + $dateParts = explode('-', $etaString); + if (count($dateParts) === 3) { + $etaString = $dateParts[1] . '-' . $dateParts[2]; + } + + $dateParts = explode('-', $etdString); + if (count($dateParts) === 3) { + $etdString = $dateParts[1] . '-' . $dateParts[2]; + } + } + } + } + + if (!empty($etaString) && preg_match('/\b\d{1,2}[-\/.]\d{1,2}\b/', $etaString)) { + $etaString = str_replace(['.', '-', '/'], '/', $etaString); + $etaParts = explode('/', $etaString); + $etaMonth = intval($etaParts[0]); + $etaDay = intval($etaParts[1]); + $etaDate = DateTime::createFromFormat("Y/m/d", "$currentYear/$etaString"); + + if($trackingYear < $currentYear){ + $etaDate = DateTime::createFromFormat("Y/m/d", ($trackingYear) . "/$etaString"); + } + else{ + $etaYear = $currentYear; + if ($etaMonth <= 2 && $trackingDate->month == 12) { + $etaYear = $trackingDate->year + 1; + } + $etaDate = Carbon::createFromDate($etaYear, $etaMonth, $etaDay); + } + + if($etaDate){ + $eta = $etaDate->format('Y-m-d'); + } + Log::info('ETA: '.$eta); + Log::info('ETD: '.$etd); + } + + if (!empty($etdString) && preg_match('/\b\d{1,2}[-\/.]\d{1,2}\b/', $etdString)) { + $etdString = str_replace(['.', '-', '/'], '/', $etdString); + $etdParts = explode('/', $etdString); + $etdMonth = intval($etdParts[0]); + $etdDay = intval($etdParts[1]); + $etdDate = DateTime::createFromFormat("Y/m/d", "$currentYear/$etdString"); + + if($trackingYear < $currentYear){ + $etdDate = DateTime::createFromFormat("Y/m/d", ($trackingYear) . "/$etdString"); + } + else{ + $etdYear = $currentYear; + if ($etdMonth <= 1 && $trackingDate->month == 12) { + $etdYear = $trackingDate->year + 1; + } + $etdDate = Carbon::createFromDate($etdYear, $etdMonth, $etdDay); + } + + if($etdDate){ + $etd = $etdDate->format('Y-m-d'); + } + Log::info('ETD: '.$etd); + Log::info('ETA: '.$eta); + } + } + + return [ + 'etd' => $etd ? date('Y-m-d', strtotime($etd)) : null, + 'eta' => $eta ? date('Y-m-d', strtotime($eta)) : null, + ]; + } +} + diff --git a/app/Classes/Modules/PackingLists/Processors/V3/FetchContainersUpdatesYdPortalV3Processor.php b/app/Classes/Modules/PackingLists/Processors/V3/FetchContainersUpdatesYdPortalV3Processor.php new file mode 100644 index 00000000..bba9ca01 --- /dev/null +++ b/app/Classes/Modules/PackingLists/Processors/V3/FetchContainersUpdatesYdPortalV3Processor.php @@ -0,0 +1,190 @@ +updatesContractObligations = $updatesContractObligations; + $this->createsSchedule = $createsSchedule; + $this->packingListToPerfexCRMProcessor = $packingListToPerfexCRMProcessor; + } + + + /** + * @param Container $container + * @return void + * @throws MalformedRequestException + */ + public function execute(Container $container) + { + Log::info('FetchContainersUpdatesFromYdPortalV2Processor starts with container id ' . $container->id . ' created_at ' . $container->created_at); + // return; + + $time_start = microtime(true); + + $packingList = $container->packingLists()->first(); + $reference = $packingList->reference; + + Log::info('FetchContainersUpdatesFromYdPortalV2Processor starts with packingList id ' . $packingList->id . ' created_at ' . $packingList->created_at); + Log::info('FetchContainersUpdatesFromYdPortalV2Processor starts with reference ' . $reference); + if (!$container->created_at->greaterThanOrEqualTo(Carbon::now()->subYear())) { + return; + } + + $trackingRows = YDOrderTracking::where('tracking_no', $reference)->get(); + Log::info('YDContainerUpdates trackingRows ' . (count($trackingRows) > 0 ? json_encode($trackingRows) : 'NOT FOUND')); + Log::info('YDContainerUpdates order ' . json_encode($packingList->owner)); + + $unstuffingDate = null; + $delayDate = null; + $checkShipSailDate = null; + $checkShipArrivalDate = null; + + foreach ($trackingRows as $trackingRow) { + if($trackingRow->eta){ + if(!$delayDate){ + $delayDate = Carbon::parse($trackingRow->eta); + } + if(Carbon::parse($trackingRow->eta) > $delayDate){ + $delayDate = Carbon::parse($trackingRow->eta); + } + } + } + + foreach ($trackingRows as $trackingRow) { + if ($trackingRow->tracking === '到港') { + Log::info('YDContainerUpdates - 到港 delayDate ' . $delayDate); + Log::info('YDContainerUpdates - 到港 $trackingRow->tracking_time ' . $trackingRow->tracking_time); + $delayDate = Carbon::parse($trackingRow->tracking_time); + $checkShipArrivalDate = Carbon::parse($trackingRow->tracking_time); + } + + if ($trackingRow->tracking === '已开船') { + Log::info('YDContainerUpdates - 已开船 delayDate ' . $delayDate); + if(!$delayDate){ + Log::info('YDContainerUpdates - 已开船 $trackingRow->tracking_time add 5 days ' . $trackingRow->tracking_time); + $delayDate = Carbon::parse($trackingRow->tracking_time)->addDays('5'); + } + $checkShipSailDate = Carbon::parse($trackingRow->tracking_time); + } + + if ($trackingRow->tracking === '货物已进目的港仓库') { + Log::info('YDContainerUpdates - 货物已进目的港仓库 delayDate ' . $delayDate); + $unstuffingDate = Carbon::parse($trackingRow->tracking_time); + } + } + + if($checkShipSailDate){ + //check if ship has sailed + if($checkShipSailDate->isPast()){ + foreach ($container->packingLists as $packingList){ + if(config('perfexcrm.is_enabled') == 'true'){ + $this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::SHIP_SAILED); + } + } + } + } + + if($checkShipArrivalDate){ + //check if ship has arrived at destination + if($checkShipArrivalDate->isPast()){ + foreach ($container->packingLists as $packingList){ + if(config('perfexcrm.is_enabled') == 'true'){ + $this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::SHIP_ARRIVED); + } + } + } + } + + if($delayDate){ + Log::info('YDContainerUpdates delayDate ' . $delayDate); + $transport = $container->transports()->first(); + Log::info('YDContainerUpdates transport ' . json_encode($transport)); + if(!$transport->schedules()->whereDate('eta', '>=', $delayDate)->first()) { //If no record + $etd = $transport->schedules()->where('status', '=', ApprovalStatus::APPROVED)->first()->etd; + Log::info('YDContainerUpdates etd ' . json_encode($etd)); + $transport->schedules()->update(['status' => ApprovalStatus::EXPIRED]); + $this->createsSchedule->execute($transport, new ScheduleObject($etd, $delayDate, ApprovalStatus::APPROVED)); + foreach ($container->packingLists as $packingList){ + if(!($packingList->owner instanceof Order)) continue; + $user = $packingList->owner->companyModule->employees()->first(); + if(app()->environment(['production'])) { + $user->notify(new ShipmentRescheduleEmail($user, $packingList)); + } + } + } + else{ + Log::info('YDContainerUpdates NO DELAY'); + } + } + + if($unstuffingDate){ + $container->update(['status' => ApprovalStatus::COMPLETED]); + $container->transports()->first()->update(['drop_date' => $unstuffingDate, 'status' => ApprovalStatus::COMPLETED]); + + /** @var PackingList $packingList */ + foreach($container->packingLists as $packingList){ + + if($packingList->status === ApprovalStatus::PENDING_VERIFICATION){ + $packingList->status = ApprovalStatus::APPROVED; + $packingList->save(); + } + + if(!($packingList->owner instanceof Order)) continue; + + $signature = $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::SUPERVISOR)->first()->appointee->entity_sigiture; + foreach($packingList->steps()->where('reference', '!=', 'DELIVERY')->get() as $step){ + if(app()->environment(['production'])) { + $this->updatesContractObligations->execute($signature, $step->obligation_hash_id); + } + $step->update(['status' => ApprovalStatus::COMPLETED]); + } + if(config('perfexcrm.is_enabled') == 'true'){ + $this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::UNSTUFFING); + } + } + } + + $time_end = microtime(true); + + $execution_time = ($time_end - $time_start)/60; + + Log::info('FetchContainersUpdatesFromYdPortalV2Processor ends with container id ' . $container->id . ' => Total Execution Time: '.$execution_time.' Mins.'); + Log::info('---'); + } +} + diff --git a/app/Classes/Modules/PackingLists/Processors/V3/FetchContainersYdPortalV3Processor.php b/app/Classes/Modules/PackingLists/Processors/V3/FetchContainersYdPortalV3Processor.php new file mode 100644 index 00000000..b6f89e80 --- /dev/null +++ b/app/Classes/Modules/PackingLists/Processors/V3/FetchContainersYdPortalV3Processor.php @@ -0,0 +1,169 @@ +createsTransport = $createsTransport; + $this->createsSchedule = $createsSchedule; + $this->fetchesContainer = $fetchesContainer; + $this->createContainerProcessor = $createContainerProcessor; + $this->packingListToPerfexCRMProcessor = $packingListToPerfexCRMProcessor; + } + + + /** + * @param PackingList $packingList + * @return void + * @throws MalformedRequestException + * @throws AccessForbiddenException + * @throws RequestValidationException + */ + public function execute(PackingList $packingList) + { + Log::info('FetchContainersFromYdPortalV2Processor starts with packingList id '. $packingList->id); + // return; + + $time_start = microtime(true); + + $containerReference = null; + $loadingDate = null; + $etd = null; + $eta = null; + $reference = $packingList->reference; + + Log::info('YDContainer reference ' . $reference); + $trackingRows = YDOrderTracking::where('tracking_no', $reference)->get(); + Log::info('YDContainer trackingRows ' . json_encode($trackingRows)); + + foreach ($trackingRows as $trackingRow) { + if (strpos($trackingRow->tracking, '货物装柜完成。') !== false) { + $tracking = explode(':', $trackingRow->tracking); + $containerReference = explode('预计到港时间', $tracking[1])[0]; + $loadingDate = Carbon::parse($trackingRow->tracking_time); + $etd = Carbon::parse($tracking[2])->subDays(5); + $eta = Carbon::parse($tracking[2]); + } + } + + foreach ($trackingRows as $trackingRow) { + if($trackingRow->etd){ + Log::info('YDContainer etd DB ' . $trackingRow->etd); + Log::info('YDContainer etd DB Carbon ' . Carbon::parse($trackingRow->etd)); + Log::info('YDContainer etd existing ' . $etd); + if(Carbon::parse($trackingRow->etd) > $etd){ + $etd = Carbon::parse($trackingRow->etd); + } + } + + if($trackingRow->eta){ + Log::info('YDContainer eta DB ' . $trackingRow->eta); + Log::info('YDContainer eta DB Carbon ' . Carbon::parse($trackingRow->eta)); + Log::info('YDContainer eta existing ' . $eta); + if(Carbon::parse($trackingRow->eta) > $eta){ + $eta = Carbon::parse($trackingRow->eta); + } + } + } + Log::info('YDContainer containerReference ' . json_encode($containerReference)); + + if($containerReference) { + try { + Log::info('YDContainer try'); + $container = $this->fetchesContainer->execute(['reference' => $containerReference]); + $container->packingLists()->detach($packingList); + $container->packingLists()->attach($packingList); + } catch (ResourceNotFoundException $exception){ + Log::info('YDContainer catch'); + if(!($packingList->owner instanceof Order)) return; + + $originWarehouse = $packingList->owner->orderRoles()->where('role_id', '=', OrderRoleTypes::ORIGIN_WAREHOUSE)->first()->appointee; + + + $containerObject = new ContainerObject($containerReference, '', '', ContainerTypes::FORTY_FEET_DRY_CONTAINER, $loadingDate, ApprovalStatus::PENDING_VERIFICATION); + + /** @var Container $container */ + $container = $this->createContainerProcessor->execute($containerObject, $originWarehouse); + + $container->packingLists()->detach($packingList); + $container->packingLists()->attach($packingList); + + if(config('perfexcrm.is_enabled') == 'true'){ + $this->packingListToPerfexCRMProcessor->execute($packingList, PerfexCRMTasksYDStages::LOAD_CONTAINER); + } + + $transport = $container->transports()->first(); + + if(!$transport){ + $transportObject = new TransportObject(TransportType::SEA, null, null, $etd, null, ApprovalStatus::APPROVED); + /** @var Transport $transport */ + $transport = $this->createsTransport->execute($transportObject, $container); + $this->createsSchedule->execute($transport, new ScheduleObject($etd, $eta, ApprovalStatus::APPROVED)); + } + } + + Log::info('YDContainer containerReference ' . json_encode($containerReference)); + Log::info('YDContainer loadingDate ' . $loadingDate); + Log::info('YDContainer etd ' . $etd); + Log::info('YDContainer eta ' . $eta); + } + + $time_end = microtime(true); + + $execution_time = ($time_end - $time_start)/60; + + Log::info('FetchContainersFromYdPortalV2Processor ends with packingList id '. $packingList->id . ' => Total Execution Time: '.$execution_time.' Mins.'); + Log::info('---'); + } +} + diff --git a/app/Console/Commands/V2/ProcessYDByTrakingNoDataV2Command.php b/app/Console/Commands/V2/ProcessYDByTrakingNoDataV2Command.php new file mode 100644 index 00000000..56546024 --- /dev/null +++ b/app/Console/Commands/V2/ProcessYDByTrakingNoDataV2Command.php @@ -0,0 +1,58 @@ +fetchByTrakingNoYdPortalV2CommandJob(); + + foreach ($jobs2 as $index => $job) { + dispatch($job)->delay(now()->addSeconds($index * 3)); + } + } + + private function fetchByTrakingNoYdPortalV2CommandJob(){ + $jobs = []; + + $maxFetchTime = Carbon::now()->subMonths(4); + $packingLists = PackingList::where('type', PackingListType::SHIPPING_PACKING_LIST)->whereDate('created_at', '>=', $maxFetchTime)->get(); + $count = 0; + foreach ($packingLists as $packingList) { + $jobs[] = new FetchByTrakingNoYdPortalV2CommandJob($packingList); + Log::info('Dispatched FetchByTrakingNoYdPortalV2CommandJob for packingList with id ' . $packingList->id . ' reference ' . $packingList->reference . ' created_at ' . $packingList->created_at); + $count++; + } + Log::info('Total FetchByTrakingNoYdPortalV2CommandJob dispatched: ' . $count); + + return $jobs; + } +} diff --git a/app/Console/Commands/V2/ProcessYDPortalDataV2Command.php b/app/Console/Commands/V2/ProcessYDPortalDataV2Command.php index facd3ef3..0c974e87 100644 --- a/app/Console/Commands/V2/ProcessYDPortalDataV2Command.php +++ b/app/Console/Commands/V2/ProcessYDPortalDataV2Command.php @@ -7,6 +7,8 @@ use App\Classes\Jobs\Commands\V2\YD\FetchContainersFromYdPortalV2CommandJob; use App\Classes\Jobs\Commands\V2\YD\FetchContainersUpdatesFromYdPortalV2CommandJob; use App\Classes\Jobs\Commands\V2\YD\FetchDeliveryUpdatesFromYdPortalV2CommandJob; use App\Classes\Jobs\Commands\V2\YD\FetchOrderListsFromYdPortalV2CommandJob; +use App\Classes\Jobs\Commands\V3\YD\FetchContainersYdPortalV3CommandJob; +use App\Classes\Jobs\Commands\V3\YD\FetchContainersUpdatesYdPortalV3CommandJob; use App\Models\PackingList; use App\Models\Container; @@ -42,10 +44,10 @@ class ProcessYDPortalDataV2Command extends Command public function handle() { $jobs = []; - $jobs = array_merge($jobs, $this->fetchPackingListsFromYdPortalV2CommandJobs()); - $jobs = array_merge($jobs, $this->fetchContainersFromYdPortalV2CommandJobs()); - $jobs2 = $this->fetchContainersUpdatesFromYdPortalV2CommandJob(); - $jobs3 = $this->fetchDeliveryUpdatesFromYdPortalV2CommandJobs(); + // $jobs = array_merge($jobs, $this->fetchPackingListsFromYdPortalV2CommandJobs()); //cief todo + $jobs = array_merge($jobs, $this->fetchContainersYdPortalV3CommandJobs()); + $jobs2 = $this->fetchContainersUpdatesYdPortalV3CommandJob(); + // $jobs3 = $this->fetchDeliveryUpdatesFromYdPortalV2CommandJobs(); //cief todo // The following job is intentionally excluded ////$jobs = array_merge($jobs, $this->fetchOrderListsFromYdPortalV2CommandJob()); @@ -53,18 +55,20 @@ class ProcessYDPortalDataV2Command extends Command // Bus::chain($jobs)->dispatch(); foreach ($jobs as $index => $job) { - dispatch($job)->delay(now()->addSeconds($index * 2)); + // dispatch($job)->delay(now()->addSeconds($index * 2)); + dispatch($job); } foreach ($jobs2 as $index => $job) { - dispatch($job)->delay(now()->addSeconds($index * 1)); - } - - foreach ($jobs3 as $index => $job) { - $delayInSeconds = intdiv($index, 2); - dispatch($job)->delay(now()->addSeconds($delayInSeconds)); + // dispatch($job)->delay(now()->addSeconds($index * 1)); + dispatch($job); } + //cief todo + // foreach ($jobs3 as $index => $job) { + // $delayInSeconds = intdiv($index, 2); + // dispatch($job)->delay(now()->addSeconds($delayInSeconds)); + // } } private function fetchPackingListsFromYdPortalV2CommandJobs(){ @@ -138,6 +142,37 @@ class ProcessYDPortalDataV2Command extends Command return $jobs; } + private function fetchContainersYdPortalV3CommandJobs(){ + $jobs = []; + $maxFetchTime = Carbon::now()->subMonths(4); + $packingLists = PackingList::where('type', PackingListType::SHIPPING_PACKING_LIST)->whereDate('created_at', '>=', $maxFetchTime)->doesntHave('containers')->get(); + + $count = 0; + foreach ($packingLists as $packingList) { + $jobs[] = new FetchContainersYdPortalV3CommandJob($packingList); + Log::info('Dispatched FetchContainersYdPortalV3CommandJob for packingList with id ' . $packingList->id . ' created_at ' . $packingList->created_at); + $count++; + } + Log::info('Total fetchContainersYdPortalV3CommandJobs dispatched: ' . $count); + + return $jobs; + } + + private function fetchContainersUpdatesYdPortalV3CommandJob(){ + $jobs = []; + $containers = Container::where('status', ApprovalStatus::PENDING_VERIFICATION)->get(); + + $count = 0; + foreach ($containers as $container) { + $jobs[] = new FetchContainersUpdatesYdPortalV3CommandJob($container); + Log::info('Dispatched fetchContainersUpdatesYdPortalV3CommandJob for container with id ' . $container->id); + $count++; + } + Log::info('Total fetchContainersUpdatesYdPortalV3CommandJob dispatched: ' . $count); + + return $jobs; + } + private function fetchDeliveryUpdatesFromYdPortalV2CommandJobs(){ $jobs = []; diff --git a/app/Models/YDOrderTracking.php b/app/Models/YDOrderTracking.php new file mode 100644 index 00000000..d265462e --- /dev/null +++ b/app/Models/YDOrderTracking.php @@ -0,0 +1,25 @@ + env('OPENAI_BASE_URL', 'https://api.openai.com'), + 'api_key' => env('OPENAI_API_KEY', ''), + 'is_enabled' => env('OPENAI_IS_ENABLED', 'true'), +]; diff --git a/config/perfexcrm.php b/config/perfexcrm.php index 4805c062..255a837b 100644 --- a/config/perfexcrm.php +++ b/config/perfexcrm.php @@ -1,7 +1,7 @@ env('PERFEXCRM_BASE_URL', 'http://192.168.1.100:8084'), //cief todo: Update crm api domain here + 'base_url' => env('PERFEXCRM_BASE_URL', 'http://192.168.1.100:8084'), 'api_key' => env('PERFEXCRM_API_KEY', ''), 'is_enabled' => env('PERFEXCRM_IS_ENABLED', 'true'), ]; diff --git a/database/migrations/2024_11_02_113339_create_yd_order_tracking_table.php b/database/migrations/2024_11_02_113339_create_yd_order_tracking_table.php new file mode 100644 index 00000000..bc92ebbb --- /dev/null +++ b/database/migrations/2024_11_02_113339_create_yd_order_tracking_table.php @@ -0,0 +1,40 @@ +bigIncrements('id'); + $table->bigInteger('order_tracking_id'); + $table->string('tracking_no'); + $table->bigInteger('package_id')->index(); + $table->string('tracking')->nullable(); + $table->dateTime('tracking_time'); + $table->dateTime('add_time'); + $table->text('remark')->nullable(); + $table->date('eta')->nullable(); + $table->date('etd')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('yd_order_tracking'); + } +}