/**
     * Runs the export of the incoming payments
     */
    public function run()
    {
        // Start
        PlentymarketsConfig::getInstance()->setItemIncomingPaymentExportStart(time());
        $now = time();
        $lastUpdateTimestamp = date('Y-m-d H:i:s', PlentymarketsConfig::getInstance()->getItemIncomingPaymentExportLastUpdate(time()));
        $status = explode('|', PlentymarketsConfig::getInstance()->getOrderPaidStatusID(12));
        $status = array_map('intval', $status);
        if (!count($status)) {
            $status = array(12);
        }
        $Result = Shopware()->Db()->query('
			SELECT
					DISTINCT orderID
				FROM s_order_history
					JOIN plenty_order ON shopwareId = orderID
				WHERE
					change_date > \'' . $lastUpdateTimestamp . '\' AND
					payment_status_id IN (' . implode(', ', $status) . ') AND
					IFNULL(plentyOrderPaidStatus, 0) != 1
		');
        while (($order = $Result->fetchObject()) && is_object($order)) {
            try {
                $ExportEntityIncomingPayment = new PlentymarketsExportEntityOrderIncomingPayment($order->orderID);
                $ExportEntityIncomingPayment->book();
            } catch (PlentymarketsExportEntityException $E) {
                PlentymarketsLogger::getInstance()->error('Sync:Order:IncomingPayment', $E->getMessage(), $E->getCode());
            }
        }
        // Set timestamps
        PlentymarketsConfig::getInstance()->setItemIncomingPaymentExportTimestampFinished(time());
        PlentymarketsConfig::getInstance()->setItemIncomingPaymentExportLastUpdate($now);
    }
 /**
  * Export the order
  */
 protected function exportOrder()
 {
     $VariantResource = self::getVariantApi();
     // Build the Request
     $Request_AddOrders = new PlentySoapRequest_AddOrders();
     $Request_AddOrders->Orders = array();
     //
     $Object_Order = new PlentySoapObject_Order();
     //
     $methodOfPayment = $this->getMethodOfPaymentId();
     if ($methodOfPayment == MOP_AMAZON_PAYMENT) {
         $externalOrderID = sprintf('Swag/%d/%s/%s', $this->Order->getId(), $this->Order->getNumber(), $this->Order->getTransactionId());
     } else {
         $externalOrderID = sprintf('Swag/%d/%s', $this->Order->getId(), $this->Order->getNumber());
     }
     $isOrderNet = (bool) $this->Order->getNet() || (bool) $this->Order->getTaxFree();
     // Order head
     $Object_OrderHead = new PlentySoapObject_OrderHead();
     $Object_OrderHead->Currency = PlentymarketsMappingController::getCurrencyByShopwareID($this->Order->getCurrency());
     $Object_OrderHead->CustomerID = $this->PLENTY_customerID;
     $Object_OrderHead->DeliveryAddressID = $this->PLENTY_addressDispatchID;
     $Object_OrderHead->ExternalOrderID = $externalOrderID;
     $Object_OrderHead->IsNetto = $isOrderNet;
     $Object_OrderHead->Marking1ID = PlentymarketsConfig::getInstance()->getOrderMarking1(null);
     $Object_OrderHead->MethodOfPaymentID = $this->getMethodOfPaymentId();
     $Object_OrderHead->OrderTimestamp = $this->getOrderTimestamp();
     $Object_OrderHead->OrderType = 'order';
     $Object_OrderHead->ResponsibleID = PlentymarketsConfig::getInstance()->getOrderUserID(null);
     $Object_OrderHead->ShippingCosts = $this->getShippingCosts();
     $Object_OrderHead->ShippingProfileID = $this->getParcelServicePresetId();
     $Object_OrderHead->StoreID = $this->getShopId();
     $Object_OrderHead->ReferrerID = $this->getReferrerId();
     $Object_Order->OrderHead = $Object_OrderHead;
     // Order infos
     $Object_OrderHead->OrderInfos = array();
     if ($Object_OrderHead->MethodOfPaymentID == MOP_DEBIT) {
         $Customer = $this->Order->getCustomer();
         if ($Customer) {
             $Debit = $Customer->getDebit();
             if ($Debit && $Debit->getAccountHolder()) {
                 $info = 'Account holder: ' . $Debit->getAccountHolder() . chr(10);
                 $info .= 'Bank name: ' . $Debit->getBankName() . chr(10);
                 $info .= 'Bank code: ' . $Debit->getBankCode() . chr(10);
                 $info .= 'Account number: ' . $Debit->getAccount() . chr(10);
                 $Object_OrderInfo = new PlentySoapObject_OrderInfo();
                 $Object_OrderInfo->Info = $info;
                 $Object_OrderInfo->InfoCustomer = 0;
                 $Object_OrderInfo->InfoDate = $this->getOrderTimestamp();
                 $Object_OrderHead->OrderInfos[] = $Object_OrderInfo;
             }
             $PaymentInstances = $Customer->getPaymentInstances();
             if ($PaymentInstances) {
                 foreach ($PaymentInstances as $PaymentInstance) {
                     if ($this->Order->getId() === $PaymentInstance->getOrder()->getId()) {
                         $Object_BankData = new PlentySoapObject_BankData();
                         $Object_BankData->OwnerFirstname = $PaymentInstance->getFirstName();
                         $Object_BankData->OwnerLastname = $PaymentInstance->getLastName();
                         $Object_BankData->BankName = $PaymentInstance->getBankName();
                         $Object_BankData->IBAN = $PaymentInstance->getIban();
                         $Object_BankData->BIC = $PaymentInstance->getBic();
                         $Object_SetBankCreditCardData = new PlentySoapObject_SetBankCreditCardData();
                         $Object_SetBankCreditCardData->CustomerID = $this->PLENTY_customerID;
                         $Object_SetBankCreditCardData->BankData = $Object_BankData;
                         $Request_SetBankCreditCardData = new PlentySoapRequest_SetBankCreditCardData();
                         $Request_SetBankCreditCardData->CustomerData[] = $Object_SetBankCreditCardData;
                         $Response_SetBankCreditCardData = PlentymarketsSoapClient::getInstance()->SetBankCreditCardData($Request_SetBankCreditCardData);
                         if (!$Response_SetBankCreditCardData->Success) {
                             // Set the error end quit
                             $this->setError(self::CODE_ERROR_SOAP);
                             throw new PlentymarketsExportEntityException('The order with the number »' . $this->Order->getNumber() . '« could not be exported');
                         }
                     }
                 }
             }
         }
     }
     if ($this->Order->getInternalComment()) {
         $Object_OrderInfo = new PlentySoapObject_OrderInfo();
         $Object_OrderInfo->Info = $this->Order->getInternalComment();
         $Object_OrderInfo->InfoCustomer = 0;
         $Object_OrderInfo->InfoDate = $this->getOrderTimestamp();
         $Object_OrderHead->OrderInfos[] = $Object_OrderInfo;
     }
     if ($this->Order->getCustomerComment()) {
         $Object_OrderInfo = new PlentySoapObject_OrderInfo();
         $Object_OrderInfo->Info = $this->Order->getCustomerComment();
         $Object_OrderInfo->InfoCustomer = 1;
         $Object_OrderInfo->InfoDate = $this->getOrderTimestamp();
         $Object_OrderHead->OrderInfos[] = $Object_OrderInfo;
     }
     if ($this->Order->getComment()) {
         $Object_OrderInfo = new PlentySoapObject_OrderInfo();
         $Object_OrderInfo->Info = $this->Order->getComment();
         $Object_OrderInfo->InfoCustomer = 1;
         $Object_OrderInfo->InfoDate = $this->getOrderTimestamp();
         $Object_OrderHead->OrderInfos[] = $Object_OrderInfo;
     }
     $Object_Order->OrderItems = array();
     /** @var Shopware\Models\Order\Detail $Item */
     foreach ($this->Order->getDetails() as $Item) {
         $number = $Item->getArticleNumber();
         $itemText = '';
         // Variant
         try {
             $itemId = null;
             try {
                 // get the detail id by the order number
                 $articleDetailID = $VariantResource->getIdFromNumber($Item->getArticleNumber());
             } catch (Exception $E) {
                 $articleDetailID = -1;
             }
             // get the sku from the detail id
             $sku = PlentymarketsMappingController::getItemVariantByShopwareID($articleDetailID);
         } catch (PlentymarketsMappingExceptionNotExistant $E) {
             // Base item
             try {
                 $itemId = PlentymarketsMappingController::getItemByShopwareID($Item->getArticleId());
                 $sku = null;
             } catch (PlentymarketsMappingExceptionNotExistant $E) {
                 $itemId = -2;
                 $sku = null;
                 // Mandatory because there will be no mapping to any item
                 $itemText = $Item->getArticleName();
             }
         }
         //
         if ($itemId > 0 || !empty($sku)) {
             if (PlentymarketsConfig::getInstance()->getOrderItemTextSyncActionID(EXPORT_ORDER_ITEM_TEXT_SYNC) == EXPORT_ORDER_ITEM_TEXT_SYNC) {
                 $itemText = $Item->getArticleName();
             } else {
                 $itemText = null;
             }
         }
         // Coupon
         if ($Item->getMode() == 2) {
             $itemId = -1;
             $rowType = 'Coupon';
         }
         // Additional coupon identifiers für 3rd party plugins
         $couponIdentifiers = PyConf()->get('OrderAdditionalCouponIdentifiers', '');
         $couponIdentifiers = explode('|', $couponIdentifiers);
         if (in_array($number, $couponIdentifiers)) {
             $itemId = -1;
             $rowType = 'Coupon';
         } else {
             // PAYONE fix
             if ($number == 'SHIPPING' && !$Object_OrderHead->ShippingCosts) {
                 $Object_OrderHead->ShippingCosts = $Item->getPrice();
                 continue;
             }
             $discountNumber = Shopware()->Config()->get('discountnumber');
             $surchargeNumber = Shopware()->Config()->get('surchargenumber');
             $paymentSurchargeNumber = Shopware()->Config()->get('paymentsurchargenumber');
             $paymentSurchargeAbsoluteNumber = Shopware()->Config()->get('paymentSurchargeAbsoluteNumber');
             $shippingDiscountNumber = Shopware()->Config()->get('shippingdiscountnumber');
             switch ($number) {
                 case $paymentSurchargeNumber:
                 case $paymentSurchargeAbsoluteNumber:
                     $rowType = 'SurchargeForPaymentMethod';
                     break;
                 case $discountNumber:
                     $rowType = 'Discount';
                     break;
                 case $surchargeNumber:
                     $rowType = 'Surcharge';
                     break;
                 case $shippingDiscountNumber:
                     $rowType = 'SurchargeForShippingMethod';
                     break;
                 default:
                     $rowType = 'Default';
                     break;
             }
         }
         if ($isOrderNet) {
             // Calculate the gross amount (needed by plentymakets even though it is a net sales order)
             $itemPrice = $Item->getPrice() * ((100 + (double) $Item->getTaxRate()) / 100);
         } else {
             $itemPrice = $Item->getPrice();
         }
         $Object_OrderItem = new PlentySoapObject_OrderItem();
         $Object_OrderItem->ExternalOrderItemID = $number;
         $Object_OrderItem->ItemID = $itemId;
         $Object_OrderItem->ReferrerID = $Object_OrderHead->ReferrerID;
         $Object_OrderItem->ItemText = $itemText;
         $Object_OrderItem->Price = $itemPrice;
         $Object_OrderItem->Quantity = $Item->getQuantity();
         $Object_OrderItem->SKU = $sku;
         $Object_OrderItem->VAT = $Item->getTaxRate();
         $Object_OrderItem->RowType = $rowType;
         $Object_Order->OrderItems[] = $Object_OrderItem;
     }
     $Request_AddOrders->Orders[] = $Object_Order;
     // Do the request
     $Response_AddOrders = PlentymarketsSoapClient::getInstance()->AddOrders($Request_AddOrders);
     if (!$Response_AddOrders->Success) {
         // Set the error end quit
         $this->setError(self::CODE_ERROR_SOAP);
         throw new PlentymarketsExportEntityException('The order with the number »' . $this->Order->getNumber() . '« could not be exported', 4010);
     }
     //
     $plentyOrderID = null;
     $plentyOrderStatus = 0.0;
     foreach ($Response_AddOrders->ResponseMessages->item[0]->SuccessMessages->item as $SuccessMessage) {
         switch ($SuccessMessage->Key) {
             case 'OrderID':
                 $plentyOrderID = (int) $SuccessMessage->Value;
                 break;
             case 'Status':
                 $plentyOrderStatus = (double) $SuccessMessage->Value;
                 break;
         }
     }
     if ($plentyOrderID && $plentyOrderStatus) {
         $this->setSuccess($plentyOrderID, $plentyOrderStatus);
     } else {
         // Set the error end quit
         $this->setError(self::CODE_ERROR_SOAP);
         throw new PlentymarketsExportEntityException('The order with the number »' . $this->Order->getNumber() . '« could not be exported (no order id or order status respectively)', 4020);
     }
     $paymentStatusPaid = explode('|', PlentymarketsConfig::getInstance()->getOrderPaidStatusID(12));
     // Directly book the incoming payment
     if ($this->Order->getPaymentStatus() && in_array($this->Order->getPaymentStatus()->getId(), $paymentStatusPaid)) {
         // May throw an exception
         $IncomingPayment = new PlentymarketsExportEntityOrderIncomingPayment($this->Order->getId());
         $IncomingPayment->book();
     }
 }
 /**
  * @throws PlentymarketsExportEntityException
  */
 protected function bookIncommingPayment()
 {
     $paymentStatusPaid = explode('|', PlentymarketsConfig::getInstance()->getOrderPaidStatusID(12));
     // Directly book the incoming payment
     if ($this->Order->getPaymentStatus() && in_array($this->Order->getPaymentStatus()->getId(), $paymentStatusPaid)) {
         // May throw an exception
         $IncomingPayment = new PlentymarketsExportEntityOrderIncomingPayment($this->Order->getId());
         $IncomingPayment->book();
     }
 }