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 stock import for Product Variants #1490

Merged
merged 9 commits into from
Sep 26, 2024
69 changes: 51 additions & 18 deletions src/elements/CommerceProduct.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use craft\feedme\services\Process;
use craft\fields\Matrix;
use craft\fields\Table;
use craft\helpers\ArrayHelper;
use craft\helpers\Json;
use DateTime;
use Exception;
Expand Down Expand Up @@ -480,31 +481,63 @@ private function _parseVariants($event): void

private function _inventoryUpdate($event): void
{
/** @var Product $product */
$product = $event->element;

// Index variants by SKU for lookup:
$variantsBySku = ArrayHelper::index($event->contentData['variants'], 'sku');

/** @var Commerce $commercePlugin */
$commercePlugin = Commerce::getInstance();
$variants = $event->element->getVariants();
$variants = $product->getVariants();

// Queue up a changeset:
$updateInventoryLevels = UpdateInventoryLevelCollection::make();

foreach ($variants as $variant) {
if ($inventoryItem = $commercePlugin->getInventory()->getInventoryItemByPurchasable($variant)) {
/** @var InventoryLevel $firstInventoryLevel */
$firstInventoryLevel = $commercePlugin->getInventory()->getInventoryLevelsForPurchasable($variant)->first();
if ($firstInventoryLevel && $firstInventoryLevel->getInventoryLocation()) {
$feedData = $event->feedData;
$data = Json::decodeIfJson($event->feedData, true);
$stock = $data['stock'] ?? 0;
$updateInventoryLevels->push(new UpdateInventoryLevel([
'type' => \craft\commerce\enums\InventoryTransactionType::AVAILABLE->value,
'updateAction' => \craft\commerce\enums\InventoryUpdateQuantityType::SET,
'inventoryItem' => $inventoryItem,
'inventoryLocation' => $firstInventoryLevel->getInventoryLocation(),
'quantity' => $stock,
'note' => '',
])
);
}
// Do we have a node for this variant at all?
if (!isset($variantsBySku[$variant->sku])) {
continue;
}

$stock = $variantsBySku[$variant->sku]['stock'] ?? null;

// What if the `stock` key wasn't in the incoming data?
if (is_null($stock)) {
Plugin::error(sprintf('No stock value was present in the import data for %s.', $variant->sku));

continue;
}

// Load InventoryItem model:
$inventoryItem = $commercePlugin->getInventory()->getInventoryItemByPurchasable($variant);

if (!$inventoryItem) {
// Not tracking, never mind!
continue;
}
angrybrad marked this conversation as resolved.
Show resolved Hide resolved

/** @var InventoryLevel $firstInventoryLevel */
$level = $commercePlugin->getInventory()->getInventoryLevelsForPurchasable($variant)->first();
$location = $level->getInventoryLocation();

if (!$level || !$location) {
// Again, looks like there's nothing to track…
continue;
}

$update = new UpdateInventoryLevel([
'type' => \craft\commerce\enums\InventoryTransactionType::AVAILABLE->value,
'updateAction' => \craft\commerce\enums\InventoryUpdateQuantityType::SET,
'inventoryItem' => $inventoryItem,
'inventoryLocation' => $location,
'quantity' => $stock,
'note' => sprintf('Imported via feed ID #%s', $event->feed['id']),
]);

$updateInventoryLevels->push($update);

Plugin::info(sprintf('Updating stock for the default inventory location for %s to %s.', $variant->sku, $stock));
}

if ($updateInventoryLevels->count() > 0) {
Expand Down
Loading