Files
kupshop/bundles/KupShop/FeedsBundle/Wrapper/DeliveryWrapper.php
2025-08-02 16:30:27 +02:00

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;
}
}
}