Files
grzanieplus.pl/plugins/stSoteshopTaskImportPlugin/lib/stSoteshopTaskImportTask.class.php
2025-03-12 17:06:23 +01:00

400 lines
13 KiB
PHP

<?php
class stSoteshopTaskImportTask extends stTaskSchedulerImportAbstract
{
/**
* Stan magazynowy importowanego produktu
*
* @var bool|null
*/
protected $hasProductStock = null;
/**
* Opcje importowanego produktu
*
* @var array|null
*/
protected $productOptions = null;
protected $newProductImageMapping = [];
public function initializeReader(): stTaskSchedulerImportReaderInterface
{
return new stTaskSchedulerImportXmlReader('product');
}
public function process(array $data)
{
if ($this->getConfigurationParameter('ignore_with_no_image') && !isset($data['product']['photos']))
{
return false;
}
if ($this->getConfigurationParameter('ignore_with_no_image') && isset($data['product']['photos']) && empty($data['product']['photos']))
{
return false;
}
if ($this->getConfigurationParameter('ignore_with_empty_price') && isset($data['product']['price']) && empty($data['product']['price']['@value']))
{
return false;
}
if ($this->getConfigurationParameter('ignore_with_empty_price') && isset($data['product']['price']))
{
if($data['product']['price']['@value']=="0.00"){
return false;
}
}
if (!$this->hasProductStock($data['product']) && $this->getConfigurationParameter('ignore_with_no_stock'))
{
return false;
}
/**
* Pobiera wcześniej utworzoną instancję modelu produktu po kodzie lub tworzy i zwraca nową instancję produktu
* z ustawionym kodem, domyślną wersją językową i domyślną dostępnością
*/
$product = $this->getProductUtility()->getOrCreateProduct($data['product']['@attributes']['code']);
$isNew = $product->isNew();
$product->setName($data['product']['name']['@value']);
if (isset($data['product']['categories']['category']))
{
$this->addCategories($product, $data['product']['categories']['category']);
}
if (isset($data['product']['@attributes']['active']))
{
$product->setActive($data['product']['@attributes']['active']);
}
$product->setVatValue($data['product']['tax']['@value']);
if (!$this->getConfigurationParameter('disable_description_update') || $isNew)
{
$product->setDescription($data['product']['description']['@value']);
$product->setShortDescription($data['product']['shortDescription']['@value']);
}
if (isset($data['product']['stock']))
{
$product->setStock($data['product']['stock']['@value']);
if (isset($data['product']['stock']['@attributes']['unit']))
{
$product->setUom($data['product']['stock']['@attributes']['unit']);
}
}
if (isset($data['product']['@attributes']['ean']))
{
$product->setManCode($data['product']['@attributes']['ean']);
}
if (isset($data['product']['attributes']['@attributes']['title']))
{
$product->setAttributesLabel($data['product']['attributes']['@attributes']['title']);
}
if (isset($data['product']['producer']))
{
$this->getProductUtility()->addProducer($product, $data['product']['producer']['@value']);
}
if (isset($data['product']['availability']))
{
$this->getProductUtility()->addAvailability($product, $data['product']['availability']['@value']);
}
$this->addPrices($product, $data['product']);
$product->save();
if (isset($data['product']['photos']['photo']) && (!$this->getConfigurationParameter('disable_image_update') || $isNew))
{
$this->addPhotos($product, $data['product']['photos']['photo'], $isNew);
}
if (isset($data['product']['options']) && (!$this->getConfigurationParameter('disable_options_update') || $isNew))
{
$this->addOptions($product, $data['product']['options'], $isNew);
}
if (isset($data['product']['attributes']) && (!$this->getConfigurationParameter('disable_attributes_update') || $isNew))
{
$this->addAttributes($product, $data['product']['attributes']);
}
}
protected function addOptions(Product $product, array $options, bool $isNew)
{
$config = stConfig::getInstance('stProduct');
$defaultPriceType = $config->get('global_price_netto') ? 'netto' : 'brutto';
$priceType = isset($options['@attributes']['priceType']) ? $options['@attributes']['priceType'] : $defaultPriceType;
$options = $this->transformProductOptions($options);
$this->getProductUtility()->setProductOptions($product, $options, $priceType, function(ProductOptionsValue $pov, array $attributes) use ($isNew) {
if ((!$this->getConfigurationParameter('disable_image_update') || $isNew) && isset($attributes['product_image']))
{
$imageId = $attributes['product_image'];
$pov->setSfAssetId($this->newProductImageMapping[$imageId]);
}
});
}
protected function addAttributes(Product $product, array $attributes)
{
$attributes = $this->transformProductAttributes($attributes);
$this->getProductUtility()->addAttributes($product, $attributes);
}
protected function addPhotos(Product $product, array $photos, bool $isNew)
{
$this->newProductImageMapping = [];
$this->getProductUtility()->getFileDownloader()->setOption('encode', false);
/**
* Usuwa wcześniej zaimportowane zdjęcia jest to koniecze w celu zapewnienia poprawnej kolejności
* nowo dodawanych zdjęć do produktu
*/
if (!$isNew)
{
$this->getProductUtility()->removeImages($product);
}
/**
* Pobiera i dodaje nowe zdjęcia do produktu
* W przypadku wystąpienia błędu podczas zdjęcia zostaje pominięte a
* błąd zostaje odnotowany w logach zadania importu
*/
foreach ($this->getCollection($photos) as $photo)
{
$id = $photo['@attributes']['id'];
$default = isset($photo['@attributes']['main']) && $photo['@attributes']['main'];
$asset = $this->getProductUtility()->addImageFromUrl($product, $photo['@value'], $default);
if (null !== $asset)
{
$this->newProductImageMapping[$id] = $asset->getId();
}
}
}
/**
* Dodaje kategorie do produktu
*
* @param Product $product Obiekt modelu produktu
* @param array $data Dane kategorii
* @return stTaskSchedulerImportCategoryMapping
* @throws PropelException
* @throws SQLException
* @throws stTaskSchedulerImportLogException
*/
protected function addCategories(Product $product, array $data): stTaskSchedulerImportCategoryMapping
{
$categories = [];
$default = null;
foreach ($this->getCollection($data) as $index => $category)
{
if (isset($category['@attributes']['main']) && $category['@attributes']['main'])
{
$default = $index;
}
$categories[] = $category['@value'];
}
return $this->getProductUtility()->addCategories($product, $categories, '/', $default);
}
protected function addPrices(Product $product, array $data)
{
if (isset($data['price']))
{
$price = $data['price']['@value'];
$price = stPrice::fix($price);
$priceType = $this->getPriceType($data['price']);
$price = $this->getProductUtility()->applyPriceMargin($price);
if ($priceType == 'netto')
{
$product->setPriceNetto($price);
$product->setPriceBrutto(null);
}
else
{
$product->setPriceBrutto($price);
$product->setPriceNetto(null);
}
}
if (isset($data['oldPrice']))
{
$oldPrice = $data['oldPrice']['@value'];
$priceType = $this->getPriceType($data['oldPrice']);
$oldPrice = stPrice::fix($oldPrice);
$oldPrice = $this->getProductUtility()->applyPriceMargin($oldPrice);
if ($priceType == 'netto')
{
$product->setOldPriceNetto($oldPrice);
$product->setOldPriceBrutto(null);
}
else
{
$product->setOldPriceBrutto($oldPrice);
$product->setOldPriceNetto(null);
}
}
if (isset($data['wholesale']))
{
foreach ($this->getCollection($data['wholesale']['price']) as $wholesale)
{
$group = ucfirst($wholesale['@attributes']['group']);
$type = ucfirst($this->getPriceType($wholesale));
$wholesalePrice = $wholesale['@value'];
$wholesalePrice = stPrice::fix($wholesalePrice);
$wholesalePrice = $this->getProductUtility()->applyPriceMargin($wholesalePrice);
call_user_func([$product, 'setWholesale'.$group.$type], $wholesalePrice);
if ($type == "Netto")
{
call_user_func([$product, 'setWholesale'.$group."Brutto"], null);
}
else
{
call_user_func([$product, 'setWholesale'.$group."Netto"], null);
}
}
}
}
protected function getPriceType(array $price): string
{
return isset($price['@attributes']['type']) ? $price['@attributes']['type'] : 'netto';
}
protected function transformProductOptions(array $data): array
{
if (null === $this->productOptions)
{
$results = [];
$options = !isset($data['option']['@attributes']) ? $data['option'] : [
0 => $data['option']
];
foreach ($options as $optionData)
{
$optionAttributes = $optionData['@attributes'];
$optionName = $optionAttributes['name'];
unset($optionAttributes['name']);
$values = !isset($optionData['value']['@attributes']) ? $optionData['value'] : [
0 => $optionData['value']
];
$results[$optionName]['@attributes'] = $optionAttributes;
foreach ($values as $valueData)
{
$attributes = $valueData['@attributes'];
$optionValue = $attributes['name'];
unset($attributes['name']);
if (isset($valueData['option']))
{
$results[$optionName][$optionValue] = [
'@children' => $this->transformProductOptions($valueData)
];
}
else
{
if (isset($attributes['stock']) && !$this->hasProductStock)
{
$this->hasProductStock = floatval($attributes['stock']) > 0;
}
}
$results[$optionName][$optionValue] = [
'@attributes' => $attributes,
];
}
}
$this->productOptions = $results;
}
return $this->productOptions;
}
protected function transformProductAttributes(array $data): array
{
$results = [];
$attributes = $this->getCollection($data['attribute']);
foreach ($attributes as $attribute)
{
$attributeName = $attribute['@attributes']['name'];
$results[$attributeName] = [
'type' => isset($attribute['@attributes']['type']) ? $attribute['@attributes']['type'] : 'T',
'values' => [],
];
$values = $this->getCollection($attribute['value']);
foreach ($values as $value)
{
$results[$attributeName]['values'][$value['@value']] = $value['@attributes'];
}
}
return $results;
}
/**
* Sprawdza czy importowany produkt posiada stan magazynowy
*
* @param array $data
* @return bool
*/
protected function hasProductStock(array $data): bool
{
$this->hasProductStock = false;
$this->productOptions = null;
if (isset($data['product']['stock']))
{
$this->hasProductStock = $data['product']['stock']['@value'] > 0;
}
if (isset($data['options']))
{
$this->transformProductOptions($data['options']);
}
return $this->hasProductStock;
}
}