251 lines
7.9 KiB
PHP
251 lines
7.9 KiB
PHP
<?php
|
|
|
|
namespace KupShop\FeedsBundle\Wrapper;
|
|
|
|
use KupShop\KupShopBundle\Context\CountryContext;
|
|
use KupShop\KupShopBundle\Util\Delivery\RestrictionUtils;
|
|
use Product;
|
|
|
|
class DeliveryWrapper extends BaseWrapper
|
|
{
|
|
protected static $objectType = \Product::class;
|
|
|
|
/** @var \Product */
|
|
protected $object;
|
|
|
|
/**
|
|
* @var CountryContext
|
|
*/
|
|
private $countryContext;
|
|
|
|
/** @var \KupShop\FeedsBundle\Utils\DeliveryWrapper[] */
|
|
private $allDeliveryWrappers;
|
|
|
|
/** @var \KupShop\FeedsBundle\Utils\DeliveryWrapper[] */
|
|
private $deliveryWrappers;
|
|
|
|
/** @var \KupShop\FeedsBundle\Utils\DeliveryWrapper[] */
|
|
private $deliveryWrappersIncludingInPerson;
|
|
|
|
private $deliveryTimes;
|
|
|
|
/** @var RestrictionUtils */
|
|
protected $restrictionUtils;
|
|
|
|
public function __construct(CountryContext $countryContext)
|
|
{
|
|
$this->countryContext = $countryContext;
|
|
}
|
|
|
|
/**
|
|
* @required
|
|
*
|
|
* @private
|
|
*/
|
|
public function setRestrictionUtils(RestrictionUtils $restrictionUtils): void
|
|
{
|
|
$this->restrictionUtils = $restrictionUtils;
|
|
$this->restrictionUtils->setType('delivery');
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function getRestrictionUtils(): RestrictionUtils
|
|
{
|
|
return $this->restrictionUtils;
|
|
}
|
|
|
|
/** Datum doručení */
|
|
public function field_deliveryDate()
|
|
{
|
|
return $this->getDeliveryTimes()['delivery']['date'];
|
|
}
|
|
|
|
/** Datum vyzvednutí */
|
|
public function field_pickupDate()
|
|
{
|
|
return $this->getDeliveryTimes()['pickup']['date'];
|
|
}
|
|
|
|
/** Datum do kdy se musí objednat, aby se odeslalo ještě dnes */
|
|
public function field_deliveryDeadline()
|
|
{
|
|
return $this->getDeliveryTimes()['delivery']['deadline'];
|
|
}
|
|
|
|
/** Datum do kdy se musí objednat, aby se připravilo ještě dnes */
|
|
public function field_pickupDeadline()
|
|
{
|
|
return $this->getDeliveryTimes()['pickup']['deadline'];
|
|
}
|
|
|
|
protected function getDeliveryTimes()
|
|
{
|
|
if (!$this->deliveryTimes) {
|
|
$this->deliveryTimes = [
|
|
'pickup' => [
|
|
'date' => null,
|
|
'deadline' => null,
|
|
],
|
|
'delivery' => [
|
|
'date' => null,
|
|
'deadline' => null,
|
|
],
|
|
];
|
|
$now = new \DateTime();
|
|
|
|
foreach ($this->getDeliveryWrappers(true) as $deliveryWrapper) {
|
|
$delivery = $deliveryWrapper->getDelivery();
|
|
// ignore zasilkovna
|
|
if (($delivery instanceof \Zasilkovna) || !$delivery->isCountrySupported($this->countryContext->getActiveId())) {
|
|
continue;
|
|
}
|
|
|
|
$date = $delivery->getDeliveryDate();
|
|
if (!$date) {
|
|
continue;
|
|
}
|
|
|
|
$deadline = new \DateTime();
|
|
|
|
$time = $delivery->time_hours ?: '18:00';
|
|
$deadline->modify($time);
|
|
$date->modify($time);
|
|
|
|
if ($deadline < $now) {
|
|
$deadline->add(new \DateInterval('P1D'));
|
|
}
|
|
|
|
if ($deadline > $date) {
|
|
$deadline = $date;
|
|
}
|
|
|
|
if ($delivery->isInPerson()) {
|
|
if (is_null($this->deliveryTimes['pickup']['date']) || $this->deliveryTimes['pickup']['date'] > $date) {
|
|
$this->deliveryTimes['pickup'] = [
|
|
'date' => $date,
|
|
'deadline' => $deadline,
|
|
];
|
|
}
|
|
} else {
|
|
if (is_null($this->deliveryTimes['delivery']['date']) || $this->deliveryTimes['delivery']['date'] > $date) {
|
|
$this->deliveryTimes['delivery'] = [
|
|
'date' => $date,
|
|
'deadline' => $deadline,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->deliveryTimes;
|
|
}
|
|
|
|
/** Nejnižší cena za dopravu */
|
|
public function field_lowestPrice()
|
|
{
|
|
$minPrice = null;
|
|
|
|
foreach ($this->getDeliveryWrappers() as $deliveryWrapper) {
|
|
$price = $deliveryWrapper->getFinalPrice($this->object);
|
|
|
|
if ($minPrice == null) {
|
|
$minPrice = $price;
|
|
} elseif (isset($price)) {
|
|
$minPrice = \Decimal::min($minPrice, $price);
|
|
}
|
|
}
|
|
|
|
return $minPrice ? $minPrice->asFloat() : $minPrice;
|
|
}
|
|
|
|
/** Nejnižší cena za dopravu dobírkou */
|
|
public function field_lowestPriceCod()
|
|
{
|
|
$minPrice = null;
|
|
|
|
foreach ($this->getDeliveryWrappers() as $deliveryWrapper) {
|
|
$price = $deliveryWrapper->getFinalPriceWithCOD($this->object);
|
|
|
|
if ($minPrice == null) {
|
|
$minPrice = $price;
|
|
} elseif (isset($price)) {
|
|
$minPrice = \Decimal::min($minPrice, $price);
|
|
}
|
|
}
|
|
|
|
return $minPrice ? $minPrice->asFloat() : $minPrice;
|
|
}
|
|
|
|
/** Doprava zdarma od */
|
|
public function field_freeDeliveryFrom()
|
|
{
|
|
$minPrice = null;
|
|
|
|
foreach ($this->getDeliveryWrappers() as $deliveryWrapper) {
|
|
$price = $deliveryWrapper->getPriceDontCountinFrom();
|
|
|
|
if ($minPrice == null) {
|
|
$minPrice = $price;
|
|
} elseif (isset($price)) {
|
|
$minPrice = \Decimal::min($minPrice, $price);
|
|
}
|
|
}
|
|
|
|
return $minPrice ? $minPrice->asFloat() : $minPrice;
|
|
}
|
|
|
|
/**
|
|
* @return \KupShop\FeedsBundle\Utils\DeliveryWrapper[]
|
|
*/
|
|
protected function getDeliveryWrappers(bool $includingInPerson = false, bool $all = false): array
|
|
{
|
|
if (!isset($this->deliveryWrappers)) {
|
|
$allDeliveryWrappers = [];
|
|
$deliveryWrappers = [];
|
|
$deliveryWrappersIncludingInPerson = [];
|
|
if (findModule('deliveries')) {
|
|
foreach (\DeliveryType::getAll() as $deliveryType) {
|
|
$delivery = $deliveryType->getDelivery();
|
|
$index = $delivery->id;
|
|
if (!isset($allDeliveryWrappers[$index])) {
|
|
$allDeliveryWrappers[$index] = $tmpWrapper = new \KupShop\FeedsBundle\Utils\DeliveryWrapper($delivery);
|
|
// assign product to Utils\DeliveryWrapper - necessary for free delivery calculation
|
|
$tmpWrapper->setProduct($this->object);
|
|
}
|
|
|
|
// HardRequirements - checkCountries & checkUsersGroups
|
|
if (!$this->getRestrictionUtils()->checkHardRequirements($delivery)) {
|
|
continue;
|
|
}
|
|
|
|
/** @var $deliveryWrapper \KupShop\FeedsBundle\Utils\DeliveryWrapper */
|
|
$deliveryWrapper = $allDeliveryWrappers[$index];
|
|
$deliveryWrapper->processDeliveryType($deliveryType);
|
|
|
|
// deliveries that pass isCountrySupported check
|
|
$deliveryWrappersIncludingInPerson[$index] = $allDeliveryWrappers[$index];
|
|
|
|
if (!$delivery->isInPerson()) {
|
|
$deliveryWrappers[$index] = $deliveryWrapper;
|
|
}
|
|
}
|
|
}
|
|
$this->allDeliveryWrappers = $allDeliveryWrappers;
|
|
$this->deliveryWrappers = $deliveryWrappers;
|
|
$this->deliveryWrappersIncludingInPerson = $deliveryWrappersIncludingInPerson;
|
|
}
|
|
|
|
foreach ($this->deliveryWrappersIncludingInPerson as $index => $wrapper) {
|
|
$wrapper->setProduct($this->object);
|
|
}
|
|
|
|
if ($all) {
|
|
return $this->allDeliveryWrappers;
|
|
} else {
|
|
return $includingInPerson ? $this->deliveryWrappersIncludingInPerson : $this->deliveryWrappers;
|
|
}
|
|
}
|
|
}
|