Creates, calculates and returns oxPrice object for basket product.

@param float  $dAmount  Amount
@param array  $aSelList Selection list
@param object $oBasket  User shopping basket object

@return \OxidEsales\Eshop\Core\Price
353144
public function getBasketPrice($dAmount, $aSelList, $oBasket)
    {
        $oUser = $oBasket->getBasketUser();
        $this->setArticleUser($oUser);

        $oBasketPrice = $this->_getPriceObject($oBasket->isCalculationModeNetto());

        // get base price
        $dBasePrice = $this->getBasePrice($dAmount);

        $dBasePrice = $this->_modifySelectListPrice($dBasePrice, $aSelList);
        $dBasePrice = $this->_preparePrice($dBasePrice, $this->getArticleVat(), $oBasket->isCalculationModeNetto());

        // applying select list price

        // setting price
        $oBasketPrice->setPrice($dBasePrice);

        $dVat = \OxidEsales\Eshop\Core\Registry::get(\OxidEsales\Eshop\Application\Model\VatSelector::class)->getBasketItemVat($this, $oBasket);
        $this->_calculatePrice($oBasketPrice, $dVat);

        // returning final price object
        return $oBasketPrice;
    }
1248719
public function getPaymorrowTotalAmount()
    {
        /** @var OxpsPaymorrowOxBasket|oxBasket $this */

        $dTotalPrice = (double) $this->getPrice()->getPrice();

        // Add surcharge price in case it is not yet included in basket
        $oSurchargePrice = $this->_getPaymentMethodSurcharge();

        if ( !empty( $oSurchargePrice ) and is_object( $oSurchargePrice ) ) {
            $dTotalPrice += (double) $oSurchargePrice->getPrice();
        }

        return $dTotalPrice;
    }
1353644
public function walkSelectStatement(SelectStatement $AST)
    {
        $queryComponents = $this->getQueryComponents();
        // Get the root entity and alias from the AST fromClause
        $from      = $AST->fromClause->identificationVariableDeclarations;
        $fromRoot  = reset($from);
        $rootAlias = $fromRoot->rangeVariableDeclaration->aliasIdentificationVariable;
        $rootClass = $queryComponents[$rootAlias]['metadata'];

        $this->validate($AST);
        $property = $rootClass->getProperty($rootClass->getSingleIdentifierFieldName());

        if ($property instanceof AssociationMetadata) {
            throw new RuntimeException(
                'Paginating an entity with foreign key as identifier only works when using the Output Walkers. ' .
                'Call Paginator#setUseOutputWalkers(true) before iterating the paginator.'
            );
        }

        $this->getQuery()->setHint(self::IDENTIFIER_TYPE, $property->getType());

        $pathExpression = new PathExpression(
            PathExpression::TYPE_STATE_FIELD | PathExpression::TYPE_SINGLE_VALUED_ASSOCIATION,
            $rootAlias,
            $property->getName()
        );

        $pathExpression->type = PathExpression::TYPE_STATE_FIELD;

        $AST->selectClause->selectExpressions = [new SelectExpression($pathExpression, '_dctrn_id')];
        $AST->selectClause->isDistinct        = true;

        if (! isset($AST->orderByClause)) {
            return;
        }

        foreach ($AST->orderByClause->orderByItems as $item) {
            if ($item->expression instanceof PathExpression) {
                $AST->selectClause->selectExpressions[] = new SelectExpression(
                    $this->createSelectExpressionItem($item->expression),
                    '_dctrn_ord' . $this->aliasCounter++
                );

                continue;
            }

            if (is_string($item->expression) && isset($queryComponents[$item->expression])) {
                $qComp = $queryComponents[$item->expression];

                if (isset($qComp['resultVariable'])) {
                    $AST->selectClause->selectExpressions[] = new SelectExpression(
                        $qComp['resultVariable'],
                        $item->expression
                    );
                }
            }
        }
    }
941915
protected function _markVouchers($oBasket, $oUser)
    {
        $this->_aVoucherList = $oBasket->getVouchers();

        if (is_array($this->_aVoucherList)) {
            foreach ($this->_aVoucherList as $sVoucherId => $oSimpleVoucher) {
                $oVoucher = oxNew(\OxidEsales\Eshop\Application\Model\Voucher::class);
                $oVoucher->load($sVoucherId);
                $oVoucher->markAsUsed($this->oxorder__oxid->value, $oUser->oxuser__oxid->value, $oSimpleVoucher->dVoucherdiscount);

                $this->_aVoucherList[$sVoucherId] = $oVoucher;
            }
        }
    }
980832
protected function _getCategoryDiscountValue($dPrice)
    {
        $oDiscount = $this->_getSerieDiscount();
        $aBasketItems = $this->_getBasketItems($oDiscount);

        // Basket Item Count and isAdmin check (unable to access property $oOrder->_getOrderBasket()->_blSkipVouchersAvailabilityChecking)
        if (!count($aBasketItems) && !$this->isAdmin()) {
            $oEx = oxNew(\OxidEsales\Eshop\Core\Exception\VoucherException::class);
            $oEx->setMessage('ERROR_MESSAGE_VOUCHER_NOVOUCHER');
            $oEx->setVoucherNr($this->oxvouchers__oxvouchernr->value);
            throw $oEx;
        }

        $oProductPrice = oxNew(\OxidEsales\Eshop\Core\Price::class);
        $oProductTotal = oxNew(\OxidEsales\Eshop\Core\Price::class);

        foreach ($aBasketItems as $aBasketItem) {
            $oProductPrice->setPrice($aBasketItem['price']);
            $oProductPrice->multiply($aBasketItem['amount']);
            $oProductTotal->add($oProductPrice->getBruttoPrice());
        }

        $dProduct = $oProductTotal->getBruttoPrice();
        $dVoucher = $oDiscount->getAbsValue($dProduct);

        return ($dVoucher > $dProduct) ? $dProduct : $dVoucher;
    }
1014122
protected function _getAmountPrice($amount = 1)
    {
        startProfile("_getAmountPrice");

        $dPrice = $this->_getGroupPrice();
        $oAmtPrices = $this->_getAmountPriceList();
        foreach ($oAmtPrices as $oAmPrice) {
            if ($oAmPrice->oxprice2article__oxamount->value <= $amount
                && $amount <= $oAmPrice->oxprice2article__oxamountto->value
                && $dPrice > $oAmPrice->oxprice2article__oxaddabs->value
            ) {
                $dPrice = $oAmPrice->oxprice2article__oxaddabs->value;
            }
        }

        stopProfile("_getAmountPrice");

        return $dPrice;
    }
1317741
public function checkForStock($dAmount, $dArtStockAmount = 0, $selectForUpdate = false)
    {
        $myConfig = \OxidEsales\Eshop\Core\Registry::getConfig();
        if (!$myConfig->getConfigParam('blUseStock')) {
            return true;
        }

        $oDb = \OxidEsales\Eshop\Core\DatabaseProvider::getDb(\OxidEsales\Eshop\Core\DatabaseProvider::FETCH_MODE_ASSOC);
        // fetching DB info as its up-to-date
        $sQ = 'select oxstock, oxstockflag from oxarticles where oxid = ' . $oDb->quote($this->getId());
        $sQ .= $selectForUpdate ? ' FOR UPDATE ' : '';
        $rs = $oDb->select($sQ);

        $iOnStock = 0;
        if ($rs !== false && $rs->count() > 0) {
            $iOnStock = $rs->fields['oxstock'] - $dArtStockAmount;
            $iStockFlag = $rs->fields['oxstockflag'];

            //When using stockflag 1 and 4 with basket reservations enabled but disallowing
            //negative stock values we would allow to reserve more items than are initially available
            //by keeping the stock level not lower than zero. When discarding reservations
            //stock level might differ from original value.
            if (!$myConfig->getConfigParam('blPsBasketReservationEnabled')
                 || ($myConfig->getConfigParam('blPsBasketReservationEnabled')
                     && $myConfig->getConfigParam('blAllowNegativeStock'))
            ) {
                // foreign stock is also always considered as on stock
                if ($iStockFlag == 1 || $iStockFlag == 4) {
                    return true;
                }
            }
            if (!$myConfig->getConfigParam('blAllowUnevenAmounts')) {
                $iOnStock = floor($iOnStock);
            }
        }
        if (\OxidEsales\Eshop\Core\Registry::getConfig()->getConfigParam('blPsBasketReservationEnabled')) {
            $iOnStock += $this->getSession()->getBasketReservations()->getReservedAmount($this->getId());
        }
        if ($iOnStock >= $dAmount) {
            return true;
        } else {
            if ($iOnStock > 0) {
                return $iOnStock;
            } else {
                $oEx = oxNew(\OxidEsales\Eshop\Core\Exception\ArticleInputException::class);
                $oEx->setMessage('ERROR_MESSAGE_ARTICLE_ARTICLE_NOT_BUYABLE');
                \OxidEsales\Eshop\Core\Registry::getUtilsView()->addErrorToDisplay($oEx);

                return false;
            }
        }
    }
1175452
public function getBasePrice($dAmount = 1)
    {
        // override this function if you want e.g. different prices
        // for diff. user groups.

        // Performance
        $myConfig = \OxidEsales\Eshop\Core\Registry::getConfig();
        if (!$myConfig->getConfigParam('bl_perfLoadPrice') || !$this->_blLoadPrice) {
            return;
        }

        // GroupPrice or DB price ajusted by AmountPrice
        $dPrice = $this->_getModifiedAmountPrice($dAmount);

        return $dPrice;
    }
662523
public function isForBasket($oBasket)
    {
        // initial configuration check
        if ($this->oxdiscount__oxamount->value == 0 && $this->oxdiscount__oxprice->value == 0) {
            return false;
        }

        $oSummary = $oBasket->getBasketSummary();
        // amounts check
        if ($this->oxdiscount__oxamount->value && ($oSummary->iArticleCount < $this->oxdiscount__oxamount->value || $oSummary->iArticleCount > $this->oxdiscount__oxamountto->value)) {
            return false;
            // price check
        } elseif ($this->oxdiscount__oxprice->value) {
            $dRate = $oBasket->getBasketCurrency()->rate;
            if ($oSummary->dArticleDiscountablePrice < $this->oxdiscount__oxprice->value * $dRate || $oSummary->dArticleDiscountablePrice > $this->oxdiscount__oxpriceto->value * $dRate) {
                return false;
            }
        }

        // oxobject2discount configuration check
        $oDb = \OxidEsales\Eshop\Core\DatabaseProvider::getDb();
        $sQ = 'select 1 from oxobject2discount where oxdiscountid = ' . $oDb->quote($this->oxdiscount__oxid->value) . ' and oxtype in ("oxarticles", "oxcategories" ) ';

        return !((bool) $oDb->getOne($sQ));
    }
743905
public function createOperation(
        $amount,
        $originAmount,
        DateTime $cycleDate,
        $paymentVoucher,
        $vendor,
        $adjustedOperationsIds = null
    ) {
        //Set hipay id
        $hipayId = $vendor->getHiPayId();

        //Call implementation function
        $operation = $this->operationManager->create($amount, $cycleDate, $paymentVoucher, $vendor->getMiraklId());

        $operation->setHiPayId($hipayId);

        //Sets mandatory values
        $operation->setMiraklId($vendor->getMiraklId());
        $operation->setStatus(new Status(Status::CREATED));
        $operation->setUpdatedAt(new DateTime());
        $operation->setAmount($amount);
        $operation->setOriginAmount($originAmount);
        $operation->setCycleDate($cycleDate);
        $operation->setPaymentVoucher((string)$paymentVoucher);

        // if adjustments were made, save adjusted operations
        if ($adjustedOperationsIds !== null) {
            $operation->setAdjustmentIds(json_encode($adjustedOperationsIds));
        }

        $this->isOperationValid($operation);

        $this->operationsLogs[] = $this->logOperationsManager->create(
            $vendor->getMiraklId(),
            $hipayId,
            (string)$paymentVoucher,
            $amount,
            $originAmount,
            $this->hipay->getBalance($vendor)
        );
        return $operation;
    }
486289
public function isForBasketAmount($oBasket)
    {
        $dAmount = 0;
        $aBasketItems = $oBasket->getContents();
        foreach ($aBasketItems as $oBasketItem) {
            $oBasketArticle = $oBasketItem->getArticle(false);

            if ($this->oxdiscount__oxaddsumtype->value != 'itm') {
                $blForBasketItem = $this->isForBasketItem($oBasketArticle);
            } else {
                $blForBasketItem = $this->isForBundleItem($oBasketArticle);
            }

            if ($blForBasketItem) {
                $dRate = $oBasket->getBasketCurrency()->rate;
                if ($this->oxdiscount__oxprice->value) {
                    if (($oPrice = $oBasketArticle->getPrice())) {
                        $dAmount += ($oPrice->getPrice() * $oBasketItem->getAmount()) / $dRate;
                    }
                } elseif ($this->oxdiscount__oxamount->value) {
                    $dAmount += $oBasketItem->getAmount();
                }
            }
        }

        return $this->isForAmount($dAmount);
    }
354943
protected function _addArticlesToBasket($oBasket, $aArticles)
    {
        // if no order articles
        if (count($aArticles) > 0) {
            //adding order articles to basket
            foreach ($aArticles as $oArticle) {
                $aSel = isset($oArticle->oxorderarticles__oxselvariant) ? $oArticle->oxorderarticles__oxselvariant->value : null;
                $aPersParam = isset($oArticle->oxorderarticles__oxpersparam) ? $oArticle->getPersParams() : null;
                $oBasket->addToBasket(
                    $oArticle->oxorderarticles__oxartid->value,
                    $oArticle->oxorderarticles__oxamount->value,
                    $aSel,
                    $aPersParam
                );
            }
        }
    }
1295267
public function reserveBasket(\OxidEsales\Eshop\Application\Model\Basket $oBasket)
    {
        if (!$this->isAdmin()) {
            $this->_reserveArticles($this->_basketDifference($oBasket));
        }
    }
861630
public function setOrderReferenceDetails($oBasket = null, array $aRequestParameters = array())
    {
        //Set default params
        $aRequestParameters['amazon_order_reference_id'] = $this->getSession()->getVariable('amazonOrderReferenceId');

        if ($oBasket !== null) {
            $oActiveShop = $this->getConfig()->getActiveShop();
            $sShopName = $oActiveShop->getFieldData('oxname');
            $sOxidVersion = $oActiveShop->getFieldData('oxversion');
            $sModuleVersion = bestitAmazonPay4Oxid_init::getCurrentVersion();

            $aRequestParameters = array_merge(
                $aRequestParameters,
                array(
                    'amount' => $oBasket->getPrice()->getBruttoPrice(),
                    'currency_code' => $oBasket->getBasketCurrency()->name,
                    'platform_id' => 'A26EQAZK19E0U2',
                    'store_name' => $sShopName,
                    'custom_information' => "created by best it, OXID eShop v{$sOxidVersion}, v{$sModuleVersion}"
                )
            );
        }

        $this->_addSandboxSimulationParams('setOrderReferenceDetails', $aRequestParameters);

        return $this->_convertResponse($this->_getAmazonClient()->setOrderReferenceDetails($aRequestParameters));
    }
252122
public function validatePayment( $oBasket )
    {
        $mReturn = $this->_OxpsPaymorrowOxOrder_validatePayment_parent( $oBasket );

        if ( is_null( $mReturn ) ) {

            /** @var oxPayment|OxpsPaymorrowOxPayment $oPayment */
            $oPayment = oxNew( 'oxPayment' );
            $sPaymentId = (string) $oBasket->getPaymentId();

            if ( !$oPayment->load( $sPaymentId ) or !$oPayment->isPaymorrowActiveAndMapped() ) {
                return $mReturn;
            }

            /** @var OxpsPaymorrowRequestControllerProxy $pmGateWay */
            $pmGateWay = oxNew( 'OxpsPaymorrowRequestControllerProxy');

            if ( !$pmGateWay->validatePendingOrder() ) {

                return self::ORDER_STATE_INVALIDPAYMENT;
            }
        }

        return $mReturn;
    }
1196781
public function execute($iAmount, $sCurrency)
    {
        //  Ensure we have a driver
        if (empty($this->oDriver)) {
            throw new ChargeRequestException('No driver selected.', 1);
        }

        //  Ensure we have an invoice
        if (empty($this->oInvoice)) {
            throw new ChargeRequestException('No invoice selected.', 1);
        }

        // --------------------------------------------------------------------------

        if (!is_int($iAmount) || $iAmount <= 0) {
            throw new ChargeRequestException('Amount must be a positive integer.', 1);
        }

        // --------------------------------------------------------------------------

        //  @todo: validate currency

        // --------------------------------------------------------------------------

        //  Create a charge against the invoice if one hasn't been specified
        if (empty($this->oPayment)) {

            $iPaymentId = $this->oPaymentModel->create(
                [
                    'driver'       => $this->oDriver->getSlug(),
                    'description'  => $this->getDescription(),
                    'invoice_id'   => $this->oInvoice->id,
                    'currency'     => $sCurrency,
                    'amount'       => $iAmount,
                    'url_continue' => $this->getContinueUrl(),
                    'custom_data'  => $this->oCustomData,
                ]
            );

            if (empty($iPaymentId)) {
                throw new ChargeRequestException('Failed to create new payment.', 1);
            }

            $this->setPayment($iPaymentId);
        }

        $mFields = $this->oDriver->getPaymentFields();

        if (!empty($mFields) && $mFields == 'CARD') {
            $oDriverData = $this->oCard;
        } else {
            $oDriverData = $this->oCustomField;
        }

        //  Return URL for drivers which implement a redirect flow
        $sSuccessUrl = site_url('invoice/payment/' . $this->oPayment->id . '/' . $this->oPayment->token . '/complete');
        $sFailUrl    = site_url('invoice/invoice/' . $this->oInvoice->ref . '/' . $this->oInvoice->token . '/pay');

        //  Execute the charge
        $oChargeResponse = $this->oDriver->charge(
            $iAmount,
            $sCurrency,
            $oDriverData,
            $this->oCustomData,
            $this->getDescription(),
            $this->oPayment,
            $this->oInvoice,
            $sSuccessUrl,
            $sFailUrl,
            $this->getContinueUrl()
        );

        //  Validate driver response
        if (empty($oChargeResponse)) {
            throw new ChargeRequestException('Response from driver was empty.', 1);
        }

        if (!($oChargeResponse instanceof ChargeResponse)) {
            throw new ChargeRequestException(
                'Response from driver must be an instance of \Nails\Invoice\Factory\ChargeResponse.',
                1
            );
        }

        //  Handle the response
        if ($oChargeResponse->isRedirect() && $this->isAutoRedirect()) {

            /**
             * Driver uses a redirect flow, determine whether we can use a basic header redirect,
             * or if we need to POST some data to the endpoint
             */

            $sRedirectUrl = $oChargeResponse->getRedirectUrl();
            $aPostData    = $oChargeResponse->getRedirectPostData();

            if (empty($aPostData)) {

                redirect($sRedirectUrl);

            } else {

                $oCi = get_instance();
                echo $oCi->load->view('structure/header/blank', getControllerData(), true);
                echo $oCi->load->view(
                    'invoice/pay/post',
                    [
                        'redirectUrl' => $sRedirectUrl,
                        'postFields'  => $aPostData,
                    ],
                    true
                );
                echo $oCi->load->view('structure/footer/blank', getControllerData(), true);
                exit();
            }

        } elseif ($oChargeResponse->isProcessing()) {

            //  Driver has started processing the charge, but it hasn't been confirmed yet
            $this->setPaymentProcessing(
                $oChargeResponse->getTxnId(),
                $oChargeResponse->getFee()
            );

        } elseif ($oChargeResponse->isComplete()) {

            //  Driver has confirmed that payment has been taken.
            $this->setPaymentComplete(
                $oChargeResponse->getTxnId(),
                $oChargeResponse->getFee()
            );

        } elseif ($oChargeResponse->isFailed()) {

            //  Update the payment
            $sPaymentClass = get_class($this->oPaymentModel);
            $bResult       = $this->oPaymentModel->update(
                $this->oPayment->id,
                [
                    'status'    => $sPaymentClass::STATUS_FAILED,
                    'fail_msg'  => $oChargeResponse->getError()->msg,
                    'fail_code' => $oChargeResponse->getError()->code,
                ]
            );

            if (empty($bResult)) {
                throw new ChargeRequestException('Failed to update existing payment.', 1);
            }
        }

        //  Set the success and fail URLs
        $oChargeResponse->setSuccessUrl($sSuccessUrl);
        $oChargeResponse->setFailUrl($sFailUrl);
        $oChargeResponse->setContinueUrl($this->getContinueUrl());

        //  Lock the response so it cannot be altered
        $oChargeResponse->lock();

        return $oChargeResponse;
    }
424842
public function calculate($oBasket)
    {
        //getting basket price with applied discounts and vouchers
        $dPrice = $this->getPaymentValue($this->getBaseBasketPriceForPaymentCostCalc($oBasket));

        if (!$dPrice) {
            $dPrice = 0;
        }
        // calculating total price
        $oPrice = oxNew(\OxidEsales\Eshop\Core\Price::class);
        $oPrice->setNettoMode($this->_blPaymentVatOnTop);

        $oPrice->setPrice($dPrice);
        if ($dPrice > 0) {
            $oPrice->setVat($oBasket->getAdditionalServicesVatPercent());
        }

        $this->_oPrice = $oPrice;
    }