Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
55.17% covered (warning)
55.17%
16 / 29
CRAP
70.59% covered (success)
70.59%
72 / 102
Senh\Lib\Prices\PricesHelper
0.00% covered (danger)
0.00%
0 / 1
55.17% covered (warning)
55.17%
16 / 29
218.12
70.59% covered (success)
70.59%
72 / 102
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 getMinimalPrice1
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setMinimalPrice1
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getMinimalPriceN
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setMinimalPriceN
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getInternalProduct
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
2 / 2
 getPrice1
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
6 / 6
 getCommission1
0.00% covered (danger)
0.00%
0 / 1
8.30
83.33% covered (success)
83.33%
10 / 12
 getReduction1
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 getFormattedPrice1
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getCurrentVariantPrice1
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getCurrentVariantFormattedPrice1
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getCurrentVariantCommission1
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getPriceN
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
6 / 6
 getCommissionN
0.00% covered (danger)
0.00%
0 / 1
8.30
83.33% covered (success)
83.33%
10 / 12
 getReductionN
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 getFormattedPriceN
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getCurrentVariantPriceN
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getCurrentVariantFormattedPriceN
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 getCurrentVariantCommissionN
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 2
 formatPrice
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 4
 getSessionSaleIdByProductId
0.00% covered (danger)
0.00%
0 / 1
7.77
75.00% covered (success)
75.00%
9 / 12
 getProductIdBySessionSaleId
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 5
 getSessionSale
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
4 / 4
 getSessionSaleId
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 1
 getSessionSaleProperty
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
2 / 2
 getSessionSaleVariant
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 setSessionSaleProperty
0.00% covered (danger)
0.00%
0 / 1
5.07
85.71% covered (success)
85.71%
6 / 7
 getVariantForProductId
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
1 / 1
<?php
namespace Senh\Lib\Prices;
use Senh\Lib\Managers\InternalProductManager;
use Senh\Lib\Models\InternalProductModel;
use Senh\Lib\Prices\KortingFactory;
class PricesHelper
{
    /**
     * @var KortingFactory
     */
    protected $kortingFactory;
    /**
     * @var InternalProductManager;
     */
    protected $internalProductManager;
    /**
     * @var InternalProductModel
     */
    protected $internalProduct;
    /**
     * @var int
     */
    protected $minimalPrice1 = 200;
    /**
     * @var int
     */
    protected $minimalPriceN = 200;
    /**
     * PricesHelper constructor.
     * @param KortingFactory $kortingFactory
     * @param InternalProductManager $internalProductManager
     */
    public function __construct(KortingFactory $kortingFactory, InternalProductManager $internalProductManager)
    {
        $this->kortingFactory = $kortingFactory;
        $this->internalProductManager = $internalProductManager;
    }
    /**
     * @return int
     */
    public function getMinimalPrice1()
    {
        return $this->minimalPrice1;
    }
    /**
     * @param int $minimalPrice1
     */
    public function setMinimalPrice1($minimalPrice1)
    {
        $this->minimalPrice1 = $minimalPrice1;
    }
    /**
     * @return int
     */
    public function getMinimalPriceN()
    {
        return $this->minimalPriceN;
    }
    /**
     * @param int $minimalPriceN
     */
    public function setMinimalPriceN($minimalPriceN)
    {
        $this->minimalPriceN = $minimalPriceN;
    }
    /**
     * Gets internal product, $productId is dominant, if saleId is set, productId will be retrieved from session
     * @param null|string $saleId
     * @param null|int $productId
     * @return mixed
     */
    protected function getInternalProduct($saleId = null, $productId = null)
    {
        $productId ?: $this->getProductIdBySessionSaleId($saleId);
        return $this->internalProductManager->getSingle($productId);
    }
    /**
     * @param $productId
     * @param null $variant
     * @param bool $withReduction
     * @return int|null
     * @throws \Exception
     */
    public function getPrice1($productId, $variant = null, $withReduction = true)
    {
        $internalProduct = $this->getInternalProduct(null, $productId);
        if (!$internalProduct) {
            return (int)$this->getSessionSaleProperty('price', null, $productId);
        }
        $price = $internalProduct->getPrice1($variant);
        $reducedPrice = !$withReduction ? $price : $price - $this->getReduction1($productId, $variant);
        return $reducedPrice < $this->getMinimalPrice1() ? $this->getMinimalPrice1() : $reducedPrice;
    }
    /**
     * @param $productId
     * @param $variant
     * @return int
     * @throws \Exception
     */
    public function getCommission1($productId, $variant = null)
    {
        // blacklisted
        if ($this->getSessionSaleProperty('is_blacklisted_affiliate', null, $productId) === true) {
            return 0;
        }
        // specific affiliate overwrite
        if (
            $this->getSessionSaleProperty('aff_comm_onetime_overwrite', null, $productId) &&
            (
                !$this->kortingFactory->hasModel() ||
                !$this->kortingFactory->getModel()->hasAllowedProductId($productId)
            )
        ) {
            return $this->getSessionSaleProperty('aff_comm_onetime_overwrite', null, $productId);
        }
        $internalProduct = $this->getInternalProduct(null, $productId);
        if (!$internalProduct) {
            return $this->getSessionSaleProperty('aff_comm_onetime', null, $productId);
        }
        if ($this->kortingFactory->hasModelWithAllowedProductId($productId) && $this->kortingFactory->getModel()->getCommission1($productId)) {
            return $this->kortingFactory->getModel()->getCommission1($productId);
        }
        return $internalProduct->getCommission1($variant);
    }
    /**
     * @param $productId
     * @param $variant
     * @return int
     */
    public function getReduction1($productId, $variant = null)
    {
        return $this->kortingFactory->hasModelWithAllowedProductId($productId) ? $this->kortingFactory->getModel()->getKorting1($productId) : 0;
    }
    /**
     * @param $productId
     * @param null $variant
     * @param bool $withReduction
     * @return string
     * @throws \Exception
     */
    public function getFormattedPrice1($productId, $variant = null, $withReduction = true)
    {
        $price = $this->getPrice1($productId, $variant, $withReduction);
        return $this->formatPrice($price);
    }
    public function getCurrentVariantPrice1($productId, $withReduction = true)
    {
        $variant = $this->getSessionSaleVariant(null, $productId);
        return $this->getPrice1($productId, $variant, $withReduction);
    }
    /**
     * @param $productId
     * @param bool $withReduction
     * @return string
     * @throws \Exception
     */
    public function getCurrentVariantFormattedPrice1($productId, $withReduction = true)
    {
        $price = $this->getCurrentVariantPrice1($productId, $withReduction);
        return $this->formatPrice($price);
    }
    public function getCurrentVariantCommission1($productId, $withReduction = true)
    {
        $variant = $this->getSessionSaleVariant(null, $productId);
        return $this->getCommission1($productId, $variant, $withReduction);
    }
    /**
     * @param $productId
     * @param null $variant
     * @param bool $withReduction
     * @return int|null
     * @throws \Exception
     */
    public function getPriceN($productId, $variant = null, $withReduction = true)
    {
        $internalProduct = $this->getInternalProduct(null, $productId);
        if (!$internalProduct) {
            return (int)$this->getSessionSaleProperty('price_memb', null, $productId);
        }
        $price = $internalProduct->getPriceN($variant);
        $reducedPrice = !$withReduction ? $price : $price - $this->getReductionN($productId, $variant);
        return $reducedPrice < $this->getMinimalPriceN() ? $this->getMinimalPriceN() : $reducedPrice;
    }
    /**
     * @param $productId
     * @param $variant
     * @return int
     * @throws \Exception
     */
    public function getCommissionN($productId, $variant = null)
    {
        // blacklisted
        if ($this->getSessionSaleProperty('is_blacklisted_affiliate', null, $productId) === true) {
            return 0;
        }
        // specific affiliate overwrite
        if (
            $this->getSessionSaleProperty('aff_comm_memb_overwrite', null, $productId) &&
            (
                !$this->kortingFactory->hasModel() ||
                !$this->kortingFactory->getModel()->hasAllowedProductId($productId)
            )
        ) {
            return $this->getSessionSaleProperty('aff_comm_memb_overwrite', null, $productId);
        }
        $internalProduct = $this->getInternalProduct(null, $productId);
        if (!$internalProduct) {
            return $this->getSessionSaleProperty('aff_comm_memb', null, $productId);
        }
        if ($this->kortingFactory->hasModelWithAllowedProductId($productId) && $this->kortingFactory->getModel()->getCommissionN($productId)) {
            return $this->kortingFactory->getModel()->getCommissionN($productId);
        }
        return $internalProduct->getCommissionN($variant);
    }
    /**
     * @param $productId
     * @param $variant
     * @return int
     */
    public function getReductionN($productId, $variant = null)
    {
        return $this->kortingFactory->hasModelWithAllowedProductId($productId) ? $this->kortingFactory->getModel()->getKortingN($productId) : 0;
    }
    /**
     * @param $productId
     * @param null $variant
     * @param bool $withReduction
     * @return string
     * @throws \Exception
     */
    public function getFormattedPriceN($productId, $variant = null, $withReduction = true)
    {
        $price = $this->getPriceN($productId, $variant, $withReduction);
        return $this->formatPrice($price);
    }
    public function getCurrentVariantPriceN($productId, $withReduction = true)
    {
        $variant = $this->getSessionSaleVariant(null, $productId);
        return $this->getPriceN($productId, $variant, $withReduction);
    }
    /**
     * @param $productId
     * @param bool $withReduction
     * @return string
     * @throws \Exception
     */
    public function getCurrentVariantFormattedPriceN($productId, $withReduction = true)
    {
        $price = $this->getCurrentVariantPriceN($productId, $withReduction);
        return $this->formatPrice($price);
    }
    public function getCurrentVariantCommissionN($productId, $withReduction = true)
    {
        $variant = $this->getSessionSaleVariant(null, $productId);
        return $this->getCommissionN($productId, $variant, $withReduction);
    }
    /**
     * @param $priceCents
     * @return string
     */
    public function formatPrice($priceCents)
    {
        $price = $priceCents / 100;
        if (abs($price - round($price)) < 0.001) {
            return round($price).',-';
        }
        return number_format($price, 2, ',', '.');
    }
    /**
     * @param $productId
     * @return null|string
     */
    public function getSessionSaleIdByProductId($productId)
    {
        $matches = [];
        $sessionVariant = $this->getVariantForProductId($productId); // more precision match (in case one productId exists in multiple session sales)
        foreach ($_SESSION['sale'] as $saleId => $sale) {
            $saleProductId = $sale['productID'];
            $saleVariant = isset($sale['variant']) ? $sale['variant'] : null;
            if ($productId == $saleProductId) {
                if ($saleVariant == $sessionVariant) {
                    return $saleId;
                }
                $matches[$saleVariant] = $saleId;
            }
        }
        if (!$matches) {
            return null;
        }
        return isset($matches['default']) ? $matches['default'] : reset($matches);
    }
    /**
     * @param $saleId
     * @return null|string
     */
    public function getProductIdBySessionSaleId($saleId)
    {
        $saleId = $saleId ?: $this->getSessionSaleId();
        foreach ($_SESSION['sale'] as $saleId => $sale) {
            if ($sale['sale_id'] == $saleId) {
                return $productId;
            }
        }
        return null;
    }
    /**
     * Get sale by saleId or productId. Order of importance: saleId, productId, the session's saleId
     * @param null $saleId
     * @param null $productId
     * @return null|array
     */
    public function getSessionSale($saleId = null, $productId = null)
    {
        if (!$saleId && $productId) {
            $saleId = $this->getSessionSaleIdByProductId($productId);
        }
        $saleId = $saleId ?: $this->getSessionSaleId();
        return isset($_SESSION['sale'][$saleId]) ? $_SESSION['sale'][$saleId] : null;
    }
    /**
     * @return null|string
     */
    public function getSessionSaleId()
    {
        return isset($_SESSION['sale_id']) ? $_SESSION['sale_id'] : null;
    }
    /**
     * @param $property
     * @param $saleId
     * @param $productId
     * @return mixed|null
     */
    public function getSessionSaleProperty($property, $saleId = null, $productId = null)
    {
        $sale = $this->getSessionSale($saleId, $productId);
        return $sale && isset($sale[$property]) ? $sale[$property] : null;
    }
    /**
     * @param null $saleId
     * @return mixed|null
     */
    public function getSessionSaleVariant($saleId = null, $productId = null)
    {
        return $this->getSessionSaleProperty('variant', $saleId, $productId);
    }
    /**
     * @param $property
     * @param $value
     * @param $saleId
     * @param $productId
     * @return bool: success (false in case of productId that does not match a saleId)
     */
    public function setSessionSaleProperty($property, $value, $saleId = null, $productId = null)
    {
        if (!$saleId && $productId) {
            $saleId = $this->getSessionSaleIdByProductId($productId);
        }
        $saleId = $saleId ?: $this->getSessionSaleId();
        if (!$saleId) {
            return false;
        }
        $_SESSION['sale'][$saleId][$property] = $value;
        return true;
    }
    public function getVariantForProductId($productId)
    {
        return isset($_SESSION['variants']) && isset($_SESSION['variants'][$productId]) ? $_SESSION['variants'][$productId] : null;
    }
}