400 lines
13 KiB
PHP
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;
|
|
}
|
|
} |