<?php

/**
 * Class d3_oxorder_heidelpay
 */
class d3_oxorder_heidelpay extends d3_oxorder_heidelpay_parent
{

    /**
     * {@inheritdoc}
     */
    protected function _setOrderStatus($sStatus)
    {
        if (false == d3_cfg_mod::get('d3heidelpay')->isActive()) {
            return parent::_setOrderStatus($sStatus);
        }

        $oDB = oxDb::getDb();

        $sOldStatus = $oDB->getOne('select oxtransstatus from oxorder where oxid="' . $this->getId() . '"');
        $sPaid      = $oDB->getOne('select oxpaid from oxorder where oxid="' . $this->getId() . '"');
        $sPaymentId = $this->getFieldData('oxpaymenttype');

        /** @var d3_d3heidelpay_models_settings_heidelpay $oSettings */
        $oSettings = oxNew('d3_d3heidelpay_models_settings_heidelpay', d3_cfg_mod::get('d3heidelpay'));

        /** @var oxPayment $oPayment */
        $oPayment = oxNew('oxPayment');
        $oPayment->load($sPaymentId);

        if (false == $oSettings->isAssignedToHeidelPayment($oPayment)) {
            return parent::_setOrderStatus($sStatus);
        }

        $blIsPrepayment = $oSettings->getPayment($oPayment) instanceof d3_d3heidelpay_models_payment_prepayment;
        $blIsWaiting    = $sOldStatus == 'WAITING' && $sPaid == '0000-00-00 00:00:00';
        if ($blIsPrepayment && $blIsWaiting) {
            $sStatus = "WAITING";
        }

        return parent::_setOrderStatus($sStatus);
    }

    /**
     * Returns bank transfer data if available
     *
     * @return stdClass|null
     */
    public function getHeidelpayBankTransferData()
    {
        if (false == d3_cfg_mod::get('d3heidelpay')->isActive()) {
            return null;
        }

        /** @var d3hpprepaymentdata $oPrePaymentData */
        $oPrePaymentData = oxNew("d3hpprepaymentdata");

        /** @var d3_d3heidelpay_models_settings_heidelpay $oSettings */
        /** @var oxPayment $oPayment */
        $oSettings = oxNew('d3_d3heidelpay_models_settings_heidelpay', d3_cfg_mod::get('d3heidelpay'));
        $oPayment  = oxNew('oxPayment');
        $oPayment->load($this->getFieldData('oxpaymenttype'));
        if (false == $oSettings->isAssignedToHeidelPayment($oPayment)) {
            return null;
        }

        $oHeidelpayment = $oSettings->getPayment($oPayment);

        if ($oHeidelpayment instanceof d3_d3heidelpay_models_payment_prepayment || $oHeidelpayment instanceof d3_d3heidelpay_models_payment_billsafe) {
            return $oPrePaymentData->getBankTransferData($this);
        }

        return null;
    }

    /**
     * @param oxBasket $oBasket
     * @param oxUser   $oUser
     *
     * @return int|null
     */
    public function d3CreateTemporaryOrder(oxBasket $oBasket, oxUser $oUser)
    {
        /* D3 START disabled - 03.03.2016 - KH <!--
        We can't use the session challenge for this break up.
        We need every "hotfix"- payment->toOrder a new order

        $sGetChallenge = oxRegistry::getSession()->getVariable('sess_challenge');
        if ($this->_checkOrderExist($sGetChallenge)) {
            oxRegistry::getUtils()->logger('BLOCKER');

            // we might use this later, this means that somebody klicked like mad on order button
            return self::ORDER_STATE_ORDEREXISTS;
        }

        // if not recalculating order, use sess_challenge id, else leave old order id

        // use this ID
        $this->setId($sGetChallenge);
        --> */

        $this->setId(oxRegistry::get('oxUtilsObject')->generateUID());

        // validating various order/basket parameters before finalizing
        $iOrderState = $this->validateOrder($oBasket, $oUser);
        if ($iOrderState) {
            return $iOrderState;
        }

        /* D3 START added - HotFix - 08.03.2016 - KH */
        if (false == d3_cfg_mod::get('d3heidelpay')->getValue('blD3HpHFSetZeroOrderNumber') && false == $this->oxorder__oxordernr->value) {
            $this->_setNumber();
        }
        /* D3 END   added - HotFix - 08.03.2016 - KH */

        // copies user info
        $this->_setUser($oUser);

        // copies basket info
        $this->_loadFromBasket($oBasket);

        // payment information
        $this->_setPayment($oBasket->getPaymentId());

        // set folder information, if order is new
        // #M575 in recalculating order case folder must be the same as it was

        $this->_setFolder();

        //#4005: Order creation time is not updated when order processing is complete
        $this->_updateOrderDate();

        // marking as not finished
        $this->_setOrderStatus('PENDING');

        /* D3 START added - #4998 - 29.04.2016 - KH */
        $aVouchers = $oBasket->getVouchers();
        if (count($aVouchers)) {
            $aVoucherIds = array();
            $moduleConfig = d3_cfg_mod::get('d3heidelpay');
            $pendingLimit = $moduleConfig->getValue('sD3HpHFOrderPendingTime');
            foreach ($aVouchers as $sVoucherId => $oStdVoucher) {
                $oVoucher = oxNew('oxvoucher');
                if ($oVoucher->load($oStdVoucher->sVoucherId)) {
                    $aVoucherIds[$oStdVoucher->sVoucherId] = $oStdVoucher->sVoucherId;
                    $oVoucher->assign(array('oxreserved' => time() + $pendingLimit * 3600));
                    $oVoucher->save();
                }
            }
            $this->assign(array('d3heidelpayvouchers' => implode('|', $aVoucherIds)));
        }
        /* D3 END   added - #4998 - 29.04.2016 - KH */

        //saving all order data to DB
        $this->save();

        /* D3 START added - Hotfix - 10.03.2016 - KH */
        // set order ID for thankyou
        $oBasket->setOrderId($this->getId());
        oxRegistry::getSession()->setVariable('sess_challenge', $this->getId());
        /* D3 END   added - Hotfix - 10.03.2016 - KH */

        return;
    }

    /**
     * @param oxBasket $oBasket
     * @param oxUser                $oUser
     *
     * @return bool|int|void
     */
    public function d3FinalizeTemporaryOrder(oxBasket $oBasket, oxUser $oUser)
    {
        $oUserPayment = $this->_setPayment($oBasket->getPaymentId());
        // executing payment (on failure deletes order and returns error code)
        // in case when recalculating order, payment execution is skipped

        $blRet = $this->_executePayment($oBasket, $oUserPayment);
        if ($blRet !== true) {
            return $blRet;
        }

        if (!$this->oxorder__oxordernr->value) {
            $this->_setNumber();
        } else {
            oxNew('oxCounter')->update($this->_getCounterIdent(), $this->oxorder__oxordernr->value);
        }

        // executing TS protection
        if ($oBasket->getTsProductId()) {
            $blRet = $this->_executeTsProtection($oBasket);
            if ($blRet !== true) {
                return $blRet;
            }
        }

        // deleting remark info only when order is finished
        oxRegistry::getSession()->deleteVariable('ordrem');
        oxRegistry::getSession()->deleteVariable('stsprotection');

        //#4005: Order creation time is not updated when order processing is complete
        //$this->_updateOrderDate();

        // updating order trans status (success status)
        $this->_setOrderStatus('OK');

        // store orderid
        $oBasket->setOrderId($this->getId());

        // updating wish lists
        $this->_updateWishlist($oBasket->getContents(), $oUser);

        // updating users notice list
        $this->_updateNoticeList($oBasket->getContents(), $oUser);

        // marking vouchers as used and sets them to $this->_aVoucherList (will be used in order email)
        // skipping this action in case of order recalculation
        $this->_markVouchers($oBasket, $oUser);

        // send order by email to shop owner and current user
        // skipping this action in case of order recalculation
        $iRet = $this->_sendOrderByEmail($oUser, $oBasket, $oUserPayment);

        return $iRet;
    }

    /**
     * @return oxBasket
     * @throws oxArticleException
     * @throws oxArticleInputException
     * @throws oxNoArticleException
     */
    public function d3GetOrderBasket()
    {
        $this->reloadDelivery(false);
        $this->reloadDiscount(false);
        $oBasket = $this->_getOrderBasket(false);

        foreach( $this->getOrderArticles() as $oOrderArticle ) {
            $oBasket->addOrderArticleToBasket( $oOrderArticle );
        }

        /* D3 START added - #4998 - 29.04.2016 - KH */
        $aVouchers = explode('|', $this->getFieldData('d3heidelpayvouchers'));
        if (count($aVouchers)) {
            $oBasket->setSkipVouchersChecking(true);
            foreach ($aVouchers as $sVoucherId) {
                $oVoucher = oxNew('oxvoucher');
                if ($oVoucher->load($sVoucherId)) {
                    $oBasket->addVoucher($sVoucherId);
                }
            }
        }
        /* D3 END   added - #4998 - 29.04.2016 - KH */

        //$oBasket->setVoucherDiscount($this->oxorder__oxvoucherdiscount->value);
        $oBasket->calculateBasket();

        foreach ($oBasket->getContents() as $oBasketItem) {
            /** @var oxBasketItem $oBasketItem */
            $oArticle = oxnew('oxarticle');
            $oArticle->load($oBasketItem->getArticle()->getProductId());
            $oBasketItem->d3SetArticle($oArticle);
        }

        return $oBasket;
    }
}
