Files
kupshop/class/class.Delivery.php
2025-08-02 16:30:27 +02:00

1089 lines
32 KiB
PHP

<?php
use KupShop\AdminBundle\Util\ActivityLog;
use KupShop\DeliveryPriceListBundle\DeliveryPriceCalculator;
use KupShop\I18nBundle\Translations\DeliveryTypeDeliveriesTranslation;
use KupShop\KupShopBundle\Context\CountryContext;
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Context\LanguageContext;
use KupShop\KupShopBundle\Context\VatContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\KupShopBundle\Util\Contexts;
use KupShop\KupShopBundle\Util\DateUtil;
use KupShop\KupShopBundle\Util\Delivery\RestrictionParams;
use KupShop\KupShopBundle\Util\Delivery\RestrictionUtils;
use KupShop\KupShopBundle\Util\Price\Price;
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
use KupShop\KupShopBundle\Util\Price\PriceUtil;
use KupShop\OrderingBundle\Entity\Purchase\PurchaseState;
use KupShop\OrderingBundle\Event\DeliveryCheckEvent;
use KupShop\OrderingBundle\Exception\DeliveryException;
use KupShop\OrderingBundle\Exception\PaymentException;
use Query\Translation;
use Symfony\Component\DependencyInjection\Container;
#[AllowDynamicProperties]
class DeliveryBase implements ArrayAccess
{
public const TYPE_ADDRESS = 1;
public const TYPE_IN_PERSON = 2;
public const TYPE_POINT = 3;
public const TYPE_VIRTUAL = 4;
// Delivery class info
public static $type = self::TYPE_ADDRESS;
public static $className;
private static $cache;
/** @var Exception */
public $exception;
// Shop Settings
public $config = [];
public $id;
public $name;
public $description;
public $cart_description;
public $totalWeight;
public $maxItemWeight;
/**
* @var Decimal
*/
protected $price;
protected $priceCache;
protected $currency;
protected $delivery_type_currency;
public $defaultIcon = '../../common/static/deliveries/generic.svg';
public $photo;
public $class;
public $time_days;
public $time_hours;
public $is_open;
/**
* @var bool
*/
private $freeDelivery = false;
/** @var Price */
private $totalPrice;
private $freeShipping;
/**
* @var Price
*/
protected $price_dont_countin_from;
protected $price_dont_countin_from_reg;
protected $price_dont_countin_from_delivery;
protected $price_dont_countin_from_reg_delivery;
protected $deliveryCurrency;
public $data = [];
protected $countries;
// Šablona, která se zobrazí v košíku u výběru dopravy. Musí umět se vypsat víckrát, může být víc doprav se stejným dopravcem.
protected $templateDescription;
// Šablona, která se zobrazá v košíku u výběru dopravy ale pouze jednou pro jednoho dopravce. Pro inicializaci widgetů a pod.
protected $templateInit;
// Šablona v administraci na detailu objednávky
protected $AdminTemplateSettings;
// Šablona v nastavení konkrétní dopravy s možností upravit nastavení dopravce
protected $adminWindowTemplate;
protected $heureka_delivery_id;
protected $zbozi_delivery_id;
protected $track_and_trace;
protected $custom_data;
public $id_pricelist;
/** @var RestrictionUtils */
protected $restrictionUtils;
/** @var RestrictionParams */
protected $restrictionParams;
protected $pricelist;
/** @var PurchaseState */
protected $purchaseState;
public static function getSettingsConfiguration(): array
{
return [];
}
public static function includeClass($name)
{
global $cfg;
$name = preg_replace('/[^a-zA-Z-]/', '', $name);
$class = "deliveries/class.{$name}.php";
if (file_exists($cfg['Path']['web_root'].$class) && !isFunctionalTests()) {
require_once $cfg['Path']['web_root'].$class;
return;
}
if (!file_exists($cfg['Path']['shared_class'].$class)) {
throw new Exception('Dopravní modul '.$name.' neexistuje');
}
require_once $cfg['Path']['shared_class'].$class;
}
/** Factory function for Delivery classes.
* @param string $name Delivery class name
*
* @return Delivery
*/
public static function getClass(?string $name)
{
if ($deliveryClass = ServiceContainer::getService('kupshop.delivery.'.strtolower($name ?? ''), Container::NULL_ON_INVALID_REFERENCE)) {
return $deliveryClass;
}
if ($name) {
Delivery::includeClass($name);
} else {
$name = 'Delivery';
}
return new $name();
}
/** List all Delivery implementations.
*/
public static function listClasses()
{
global $cfg;
$classDir = $cfg['Path']['shared_class'].'deliveries/';
$shopClassDir = $cfg['Path']['web_root'].'deliveries/';
$classesDir = array_merge(glob($classDir.'class.*.php'), glob($shopClassDir.'class.*.php'));
foreach ($classesDir as $class) {
$class = basename($class);
preg_match('/class.([a-zA-Z]+).php/', $class, $matches);
$class = $matches[1];
Delivery::includeClass($class);
if (!$class::isEnabled()) {
continue;
}
$classes[$class] = $class::$className;
}
return $classes;
}
public function createFromArray($row)
{
foreach ($row as $key => $value) {
if ($key == 'data') {
$this->custom_data = $value;
} else {
$this->$key = $value;
}
}
if (!empty($this->price_registered) && User::getCurrentUser()) {
$this->price = $this->price_registered;
}
// Potrebuju menu z dopravy, nechci tu z delivery pricelistu
$this->deliveryCurrency = $this->currency;
if (findModule(Modules::DELIVERY_PRICELIST)) {
if (isset($this->id_pricelist) && !empty($this->pricelist_currency)) {
$this->currency = $this->pricelist_currency;
}
}
$priceUtil = ServiceContainer::getService(PriceUtil::class);
if ($this->getPriceDontCountinFrom() !== null) {
$this->price_dont_countin_from = new Price(toDecimal($this->getPriceDontCountinFrom()), $priceUtil->getCurrencyById($this->delivery_type_currency), 0);
}
if (User::getCurrentUser() && $this->price_dont_countin_from_reg) {
$this->price_dont_countin_from = new Price(toDecimal($this->price_dont_countin_from_reg), $priceUtil->getCurrencyById($this->delivery_type_currency), 0);
}
if ($this->getPriceDontCountinFromDelivery() !== null) {
$this->price_dont_countin_from_delivery = new Price(toDecimal($this->getPriceDontCountinFromDelivery()), $priceUtil->getCurrencyById($this->deliveryCurrency), 0);
}
if (User::getCurrentUser() && $this->price_dont_countin_from_reg_delivery) {
$this->price_dont_countin_from_delivery = new Price(toDecimal($this->price_dont_countin_from_reg_delivery), $priceUtil->getCurrencyById($this->deliveryCurrency), 0);
}
if ($this->price_dont_countin_from_reg_delivery !== null) {
$this->price_dont_countin_from_reg_delivery = new Price(toDecimal($this->price_dont_countin_from_reg_delivery), $priceUtil->getCurrencyById($this->deliveryCurrency), 0);
}
if (!empty($this->custom_data) && is_string($this->custom_data)) {
$this->custom_data = json_decode($this->custom_data, true);
}
}
/** Get payment HTML when payment selected.
*/
public function getCartDescription()
{
if ($this->templateDescription) {
$smarty = createSmarty(false, true);
$smarty->assign([
'object' => $this,
'deliveryPrefix' => "delivery_data[{$this->id}]",
]);
return $smarty->fetch($this->templateDescription);
}
return null;
}
public function getInitTemplate($smarty)
{
if ($this->templateInit) {
$params = [
'object' => $this,
];
$_smarty_tpl_vars = $smarty->tpl_vars;
$ret = $smarty->_subTemplateRender($this->templateInit, $smarty->cache_id, $smarty->compile_id, 0, null, $params, 0, false);
$smarty->tpl_vars = $_smarty_tpl_vars;
return $ret;
}
return null;
}
public function getName()
{
return static::$className;
}
public function getClassName()
{
return static::$className;
}
public function isInPerson()
{
return static::$type === self::TYPE_IN_PERSON;
}
public function isVirtual()
{
return static::$type === self::TYPE_VIRTUAL;
}
public function getType()
{
return static::$type;
}
public function __construct()
{
$this->loadConfig();
}
public function loadConfig()
{
if (!static::$className) {
return;
}
global $cfg;
$this->config = array_merge($this->config, getVal(get_class($this), $cfg['Modules']['deliveries'] ?? [], []));
}
public function storeDeliveryInfo($data)
{
$this->data = [];
if (findModule(Modules::DELIVERY_PRICELIST)) {
$this->data += $this->getPackageInfo();
}
return $this->data;
}
public function loadDeliveryInfo($data)
{
foreach ($data as $key => $value) {
$this->$key = $value;
}
$this->data = $data;
}
public function printDeliveryInfo()
{
return '';
}
public function getPointId()
{
return null;
}
public function setPointId($id): self
{
if ($this->getType() === Delivery::TYPE_POINT) {
throw new RuntimeException('Not implemented!');
}
return $this;
}
public function printDeliverySettings($order)
{
if (!$this->AdminTemplateSettings) {
return '';
}
$info = $this->getInfo();
$smarty = createSmarty(false, true);
$smarty->assign([
'info' => $info,
'delivery_data' => $this['data'],
'object' => $this,
'order' => $order,
]);
return $smarty->fetch($this->AdminTemplateSettings);
}
/**
* @param $order Order
*/
public function applyToOrder(&$data, $order)
{
if (findModule(Modules::PRODUCTS, Modules::SUB_WEIGHT)) {
$this->totalWeight = $order->getTotalWeight();
$this->maxItemWeight = $order->getMaxItemWeight();
}
}
public function applyToCart(CartBase $cart)
{
if (findModule(Modules::PRODUCTS, Modules::SUB_WEIGHT)) {
$this->totalWeight = $cart->getTotalWeight();
$this->maxItemWeight = $cart->getMaxItemWeight();
}
}
public function getPackageInfo()
{
if (isset($this->id_pricelist) && findModule(Modules::DELIVERY_PRICELIST)) {
$priceList = $this->getPriceList();
$priceList->setDivide(false);
$priceList->setPricelistId($this->id_pricelist);
// set weight of cart
$priceList->setTotalWeight($this->totalWeight);
$priceList->setMaxItemWeight($this->maxItemWeight);
return $priceList->getCountOfPackages();
}
return [];
}
public function getPriceFromPricelist($pricelistId, $totalCartWeight, $maxItemWeight)
{
$priceList = $this->getPriceList();
$priceList->setDivide(false);
$priceList->setPricelistId($pricelistId);
// set weight of cart
$priceList->setTotalWeight($totalCartWeight);
$priceList->setMaxItemWeight($maxItemWeight);
// set country
$countryContext = Contexts::get(CountryContext::class);
$priceList->setCountry($countryContext->getActive()->getId());
if ($priceList->isDeliverySupported()) {
// check weightgroup maxweight
if ($checkWg = $priceList->checkWeightGroup()) {
// if weight of cart > maxweight of weightgroup && onMaxWeight is set to divide
if ($checkWg === 'divide') {
$priceList->setDivide(true);
}
} else {
// Vahovy limit pro tento typ dopravy byl prekrocen
$this->exception = new DeliveryException(translate_shop('weight_limit', 'delivery'), translate_shop('weight_limit_short', 'delivery'), DeliveryException::ERROR_DELIVERY_DISABLED);
}
} else {
$this->exception = new DeliveryException(translate_shop('unavailable', 'delivery'), translate_shop('unavailable_short', 'delivery'), DeliveryException::ERROR_DELIVERY_DISABLED);
}
// returns price without vat
return $priceList->getPriceWithoutVat(getAdminVat()['value'])->round(4);
}
public function processAdminWindowData($data)
{
return $data;
}
public function getDispatchDate()
{
$today = true;
if (DateUtil::compareTimes($this->time_hours)) {
$today = false;
}
return $this->calcWorkingDays($today ? 0 : 1, new DateTime());
}
// Delivery date
public function getDeliveryDate()
{
$days = $this->getDeliveryDays()['min'] ?? null;
if ($days === null) {
return false;
}
$fromDay = new DateTime();
return $this->calcWorkingDays($days, $fromDay);
}
// Returns delivery days - min & max
public function getDeliveryDays(?DateTime $fromDay = null)
{
if (findModule(Modules::DELIVERY_PRICELIST)) {
$days = $this->getDeliveryTimeFromPricelist();
}
if (is_null($this->time_days) && !isset($days)) {
return false;
}
if (!isset($days)) {
$days = ['min' => intval($this->time_days)];
}
$fromDay ??= new DateTime();
if ((!empty($this->time_hours) && DateUtil::compareTimes($this->time_hours, $fromDay->format('H:i:s')))
|| !$this->isWorkday($fromDay)
) {
$days['min']++;
if (isset($days['max']) && $days['max'] != null) {
$days['max']++;
}
}
return $days;
}
/**
* @param $date DateTime
*
* @return bool
*/
public function isWorkday($date, ?array $countries = null)
{
return DateUtil::isWorkday($date, $countries);
}
/**
* @param $fromDay DateTime
*
* @return DateTime
*/
public function calcWorkingDays($days, $fromDay = null)
{
$dbcfg = Settings::getDefault();
switch ($dbcfg->delivery_config['holidaysByCountry'] ?? null) {
// zeme doruceni
case 'delivery':
$countries = [Contexts::get(CountryContext::class)->getActiveId()];
break;
// zeme doruceni + zeme expedice
case 'dispatchDelivery':
$countries = array_unique(['CZ', Contexts::get(CountryContext::class)->getActiveId()]);
break;
// zeme expedice
default:
$countries = ['CZ'];
}
return DateUtil::calcWorkingDays($days, $fromDay, [$this, 'isWorkday'], $countries);
}
public function getSupportedCountries()
{
if (isset($this->countries)) {
return $this->countries;
}
$countries = $this->getCustomData()['restrictions']['countries'] ?? null;
$supported = array_keys(Contexts::get(CountryContext::class)->getSupported());
if (!$countries) {
$this->countries = $supported;
} else {
$invert = $this->getCustomData()['restrictions']['countries_invert'] ?? false;
if ($invert) {
$this->countries = array_diff($supported, $countries);
} else {
$this->countries = array_intersect($supported, $countries);
}
}
return $this->countries;
}
protected function getRestrictionUtils()
{
if (!isset($this->restrictionUtils)) {
$this->restrictionUtils = ServiceContainer::getService(RestrictionUtils::class);
}
return $this->restrictionUtils->setType('delivery');
}
/**
* @param Price $totalPrice
*
* @return bool
*/
public function accept($totalPrice, $freeDelivery, ?PurchaseState $purchaseState = null)
{
$this->totalPrice = $totalPrice;
$this->freeShipping = $freeDelivery;
if ($purchaseState) {
$this->purchaseState = $purchaseState;
}
if ($freeDelivery
|| ($totalPrice && $this->getPriceDontCountinFromDelivery() && !PriceCalculator::firstLower($totalPrice, $this->getPriceDontCountinFromDelivery()))
|| ($totalPrice && $this->getPriceDontCountinFrom() && !PriceCalculator::firstLower($totalPrice, $this->getPriceDontCountinFrom()))) {
$this->freeDelivery = true;
}
return $this->getRestrictionUtils()->checkHardRequirements($this);
}
public function isCountrySupported($countryCode)
{
if (!$countryCode) {
return false;
}
return array_search(strtoupper($countryCode), $this->getSupportedCountries()) !== false;
}
/**
* @return Delivery[]
*/
public static function getAll($figure = true)
{
$language = Contexts::get(LanguageContext::class)->getActiveId();
if (!isset(self::$cache[$language])) {
$qb = sqlQueryBuilder()->select('dtd.*, MIN(dt.price_dont_countin_from) AS price_dont_countin_from,
MIN(dt.price_dont_countin_from_reg) AS price_dont_countin_from_reg,
dt.currency AS delivery_type_currency, dtd.price_dont_countin_from AS price_dont_countin_from_delivery,
dtd.price_dont_countin_from_reg as price_dont_countin_from_reg_delivery, MAX(dt.figure) as figure, dtd.date_updated as date_updated')
->from('delivery_type_delivery', 'dtd')
->leftJoin('dtd', 'delivery_type', 'dt', 'dt.id_delivery = dtd.id')
->andWhere(Translation::coalesceTranslatedFields(DeliveryTypeDeliveriesTranslation::class))
->groupBy('dtd.id')
->orderBy('dtd.position');
if (findModule(Modules::DELIVERY_PRICELIST)) {
$qb->addSelect('dp.id_currency as pricelist_currency')
->leftJoin('dtd', 'delivery_pricelists', 'dp', 'dtd.id_pricelist = dp.id');
}
$deliveries = [];
foreach ($qb->execute() as $row) {
$delivery = Delivery::getClass(getVal('class', $row));
$delivery->createFromArray($row);
$deliveries[$delivery->id] = $delivery;
}
if (findModule(Modules::DELIVERY_PRICELIST)) {
$deliveryPriceCalculator = ServiceContainer::getService(DeliveryPriceCalculator::class);
$deliveryPriceCalculator->multiFetchDeliveryTime($deliveries);
}
self::$cache[$language] = $deliveries;
}
$deliveries = self::$cache[$language];
if ($figure) {
$deliveries = array_filter($deliveries, function ($d) {return $d['figure'] == 'Y'; });
}
return $deliveries;
}
public static function clearCache()
{
self::$cache = null;
}
public function getHeurekaDeliveryID()
{
if (!empty($this->heureka_delivery_id)) {
return $this->heureka_delivery_id;
}
return null;
}
public function getZboziDeliveryID()
{
if (!empty($this->zbozi_delivery_id)) {
return $this->zbozi_delivery_id;
}
return null;
}
public function getAdminWindowTemplate()
{
return $this->adminWindowTemplate;
}
public function requiresDeliveryAddress()
{
return static::$type === self::TYPE_ADDRESS;
}
protected function getDeliveryTimeFromPricelist()
{
if (findModule(Modules::DELIVERY_PRICELIST)) {
return $this->pricelistDeliveryTime ?? null;
}
return null;
}
public function getTrackAndTraceLink($package_id, ?Order $order = null)
{
if (empty($this->track_and_trace)) {
return null;
}
if (is_array($this->track_and_trace) && $order) {
$tat = $this->track_and_trace[$order->delivery_country] ?? reset($this->track_and_trace);
} else {
$tat = is_array($this->track_and_trace) ? reset($this->track_and_trace) : $this->track_and_trace;
}
if (!empty($package_id)) {
$tat = str_replace('[PACKAGE_ID]', $package_id, $tat);
}
return $tat;
}
public function setPrice(Price $price)
{
$this->priceCache = $price;
}
private function preparePrice()
{
if (isset($this->id_pricelist) && findModule(Modules::DELIVERY_PRICELIST)) {
return $this->getPriceFromPricelist($this->id_pricelist, $this->totalWeight, $this->maxItemWeight);
}
return toDecimal($this->price);
}
public function getPrice(?float $vat = null): Price
{
$vat = $this->getDeliveryVat($vat);
if (!empty($this->priceCache)) {
if ($this->priceCache->getVat()->equals(toDecimal($vat))) {
return $this->priceCache;
}
}
$price = $this->preparePrice();
// free delivery
if ($this->freeDelivery) {
$price = toDecimal(0);
}
return $this->priceCache = $this->getDeliveryPrice($price, $vat);
}
public function getPriceSelected(DeliveryType $deliveryType)
{
$totalPrice = $this->totalPrice;
$price = $this->preparePrice();
if ($this->freeShipping
|| ($totalPrice && $this->getPriceDontCountinFromDelivery() && !PriceCalculator::firstLower($totalPrice, $this->getPriceDontCountinFromDelivery()))
|| ($totalPrice && $deliveryType->getPriceDontCountinFrom() && !PriceCalculator::firstLower($totalPrice, $deliveryType->getPriceDontCountinFrom()))) {
$price = toDecimal(0);
}
return $this->getDeliveryPrice($price, $deliveryType->vat);
}
protected function getDeliveryPrice($price, $vat = null)
{
$dbcfg = Settings::getDefault();
$vat = $this->getDeliveryVat($vat);
$vatContext = Contexts::get(VatContext::class);
$noVat = ($vat == 0) && ($vatContext->getActive() == $vatContext::NO_VAT);
if (($dbcfg->delivery_config['vats_from_top'] ?? 'N') == 'Y') {
$price = $price->addVat(getAdminVat()['value'])->removeVat($vat)->value();
if ($noVat) {
$defaultVat = $vatContext->getDefault()['vat'] ?? 0;
$price = $price->removeVat($defaultVat)->value();
}
}
$priceUtil = ServiceContainer::getService(PriceUtil::class);
$currency = $priceUtil->getCurrencyById($this->currency);
$price = new Price($price, $currency, $vat);
$activeCurrency = Contexts::get(CurrencyContext::class)->getActive();
$price = PriceCalculator::convert($price, $activeCurrency);
$priceWithoutVat = $price->getPriceWithoutVat(); // kvuli spravnemu zaokrouhleni
$price = new Price($priceWithoutVat, $activeCurrency, $price->getVat());
return $price;
}
protected function getDeliveryVat($vat = null)
{
$dbcfg = Settings::getDefault();
return (($dbcfg->delivery_config['from_products'] ?? 'N') == 'Y' && $this->purchaseState)
? $this->purchaseState->getDeliveryVat() ?? $vat ?? getVat()
: $vat ?? getVat();
}
public function getCustomData()
{
return $this->custom_data;
}
/**
* @return Price
*/
public function getPriceDontCountinFromDelivery($reg = null)
{
if ($reg === true) {
return $this->price_dont_countin_from_reg_delivery;
}
return $this->price_dont_countin_from_delivery;
}
/**
* @return Price
*/
public function getPriceDontCountinFrom()
{
return $this->price_dont_countin_from;
}
/**
* Implements ArrayAccess interface.
*/
public function offsetSet($offset, $value): void
{
$this->{$offset} = $value;
}
public function offsetExists($offset): bool
{
return isset($this->{$offset});
}
public function offsetUnset($offset): void
{
unset($this->{$offset});
}
public function offsetGet($offset): mixed
{
if ($offset == 'price') {
return ServiceContainer::getService(\KupShop\KupShopBundle\Wrapper\PriceWrapper::class)->setObject($this->getPrice());
}
if ($offset == 'photo') {
return $this->getPhoto();
}
return isset($this->{$offset}) ? $this->{$offset} : null;
}
public function setException(Exception $exception)
{
$this->exception = $exception;
}
public function check(Cart $cart)
{
$deliveryAddress = array_merge($cart->invoice, array_filter($cart->delivery));
if ($cart->hasData('user') && $cart->hasData('delivery', false) && !$this->isCountrySupported($deliveryAddress['country'] ?? '')) {
return 18;
}
if ($this->exception && $cart->hasData('delivery', false)) {
throw $this->exception;
}
try {
$this->checkRestrictions($cart->getPurchaseState());
} catch (DeliveryException $exception) {
$this->exception = $exception;
throw $this->exception;
}
try {
ServiceContainer::getService('event_dispatcher')->dispatch(
new DeliveryCheckEvent($this, $cart)
);
} catch (DeliveryException $e) {
$this->exception = $e;
throw $e;
}
return null;
}
public function checkRestrictions(PurchaseState $purchaseState)
{
$customData = $this->getCustomData();
$this->checkSoftRestrictions($purchaseState);
if ($productsFilter = $customData['restrictions']['productsFilter'] ?? null) {
$this->getRestrictionUtils()->checkProductsFilter($productsFilter, $purchaseState->getProductList());
}
return true;
}
public function checkSoftRestrictions(PurchaseState $purchaseState): void
{
$customData = $this->getCustomData();
if (($customData['restrictions']['enabled'] ?? false) !== 'Y') {
return;
}
if (!isset($this->restrictionParams)) {
$this->restrictionParams = $this->getRestrictionUtils()
->createParamsFromConfig($this->config ?? [], $customData['restrictions'] ?? []);
}
$this->getRestrictionUtils()->checkSoftRequirements(
$this->getRestrictionParams($purchaseState),
$this->restrictionParams
);
}
protected function getRestrictionParams(PurchaseState $purchaseState): RestrictionParams
{
return $purchaseState->getDeliveryRestrictionParams();
}
public function checkSelected(Cart $cart, ?Payment $payment = null)
{
// check selected combination of delivery and payment
$error = $this->check($cart);
if ($error) {
return $error;
}
if ($payment) {
try {
$error = $payment->check($cart);
} catch (PaymentException $exception) {
$payment->exception = $exception;
throw $payment->exception;
}
}
if (($cart->max_step != 0) && ($payment instanceof Dobirka)) {
if (isset($this->restrictionParams) && ($limit = $this->restrictionParams->getMaxCOD())) {
// zapnute Přepravní omezení a nastavena Maximální hodnota dobírky
$rParams = new RestrictionParams();
$rParams->setMaxCOD($cart->getPurchaseState()->getTotalPrice()->getPriceWithVat()->asFloat());
try {
$this->getRestrictionUtils()->checkSoftRequirements($rParams, $this->restrictionParams);
} catch (DeliveryException $e) {
$printPrice = printPrice($limit);
throw new PaymentException(
sprintf($e->getMessage(), $printPrice),
sprintf($e->getShortMessage(), $printPrice),
DeliveryException::ERROR_DELIVERY_DISABLED
);
}
}
}
return $error;
}
public function zipExists($invoice)
{
if (!empty($invoice['zip']) && in_array($invoice['country'], ['CZ', 'SK'])) {
$zipInvoice = sqlQueryBuilder()->select('zip')->from('kupshop_shared.delivery_zip_codes')
->where(\Query\Operator::equals(['zip' => $invoice['zip']]))
->andWhere(\Query\Operator::equals(['country' => $invoice['country']]))
->execute()->fetch();
if (!$zipInvoice) {
throw new \KupShop\OrderingBundle\Exception\DeliveryException(translate('false_zip', 'order_error'));
}
}
}
public static function isEnabled()
{
return true;
}
public function importFromBalikobot($url = null, $where = null)
{
increaseMemoryLimit(1024);
$url = ($url ?: static::$jsonDeliveryBalikobot);
if (empty($url)) {
return false;
}
$json = file_get_contents($url);
$data = json_decode_strict($json, true);
if (!empty($data['branches'])) {
sqlGetConnection()->transactional(function () use ($data, $where) {
sqlQueryBuilder()->delete(static::$tableName)->andWhere($where)->execute();
$tableColumns = static::$tableColumns ?? [];
if (empty($tableColumns)) {
$tableColumns = [
'type' => 'type',
'id' => 'id',
'zip' => 'zip',
'name' => 'name',
'street' => 'street',
'city' => 'city',
'country' => 'country',
];
}
$excludeColumns = static::$excludeColumns ?? [];
$faultyBranches = [];
foreach ($data['branches'] as $id => $branch) {
$insert = [];
$custom_data = [];
foreach ($branch as $title => $value) {
if (array_key_exists($title, $tableColumns)) {
if ($title == 'zip') {
$value = str_replace(' ', '', $value);
}
$insert[$tableColumns[$title]] = $value;
} elseif (!in_array($title, $excludeColumns)) {
$custom_data[$title] = $value;
}
}
$insert = $this->importCustomData($custom_data, $insert);
try {
sqlQueryBuilder()->insert(static::$tableName)->directValues($insert)->execute();
} catch (\Exception $exception) {
$faultyBranches[] = $insert;
}
}
if (!empty($faultyBranches)) {
addActivityLog(ActivityLog::SEVERITY_NOTICE, ActivityLog::TYPE_SYNC, 'Duplicitní výdejní místa dopravy', $faultyBranches);
}
});
return true;
}
return false;
}
public function importCustomData($custom_data, $insert)
{
if ($custom_data) {
$insert['data'] = json_encode($custom_data);
}
return $insert;
}
public function getPriceList(): DeliveryPriceCalculator
{
if (!$this->pricelist) {
$this->pricelist = ServiceContainer::getService(DeliveryPriceCalculator::class);
}
return $this->pricelist;
}
public function getPhoto()
{
if (empty($this->id)) {
return null;
}
$icon = $this->getPhotoPath();
return getImage($this->id, basename($icon), dirname($icon), 9, $this->name, strtotime($this->date_updated));
}
public function getPhotoPath()
{
if ($this->photo) {
return '../delivery/'.$this->photo;
}
return $this->defaultIcon;
}
public function __toString()
{
return static::class;
}
}
if (empty($subclass)) {
class Delivery extends DeliveryBase
{
}
}