/**
  * Builds an index and checks if all items are present
  *
  * @throws Exception
  */
 protected function index()
 {
     $bundleHeadSku = explode('-', $this->PLENTY_bundle->SKU);
     $this->PLENTY_bundleHeadId = (int) $bundleHeadSku[0];
     // Check whether all bundle items are present in shopware
     foreach ($this->PLENTY_bundle->Items->item as $PlentySoapObject_BundleItem) {
         /** @var PlentySoapObject_BundleItem $PlentySoapObject_BundleItem */
         $bundleItemSku = explode('-', $PlentySoapObject_BundleItem->SKU);
         $plentyBundleItemId = $bundleItemSku[0];
         try {
             // Variant
             if (isset($bundleItemSku[2]) && $bundleItemSku[2] > 0) {
                 $shopwareBundleItemDetailId = PlentymarketsMappingController::getItemVariantByPlentyID($PlentySoapObject_BundleItem->SKU);
                 // The detail is needed
                 $detail = Shopware()->Models()->find('Shopware\\Models\\Article\\Detail', $shopwareBundleItemDetailId);
                 $isVariant = true;
             } else {
                 $shopwareBundleItemId = PlentymarketsMappingController::getItemByPlentyID($plentyBundleItemId);
                 /** @var Shopware\Models\Article\Article $shopwareItem */
                 $shopwareItem = Shopware()->Models()->find('Shopware\\Models\\Article\\Article', $shopwareBundleItemId);
                 // The detail is needed
                 $detail = $shopwareItem->getMainDetail();
                 $isVariant = false;
             }
         } catch (PlentymarketsMappingExceptionNotExistant $E) {
             throw new PlentymarketsImportException('The item bundle with SKU »' . $this->PLENTY_bundle->SKU . '« can not be imported. Not all of the items included in the bundle are available in shopware.', 3710);
         }
         $this->SHOPWARE_bundleItemDetailList[$detail->getId()] = array('detail' => $detail, 'quantity' => (int) $PlentySoapObject_BundleItem->Quantity, 'isVariant' => $isVariant);
     }
 }
 /**
  * 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.');
         }
     }
 }
 /**
  * Sets the variant details
  */
 protected function setVariants()
 {
     // No variants
     if (is_null($this->ItemBase->AttributeValueSets)) {
         return;
     }
     // Internal number cache
     $numbersUsed = array();
     $detailBase = $this->details + $this->data;
     unset($detailBase['id']);
     unset($detailBase['attribute']);
     /** @var PlentySoapObject_ItemAttributeValueSet $AttributeValueSet */
     foreach ($this->ItemBase->AttributeValueSets->item as $AttributeValueSet) {
         // Copy the base details
         $details = $detailBase;
         // SKU
         $sku = sprintf('%s-%s-%s', $this->ItemBase->ItemID, $AttributeValueSet->PriceID, $AttributeValueSet->AttributeValueSetID);
         // Strip whitespaces
         $number = trim($AttributeValueSet->ColliNo);
         try {
             // Set the details id
             $details['id'] = PlentymarketsMappingController::getItemVariantByPlentyID($sku);
             if (PlentymarketsConfig::getInstance()->getItemNumberImportActionID(IMPORT_ITEM_NUMBER) == IMPORT_ITEM_NUMBER) {
                 // If this number does not belong to this item
                 if (!PlentymarketsImportItemHelper::isNumberExistantVariant($number, $details['id'])) {
                     // and check if the number is valid
                     if (!PlentymarketsImportItemHelper::isNumberValid($number)) {
                         throw new PlentymarketsImportItemNumberException('The item variation number »' . $number . '« of item »' . $this->data['name'] . '« with the id »' . $this->ItemBase->ItemID . '« is invalid', 3110);
                     }
                     // check if the number is available anyway
                     if (PlentymarketsImportItemHelper::isNumberExistant($number)) {
                         throw new PlentymarketsImportItemNumberException('The item variation number »' . $number . '« of item »' . $this->data['name'] . '« with the id »' . $this->ItemBase->ItemID . '« is already in use', 3111);
                     }
                     // check if the number is in the internal cache
                     if (isset($numbersUsed[$number])) {
                         throw new PlentymarketsImportItemNumberException('The item variation number »' . $number . '« of item »' . $this->data['name'] . '« with the id »' . $this->ItemBase->ItemID . '« would be assigned twice', 3112);
                     }
                     // Use this number
                     $details['number'] = $number;
                     // Cache the number
                     $numbersUsed[$number] = true;
                 }
             }
         } catch (PlentymarketsMappingExceptionNotExistant $e) {
             // Numbers should be synced
             if (PlentymarketsConfig::getInstance()->getItemNumberImportActionID(IMPORT_ITEM_NUMBER) == IMPORT_ITEM_NUMBER) {
                 // Nummer ist ungültig oder in Benutzung
                 if (!PlentymarketsImportItemHelper::isNumberValid($number)) {
                     throw new PlentymarketsImportItemNumberException('The item variation number »' . $number . '« of item »' . $this->data['name'] . '« with the id »' . $this->ItemBase->ItemID . '« is invalid', 3110);
                 }
                 // check if the number is available
                 if (PlentymarketsImportItemHelper::isNumberExistant($number)) {
                     throw new PlentymarketsImportItemNumberException('The item variation number »' . $number . '« of item »' . $this->data['name'] . '« with the id »' . $this->ItemBase->ItemID . '« is already in use', 3111);
                 }
                 // check if the number is in the internal cache
                 if (isset($numbersUsed[$number])) {
                     throw new PlentymarketsImportItemNumberException('The item variation number »' . $number . '« of item »' . $this->data['name'] . '« with the id »' . $this->ItemBase->ItemID . '« would be assigned twice', 3112);
                 }
                 // Use this number
                 $details['number'] = $number;
                 // Cache the number
                 $numbersUsed[$number] = true;
             } else {
                 // A new number is generated
                 $details['number'] = PlentymarketsImportItemHelper::getItemNumber();
             }
         }
         $shippingTime = PlentymarketsUtils::getShippingTimeByAvailabilityId($AttributeValueSet->Availability);
         if ($shippingTime) {
             $details['shippingtime'] = $shippingTime;
         }
         $details['additionaltext'] = $AttributeValueSet->AttributeValueSetName;
         $details['ean'] = $AttributeValueSet->EAN;
         $details['X_plentySku'] = $sku;
         $this->variants[$AttributeValueSet->AttributeValueSetID] = $details;
     }
 }
 /**
  * Updates the stock for the given PlentySoapObject_GetCurrentStocks object
  *
  * @param PlentySoapObject_GetCurrentStocks $CurrentStock
  */
 public function update($CurrentStock)
 {
     try {
         // Master item
         if (preg_match('/\\d+\\-\\d+\\-0/', $CurrentStock->SKU)) {
             $parts = explode('-', $CurrentStock->SKU);
             $itemId = PlentymarketsMappingController::getItemByPlentyID((int) $parts[0]);
             $Item = Shopware()->Models()->find('Shopware\\Models\\Article\\Article', $itemId);
             // Book
             $this->updateByDetail($Item->getMainDetail(), $CurrentStock->NetStock);
         } else {
             $itemDetailId = PlentymarketsMappingController::getItemVariantByPlentyID($CurrentStock->SKU);
             // Book
             $this->updateById($itemDetailId, $CurrentStock->NetStock);
         }
     } catch (PlentymarketsMappingExceptionNotExistant $E) {
     } catch (Exception $E) {
         PlentymarketsLogger::getInstance()->error('Sync:Item:Stock', 'The stock of the item detail with the id »' . $itemDetailId . '« could not be updated (' . $E->getMessage() . ')', 3510);
     }
 }