/**
  * Links the items (similar/accessory)
  */
 public function link()
 {
     $Request_AddLinkedItems = new PlentySoapRequest_AddLinkedItems();
     $Request_AddLinkedItems->CrosssellingList = array();
     foreach ($this->SHOPWARE_Article->getSimilar() as $Similar) {
         $Object_AddLinkedItems = new PlentySoapObject_AddLinkedItems();
         $Object_AddLinkedItems->Relationship = 'Similar';
         // string
         $Object_AddLinkedItems->CrossItemSKU = PlentymarketsMappingController::getItemByShopwareID($Similar->getId());
         // string
         $Request_AddLinkedItems->CrosssellingList[] = $Object_AddLinkedItems;
     }
     foreach ($this->SHOPWARE_Article->getRelated() as $Related) {
         $Object_AddLinkedItems = new PlentySoapObject_AddLinkedItems();
         $Object_AddLinkedItems->Relationship = 'Accessory';
         // string
         $Object_AddLinkedItems->CrossItemSKU = PlentymarketsMappingController::getItemByShopwareID($Related->getId());
         $Request_AddLinkedItems->CrosssellingList[] = $Object_AddLinkedItems;
     }
     if (!count($Request_AddLinkedItems->CrosssellingList)) {
         return;
     }
     $Request_AddLinkedItems->MainItemSKU = PlentymarketsMappingController::getItemByShopwareID($this->SHOPWARE_Article->getId());
     // string
     // Do the request
     PlentymarketsSoapClient::getInstance()->AddLinkedItems($Request_AddLinkedItems);
 }
 /**
  * prepare: copy the mapping table
  */
 public function __construct()
 {
     Shopware()->Db()->query('DROP TABLE IF EXISTS plenty_mapping_category_old');
     Shopware()->Db()->query('CREATE TABLE plenty_mapping_category_old LIKE plenty_mapping_category');
     Shopware()->Db()->query('INSERT plenty_mapping_category_old SELECT * FROM plenty_mapping_category');
     Shopware()->Db()->query('TRUNCATE TABLE plenty_mapping_category');
     // Clear the mapping cache
     PlentymarketsMappingController::clearCache('Category');
 }
 /**
  * Runs the actual export
  */
 public function run()
 {
     $repository = Shopware()->Models()->getRepository('Shopware\\CustomModels\\Bundle\\Bundle');
     /** @var Shopware\CustomModels\Bundle\Bundle $bundle */
     foreach ($repository->findAll() as $bundle) {
         try {
             PlentymarketsMappingController::getItemBundleByShopwareID($bundle->getId());
             continue;
         } catch (PlentymarketsMappingExceptionNotExistant $e) {
         }
         $exportEntityItemBundle = new PlentymarketsExportEntityItemBundle($bundle);
         $exportEntityItemBundle->export();
     }
 }
 /**
  * Does the actual import
  */
 public function import()
 {
     try {
         $SHOPWARE_id = PlentymarketsMappingController::getPropertyGroupByPlentyID($this->Group->PropertyGroupID);
         PyLog()->message('Sync:Item:Producer', 'Updating the property group »' . $this->Group->FrontendName . '«');
     } catch (PlentymarketsMappingExceptionNotExistant $E) {
         PyLog()->message('Sync:Item:Producer', 'Skipping the property group »' . $this->Group->FrontendName . '«');
         return;
     }
     /** @var Shopware\Models\Property\Group $Group */
     $Group = Shopware()->Models()->find('Shopware\\Models\\Property\\Group', $SHOPWARE_id);
     // Set the new data
     $Group->setName($this->Group->FrontendName);
     Shopware()->Models()->persist($Group);
     Shopware()->Models()->flush();
 }
 /**
  * Does the actual import
  */
 public function import()
 {
     try {
         $SHOPWARE_id = PlentymarketsMappingController::getProducerByPlentyID($this->Producer->ProducerID);
         PyLog()->message('Sync:Item:Producer', 'Updating the producer »' . $this->Producer->ProducerName . '«');
     } catch (PlentymarketsMappingExceptionNotExistant $E) {
         PyLog()->message('Sync:Item:Producer', 'Skipping the producer »' . $this->Producer->ProducerName . '«');
         return;
     }
     /** @var Shopware\Models\Article\Supplier $Supplier */
     $Supplier = Shopware()->Models()->find('Shopware\\Models\\Article\\Supplier', $SHOPWARE_id);
     // Set the new data
     $Supplier->setName($this->Producer->ProducerName);
     Shopware()->Models()->persist($Supplier);
     Shopware()->Models()->flush();
 }
 /**
  * Handles the actual import
  *
  * @param integer $shopwareOrderId
  * @param PlentySoapObject_OrderHead $Order
  */
 public function handle($shopwareOrderId, $Order)
 {
     try {
         $status = sprintf("%.1f", (double) $Order->OrderStatus);
         $message = sprintf('plentymarkets Status %s', $status);
         $orderStatus = PlentymarketsMappingController::getOrderStatusByPlentyID($status);
         self::$OrderModule->setOrderStatus($shopwareOrderId, $orderStatus, false, $message);
     } catch (Exception $e) {
     }
     try {
         $status = sprintf("%.1f", (double) $Order->OrderStatus);
         $message = sprintf('plentymarkets Status %s', $status);
         $paymentStatus = PlentymarketsMappingController::getPaymentStatusByPlentyID($status);
         self::$OrderModule->setPaymentStatus($shopwareOrderId, $paymentStatus, false, $message);
     } catch (Exception $e) {
     }
 }
 /**
  * Does the actual import
  */
 public function import()
 {
     try {
         $SHOPWARE_id = PlentymarketsMappingController::getPropertyByPlentyID($this->Option->PropertyID);
         PyLog()->message('Sync:Item:Property:Option', 'Updating the property option »' . $this->Option->PropertyFrontendName . '«');
     } catch (PlentymarketsMappingExceptionNotExistant $E) {
         PyLog()->message('Sync:Item:Property:Option', 'Skipping the property option »' . $this->Option->PropertyFrontendName . '«');
         return;
     }
     $propertyParts = explode(';', $SHOPWARE_id);
     $optionId = $propertyParts[1];
     /** @var Shopware\Models\Property\Option $Option */
     $Option = Shopware()->Models()->find('Shopware\\Models\\Property\\Option', $optionId);
     // Set the new data
     $Option->setName($this->Option->PropertyFrontendName);
     Shopware()->Models()->persist($Option);
     Shopware()->Models()->flush();
 }
 /**
  * Updates the item prices
  */
 public static function importItemPrices()
 {
     $numberOfPricesUpdates = 0;
     PlentymarketsLogger::getInstance()->message('Sync:Item:Price', 'LastUpdate: ' . date('r', PlentymarketsConfig::getInstance()->getImportItemPriceLastUpdateTimestamp(time())));
     $timestamp = PlentymarketsConfig::getInstance()->getImportItemPriceLastUpdateTimestamp(time());
     $now = time();
     $Request_GetItemsPriceUpdate = new PlentySoapRequest_GetItemsPriceUpdate();
     $Request_GetItemsPriceUpdate->LastUpdateFrom = $timestamp;
     $Request_GetItemsPriceUpdate->Page = 0;
     do {
         $Response_GetItemsPriceUpdate = PlentymarketsSoapClient::getInstance()->GetItemsPriceUpdate($Request_GetItemsPriceUpdate);
         $pages = max($Response_GetItemsPriceUpdate->Pages, 1);
         PlentymarketsLogger::getInstance()->message('Sync:Item:Price', 'Page: ' . ($Request_GetItemsPriceUpdate->Page + 1) . '/' . $pages);
         /** @var PlentySoapResponseObject_GetItemsPriceUpdate $ItemsPriceUpdate */
         foreach ($Response_GetItemsPriceUpdate->ItemsPriceUpdate->item as $ItemsPriceUpdate) {
             try {
                 // Base item
                 if (preg_match('/\\d+\\-\\d+\\-0/', $ItemsPriceUpdate->SKU)) {
                     $sku = explode('-', $ItemsPriceUpdate->SKU);
                     $itemID = PlentymarketsMappingController::getItemByPlentyID($sku[0]);
                     $PlentymarketsImportEntityItemPrice = new PlentymarketsImportEntityItemPrice($ItemsPriceUpdate);
                     $PlentymarketsImportEntityItemPrice->update($itemID);
                 } else {
                     $itemDetailID = PlentymarketsMappingController::getItemVariantByPlentyID($ItemsPriceUpdate->SKU);
                     $PlentymarketsImportEntityItemPrice = new PlentymarketsImportEntityItemPrice($ItemsPriceUpdate, $ItemsPriceUpdate->Markup);
                     $PlentymarketsImportEntityItemPrice->updateVariant($itemDetailID);
                 }
                 ++$numberOfPricesUpdates;
             } catch (PlentymarketsMappingExceptionNotExistant $E) {
             }
         }
     } while (++$Request_GetItemsPriceUpdate->Page < $Response_GetItemsPriceUpdate->Pages);
     PlentymarketsConfig::getInstance()->setImportItemPriceLastUpdateTimestamp($now);
     // Log
     if ($numberOfPricesUpdates == 0) {
         PlentymarketsLogger::getInstance()->message('Sync:Item:Price', 'No price has been updated.');
     } else {
         if ($numberOfPricesUpdates == 1) {
             PlentymarketsLogger::getInstance()->message('Sync:Item:Price', '1 price has been updated.');
         } else {
             PlentymarketsLogger::getInstance()->message('Sync:Item:Price', $numberOfPricesUpdates . ' prices have been updated.');
         }
     }
 }
 /**
  * Export the missing attribtues to plentymarkets and save the mapping
  */
 protected function doExport()
 {
     // Repository
     $Repository = Shopware()->Models()->getRepository('Shopware\\Models\\Article\\Configurator\\Group');
     // Chunk configuration
     $chunk = 0;
     $size = PlentymarketsConfig::getInstance()->getInitialExportChunkSize(PlentymarketsExportController::DEFAULT_CHUNK_SIZE);
     do {
         PlentymarketsLogger::getInstance()->message('Export:Initial:Attribute', 'Chunk: ' . ($chunk + 1));
         $Groups = $Repository->findBy(array(), null, $size, $chunk * $size);
         /** @var Shopware\Models\Article\Configurator\Group $Attribute */
         foreach ($Groups as $Attribute) {
             $Request_SetItemAttributes = new PlentySoapRequest_SetItemAttributes();
             $Object_SetItemAttribute = new PlentySoapObject_SetItemAttribute();
             $Object_SetItemAttribute->BackendName = sprintf('%s (Sw %d)', $Attribute->getName(), $Attribute->getId());
             $Object_SetItemAttribute->FrontendLang = 'de';
             $Object_SetItemAttribute->FrontendName = $Attribute->getName();
             $Object_SetItemAttribute->Position = $Attribute->getPosition();
             try {
                 $attributeIdAdded = PlentymarketsMappingController::getAttributeGroupByShopwareID($Attribute->getId());
             } catch (PlentymarketsMappingExceptionNotExistant $E) {
                 if (isset($this->PLENTY_name2ID[strtolower($Object_SetItemAttribute->BackendName)])) {
                     $attributeIdAdded = $this->PLENTY_name2ID[strtolower($Object_SetItemAttribute->BackendName)];
                 } else {
                     $Request_SetItemAttributes->Attributes[] = $Object_SetItemAttribute;
                     $Response = PlentymarketsSoapClient::getInstance()->SetItemAttributes($Request_SetItemAttributes);
                     if (!$Response->Success) {
                         throw new PlentymarketsExportException('The item attribute »' . $Object_SetItemAttribute->BackendName . '« could not be created', 2911);
                     }
                     $attributeIdAdded = (int) $Response->ResponseMessages->item[0]->SuccessMessages->item[0]->Value;
                 }
                 // Add the mapping
                 PlentymarketsMappingController::addAttributeGroup($Attribute->getId(), $attributeIdAdded);
                 $this->exportAttributeTranslations($Attribute->getId(), $attributeIdAdded);
             }
             // Values
             /** @var Shopware\Models\Article\Configurator\Option $AttributeValue */
             foreach ($Attribute->getOptions() as $AttributeValue) {
                 $Request_SetItemAttributes = new PlentySoapRequest_SetItemAttributes();
                 $Object_SetItemAttribute = new PlentySoapObject_SetItemAttribute();
                 $Object_SetItemAttribute->Id = $attributeIdAdded;
                 $Object_SetItemAttributeValue = new PlentySoapObject_SetItemAttributeValue();
                 $Object_SetItemAttributeValue->BackendName = sprintf('%s (Sw %d)', $AttributeValue->getName(), $AttributeValue->getId());
                 $Object_SetItemAttributeValue->FrontendName = $AttributeValue->getName();
                 $Object_SetItemAttributeValue->Position = $AttributeValue->getPosition();
                 $Object_SetItemAttribute->Values[] = $Object_SetItemAttributeValue;
                 $Request_SetItemAttributes->Attributes[] = $Object_SetItemAttribute;
                 try {
                     PlentymarketsMappingController::getAttributeOptionByShopwareID($AttributeValue->getId());
                 } catch (PlentymarketsMappingExceptionNotExistant $E) {
                     // Workaround
                     $checknameValue = strtolower(str_replace(',', '.', $Object_SetItemAttributeValue->BackendName));
                     if (isset($this->PLENTY_idAndValueName2ID[$attributeIdAdded][$checknameValue])) {
                         PlentymarketsMappingController::addAttributeOption($AttributeValue->getId(), $this->PLENTY_idAndValueName2ID[$attributeIdAdded][$checknameValue]);
                     } else {
                         $Response = PlentymarketsSoapClient::getInstance()->SetItemAttributes($Request_SetItemAttributes);
                         if (!$Response->Success) {
                             throw new PlentymarketsExportException('The item attribute option »' . $Object_SetItemAttributeValue->BackendName . '« could not be created', 2912);
                         }
                         foreach ($Response->ResponseMessages->item[0]->SuccessMessages->item as $MessageItem) {
                             if ($MessageItem->Key == 'AttributeValueID') {
                                 PlentymarketsMappingController::addAttributeOption($AttributeValue->getId(), $MessageItem->Value);
                                 $this->exportAttributeValuesTranslations($attributeIdAdded, $AttributeValue->getId(), $MessageItem->Value);
                             }
                         }
                     }
                 }
             }
         }
         ++$chunk;
     } while (!empty($Groups) && count($Groups) == $size);
 }
 /**
  * Checks whether the mappings are completely done
  *
  * @return boolean
  */
 protected function isMappingFinished()
 {
     $isMappingFinished = PlentymarketsMappingController::isComplete();
     PlentymarketsConfig::getInstance()->set('IsMappingFinished', (int) $isMappingFinished);
     return $isMappingFinished;
 }
    /**
     * Get the mapping data: vat
     *
     * @return array
     */
    public function getVat()
    {
        $rows = Shopware()->Db()->query('
					SELECT
							C.id, CONCAT(C.tax, " %") name,
							C.tax,
							IFNULL(PMC.plentyID, -1) plentyID
						FROM s_core_tax C
						LEFT JOIN plenty_mapping_vat PMC
							ON PMC.shopwareID = C.id
						ORDER BY C.tax
				')->fetchAll();
        $plentyVat = PlentymarketsImportController::getVatList();
        foreach ($rows as &$row) {
            if ($row['plentyID'] >= 0) {
                $row['plentyName'] = $plentyVat[$row['plentyID']]['name'];
            } else {
                if ($this->auto) {
                    $plentyVat = PlentymarketsImportController::getVatList();
                    foreach ($plentyVat as $plentyData) {
                        list($name, $percent) = explode(' ', $plentyData['name']);
                        if ((double) $row['tax'] == (double) $name) {
                            $row['plentyName'] = $plentyData['name'];
                            $row['plentyID'] = $plentyData['id'];
                            PlentymarketsMappingController::addVat($row['id'], $plentyData['id']);
                            break;
                        }
                    }
                }
            }
        }
        return $rows;
    }
 /**
  * Exports the item bundle head item
  *
  * @throws PlentymarketsExportException
  */
 protected function exportHead()
 {
     // The shopware item on which the bundle is based on
     $shopwareBundleHead = $this->SHOPWARE_bundle->getArticle();
     $shopwareBundleHeadIsVariant = !is_null($shopwareBundleHead->getConfiguratorSet());
     // If the bundle head is a variant, the bundle can't be exported
     // since that feature is not provided by plentymarkets
     if ($shopwareBundleHeadIsVariant) {
         throw new PlentymarketsExportException('The item bundle with the number »' . $this->SHOPWARE_bundle->getNumber() . '« can not be exported because the master item is a variant.', 2230);
     }
     if ($this->SHOPWARE_bundle->getDiscountType() != 'abs') {
         throw new PlentymarketsExportException('The item bundle with the number »' . $this->SHOPWARE_bundle->getNumber() . '« can not be exported because the discount type is not supported.', 2240);
     }
     if ($this->SHOPWARE_bundle->getType() != 1) {
         throw new PlentymarketsExportException('The item bundle with the number »' . $this->SHOPWARE_bundle->getNumber() . '« can not be exported because the bundle type is not supported.', 2250);
     }
     // The shopware bundle head needs to be added as a plenty-bundle-item
     // The bundle head in plentymarkets is a "special" item
     $bundleItemId = PlentymarketsMappingController::getItemByShopwareID($shopwareBundleHead->getId());
     $sku = sprintf('%d-0', $bundleItemId);
     // If this item is also a bundle item in shopware,
     // we need to increase the quantity of it
     if (isset($this->PLENTY_bundleSkuList[$sku])) {
         $this->PLENTY_bundleSkuList[$sku] += 1;
     } else {
         $this->PLENTY_bundleSkuList[$sku] = 1;
     }
     // Create the bundle head
     $Request_AddItemsBase = new PlentySoapRequest_AddItemsBase();
     $Request_AddItemsBase->BaseItems = array();
     $Object_AddItemsBaseItemBase = new PlentySoapObject_AddItemsBaseItemBase();
     $Object_ItemAvailability = new PlentySoapObject_ItemAvailability();
     $validTo = $this->SHOPWARE_bundle->getValidTo();
     if ($validTo instanceof DateTime) {
         $Object_ItemAvailability->AvailableUntil = $this->SHOPWARE_bundle->getValidTo()->getTimestamp();
     }
     $Object_ItemAvailability->WebAPI = 1;
     $Object_ItemAvailability->Inactive = (int) $this->SHOPWARE_bundle->getActive();
     $Object_ItemAvailability->Webshop = (int) $this->SHOPWARE_bundle->getActive();
     $Object_AddItemsBaseItemBase->Availability = $Object_ItemAvailability;
     $storeIds = array();
     $Object_AddItemsBaseItemBase->Categories = array();
     $Object_AddItemsBaseItemBase->StoreIDs = array();
     foreach ($shopwareBundleHead->getCategories() as $category) {
         /** @var Shopware\Models\Category\Category $category */
         try {
             $categoryPath = PlentymarketsMappingController::getCategoryByShopwareID($category->getId());
         } catch (PlentymarketsMappingExceptionNotExistant $E) {
             continue;
         }
         $Object_ItemCategory = new PlentySoapObject_ItemCategory();
         $Object_ItemCategory->ItemCategoryPath = $categoryPath;
         // string
         $Object_AddItemsBaseItemBase->Categories[] = $Object_ItemCategory;
         // Get the store for this category
         $rootId = PlentymarketsUtils::getRootIdByCategory($category);
         $shops = PlentymarketsUtils::getShopIdByCategoryRootId($rootId);
         foreach ($shops as $shopId) {
             try {
                 $storeId = PlentymarketsMappingController::getShopByShopwareID($shopId);
             } catch (PlentymarketsMappingExceptionNotExistant $E) {
                 continue;
             }
             if (!isset($storeIds[$storeId])) {
                 // Activate the item for this store
                 $Object_Integer = new PlentySoapObject_Integer();
                 $Object_Integer->intValue = $storeId;
                 $Object_AddItemsBaseItemBase->StoreIDs[] = $Object_Integer;
                 // Cache
                 $storeIds[$storeId] = true;
             }
         }
     }
     $Object_AddItemsBaseItemBase->ExternalItemID = 'Swag/Bundle/' . $this->SHOPWARE_bundle->getId();
     // string
     $Object_AddItemsBaseItemBase->ItemNo = $this->SHOPWARE_bundle->getNumber();
     // string
     $Object_ItemPriceSet = new PlentySoapObject_ItemPriceSet();
     $defaultCustomerGroupKey = PlentymarketsConfig::getInstance()->get('DefaultCustomerGroupKey');
     $price = null;
     $isPriceFound = false;
     foreach ($this->SHOPWARE_bundle->getPrices() as $price) {
         /** @var Shopware\CustomModels\Bundle\Price $price */
         if ($price->getCustomerGroup()->getKey() == $defaultCustomerGroupKey) {
             $isPriceFound = true;
             break;
         }
     }
     if ($isPriceFound && $price instanceof Shopware\CustomModels\Bundle\Price) {
         $tax = $this->SHOPWARE_bundle->getArticle()->getTax()->getTax();
         $priceNet = $price->getPrice();
         $price = $priceNet + $priceNet / 100 * $tax;
         $Object_ItemPriceSet->Price = $price;
         $Object_ItemPriceSet->VAT = $tax;
     } else {
         // If there is no price, we have to set one anyway.
         // Otherwise the re-import will crash
         $Object_ItemPriceSet->Price = 1;
     }
     $Object_AddItemsBaseItemBase->PriceSet = $Object_ItemPriceSet;
     $Object_AddItemsBaseItemBase->VATInternalID = PlentymarketsMappingController::getVatByShopwareID($this->SHOPWARE_bundle->getArticle()->getTax()->getId());
     $Object_AddItemsBaseItemBase->ProducerID = PlentymarketsMappingController::getProducerByShopwareID($shopwareBundleHead->getSupplier()->getId());
     // int
     $Object_AddItemsBaseItemBase->Published = null;
     // int
     $Object_ItemTexts = new PlentySoapObject_ItemTexts();
     $Object_ItemTexts->Name = $this->SHOPWARE_bundle->getName();
     // string
     $Object_AddItemsBaseItemBase->Texts = $Object_ItemTexts;
     $Request_AddItemsBase->BaseItems[] = $Object_AddItemsBaseItemBase;
     $Response_AddItemsBase = PlentymarketsSoapClient::getInstance()->AddItemsBase($Request_AddItemsBase);
     $ResponseMessage = $Response_AddItemsBase->ResponseMessages->item[0];
     if (!$Response_AddItemsBase->Success || $ResponseMessage->Code != 100) {
         throw new PlentymarketsExportException('The item bundle with the number »' . $this->SHOPWARE_bundle->getNumber() . '« could not be exported', 2210);
     }
     $PLENTY_priceID = null;
     foreach ($ResponseMessage->SuccessMessages->item as $SubMessage) {
         if ($SubMessage->Key == 'ItemID') {
             $this->PLENTY_bundleHeadId = (int) $SubMessage->Value;
         } else {
             if ($SubMessage->Key == 'PriceID') {
                 $PLENTY_priceID = (int) $SubMessage->Value;
             }
         }
     }
     if ($this->PLENTY_bundleHeadId && $PLENTY_priceID) {
         PlentymarketsLogger::getInstance()->message('Export:Initial:Item:Bundle', 'The item bundle with the number »' . $this->SHOPWARE_bundle->getNumber() . '« has been created with the id »' . $this->PLENTY_bundleHeadId . '«.');
         PlentymarketsMappingController::addItemBundle($this->SHOPWARE_bundle->getId(), $this->PLENTY_bundleHeadId);
     } else {
         throw new PlentymarketsExportException('The item bundle with the number »' . $this->SHOPWARE_bundle->getNumber() . '« could not be exported', 2210);
     }
 }
    /**
     * Deletes a page of invalid data
     *
     * @param integer $start
     * @param integer $offset
     */
    public function deleteInvalidData($start, $offset)
    {
        // Controller
        $controller = new PlentymarketsImportControllerItem();
        // StoreIds
        $stores = Shopware()->Db()->fetchAll('
			SELECT plentyID FROM plenty_mapping_shop
		');
        // Customer group
        $customerGroupKey = PlentymarketsConfig::getInstance()->getDefaultCustomerGroupKey();
        $customerGroupRepository = Shopware()->Models()->getRepository('Shopware\\Models\\Customer\\Group');
        $customerGroups = $customerGroupRepository->findBy(array('key' => $customerGroupKey));
        $customerGroup = array_pop($customerGroups);
        //
        foreach ($this->getInvalidData($start, $offset) as $data) {
            PyLog()->message('Fix:Item:Price', 'Start of fixing corrupt prices of the item id ' . $data['itemId']);
            // Search
            foreach (explode(',', $data['detailIds']) as $detailId) {
                try {
                    /** @var \Shopware\Models\Article\Detail $Detail */
                    $Detail = Shopware()->Models()->find('\\Shopware\\Models\\Article\\Detail', $detailId);
                    $price = new Shopware\Models\Article\Price();
                    $price->setFrom(1);
                    $price->setPrice(1);
                    $price->setPercent(0);
                    $price->setArticle($Detail->getArticle());
                    $price->setDetail($Detail);
                    $price->setCustomerGroup($customerGroup);
                    Shopware()->Models()->persist($price);
                } catch (Exception $E) {
                    PyLog()->debug($E->getMessage());
                }
            }
            Shopware()->Models()->flush();
            PyLog()->message('Fix:Item:Price', 'Finished with the fixing corrupt prices of the item id »' . $data['itemId'] . '«');
            try {
                foreach ($stores as $store) {
                    // Update the complete item from plenty
                    $controller->importItem(PlentymarketsMappingController::getItemByShopwareID($data['itemId']), $store['plentyID']);
                }
            } catch (Exception $e) {
                PyLog()->error('Fix:Item:Price', $e->getMessage());
            }
            // Stop after the first
            break;
        }
    }
 /**
  * imports the item for the given shop
  *
  * @param integer $itemId
  * @param integer $storeId
  * @throws PlentymarketsImportException
  */
 public function importItem($itemId, $storeId)
 {
     // Check whether the item has already been imported
     $full = !isset($this->itemIdsDone[$itemId]);
     // Build the request
     $Request_GetItemsBase = new PlentySoapRequest_GetItemsBase();
     $Request_GetItemsBase->GetAttributeValueSets = $full;
     $Request_GetItemsBase->GetCategories = true;
     $Request_GetItemsBase->GetCategoryNames = true;
     $Request_GetItemsBase->GetItemAttributeMarkup = $full;
     $Request_GetItemsBase->GetItemOthers = $full;
     //$Request_GetItemsBase->GetItemProperties = $full;
     $Request_GetItemsBase->GetItemProperties = true;
     $Request_GetItemsBase->GetItemSuppliers = false;
     $Request_GetItemsBase->GetItemURL = 0;
     $Request_GetItemsBase->GetLongDescription = $full;
     $Request_GetItemsBase->GetMetaDescription = false;
     $Request_GetItemsBase->GetShortDescription = $full;
     $Request_GetItemsBase->GetTechnicalData = false;
     $Request_GetItemsBase->StoreID = $storeId;
     $Request_GetItemsBase->ItemID = $itemId;
     // get the main language of the shop
     //$mainLang = array_values(PlentymarketsTranslation::getInstance()->getShopMainLanguage(PlentymarketsMappingController::getShopByPlentyID($storeId)));
     // set the main language of the shop in soap request
     //$Request_GetItemsBase->Lang = PlentymarketsTranslation::getInstance()->getPlentyLocaleFormat($mainLang[0]['locale']);
     $Request_GetItemsBase->Lang = 'de';
     // Do the request
     $Response_GetItemsBase = PlentymarketsSoapClient::getInstance()->GetItemsBase($Request_GetItemsBase);
     // On error
     if ($Response_GetItemsBase->Success == false) {
         // Re-add the item to the stack and quit
         PlentymarketsImportStackItem::getInstance()->addItem($itemId, $storeId);
         return;
     }
     // Item not found
     if (!isset($Response_GetItemsBase->ItemsBase->item[0])) {
         return;
     }
     //
     $ItemBase = $Response_GetItemsBase->ItemsBase->item[0];
     // Skip bundles
     if ($ItemBase->BundleType == 'bundle' && PlentymarketsConfig::getInstance()->getItemBundleHeadActionID(IMPORT_ITEM_BUNDLE_HEAD_NO) == IMPORT_ITEM_BUNDLE_HEAD_NO) {
         PlentymarketsLogger::getInstance()->message('Sync:Item', 'The item »' . $ItemBase->Texts->Name . '« will be skipped (bundle)');
         return;
     }
     // get the item texts in all active languages
     $itemTexts = array();
     $shopId = PlentymarketsMappingController::getShopByPlentyID($storeId);
     //if this is a main shop , get the item texts translation for its main language and its shop languages
     if (PlentymarketsTranslation::isMainShop($shopId)) {
         // get all active languages of the shop (from shopware)
         $activeLanguages = PlentymarketsTranslation::getShopActiveLanguages($shopId);
         foreach ($activeLanguages as $localeId => $language) {
             $Request_GetItemsTexts = new PlentySoapRequest_GetItemsTexts();
             $Request_GetItemsTexts->ItemsList = array();
             $Object_RequestItems = new PlentySoapObject_RequestItems();
             $Object_RequestItems->ExternalItemNumer = null;
             // string
             $Object_RequestItems->ItemId = $itemId;
             // string
             $Object_RequestItems->ItemNumber = null;
             // string
             $Object_RequestItems->Lang = PlentymarketsTranslation::getPlentyLocaleFormat($language['locale']);
             // string
             $Request_GetItemsTexts->ItemsList[] = $Object_RequestItems;
             $Response_GetItemsTexts = PlentymarketsSoapClient::getInstance()->GetItemsTexts($Request_GetItemsTexts);
             if (isset($Response_GetItemsTexts->ItemTexts->item[0])) {
                 $itemText = array();
                 // save the language infos for the item texts
                 $itemText['locale'] = $language['locale'];
                 // if mainShopId == null, then it is the main shop and no language shop
                 // each language shop has a mainShopId
                 if (!is_null($language['mainShopId'])) {
                     $itemText['languageShopId'] = PlentymarketsTranslation::getLanguageShopID($localeId, $language['mainShopId']);
                 } elseif (PlentymarketsTranslation::getPlentyLocaleFormat($language['locale']) != 'de') {
                     // set the language for the main shop if the main language is not German
                     $itemText['languageShopId'] = $shopId;
                 }
                 $itemText['texts'] = $Response_GetItemsTexts->ItemTexts->item[0];
                 $itemTexts[] = $itemText;
             }
         }
     }
     try {
         $shopId = PlentymarketsMappingController::getShopByPlentyID($storeId);
         $Shop = Shopware()->Models()->find('Shopware\\Models\\Shop\\Shop', $shopId);
         $Importuer = new PlentymarketsImportEntityItem($ItemBase, $Shop);
         // The item has already been updated
         if (!$full) {
             // so we just need to do the categories
             $Importuer->importCategories();
             //if this is a main shop , import the translation for its main language and its shop languages
             if (PlentymarketsTranslation::isMainShop($shopId)) {
                 if (!empty($itemTexts)) {
                     // Do the import for item texts translation
                     $Importuer->saveItemTextsTranslation($itemTexts);
                 }
                 // Do the import for the property value translations
                 $Importuer->importItemPropertyValueTranslations();
             }
         } else {
             // Do a full import
             $Importuer->import();
             //if this is a main shop , import the translation for its main language and its shop languages
             if (PlentymarketsTranslation::isMainShop($shopId)) {
                 if (!empty($itemTexts)) {
                     // Do the import for item texts translation
                     $Importuer->saveItemTextsTranslation($itemTexts);
                 }
                 // Do the import for the property value translations
                 $Importuer->importItemPropertyValueTranslations();
             }
             // Add it to the link controller
             PlentymarketsImportControllerItemLinked::getInstance()->addItem($ItemBase->ItemID);
             // Mark this item as done
             $this->itemIdsDone[$ItemBase->ItemID] = true;
         }
         // Log the usage data
         PyLog()->usage();
     } catch (Shopware\Components\Api\Exception\ValidationException $E) {
         PlentymarketsLogger::getInstance()->error('Sync:Item:Validation', 'The item »' . $ItemBase->Texts->Name . '« with the id »' . $ItemBase->ItemID . '« could not be imported', 3010);
         foreach ($E->getViolations() as $ConstraintViolation) {
             PlentymarketsLogger::getInstance()->error('Sync:Item:Validation', $ConstraintViolation->getMessage());
             PlentymarketsLogger::getInstance()->error('Sync:Item:Validation', $ConstraintViolation->getPropertyPath() . ': ' . $ConstraintViolation->getInvalidValue());
         }
     } catch (Shopware\Components\Api\Exception\OrmException $E) {
         PlentymarketsLogger::getInstance()->error('Sync:Item:Orm', 'The item »' . $ItemBase->Texts->Name . '« with the id »' . $ItemBase->ItemID . '« could not be imported (' . $E->getMessage() . ')', 3020);
         PlentymarketsLogger::getInstance()->error('Sync:Item:Orm', $E->getTraceAsString(), 1000);
         throw new PlentymarketsImportException('The item import will be stopped (internal database error)', 3021);
     } catch (PlentymarketsImportItemNumberException $E) {
         PlentymarketsLogger::getInstance()->error('Sync:Item:Number', $E->getMessage(), $E->getCode());
     } catch (PlentymarketsImportItemException $E) {
         PlentymarketsLogger::getInstance()->error('Sync:Item:Number', $E->getMessage(), $E->getCode());
     } catch (Exception $E) {
         PlentymarketsLogger::getInstance()->error('Sync:Item', 'The item »' . $ItemBase->Texts->Name . '« with the id »' . $ItemBase->ItemID . '« could not be imported', 3000);
         PlentymarketsLogger::getInstance()->error('Sync:Item', $E->getTraceAsString(), 1000);
         PlentymarketsLogger::getInstance()->error('Sync:Item', get_class($E));
         PlentymarketsLogger::getInstance()->error('Sync:Item', $E->getMessage());
     }
 }
    /**
     * Performs the actual import
     *
     * @throws PlentymarketsExportException
     */
    public function run()
    {
        // Get the data from plentymarkets (for every mapped shop)
        $shopIds = Shopware()->Db()->fetchAll('
			SELECT * FROM plenty_mapping_shop
		');
        foreach ($shopIds as $shopId) {
            $mainShopId = PlentymarketsMappingController::getShopByPlentyID($shopId['plentyID']);
            $mainLang = array_values(PlentymarketsTranslation::getShopMainLanguage($mainShopId));
            $Request_GetItemCategoryTree = new PlentySoapRequest_GetItemCategoryTree();
            $Request_GetItemCategoryTree->Lang = PlentymarketsTranslation::getPlentyLocaleFormat($mainLang[0]['locale']);
            $Request_GetItemCategoryTree->GetCategoryNames = true;
            $Request_GetItemCategoryTree->StoreID = $shopId['plentyID'];
            $Request_GetItemCategoryTree->GetAktivCategories = true;
            /** @var PlentySoapResponse_GetItemCategoryTree $Response_GetItemCategoryTree */
            $Response_GetItemCategoryTree = PlentymarketsSoapClient::getInstance()->GetItemCategoryTree($Request_GetItemCategoryTree);
            if (!$Response_GetItemCategoryTree->Success) {
                Shopware()->Db()->query('INSERT plenty_mapping_category SELECT * FROM plenty_mapping_category_old');
                throw new PlentymarketsImportException('The item category tree could not be retrieved', 2920);
            }
            /** @var PlentySoapObject_ItemCategoryTreeNode $Category */
            foreach ($Response_GetItemCategoryTree->MultishopTree->item[0]->CategoryTree->item as $Category) {
                $importEntityItemCategoryTree = new PlentymarketsImportEntityItemCategoryTree($Category, $shopId['plentyID'], $Request_GetItemCategoryTree->Lang);
                $importEntityItemCategoryTree->import();
            }
        }
        $this->rebuild();
    }
 /**
  * Loads the status data
  */
 public function getMappingStatusAction()
 {
     $this->View()->assign(array('success' => true, 'data' => array_values(PlentymarketsMappingController::getStatusList())));
 }
 /**
  * Retrieves the linked items from plentymarkets and links them
  */
 public function link()
 {
     // Cleanup
     $this->purge();
     /** @var PlentySoapObject_GetLinkedItems $LinkedItem */
     foreach ($this->LinkedItems->item as $LinkedItem) {
         // Get the id
         try {
             $SHOWWARE_linkedItemId = PlentymarketsMappingController::getItemByPlentyID($LinkedItem->ItemID);
         } catch (PlentymarketsMappingExceptionNotExistant $E) {
             continue;
         }
         if ($LinkedItem->Relationship == 'Accessory') {
             $table = 's_articles_relationships';
         } else {
             if ($LinkedItem->Relationship == 'Similar') {
                 $table = 's_articles_similar';
             } else {
                 continue;
             }
         }
         Shopware()->Db()->insert($table, array('articleID' => (int) $this->SHOPWARE_itemId, 'relatedarticle' => (int) $SHOWWARE_linkedItemId));
     }
     $this->purgeViews();
 }
 /**
  * Imports the item bundle
  *
  * @throws Exception
  */
 protected function importBundle()
 {
     // Get the bundle head
     $Request_GetItemsBase = new PlentySoapRequest_GetItemsBase();
     $Request_GetItemsBase->GetAttributeValueSets = false;
     $Request_GetItemsBase->GetCategories = false;
     $Request_GetItemsBase->GetCategoryNames = false;
     $Request_GetItemsBase->GetItemAttributeMarkup = false;
     $Request_GetItemsBase->GetItemOthers = false;
     $Request_GetItemsBase->GetItemProperties = false;
     $Request_GetItemsBase->GetItemSuppliers = false;
     $Request_GetItemsBase->GetItemURL = 0;
     $Request_GetItemsBase->GetLongDescription = false;
     $Request_GetItemsBase->GetMetaDescription = false;
     $Request_GetItemsBase->GetShortDescription = false;
     $Request_GetItemsBase->GetTechnicalData = false;
     $Request_GetItemsBase->ItemID = $this->PLENTY_bundleHeadId;
     $Request_GetItemsBase->Page = 0;
     /** @var PlentySoapResponse_GetItemsBase $Response_GetItemsBase */
     $Response_GetItemsBase = PlentymarketsSoapClient::getInstance()->GetItemsBase($Request_GetItemsBase);
     if ($Response_GetItemsBase->Success == false || !isset($Response_GetItemsBase->ItemsBase->item[0])) {
         throw new PlentymarketsImportException('The item bundle with SKU »' . $this->PLENTY_bundle->SKU . '« can not be imported (SOAP call failed).', 3701);
     }
     /** @var PlentySoapObject_ItemBase $ItemBase */
     $ItemBase = $Response_GetItemsBase->ItemsBase->item[0];
     try {
         // Get the existing bundle
         $shopwareBundleId = PlentymarketsMappingController::getItemBundleByPlentyID($this->PLENTY_bundleHeadId);
         /** @var Shopware\CustomModels\Bundle\Bundle $Bundle */
         $Bundle = Shopware()->Models()->find('Shopware\\CustomModels\\Bundle\\Bundle', $shopwareBundleId);
         $currentShopwareBundleHeadItemDetailId = $Bundle->getArticle()->getMainDetail()->getId();
         if (!isset($this->SHOPWARE_bundleItemDetailList[$currentShopwareBundleHeadItemDetailId])) {
             // If the item which is the bundle head in shopware
             // has been removed in plentymarkets, the bundle has to get a new
             // head item. If this is not possible, the bundle will be delete.
             try {
                 $mainDetail = $this->getShopwareBundleItemDetail();
                 /** @var Shopware\Models\Article\Article $Article */
                 $Article = $mainDetail->getArticle();
                 PyLog()->message('Sync:Item:Bundle', 'The item »' . $Article->getName() . '« with the number »' . $mainDetail->getNumber() . '« is now the master item of the item bundle with the number »' . $Bundle->getNumber() . '«.');
                 $Bundle->setArticle($Article);
             } catch (PlentymarketsImportException $e) {
                 PlentymarketsMappingController::deleteItemBundleByShopwareID($Bundle->getId());
                 PyLog()->message('Sync:Item:Bundle', 'The item bundle with the number »' . $Bundle->getNumber() . '« will be deleted because no item can be identified as the master item. The previous master item with the number »' . $Bundle->getArticle()->getMainDetail()->getNumber() . '« is no longer part of the item bundle.');
                 // Delete the bundle
                 Shopware()->Models()->remove($Bundle);
                 Shopware()->Models()->flush();
                 throw $e;
             }
         }
         $action = 'update';
     } catch (PlentymarketsMappingExceptionNotExistant $E) {
         $action = 'create';
         // Create a new one
         $Bundle = new Shopware\CustomModels\Bundle\Bundle();
         $mainDetail = $this->getShopwareBundleItemDetail();
         /** @var Shopware\Models\Article\Article $Article */
         $Article = $mainDetail->getArticle();
         PyLog()->message('Sync:Item:Bundle', 'The item »' . $Article->getName() . '« with the number »' . $mainDetail->getNumber() . '« will be the master item of the item bundle with the number »' . $ItemBase->ItemNo . '«.');
         // Set the stuff which needs to be set just one
         $Bundle->setArticle($Article);
         $Bundle->setType(1);
         $Bundle->setDiscountType('abs');
         $Bundle->setQuantity(0);
         $Bundle->setCreated();
         $Bundle->setSells(0);
         if (method_exists($Bundle, 'setDisplayGlobal')) {
             $Bundle->setDisplayGlobal(true);
         }
     }
     //
     $Bundle->setName($ItemBase->Texts->Name);
     $Bundle->setShowName(0);
     $Bundle->setNumber($ItemBase->ItemNo);
     $isLimited = $ItemBase->Stock->Limitation == 1;
     $Bundle->setLimited($isLimited);
     $isActive = $ItemBase->Availability->Inactive == 0 && $ItemBase->Availability->Webshop == 1;
     $Bundle->setActive($isActive);
     /**@var Shopware\Models\Customer\Group $CG */
     $CG = $this->getCustomerGroup();
     $shopwareBundleHeadItemId = $Bundle->getArticle()->getId();
     $items = array();
     foreach ($Bundle->getArticles() as $item) {
         /** @var Shopware\CustomModels\Bundle\Article $item */
         $itemDetailId = $item->getArticleDetail()->getId();
         // Not in the bundle or already done
         if (!isset($this->SHOPWARE_bundleItemDetailList[$itemDetailId])) {
             continue;
         }
         $quantity = $this->SHOPWARE_bundleItemDetailList[$itemDetailId]['quantity'];
         // If it is also the main item, the quantity needs to be reduced by one
         if ($item->getArticleDetail()->getArticle()->getId() == $shopwareBundleHeadItemId) {
             // If there is just one, the item is skipped since it is the HEAD - it will not be added as an item
             if ($quantity == 1) {
                 unset($this->SHOPWARE_bundleItemDetailList[$itemDetailId]);
                 continue;
             }
             // If the amount is higher - reduce item - the item is the HEAD and inside the bundle
             // in plenty it is just inside the bundle
             $quantity -= 1;
         }
         // Unset the detail - the rest of this array will be added as new items to the bundle
         unset($this->SHOPWARE_bundleItemDetailList[$itemDetailId]);
         // Update the quantity if changed
         if ($item->getQuantity() != $quantity) {
             $item->setQuantity($quantity);
         }
         $items[] = $item;
     }
     // Add all items, which aren't yet in the bundle
     foreach ($this->SHOPWARE_bundleItemDetailList as $config) {
         /** @var Shopware\Models\Article\Detail $detail */
         $detail = $config['detail'];
         // If the head is inside the bundle too, the amount needs to be reduced
         if ($detail->getArticle()->getId() == $shopwareBundleHeadItemId) {
             if ($config['quantity'] > 1) {
                 $config['quantity'] -= 1;
             } else {
                 if ($config['quantity'] == 1) {
                     continue;
                 }
             }
         }
         $ArticleNew = new Shopware\CustomModels\Bundle\Article();
         $ItemDetail = $detail;
         $quantity = $config['quantity'];
         $ArticleNew->setArticleDetail($ItemDetail);
         $ArticleNew->setQuantity($quantity);
         $items[] = $ArticleNew;
     }
     // Set the bundle items
     $Bundle->setArticles($items);
     $newPrice = $ItemBase->PriceSet->Price;
     $newPrice /= (100 + $ItemBase->PriceSet->VAT) / 100;
     $isPriceFound = false;
     $prices = array();
     foreach ($Bundle->getPrices() as $price) {
         /** @var Shopware\CustomModels\Bundle\Price $price */
         if ($price->getCustomerGroup()->getKey() == $CG->getKey()) {
             $price->setPrice($newPrice);
             $isPriceFound = true;
         }
         $prices[] = $price;
     }
     if (!$isPriceFound) {
         $Price = new Shopware\CustomModels\Bundle\Price();
         $Price->setBundle($Bundle);
         $Price->setCustomerGroup($CG);
         $Price->setPrice($newPrice);
         $prices[] = $Price;
         $Bundle->setPrices($prices);
     }
     $Bundle->setCustomerGroups(array($CG));
     Shopware()->Models()->persist($Bundle);
     Shopware()->Models()->flush();
     if ($action == 'create') {
         PlentymarketsMappingController::addItemBundle($Bundle->getId(), $this->PLENTY_bundleHeadId);
         PyLog()->message('Sync:Item:Bundle', 'The item bundle »' . $ItemBase->Texts->Name . '« with the number »' . $ItemBase->ItemNo . '« has been created');
     } else {
         PyLog()->message('Sync:Item:Bundle', 'The item bundle »' . $ItemBase->Texts->Name . '« with the number »' . $ItemBase->ItemNo . '« has been updated');
     }
 }
 /**
  * Imports the linked items
  *
  */
 public function run()
 {
     foreach (array_chunk($this->itemIds, 100) as $chunk) {
         $Request_GetLinkedItems = new PlentySoapRequest_GetLinkedItems();
         $Request_GetLinkedItems->ItemsList = array();
         //
         foreach ($chunk as $itemId) {
             $Object_GetLinkedItems = new PlentySoapObject_GetLinkedItems();
             $Object_GetLinkedItems->ItemID = $itemId;
             $Request_GetLinkedItems->ItemsList[] = $Object_GetLinkedItems;
         }
         /** @var PlentySoapResponse_GetLinkedItems $Response_GetLinkedItems */
         $Response_GetLinkedItems = PlentymarketsSoapClient::getInstance()->GetLinkedItems($Request_GetLinkedItems);
         /** @var PlentySoapResponseObject_GetLinkedItems $Item */
         foreach ($Response_GetLinkedItems->Items->item as $Item) {
             try {
                 $SHOPWARE_itemId = PlentymarketsMappingController::getItemByPlentyID($Item->ItemID);
             } catch (PlentymarketsMappingExceptionNotExistant $E) {
                 continue;
             }
             $PlentymarketsImportEntityItemLinked = new PlentymarketsImportEntityItemLinked($SHOPWARE_itemId, $Item->LinkedItems);
             $PlentymarketsImportEntityItemLinked->link();
         }
     }
 }
    /**
     * Generates "reverse mapping"
     *
     * @param array $article
     */
    public function map($article)
    {
        $details = $article['details'];
        $details[] = $article['mainDetail'];
        foreach ($details as $detail) {
            foreach ($detail['configuratorOptions'] as $option) {
                try {
                    // Mapping for the Group -> plentymarkets Attribute
                    if (!isset(self::$mapping['group'][$option['groupId']])) {
                        $plentyGroupId = PlentymarketsMappingController::getAttributeGroupByShopwareID($option['groupId']);
                    } else {
                        $plentyGroupId = self::$mapping['group'][$option['groupId']];
                    }
                } catch (PlentymarketsMappingExceptionNotExistant $E) {
                    // Name auslesen
                    $group = Shopware()->Db()->fetchRow('
						SELECT name FROM s_article_configurator_groups WHERE id = ?
					', array($option['groupId']));
                    //
                    $plentyGroupId = $this->groupName2plentyId[$group['name']];
                    //
                    PlentymarketsMappingController::addAttributeGroup($option['groupId'], $plentyGroupId);
                }
                try {
                    // Mapping for the Group -> plentymarkets Attribute
                    if (!isset(self::$mapping['option'][$option['id']])) {
                        $plentyOptionId = PlentymarketsMappingController::getAttributeOptionByShopwareID($option['id']);
                    } else {
                        $plentyOptionId = self::$mapping['option'][$option['id']];
                    }
                } catch (PlentymarketsMappingExceptionNotExistant $E) {
                    //
                    $plentyOptionId = $this->groupId2optionName2plentyId[$plentyGroupId][$option['name']];
                    //
                    PlentymarketsMappingController::addAttributeOption($option['id'], $plentyOptionId);
                    //
                }
                self::$mapping['group'][$option['groupId']] = $plentyGroupId;
                self::$mapping['option'][$option['id']] = $plentyOptionId;
            }
        }
    }
    /**
     * Retrieves the images from plentymarkets and adds them to the item
     * @return number
     */
    public function image()
    {
        $plentyId2ShopwareId = array();
        $shopwareId2PlentyPosition = array();
        $Request_GetItemsImages = new PlentySoapRequest_GetItemsImages();
        $Request_GetItemsImages->Page = 0;
        $Request_GetItemsImages->SKU = $this->PLENTY_itemId;
        // Cleanup
        $this->purge();
        /** @var \Shopware\Components\Api\Resource\Media $mediaResource */
        $mediaResource = \Shopware\Components\Api\Manager::getResource('Media');
        do {
            /** @var PlentySoapResponse_GetItemsImages $Response_GetItemsImages */
            $Response_GetItemsImages = PlentymarketsSoapClient::getInstance()->GetItemsImages($Request_GetItemsImages);
            if ($Response_GetItemsImages->Success == false) {
                PlentymarketsLogger::getInstance()->error('Sync:Item:Image', 'The images for the plentymarkets item id »' . $this->PLENTY_itemId . '« could not be retrieved', 3200);
                continue;
            }
            /** @var $Image PlentySoapResponse_ObjectItemImage */
            foreach ($Response_GetItemsImages->ItemsImages->item as $Image) {
                $shopwareStoreIds = array();
                /** @var $reference PlentySoapResponse_ObjectGetItemImageReference */
                foreach ($Image->References->item as $reference) {
                    if (strtolower($reference->ReferenceType) == 'mandant') {
                        try {
                            if (PlentymarketsMappingController::getShopByPlentyID($reference->ReferenceValue) > 0) {
                                $shopwareStoreId = PlentymarketsMappingController::getShopByPlentyID($reference->ReferenceValue);
                            }
                        } catch (PlentymarketsMappingExceptionNotExistant $E) {
                            continue;
                        }
                        if (isset($shopwareStoreId)) {
                            $shopwareStoreIds[] = $shopwareStoreId;
                        }
                    }
                }
                // Skip the image if it should not be shown
                if (empty($shopwareStoreIds)) {
                    continue;
                } else {
                    /** @var Shopware\Models\Media\Media $media */
                    $media = $mediaResource->internalCreateMediaByFileLink($Image->ImageURL);
                    $image = new \Shopware\Models\Article\Image();
                    $image->setMain(2);
                    $image->setMedia($media);
                    $image->setPath($media->getName());
                    $image->setExtension($media->getExtension());
                    // get the main language of the shop
                    //$mainLangData = array_values(PlentymarketsTranslation::getInstance()->getShopMainLanguage($shopwareStoreId));
                    //$mainLang = PlentymarketsTranslation::getInstance()->getPlentyLocaleFormat($mainLangData[0]['locale']);
                    /** @var $imageName PlentySoapResponse_ObjectGetItemImageName */
                    foreach ($Image->Names->item as $imageName) {
                        if ($imageName->Lang == 'de') {
                            // set the image title in German
                            $image->setDescription($imageName->Name);
                        }
                    }
                    if (!is_null(PlentymarketsConfig::getInstance()->getItemImageAltAttributeID()) && PlentymarketsConfig::getInstance()->getItemImageAltAttributeID() > 0 && PlentymarketsConfig::getInstance()->getItemImageAltAttributeID() <= 3) {
                        // get the attribute number for alternative text from connector's settings
                        $plenty_attributeID = PlentymarketsConfig::getInstance()->getItemImageAltAttributeID();
                        // set the value for the attribute number
                        $attribute = new \Shopware\Models\Attribute\ArticleImage();
                        $attribute->{setAttribute . $plenty_attributeID}($Image->Names->item[0]->AlternativeText);
                        $image->setAttribute($attribute);
                    }
                    $image->setPosition($Image->Position);
                    // Generate the thumbnails
                    if (version_compare('4.2', Shopware::VERSION) != 1) {
                        PlentymarketsImportItemImageThumbnailController::getInstance()->addMediaResource($media);
                    }
                    Shopware()->Models()->persist($image);
                    Shopware()->Models()->flush();
                    $imageId = $image->getId();
                    foreach ($shopwareStoreIds as $shopwareStoreId) {
                        // import the image title translations for all active shops of the image
                        $this->importImageTitleTranslation($imageId, $Image->Names->item, $shopwareStoreId);
                    }
                    $plentyId2ShopwareId[$Image->ImageID] = $imageId;
                    $shopwareId2PlentyPosition[$Image->Position] = $imageId;
                    Shopware()->DB()->query('
											UPDATE s_articles_img
												SET articleID = ?
												WHERE id = ?
										', array($this->SHOPWARE_itemId, $imageId));
                }
            }
        } while (++$Request_GetItemsImages->Page < $Response_GetItemsImages->Pages);
        if (!$shopwareId2PlentyPosition) {
            return;
        }
        ksort($shopwareId2PlentyPosition);
        $mainImageId = reset($shopwareId2PlentyPosition);
        /** @var Shopware\Models\Article\Image $mainImage */
        $mainImage = Shopware()->Models()->find('Shopware\\Models\\Article\\Image', $mainImageId);
        $mainImage->setMain(1);
        Shopware()->Models()->persist($mainImage);
        Shopware()->Models()->flush();
        // Get the variant images
        $Request_GetItemsVariantImages = new PlentySoapRequest_GetItemsVariantImages();
        $Request_GetItemsVariantImages->Items = array();
        $RequestObject_GetItemsVariantImages = new PlentySoapRequestObject_GetItemsVariantImages();
        $RequestObject_GetItemsVariantImages->ItemID = $this->PLENTY_itemId;
        $Request_GetItemsVariantImages->Items[] = $RequestObject_GetItemsVariantImages;
        /** @var PlentySoapResponse_GetItemsVariantImages $Response_GetItemsVariantImages */
        $Response_GetItemsVariantImages = PlentymarketsSoapClient::getInstance()->GetItemsVariantImages($Request_GetItemsVariantImages);
        /** @var PlentySoapObject_GetItemsVariantImagesImage $GetItemsVariantImagesImage */
        foreach ($Response_GetItemsVariantImages->Images->item as $GetItemsVariantImagesImage) {
            try {
                $shopwareOptionId = PlentymarketsMappingController::getAttributeOptionByPlentyID($GetItemsVariantImagesImage->AttributeValueID);
                $shopwareOption = Shopware()->Models()->find('Shopware\\Models\\Article\\Configurator\\Option', $shopwareOptionId);
            } catch (PlentymarketsMappingExceptionNotExistant $e) {
                continue;
            }
            if (!isset($plentyId2ShopwareId[$GetItemsVariantImagesImage->ImageID])) {
                continue;
            }
            /** @var Shopware\Models\Article\Image $shopwareImage */
            $shopwareImageId = $plentyId2ShopwareId[$GetItemsVariantImagesImage->ImageID];
            $shopwareImage = Shopware()->Models()->find('Shopware\\Models\\Article\\Image', $shopwareImageId);
            $mapping = new Shopware\Models\Article\Image\Mapping();
            $mapping->setImage($shopwareImage);
            $rule = new Shopware\Models\Article\Image\Rule();
            $rule->setMapping($mapping);
            $rule->setOption($shopwareOption);
            $mapping->getRules()->add($rule);
            $shopwareImage->setMappings($mapping);
            Shopware()->Models()->persist($mapping);
            $details = Shopware()->Db()->fetchCol('
				SELECT
						d.id
					FROM s_articles_details d
						INNER JOIN s_article_configurator_option_relations alias16 ON alias16.option_id = ' . $shopwareOptionId . ' AND alias16.article_id = d.id
					WHERE d.articleID = ' . $this->SHOPWARE_itemId . '
			');
            foreach ($details as $detailId) {
                // Get the detail object
                $detail = Shopware()->Models()->getReference('Shopware\\Models\\Article\\Detail', $detailId);
                // Create the variant image
                $variantImage = new Shopware\Models\Article\Image();
                $variantImage->setExtension($shopwareImage->getExtension());
                $variantImage->setMain($shopwareImage->getMain());
                $variantImage->setParent($shopwareImage);
                $variantImage->setArticleDetail($detail);
                // And persist it
                Shopware()->Models()->persist($variantImage);
            }
        }
        Shopware()->Models()->flush();
    }
 /**
  * Export the missing properties
  */
 protected function doExport()
 {
     $propertyGroupRepository = Shopware()->Models()->getRepository('Shopware\\Models\\Property\\Group');
     /** @var Shopware\Models\Property\Group $PropertyGroup */
     foreach ($propertyGroupRepository->findAll() as $PropertyGroup) {
         try {
             $groupIdAdded = PlentymarketsMappingController::getPropertyGroupByShopwareID($PropertyGroup->getId());
         } catch (PlentymarketsMappingExceptionNotExistant $E) {
             if (array_key_exists($PropertyGroup->getName(), $this->PLENTY_groupName2ID)) {
                 $groupIdAdded = $this->PLENTY_groupName2ID[$PropertyGroup->getName()];
             } else {
                 $Request_SetPropertyGroups = new PlentySoapRequest_SetPropertyGroups();
                 $Request_SetPropertyGroups->Properties = array();
                 $Object_SetPropertyGroup = new PlentySoapObject_SetPropertyGroup();
                 $Object_SetPropertyGroup->BackendName = $PropertyGroup->getName();
                 $Object_SetPropertyGroup->FrontendName = $PropertyGroup->getName();
                 $Object_SetPropertyGroup->Lang = 'de';
                 $Object_SetPropertyGroup->PropertyGroupID = null;
                 $Request_SetPropertyGroups->PropertyGroups[] = $Object_SetPropertyGroup;
                 $Response = PlentymarketsSoapClient::getInstance()->SetPropertyGroups($Request_SetPropertyGroups);
                 if (!$Response->Success) {
                     throw new PlentymarketsExportException('The item property group »' . $Object_SetPropertyGroup->BackendName . '« could not be exported', 2941);
                 }
                 $groupIdAdded = (int) $Response->ResponseMessages->item[0]->SuccessMessages->item[0]->Value;
             }
             PlentymarketsMappingController::addPropertyGroup($PropertyGroup->getId(), $groupIdAdded);
             // do export for property group translation
             $this->exportPropertyGroupTranslations($PropertyGroup->getId(), $groupIdAdded);
         }
         if (!isset($this->PLENTY_groupIDValueName2ID[$groupIdAdded])) {
             $this->PLENTY_groupIDValueName2ID[$groupIdAdded] = array();
         }
         /** @var Shopware\Models\Property\Option $Property */
         foreach ($PropertyGroup->getOptions() as $Property) {
             $Request_SetProperties = new PlentySoapRequest_SetProperties();
             $Request_SetProperties->Properties = array();
             $Object_SetProperty = new PlentySoapObject_SetProperty();
             $Object_SetProperty->PropertyGroupID = $groupIdAdded;
             $Object_SetProperty->PropertyID = null;
             $Object_SetProperty->Lang = 'de';
             $shopwareID = $PropertyGroup->getId() . ';' . $Property->getId();
             try {
                 PlentymarketsMappingController::getPropertyByShopwareID($shopwareID);
             } catch (PlentymarketsMappingExceptionNotExistant $E) {
                 if (array_key_exists($Property->getName(), $this->PLENTY_groupIDValueName2ID[$groupIdAdded])) {
                     $propertyIdAdded = $this->PLENTY_groupIDValueName2ID[$groupIdAdded][$Property->getName()];
                 } else {
                     $Object_SetProperty->PropertyFrontendName = $Property->getName();
                     $Object_SetProperty->PropertyBackendName = $Property->getName();
                     $Object_SetProperty->ShowOnItemPage = 1;
                     $Object_SetProperty->ShowInItemList = 1;
                     $Object_SetProperty->PropertyType = 'text';
                     $Request_SetProperties->Properties[] = $Object_SetProperty;
                     $Response_SetProperties = PlentymarketsSoapClient::getInstance()->SetProperties($Request_SetProperties);
                     if (!$Response_SetProperties->Success) {
                         throw new PlentymarketsExportException('The item property »' . $Object_SetProperty->PropertyBackendName . '« could not be created', 2942);
                     }
                     $propertyIdAdded = (int) $Response_SetProperties->ResponseMessages->item[0]->SuccessMessages->item[0]->Value;
                 }
                 PlentymarketsMappingController::addProperty($shopwareID, $propertyIdAdded);
                 $this->exportPropertyTranslations($groupIdAdded, $Property->getId(), $propertyIdAdded);
             }
         }
     }
 }
 /**
  * Returns the shop id or null
  *
  * @return integer|null
  */
 protected function getShopId()
 {
     // Sub-objects
     $Shop = $this->Order->getShop();
     // Shop
     if ($Shop) {
         try {
             return PlentymarketsMappingController::getShopByShopwareID($Shop->getId());
         } catch (PlentymarketsMappingExceptionNotExistant $E) {
         }
     }
     return null;
 }
 /**
  * Returns the customer class id
  *
  * @return integer|null
  */
 protected function getCustomerClassId()
 {
     try {
         return PlentymarketsMappingController::getCustomerClassByShopwareID($this->Customer->getGroup()->getId());
     } catch (Exception $E) {
         PyLog()->debug($E->getMessage());
         return null;
     }
 }
 /**
  * @param PlentySoapResponse_ObjectItemImage $Image
  * @param Media $mediaResource
  *
  * @return MediaModel
  *
  * @throws NotFoundException
  * @throws PlentymarketsMappingExceptionNotExistant
  */
 protected function updateMedia(PlentySoapResponse_ObjectItemImage $Image, Media $mediaResource)
 {
     $mediaId = PlentymarketsMappingController::getMediaByPlentyID($Image->ImageID);
     if (empty($mediaId)) {
         throw new PlentymarketsMappingExceptionNotExistant();
     }
     /**
      * @var MediaModel $media
      */
     $media = Shopware()->Models()->getRepository('Shopware\\Models\\Media\\Media')->find($mediaId);
     if (empty($media)) {
         throw new NotFoundException();
     }
     $attributes = $media->getAttribute();
     if (empty($attributes)) {
         $attributes = new MediaAttributes();
         $media->setAttribute($attributes);
         Shopware()->Models()->persist($attributes);
     }
     $hash = $attributes->getPlentyHash();
     if (empty($hash)) {
         $hash = $attributes->setPlentyHash(sha1_file($media->getPath()));
         Shopware()->Models()->persist($attributes);
     }
     $newHash = sha1_file($Image->ImageURL);
     if ($hash != $newHash) {
         // remove old media
         Shopware()->Models()->remove($media);
         $newMedia = $this->createMedia($Image, $mediaResource);
         // update old article images
         $images = $media->getArticles();
         /**
          * @var Shopware\Models\Article\Image $image
          */
         foreach ($images as $image) {
             $image->setMedia($newMedia);
             $image->setPath($newMedia->getName());
             $image->setExtension($newMedia->getExtension());
             $image->setDescription($newMedia->getDescription());
             Shopware()->Models()->persist($image);
         }
         $media = $newMedia;
     }
     Shopware()->Models()->flush();
     return $media;
 }
 /**
  * Rolls back the item (delete all mappings and the item in plentymarkets)
  */
 protected function rollback()
 {
     // Delete the item in plentymarktes
     $Request_DeleteItems = new PlentySoapRequest_DeleteItems();
     $Request_DeleteItems->DeleteItems = array();
     $Object_DeleteItems = new PlentySoapObject_DeleteItems();
     $Object_DeleteItems->ItemID = $this->PLENTY_itemID;
     $Request_DeleteItems->DeleteItems[] = $Object_DeleteItems;
     PlentymarketsSoapClient::getInstance()->DeleteItems($Request_DeleteItems);
     PlentymarketsLogger::getInstance()->message('Export:Initial:Item', 'The item with the id »' . $this->PLENTY_itemID . '« has been deleted in plentymarkets');
     // Delete the mapping for the main item
     PlentymarketsMappingController::deleteItemByShopwareID($this->SHOPWARE_Article->getId());
     // And for the details
     foreach ($this->SHOPWARE_Article->getDetails() as $ItemVariation) {
         PlentymarketsMappingController::deleteItemVariantByShopwareID($ItemVariation->getId());
     }
 }
 /**
  * Returns the shopware tax id
  *
  * @throws PlentymarketsImportItemException
  * @return integer
  */
 protected function getTaxId()
 {
     try {
         $taxID = PlentymarketsMappingController::getVatByPlentyID($this->ItemBase->VATInternalID);
     } catch (PlentymarketsMappingExceptionNotExistant $E) {
         throw new PlentymarketsImportItemException('The item »' . $this->ItemBase->Texts->Name . '« with the id »' . $this->ItemBase->ItemID . '« could not be imported (no valid vat/tax)', 3030);
     }
     return $taxID;
 }
 /**
  * Adds a category mapping
  *
  * @param integer $shopwareCategoryId
  * @param integer $shopId
  * @param integer $plentyCategoryId
  * @param integer $storeId
  */
 public static function addCategory($shopwareCategoryId, $shopId, $plentyCategoryId, $storeId)
 {
     PlentymarketsMappingController::addCategory(self::getIdentifier($shopwareCategoryId, $shopId), self::getIdentifier($plentyCategoryId, $storeId));
 }
 /**
  * Returns the plentymarkets customer id
  *
  * @throws PlentymarketsExportEntityException
  * @return integer
  */
 protected function getCustomerId()
 {
     try {
         return PlentymarketsMappingController::getCustomerByShopwareID($this->order['billing']['id']);
     } catch (PlentymarketsMappingExceptionNotExistant $E) {
         // Customer needs to be re-exported
         PlentymarketsLogger::getInstance()->message('Sync:Order:IncomingPayment', 'Re-exporting customer');
     }
     // Get the data
     $Customer = Shopware()->Models()->find('Shopware\\Models\\Customer\\Customer', $this->order['customerId']);
     $BillingAddress = Shopware()->Models()->find('Shopware\\Models\\Order\\Billing', $this->order['billing']['id']);
     try {
         $PlentymarketsExportEntityCustomer = new PlentymarketsExportEntityCustomer($Customer, $BillingAddress);
         $PlentymarketsExportEntityCustomer->export();
     } catch (PlentymarketsExportEntityException $E) {
         throw new PlentymarketsExportEntityException('The incoming payment of the order with the number »' . $this->order['number'] . '« could not be booked (' . $E->getMessage() . ')', 4150);
     }
     return PlentymarketsMappingController::getCustomerByShopwareID($this->order['billing']['id']);
 }
 /**
  * Exports images, variants, properties item data and items base to make sure, that the corresponding items data exist.
  */
 protected function export()
 {
     // Query builder
     $QueryBuilder = Shopware()->Models()->createQueryBuilder();
     $QueryBuilder->select('item.id')->from('Shopware\\Models\\Article\\Article', 'item');
     do {
         // Log the chunk
         PlentymarketsLogger::getInstance()->message('Export:Initial:Item', 'Chunk: ' . ($this->currentChunk + 1));
         // Set Limit and Offset
         $QueryBuilder->setFirstResult($this->currentChunk * $this->sizeOfChunk)->setMaxResults($this->sizeOfChunk);
         // Get the items
         $items = $QueryBuilder->getQuery()->getArrayResult();
         //
         $itemsAlreadyExported = 0;
         foreach ($items as $item) {
             try {
                 // If there is a plenty id for this shopware id,
                 // the item has already been exported to plentymarkets
                 PlentymarketsMappingController::getItemByShopwareID($item['id']);
                 //
                 ++$itemsAlreadyExported;
                 // already done
                 continue;
             } catch (PlentymarketsMappingExceptionNotExistant $E) {
             }
             $PlentymarketsExportEntityItem = new PlentymarketsExportEntityItem(Shopware()->Models()->find('Shopware\\Models\\Article\\Article', $item['id']));
             $PlentymarketsExportEntityItem->export();
         }
         // Remember the chunk
         $this->Config->setItemExportLastChunk($this->currentChunk);
         if ($this->maxChunks > 0) {
             // Increase number of chunks if every item has already been exported
             if ($itemsAlreadyExported == $this->sizeOfChunk) {
                 ++$this->maxChunks;
                 PlentymarketsLogger::getInstance()->message('Export:Initial:Item', 'Increasing number of chunks per run to ' . $this->maxChunks . ' since every item of chunk ' . ($this->currentChunk + 1) . ' has already been exported');
             }
             // Quit when the maximum number of chunks is reached
             if (++$this->chunksDone >= $this->maxChunks) {
                 $this->toBeContinued = true;
                 break;
             }
         }
         // Next chunk
         ++$this->currentChunk;
     } while (!empty($items) && count($items) == $this->sizeOfChunk);
 }