Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inventory update with new API endpoints #11

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"psr/log": "^1.0 || ^2.0 || ^3.0",
"setono/composite-compiler-pass": "^1.1",
"setono/doctrine-orm-trait": "^1.1",
"setono/peak-wms-php-sdk": "^1.1",
"setono/peak-wms-php-sdk": "^1.2",
"sylius/admin-bundle": "^1.0",
"sylius/core": "^1.0",
"sylius/core-bundle": "^1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,5 @@ public function set(CompletedEvent $event): void
Assert::isInstanceOf($inventoryUpdate, InventoryUpdateInterface::class);

$inventoryUpdate->setCompletedAt(new \DateTimeImmutable());

if (!$inventoryUpdate->hasErrors()) {
$inventoryUpdate->setNextUpdateThreshold($inventoryUpdate->getProcessingStartedAt());
}
}
}
12 changes: 0 additions & 12 deletions src/Model/InventoryUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Setono\SyliusPeakPlugin\Model;

class InventoryUpdate implements InventoryUpdateInterface

Check failure on line 7 in src/Model/InventoryUpdate.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

Property Setono\SyliusPeakPlugin\Model\InventoryUpdate#$nextUpdateThreshold was removed

Check failure on line 7 in src/Model/InventoryUpdate.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

Method Setono\SyliusPeakPlugin\Model\InventoryUpdate#getNextUpdateThreshold() was removed

Check failure on line 7 in src/Model/InventoryUpdate.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

Method Setono\SyliusPeakPlugin\Model\InventoryUpdate#setNextUpdateThreshold() was removed
{
protected ?int $id = null;

Expand All @@ -16,8 +16,6 @@

protected ?\DateTimeInterface $completedAt = null;

protected ?\DateTimeInterface $nextUpdateThreshold = null;

protected int $productsProcessed = 0;

/** @var list<string>|null */
Expand Down Expand Up @@ -71,16 +69,6 @@
$this->completedAt = $completedAt;
}

public function getNextUpdateThreshold(): ?\DateTimeInterface
{
return $this->nextUpdateThreshold;
}

public function setNextUpdateThreshold(?\DateTimeInterface $nextUpdateThreshold): void
{
$this->nextUpdateThreshold = $nextUpdateThreshold;
}

public function getProductsProcessed(): int
{
return $this->productsProcessed;
Expand Down
7 changes: 0 additions & 7 deletions src/Model/InventoryUpdateInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Model\VersionedInterface;

interface InventoryUpdateInterface extends ResourceInterface, VersionedInterface

Check failure on line 10 in src/Model/InventoryUpdateInterface.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

Method Setono\SyliusPeakPlugin\Model\InventoryUpdateInterface#getNextUpdateThreshold() was removed

Check failure on line 10 in src/Model/InventoryUpdateInterface.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

Method Setono\SyliusPeakPlugin\Model\InventoryUpdateInterface#setNextUpdateThreshold() was removed
{
final public const STATE_PENDING = 'pending';

Expand Down Expand Up @@ -37,13 +37,6 @@

public function setCompletedAt(?\DateTimeInterface $completedAt): void;

/**
* This is the threshold to use when fetching updated products from Peak WMS. If null, it means that all products should be fetched.
*/
public function getNextUpdateThreshold(): ?\DateTimeInterface;

public function setNextUpdateThreshold(?\DateTimeInterface $nextUpdateThreshold): void;

public function getProductsProcessed(): int;

public function setProductsProcessed(int $productsProcessed): void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
<field name="state" type="string"/>
<field name="processingStartedAt" type="datetime" nullable="true"/>
<field name="completedAt" type="datetime" nullable="true"/>
<field name="nextUpdateThreshold" type="datetime" nullable="true"/>
<field name="productsProcessed" type="integer"/>
<field name="warnings" type="json" nullable="true"/>
<field name="errors" type="json" nullable="true"/>
Expand Down
46 changes: 19 additions & 27 deletions src/Updater/InventoryUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
use Doctrine\Persistence\ManagerRegistry;
use Setono\Doctrine\ORMTrait;
use Setono\PeakWMS\Client\ClientInterface;
use Setono\PeakWMS\DataTransferObject\Product\Product;
use Setono\PeakWMS\Request\Query\Product\PageQuery;
use Setono\PeakWMS\DataTransferObject\Stock\Stock;
use Setono\PeakWMS\Request\Query\KeySetPageQuery;
use Setono\SyliusPeakPlugin\Provider\InventoryUpdateProviderInterface;
use Setono\SyliusPeakPlugin\Workflow\InventoryUpdateWorkflow;
use Sylius\Component\Core\Model\ProductVariant;
Expand Down Expand Up @@ -43,20 +43,11 @@ public function update(ProductVariantInterface $productVariant): void

$collection = $this
->client
->product()
->getByProductId($productCode)
->filter(fn (Product $product) => $product->variantId === $variantCode)
->stock()
->getByProductId($productCode, $variantCode)
;

if (count($collection) !== 1) {
throw new \RuntimeException(sprintf(
'The product with id %s either does not have a variant with id/code %s or has multiple products with the same variant id/code',
$productCode,
$variantCode,
));
}

$this->map($collection[0], $productVariant);
$this->updateOnHand((int) $collection->sum(fn (Stock $stock): int => (int) $stock->quantity), $productVariant);

$this->getManager($productVariant)->flush();
}
Expand All @@ -75,8 +66,8 @@ public function updateAll(bool $onlyUpdated = true): void
$productVariantRepository = $this->getRepository(ProductVariant::class);

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

if ($i % 100 === 0) {
Expand All @@ -90,27 +81,27 @@ public function updateAll(bool $onlyUpdated = true): void
}

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,
Assert::notNull($item->variantId, sprintf(
'Stock with id %d does not have a variant id.',
(int) $item->id,
));

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

if ($product->orderedByCustomers !== $productVariant->getOnHold()) {
if ($item->reservedQuantity !== $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,
$item->variantId,
(int) $productVariant->getOnHold(),
(int) $product->orderedByCustomers,
(int) $item->reservedQuantity,
));
}

$this->map($product, $productVariant);
$this->updateOnHand((int) $item->quantity, $productVariant);
} catch (\Throwable $e) {
$inventoryUpdate->addError($e->getMessage());
}
Expand All @@ -125,6 +116,7 @@ public function updateAll(bool $onlyUpdated = true): void
$this->inventoryUpdateTransition(InventoryUpdateWorkflow::TRANSITION_FAIL);
} finally {
$manager->flush();
$manager->clear();
}
}

Expand All @@ -136,8 +128,8 @@ private function inventoryUpdateTransition(string $transition): void
$this->getManager($inventoryUpdate)->flush();
}

private function map(Product $product, ProductVariantInterface $productVariant): void
private function updateOnHand(int $quantity, ProductVariantInterface $productVariant): void
{
$productVariant->setOnHand((int) $product->availableToSell + (int) $productVariant->getOnHold());
$productVariant->setOnHand($quantity + (int) $productVariant->getOnHold());
}
}
Loading