Model/Installments/BuilderByBrand.php
<?php
/**
* Class Builder
*
* @author MundiPagg Embeddables Team <embeddables@mundipagg.com>
* @copyright 2017 MundiPagg (http://www.mundipagg.com)
* @license http://www.mundipagg.com Copyright
*
* @link http://www.mundipagg.com
*/
namespace MundiPagg\MundiPagg\Model\Installments;
use Magento\Framework\Api\AbstractSimpleObjectBuilder;
use Magento\Framework\Api\ObjectFactory;
use MundiPagg\MundiPagg\Api\Data\InstallmentInterface;
use MundiPagg\MundiPagg\Api\Data\InstallmentInterfaceFactory;
use MundiPagg\MundiPagg\Model\Installments\Config\ConfigByBrandInterface;
use Magento\Checkout\Model\Session;
class BuilderByBrand extends AbstractSimpleObjectBuilder
{
protected $config;
protected $installmentFactory;
protected $session;
protected $grandTotal;
protected $installmentsNumber;
/**
* @param InstallmentInterfaceFactory $installmentFactory
* @param ConfigByBrandInterface $config
* @param Session $session
* @param ObjectFactory $objectFactory
*/
public function __construct(
InstallmentInterfaceFactory $installmentFactory,
ConfigByBrandInterface $config,
Session $session,
ObjectFactory $objectFactory
)
{
parent::__construct($objectFactory);
$this->setInstallmentFactory($installmentFactory);
$this->setConfig($config);
$this->setSession($session);
}
/**
* @return $this
*/
public function create()
{
$installmentsActive = $this->getConfig()->isActive();
if($installmentsActive){
if($this->getConfig()->getInstallmentUnique()){
$this->session->setCardBrand('');
}
}else{
$this->session->setCardBrand('');
$this->addInstallment(1);
return $this;
}
$installmentItems = $this->getInstallmentsNumber();
if($installmentItems > 1){
for ($i = 1; $i < $installmentItems; $i++) {
if (!$this->canProcessInstallment($i)) {
break;
}
$this->addInstallment($i);
}
}else{
$this->addInstallment(1);
}
return $this;
}
/**
* @param int $qty
* @return $this
*/
protected function addInstallment($qty)
{
$installmentAmount = $this->getGrandTotal() / $qty;
$interest = false;
$interestLabel = __('without interest');
$installment = $this->getNewInstallmentInstance();
$interestRateTotalSend = 0;
if ($this->getConfig()->isInterestByIssuer() && ($qty > $this->getConfig()->getinstallmentsMaxWithoutInterest())) {
$interestRate = $this->calcInterestRate($qty);
$installmentAmount = $this->calcPriceWithInterest($qty, $interestRate);
$interest = true;
$interestRateTotal = $interestRate * 100;
$labelInterestRate = ' ' . $interestRateTotal . '% a.m. ';
$interestRateTotalSend = ($this->calcPriceWithInterestNoFormated($qty, $interestRate) * $qty) - $this->getGrandTotal();
$interestLabel = __('with interest') . $labelInterestRate;
}
$grandTotal = $installmentAmount * $qty;
$installment->setQty($qty);
$installment->setPrice($installmentAmount);
$installment->setHasInterest($interest);
$installment->setGrandTotal($grandTotal);
$installment->setInterest($interestRateTotalSend);
$installment->setLabel($installment->getQty() . 'x ' . $installment->getPrice(true, false) . ' ' . $interestLabel . ' (Total ' .$installment->getGrandTotal(true, false) . ') ' );
$this->data[] = $installment;
return $this;
}
/**
* @param int $qty
* @return string
*/
protected function calcPriceWithInterest($qty, $interestRate)
{
$price = ( $this->getGrandTotal() * (1 + $interestRate) ) / $qty ;
return sprintf("%01.2f", $price);
}
/**
* @param int $qty
* @return string
*/
protected function calcPriceWithInterestNoFormated($qty, $interestRate)
{
$price = ( $this->getGrandTotal() * (1 + $interestRate) ) / $qty ;
return $price;
}
/**
* @param int $qty
* @return int
*/
protected function calcInterestRate($qty)
{
$interestRate = $this->getConfig()->getInterestRate();
$installmentsMaxWithoutInterest = $this->getConfig()->getinstallmentsMaxWithoutInterest();
$diff = $qty - $installmentsMaxWithoutInterest;
if ($diff > 1) {
$interestRateIncremental = $this->getConfig()->getInterestRateIncremental();
$interestRate = ( ($diff - 1) * $interestRateIncremental) + $interestRate;
}
return $interestRate;
}
/**
* @return InstallmentInterface
*/
protected function getNewInstallmentInstance()
{
return $this->getInstallmentFactory()->create();
}
/**
* @param int $i
* @return bool
*/
protected function canProcessInstallment($i)
{
$installmentAmount = $this->getGrandTotal() / $i;
return !($i > 1 && $installmentAmount < $this->getConfig()->getInstallmentMinAmount());
}
/**
* @return int
*/
protected function getInstallmentsNumber()
{
if (! $this->installmentsNumber) {
$this->installmentsNumber = (int) $this->getConfig()->getInstallmentsNumber();
$this->installmentsNumber++;
}
return $this->installmentsNumber;
}
/**
* @return float
*/
protected function getGrandTotal()
{
if (!$this->grandTotal) {
$this->grandTotal = $this->getSession()->getQuote()->getGrandTotal();
}
return $this->grandTotal;
}
/**
* @return ConfigByBrandInterface
*/
protected function getConfig()
{
return $this->config;
}
/**
* @param ConfigByBrandInterface $config
* @return $this
*/
protected function setConfig(ConfigByBrandInterface $config)
{
$this->config = $config;
return $this;
}
/**
* @return InstallmentInterfaceFactory
*/
protected function getInstallmentFactory()
{
return $this->installmentFactory;
}
/**
* @param InstallmentInterfaceFactory $installmentFactory
* @return $this
*/
protected function setInstallmentFactory(InstallmentInterfaceFactory $installmentFactory)
{
$this->installmentFactory = $installmentFactory;
return $this;
}
/**
* @return Session
*/
public function getSession()
{
return $this->session;
}
/**
* @param Session $session
* @return $this
*/
protected function setSession(Session $session)
{
$this->session = $session;
return $this;
}
}