Skip to content

Commit

Permalink
Catch exceptions when updating inventory and use the async command in…
Browse files Browse the repository at this point in the history
… the console command
  • Loading branch information
loevgaard committed Aug 29, 2024
1 parent e604e94 commit 38813a3
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 41 deletions.
7 changes: 4 additions & 3 deletions src/Command/UpdateInventoryCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@

namespace Setono\SyliusPeakPlugin\Command;

use Setono\SyliusPeakPlugin\Updater\InventoryUpdaterInterface;
use Setono\SyliusPeakPlugin\Message\Command\UpdateInventory;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Messenger\MessageBusInterface;

#[AsCommand(
name: 'setono:sylius-peak-wms:update-inventory',
description: 'This will update the inventory for all product variants',
)]
final class UpdateInventoryCommand extends Command
{
public function __construct(private readonly InventoryUpdaterInterface $inventoryUpdater)
public function __construct(private readonly MessageBusInterface $commandBus)
{
parent::__construct();
}
Expand All @@ -25,7 +26,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
{
// todo allow the user to specify a product variant id to update
// todo allow the user to force the update of _ALL_ product variants regardless of the last update time
$this->inventoryUpdater->updateAll();
$this->commandBus->dispatch(UpdateInventory::forAll());

return 0;
}
Expand Down
2 changes: 2 additions & 0 deletions src/Model/InventoryUpdateInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ interface InventoryUpdateInterface extends ResourceInterface, VersionedInterface

final public const STATE_COMPLETED = 'completed';

final public const STATE_FAILED = 'failed';

public function getId(): ?int;

public function getState(): string;
Expand Down
2 changes: 1 addition & 1 deletion src/Resources/config/services/command.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</service>

<service id="Setono\SyliusPeakPlugin\Command\UpdateInventoryCommand">
<argument type="service" id="Setono\SyliusPeakPlugin\Updater\InventoryUpdaterInterface"/>
<argument type="service" id="setono_sylius_peak.command_bus"/>

<tag name="console.command"/>
</service>
Expand Down
83 changes: 47 additions & 36 deletions src/Updater/InventoryUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,51 +68,62 @@ public function updateAll(bool $onlyUpdated = true): void
$inventoryUpdate = $this->inventoryUpdateProvider->getInventoryUpdate();
$this->getManager($inventoryUpdate)->persist($inventoryUpdate);

$this->transition($inventoryUpdate, InventoryUpdateWorkflow::TRANSITION_RESET);
$this->transition($inventoryUpdate, InventoryUpdateWorkflow::TRANSITION_PROCESS);
try {
$this->transition($inventoryUpdate, InventoryUpdateWorkflow::TRANSITION_RESET);
$this->transition($inventoryUpdate, InventoryUpdateWorkflow::TRANSITION_PROCESS);

$manager = $this->getManager(ProductVariant::class);
$productVariantRepository = $this->getRepository(ProductVariant::class);
$manager = $this->getManager(ProductVariant::class);
$productVariantRepository = $this->getRepository(ProductVariant::class);

$i = 0;
$products = $this->client->product()->iterate(PageQuery::create(updatedAfter: $inventoryUpdate->getNextUpdateThreshold()));
foreach ($products as $product) {
++$i;
$i = 0;
$products = $this->client->product()->iterate(PageQuery::create(updatedAfter: $inventoryUpdate->getNextUpdateThreshold()));
foreach ($products as $product) {
++$i;

if ($i % 100 === 0) {
$manager->flush();
$manager->clear();
}
if ($i % 100 === 0) {
$manager->flush();
$manager->clear();

try {
Assert::notNull($product->variantId, sprintf(
'Product with id %d does not have a variant id. It is expected that Peak WMS has the same structure of products as Sylius, namely that all products at least have one variant.',
(int) $product->id,
));

$productVariant = $productVariantRepository->findOneBy(['code' => $product->variantId]);
Assert::notNull($productVariant, sprintf('Product variant with code %s does not exist', $product->variantId));

if ($product->orderedByCustomers !== $productVariant->getOnHold()) {
$inventoryUpdate->addWarning(sprintf(
'Product variant with code %s has %d on hold in Sylius and %d on hold in Peak WMS',
$product->variantId,
(int) $productVariant->getOnHold(),
(int) $product->orderedByCustomers,
));
$inventoryUpdate->setProductsProcessed($i);
}

$this->map($product, $productVariant);
} catch (\InvalidArgumentException $e) {
$inventoryUpdate->addError($e->getMessage());
}
}
try {
Assert::notNull($product->variantId, sprintf(
'Product with id %d does not have a variant id. It is expected that Peak WMS has the same structure of products as Sylius, namely that all products at least have one variant.',
(int) $product->id,
));

$inventoryUpdate->setProductsProcessed($i);
$productVariant = $productVariantRepository->findOneBy(['code' => $product->variantId]);
Assert::notNull(
$productVariant,
sprintf('Product variant with code %s does not exist', $product->variantId),
);

if ($product->orderedByCustomers !== $productVariant->getOnHold()) {
$inventoryUpdate->addWarning(sprintf(
'Product variant with code %s has %d on hold in Sylius and %d on hold in Peak WMS',
$product->variantId,
(int) $productVariant->getOnHold(),
(int) $product->orderedByCustomers,
));
}

$this->map($product, $productVariant);
} catch (\InvalidArgumentException $e) {
$inventoryUpdate->addError($e->getMessage());
}
}

$manager->flush();
$inventoryUpdate->setProductsProcessed($i);
$manager->flush();

$this->transition($inventoryUpdate, InventoryUpdateWorkflow::TRANSITION_COMPLETE);
$this->transition($inventoryUpdate, InventoryUpdateWorkflow::TRANSITION_COMPLETE);
} catch (\Throwable $e) {
$inventoryUpdate->addError($e->getMessage());
$this->transition($inventoryUpdate, InventoryUpdateWorkflow::TRANSITION_FAIL);
} finally {
$this->getManager($inventoryUpdate)->flush();
}
}

private function transition(InventoryUpdateInterface $inventoryUpdate, string $transition): void
Expand Down
10 changes: 9 additions & 1 deletion src/Workflow/InventoryUpdateWorkflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ final class InventoryUpdateWorkflow

final public const TRANSITION_RESET = 'reset';

final public const TRANSITION_FAIL = 'fail';

private function __construct()
{
}
Expand All @@ -32,6 +34,7 @@ public static function getStates(): array
InventoryUpdateInterface::STATE_PENDING,
InventoryUpdateInterface::STATE_PROCESSING,
InventoryUpdateInterface::STATE_COMPLETED,
InventoryUpdateInterface::STATE_FAILED,
];
}

Expand Down Expand Up @@ -78,9 +81,14 @@ public static function getTransitions(): array
),
new Transition(
self::TRANSITION_RESET,
[InventoryUpdateInterface::STATE_PENDING, InventoryUpdateInterface::STATE_COMPLETED],
[InventoryUpdateInterface::STATE_PENDING, InventoryUpdateInterface::STATE_COMPLETED, InventoryUpdateInterface::STATE_FAILED],
InventoryUpdateInterface::STATE_PENDING,
),
new Transition(
self::TRANSITION_FAIL,
[InventoryUpdateInterface::STATE_PENDING, InventoryUpdateInterface::STATE_PROCESSING],
InventoryUpdateInterface::STATE_FAILED,
),
];
}
}

0 comments on commit 38813a3

Please sign in to comment.