diff --git a/app/Console/Commands/ForterHistoricalDataUpload.php b/app/Console/Commands/ForterHistoricalDataUpload.php new file mode 100644 index 0000000..3e2af04 --- /dev/null +++ b/app/Console/Commands/ForterHistoricalDataUpload.php @@ -0,0 +1,199 @@ +progressBar = $this->output->createProgressBar($maxNumberOfTasks); + } + + protected function advanceProgressBar() + { + $this->progressBar->advance(); + } + + protected function lineSepartor() + { + $this->newLine(); + $this->line('------------------------------------------'); + $this->newLine(); + } + + /** + * Execute the console command. + */ + public function handle() + { + try { + Log::info("[Commands\ForterHistoricalDataUpload::handle] [START]"); + + $this->printHeading(); + + $filename = 'historical-data_generated-on-' . Carbon::now()->format('Y-m-d') . '.jsonl'; + // Delete previously generated file. + Storage::disk('local_forter')->delete($filename); + + $expand = ['paymentInfo.payments[*]', 'cart']; + $fromDate = Carbon::now()->subMonths(12)->format('Y-m-d\TH:i:s.000\Z'); + + // Check how many historical orders exists + $request = CommercetoolsOrdersService::get(null, 1, true); + $request = $request->withWhere(sprintf('createdAt > "%s"', $fromDate)); + $totalOrders = $request->execute()->getTotal(); + $this->comment("Found {$totalOrders} orders."); + + // If found orders + if ($totalOrders) { + $this->comment("Processing..."); + $this->createProgressBar($totalOrders); + + $bulkLimit = 100; + $lastId = null; + $continue = true; + $skippedAlreadySent = []; + $prepared = []; + + while ($continue) { + sleep(1); + + if ($lastId === null) { + $request = CommercetoolsOrdersService::get($expand, $bulkLimit, true); + $request = $request + ->withSort('id asc') + ->withWithTotal('false') + ->withWhere(sprintf('createdAt > "%s"', $fromDate)); + } else { + $request = CommercetoolsOrdersService::get($expand, $bulkLimit, true); + $request = $request + ->withSort('id asc') + ->withWithTotal('false') + ->withWhere(sprintf('createdAt > "%s" and id > "%s"', $fromDate, $lastId)); + } + + $response = $request->execute(); + $results = $response->getResults(); + $continue = $response->getCount() == $bulkLimit; + + if (!empty($results)) { + $lastId = $results->end()->getId(); + + foreach ($results as $order) { + try { + //$this->line(" Preparing Commercetools order ID: {$order->getId()}"); + $orderModel = ForterOrder::getInstance($order); + if (!empty($orderModel->getForterResponse())) { + $skippedAlreadySent[] = $order->getId(); + } else { + $orderSchema = ForterSchemaBuilder::buildHistoricalOrderSchema($orderModel); + $jsonLine = \json_encode($orderSchema); + if (! Storage::disk('local_forter')->append($filename, $jsonLine)) { + throw new \Exception("Couldn't write data to local file ('forter/{$filename}')"); + } + $prepared[] = $order->getId(); + } + } catch (\Exception $e) { + $this->error(" [ERROR] " . $e->getMessage()); + Log::error("[Commands\ForterHistoricalDataUpload::handle] [ERROR] while preparing order (ID) {$order->getId()} | " . $e->getMessage(), ['exception' => $e]); + } + + $this->advanceProgressBar(); + //$this->newLine(); + } + } + } + + $this->newLine(); + + if ($skippedAlreadySent) { + $this->lineSepartor(); + $this->comment("Some of the orders have already been sent to the Forter and therefore have been skipped:"); + $this->line(implode(',', $skippedAlreadySent)); + } + + $this->lineSepartor(); + + if (Storage::disk('local_forter')->exists($filename) && $prepared) { + $this->comment("Orders on file: " . count($prepared)); + $this->newLine(); + + $this->info("The file in ready and can be found on: " . Storage::disk('local_forter')->path($filename)); + $this->info("Please proceed by uploading it manually to your dedicated folder on Forter's AWS (as instructed on your Forter Portal)"); + } else { + $this->comment("No file has been created."); + } + } + + // Setup Completed + $this->printEnding(); + + Log::info("[Commands\ForterHistoricalDataUpload::handle] [END]"); + } catch (\Exception $e) { + Log::error("[Commands\ForterHistoricalDataUpload::handle] [ERROR] " . $e->getMessage(), ['exception' => $e]); + if ($filename && Storage::disk('local_forter')->exists($filename)) { + Storage::disk('local_forter')->delete($filename); + } + + throw $e; + } + } + + protected function printHeading() + { + $this->newLine(); + $this->info("***********************************************************"); + $this->info("*** Forter Commercetools App - Historical Data Upload ***"); + $this->info("***********************************************************"); + $this->newLine(2); + } + + protected function printEnding() + { + $this->newLine(); + $this->info("***************************************************************"); + $this->info("*** Forter historical data upload completed successfully! ***"); + $this->info("***************************************************************"); + $this->newLine(2); + } +} diff --git a/app/Models/Forter/ForterOrder.php b/app/Models/Forter/ForterOrder.php index 1479c09..04745d2 100644 --- a/app/Models/Forter/ForterOrder.php +++ b/app/Models/Forter/ForterOrder.php @@ -224,6 +224,18 @@ public function getTaxedPriceTotalGross($field) return isset($this->_data['taxedPrice']['totalGross']) ? $this->_data['taxedPrice']['totalGross'] : []; } + /** + * @method getTotalPrice + * @return mixed + */ + public function getTotalPrice($field) + { + if ($field) { + return isset($this->_data['totalPrice'][$field]) ? $this->_data['totalPrice'][$field] : null; + } + return isset($this->_data['totalPrice']) ? $this->_data['totalPrice'] : []; + } + /** * @method getShippingInfo * @return mixed diff --git a/app/Services/Commercetools/CommercetoolsCartsService.php b/app/Services/Commercetools/CommercetoolsCartsService.php index 6ed9b5f..e8279c9 100644 --- a/app/Services/Commercetools/CommercetoolsCartsService.php +++ b/app/Services/Commercetools/CommercetoolsCartsService.php @@ -22,7 +22,7 @@ class CommercetoolsCartsService extends CommercetoolsClientService { - public static function getAll($expand = null, $limit = null) + public static function get($expand = null, $limit = null) { $request = parent::getApiClientBuilder() ->carts()->get(); @@ -32,7 +32,7 @@ public static function getAll($expand = null, $limit = null) } if ($limit) { - $request = $request->withLimit(1); + $request = $request->withLimit($limit); } return $request->execute(); diff --git a/app/Services/Commercetools/CommercetoolsExtensionsService.php b/app/Services/Commercetools/CommercetoolsExtensionsService.php index 4caa7fd..7fe0d0a 100644 --- a/app/Services/Commercetools/CommercetoolsExtensionsService.php +++ b/app/Services/Commercetools/CommercetoolsExtensionsService.php @@ -26,7 +26,7 @@ class CommercetoolsExtensionsService extends CommercetoolsClientService { - public static function getAll($expand = null, $limit = null) + public static function get($expand = null, $limit = null) { $request = parent::getApiClientBuilder() ->extensions()->get(); @@ -36,7 +36,7 @@ public static function getAll($expand = null, $limit = null) } if ($limit) { - $request = $request->withLimit(1); + $request = $request->withLimit($limit); } return $request->execute(); diff --git a/app/Services/Commercetools/CommercetoolsOrdersService.php b/app/Services/Commercetools/CommercetoolsOrdersService.php index 5d22dca..2451a6d 100644 --- a/app/Services/Commercetools/CommercetoolsOrdersService.php +++ b/app/Services/Commercetools/CommercetoolsOrdersService.php @@ -11,6 +11,7 @@ namespace App\Services\Commercetools; +use Illuminate\Support\Carbon; use Commercetools\Api\Models\Order\OrderFromCartDraftBuilder; use Commercetools\Api\Models\Order\OrderSetCustomTypeActionBuilder; use Commercetools\Api\Models\Order\OrderUpdateActionBuilder; @@ -22,7 +23,7 @@ class CommercetoolsOrdersService extends CommercetoolsClientService { - public static function getAll($expand = null, $limit = null) + public static function get($expand = null, $limit = null, $returnBuilder = false) { $request = parent::getApiClientBuilder() ->orders()->get(); @@ -32,7 +33,11 @@ public static function getAll($expand = null, $limit = null) } if ($limit) { - $request = $request->withLimit(1); + $request = $request->withLimit($limit); + } + + if ($returnBuilder) { + return $request; } return $request->execute(); @@ -64,15 +69,10 @@ public static function getByOrderNumber($orderNumber, $expand = null) public static function getOrderByPaymentId($paymentId, $expand = null) { - $request = parent::getApiClientBuilder() - ->orders()->get() + $request = self::get($expand, 1, true); + $request = $request ->withWhere('paymentInfo(payments(id=:paymentId))') - ->withPredicateVar("paymentId", $paymentId) - ->withLimit(1); - - if ($expand) { - $request = $request->withExpand($expand); - } + ->withPredicateVar("paymentId", $paymentId); $results = $request->execute()->getResults(); return !empty($results) ? $results[0] : false; diff --git a/app/Services/Commercetools/CommercetoolsPaymentsService.php b/app/Services/Commercetools/CommercetoolsPaymentsService.php index af11cd2..04d5001 100644 --- a/app/Services/Commercetools/CommercetoolsPaymentsService.php +++ b/app/Services/Commercetools/CommercetoolsPaymentsService.php @@ -29,7 +29,7 @@ class CommercetoolsPaymentsService extends CommercetoolsClientService { - public static function getAll($expand = null, $limit = null) + public static function get($expand = null, $limit = null) { $request = parent::getApiClientBuilder() ->payments()->get(); @@ -39,7 +39,7 @@ public static function getAll($expand = null, $limit = null) } if ($limit) { - $request = $request->withLimit(1); + $request = $request->withLimit($limit); } return $request->execute(); diff --git a/app/Services/Commercetools/CommercetoolsSubscriptionsService.php b/app/Services/Commercetools/CommercetoolsSubscriptionsService.php index c091c55..61fc56d 100644 --- a/app/Services/Commercetools/CommercetoolsSubscriptionsService.php +++ b/app/Services/Commercetools/CommercetoolsSubscriptionsService.php @@ -29,7 +29,7 @@ class CommercetoolsSubscriptionsService extends CommercetoolsClientService { - public static function getAll($expand = null, $limit = null) + public static function get($expand = null, $limit = null) { $request = parent::getApiClientBuilder() ->subscriptions()->get(); @@ -39,7 +39,7 @@ public static function getAll($expand = null, $limit = null) } if ($limit) { - $request = $request->withLimit(1); + $request = $request->withLimit($limit); } return $request->execute(); diff --git a/app/Services/Commercetools/CommercetoolsTypesService.php b/app/Services/Commercetools/CommercetoolsTypesService.php index c699878..6f07350 100644 --- a/app/Services/Commercetools/CommercetoolsTypesService.php +++ b/app/Services/Commercetools/CommercetoolsTypesService.php @@ -28,7 +28,7 @@ class CommercetoolsTypesService extends CommercetoolsClientService { - public static function getAll($expand = null, $limit = null) + public static function get($expand = null, $limit = null) { $request = parent::getApiClientBuilder() ->types()->get(); @@ -38,7 +38,7 @@ public static function getAll($expand = null, $limit = null) } if ($limit) { - $request = $request->withLimit(1); + $request = $request->withLimit($limit); } return $request->execute(); diff --git a/app/Services/Forter/ForterSetupService.php b/app/Services/Forter/ForterSetupService.php index bf1bc7c..918d238 100644 --- a/app/Services/Forter/ForterSetupService.php +++ b/app/Services/Forter/ForterSetupService.php @@ -73,12 +73,12 @@ public static function isValidCommercetoolsCredentials() throw new \Exception("Missing required Commercetools config value: `{$configKey}`"); } } - $orders = CommercetoolsOrdersService::getAll(null, 1)->getCount(); - $carts = CommercetoolsCartsService::getAll(null, 1)->getCount(); - $payments = CommercetoolsPaymentsService::getAll(null, 1)->getCount(); - $types = CommercetoolsTypesService::getAll(null, 1)->getCount(); - $extensions = CommercetoolsExtensionsService::getAll(null, 1)->getCount(); - $subscriptions = CommercetoolsSubscriptionsService::getAll(null, 1)->getCount(); + $orders = CommercetoolsOrdersService::get(null, 1)->getCount(); + $carts = CommercetoolsCartsService::get(null, 1)->getCount(); + $payments = CommercetoolsPaymentsService::get(null, 1)->getCount(); + $types = CommercetoolsTypesService::get(null, 1)->getCount(); + $extensions = CommercetoolsExtensionsService::get(null, 1)->getCount(); + $subscriptions = CommercetoolsSubscriptionsService::get(null, 1)->getCount(); return true; } catch (\Exception $e) { Log::error("[ForterSetupService::isValidCommercetoolsCredentials] [ERROR] " . $e->getMessage(), ['exception' => $e]); diff --git a/app/Services/Forter/SchemaBuilders/ForterSchemaBuilder.php b/app/Services/Forter/SchemaBuilders/ForterSchemaBuilder.php index 41d97cb..2cd6a8e 100644 --- a/app/Services/Forter/SchemaBuilders/ForterSchemaBuilder.php +++ b/app/Services/Forter/SchemaBuilders/ForterSchemaBuilder.php @@ -62,6 +62,27 @@ public static function buildOrderStatusSchema(ForterOrder $order) ]; } + /** + * Build order schema for historical data upload + * @method buildHistoricalOrderSchema + * @param ForterOrder $order + * @return array + */ + public static function buildHistoricalOrderSchema(ForterOrder $order) + { + return [ + 'orderId' => $order->getForterOrderId(), + 'orderType' => 'WEB', + 'checkoutTime' => $order->getCreatedAtTimestampMs(), + 'connectionInformation' => self::buildOrderConnectionInformationSchema($order), + 'totalAmount' => self::buildOrderTotalAmountSchema($order), + 'cartItems' => self::buildOrderCartItemsSchema($order), + 'payment' => self::buildOrderPaymentSchema($order), + 'primaryDeliveryDetails' => self::buildOrderPrimaryDeliveryDetailsSchema($order), + 'primaryRecipient' => self::buildOrderPrimaryRecipientSchema($order), + ]; + } + //========================================================================// public static function buildOrderConnectionInformationSchema(ForterOrder $order) @@ -153,7 +174,7 @@ public static function buildOrderPrimaryDeliveryDetailsSchema(ForterOrder $order $shippingMethodName = !empty($shippingInfo['shippingMethodName']) ? $shippingInfo['shippingMethodName'] : 'unknown'; $centAmount = !empty($shippingInfo['price']['centAmount']) ? $shippingInfo['price']['centAmount'] : '000'; $fractionDigits = !empty($shippingInfo['price']['fractionDigits']) ? $shippingInfo['price']['fractionDigits'] : 2; - $currencyCode = !empty($shippingInfo['price']['currencyCode']) ? $shippingInfo['price']['currencyCode'] : (!empty($order['taxedPrice']['totalGross']['currencyCode']) ? $order['taxedPrice']['totalGross']['currencyCode'] : $order['totalPrice']['currencyCode']); + $currencyCode = !empty($shippingInfo['price']['currencyCode']) ? $shippingInfo['price']['currencyCode'] : (!empty($order->getTaxedPriceTotalGross('currencyCode')) ? $order->getTaxedPriceTotalGross('currencyCode') : $order->getTotalPrice('currencyCode')); return [ 'deliveryMethod' => $shippingMethodName, // Name of the shipping method 'deliveryPrice' => [ diff --git a/composer.json b/composer.json index 7d3d1fb..30a848c 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "type": "project", "description": "Forter Commercetools php app (on-prem).", "keywords": ["laravel", "framework", "forter", "commercetools"], - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "require": { "php": "^8.1", diff --git a/config/filesystems.php b/config/filesystems.php index e9d9dbd..6fe47aa 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -36,6 +36,12 @@ 'throw' => false, ], + 'local_forter' => [ + 'driver' => 'local', + 'root' => storage_path('app/forter'), + 'throw' => true, + ], + 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'),