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

386 lines
14 KiB
PHP

<?php
use KupShop\KupShopBundle\Context\CurrencyContext;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use KupShop\OrderingBundle\Exception\DeliveryException;
class Zasilkovna extends Delivery
{
use DatabaseCommunication;
public static $type = Delivery::TYPE_POINT;
public static $className = 'Zásilkovna';
protected $templateDescription = 'deliveries/delivery.Zasilkovna.widget.tpl';
protected $templateInit = 'deliveries/delivery.Zasilkovna.init.tpl';
protected $AdminTemplateSettings = 'deliveries/block.delivery.Zasilkovna.tpl';
protected $adminWindowTemplate = 'delivery/settings.Zasilkovna.tpl';
public static $tableName = '`kupshop_shared`.`delivery_zasilkovna`';
protected $track_and_trace = [
'CZ' => 'https://tracking.packeta.com/cs/?id=[PACKAGE_ID]',
'DE' => 'https://tracking.packeta.com/de/?id=[PACKAGE_ID]',
'HR' => 'https://tracking.packeta.com/hr/?id=[PACKAGE_ID]',
'SI' => 'https://tracking.packeta.com/sl/?id=[PACKAGE_ID]',
'RO' => 'https://tracking.packeta.com/ro/?id=[PACKAGE_ID]',
'SK' => 'https://tracking.packeta.com/sk/?id=[PACKAGE_ID]',
'HU' => 'https://tracking.packeta.com/hu/?id=[PACKAGE_ID]',
'DK' => 'https://tracking.packeta.com/dk/?id=[PACKAGE_ID]',
'ES' => 'https://tracking.packeta.com/es/?id=[PACKAGE_ID]',
'FI' => 'https://tracking.packeta.com/fi/?id=[PACKAGE_ID]',
'FR' => 'https://tracking.packeta.com/fr/?id=[PACKAGE_ID]',
'BE' => 'https://tracking.packeta.com/fr/?id=[PACKAGE_ID]',
'IE' => 'https://tracking.packeta.com/en/?id=[PACKAGE_ID]',
'IT' => 'https://tracking.packeta.com/it/?id=[PACKAGE_ID]',
'PL' => 'https://tracking.packeta.com/pl/?id=[PACKAGE_ID]',
'SV' => 'https://tracking.packeta.com/sv/?id=[PACKAGE_ID]',
'LV' => 'https://tracking.packeta.com/lv/?id=[PACKAGE_ID]',
'LT' => 'https://tracking.packeta.com/lt/?id=[PACKAGE_ID]',
'EE' => 'https://tracking.packeta.com/et/?id=[PACKAGE_ID]',
'UA' => 'https://tracking.packeta.com/uk/?id=[PACKAGE_ID]',
'GR' => 'https://tracking.packeta.com/el/?id=[PACKAGE_ID]',
];
public static $jsonDelivery = 'http://www.zasilkovna.cz/api/v4/80aa13c913f62111/branch.json';
protected $heureka_delivery_id = 'ZASILKOVNA';
protected $zbozi_delivery_id = 'ZASILKOVNA';
public $zip;
public $config = [
'maxCOD' => 20000,
'maxWeight' => 10.0,
'maxLength' => 120.0, // Maximální rozměr strany položky
'maxSumOfDimensions' => 150.0, // Maximální součet rozměrů všech tří stran položky
// legacy config:
'limit' => [
'CZK' => 20000,
'EUR' => 700,
],
'weight_limit' => 15,
'max_length' => 70, // Maximální rozměr jedné strany zásilky: 70 cm
'max_dimensions' => 150, // Maximální součet rozměrů všech tří stran zásilky
];
public $defaultIcon = '../../common/static/deliveries/zasilkovna.svg';
public static function getSettingsConfiguration(): array
{
return [
'fields' => [
'apiKey' => [
'title' => 'API klíč',
'type' => 'text',
],
],
];
}
public function getName()
{
$info = self::getInfo();
return parent::getName().' - '.$info['name'];
}
public function storeDeliveryInfo($data): array
{
parent::storeDeliveryInfo($data);
$pointData = $data['zasilkovna_point_data'] ?? '';
$pointData = json_decode($pointData, true);
if (empty($pointData)) {
return [];
}
$label = getVal('routingCode', $pointData) ?? getVal('labelRouting', $pointData);
return $this->data += [
'fromWidget' => true,
'idZ' => $pointData['id'] ?? $pointData['idZ'] ?? '',
'carrierId' => $pointData['carrierId'] ?? null,
'zip' => getVal('zip', $pointData),
'hours' => getVal('openingHours', $pointData) ?? getVal('hours', $pointData),
'street' => getVal('street', $pointData),
'country' => strtoupper(getVal('country', $pointData)),
'city' => getVal('city', $pointData),
'place_name' => getVal('name', $pointData),
'place' => getVal('place', $pointData),
'labelRouting' => $label,
'directions' => getVal('directions', $pointData),
];
}
public function setPointId($id): self
{
$this->data['idZ'] = $id;
return $this;
}
public function getPointId()
{
return $this->data['idZ'] ?? null;
}
public function getInfo($idZ = null)
{
$data = null;
if (is_null($idZ)) {
$idZ = $this->data['idZ'] ?? null;
}
if (getVal('fromWidget', $this->data)) {
$data = $this->data;
$data['name'] = getVal('name', $this->data) ?? getVal('place_name', $this->data);
unset($data['place_name']);
} elseif ($idZ) {
$data = sqlFetchAssoc(sqlQuery('SELECT * FROM '.self::$tableName.'
WHERE id=:id',
['id' => $idZ]));
if ($data) {
$data['idZ'] = $data['id'];
$data['hours'] = unserialize($data['hours']);
$data['address'] = $data['street'].', '.$data['zip'].', '.$data['city'];
}
}
if (!$data) {
return [
'name' => 'Neznámá pobočka',
'city' => 'Neznámé',
'place' => 'Neznámé',
'street' => 'Neznámé',
'zip' => 'Neznámé',
'country' => 'Neznámé',
'idZ' => $idZ,
];
}
return $data;
}
/**
* @param $data admin order data
* @param Order $order
*
* @return bool|string
*/
public function applyToOrder(&$data, $order)
{
parent::applyToOrder($data, $order);
$info = $this->getInfo();
if (empty($info['labelRouting'])) {
$this->data['labelRouting'] = null;
return 'Není zvolena zásilkovna!';
}
$data['delivery_zip'] = $info['zip'];
$data['delivery_street'] = $info['street'];
$data['delivery_city'] = $info['city'];
$data['delivery_country'] = $info['country'];
$data['delivery_firm'] = $info['place'];
return true;
}
/**
* @param $cart CartBase
*/
public function applyToCart(CartBase $cart)
{
parent::applyToCart($cart);
$info = $this->getInfo();
if (empty($info['labelRouting'])) {
return;
}
if (isset($cart->invoice['name'])) {
$cart->delivery['name'] = $cart->invoice['name'];
$cart->delivery['surname'] = $cart->invoice['surname'];
}
$cart->delivery['zip'] = $info['zip'];
$cart->delivery['street'] = $info['street'];
$cart->delivery['city'] = $info['city'];
$cart->delivery['country'] = $info['country'];
$cart->delivery['firm'] = $info['place'];
}
public function printDeliveryInfo()
{
$info = $this->getInfo();
return "<strong>{$info['city']}</strong>, {$info['street']}, {$info['place']}, <strong>{$info['zip']}</strong>";
}
public function check(Cart $cart)
{
if ($weight_limit = ($this->config['weight_limit'] ?? 0)) {
if ($cart->getTotalWeight() > $weight_limit) {
// Vahovy limit pro tento typ dopravy byl prekrocen
throw new DeliveryException(translate_shop('weight_limit', 'delivery'),
translate_shop('weight_limit_short', 'delivery'),
DeliveryException::ERROR_DELIVERY_DISABLED);
}
}
return parent::check($cart);
}
public function checkSelected(Cart $cart, ?Payment $payment = null)
{
// check selected combination of delivery and payment
if (($cart->max_step != 0) && ($payment instanceof Dobirka)) {
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$currency = $currencyContext->getActive();
if (!empty($this->config['limit'][$currency->getId()])) {
$limit = toDecimal($this->config['limit'][$currency->getId()]);
if (!$cart->totalPricePay->lowerThan($limit)) {
throw new DeliveryException(sprintf(translate_shop('zasilkovna_dobirka_limit', 'delivery'),
$limit->printValue().' '.$currency->getSymbol()), '', DeliveryException::ERROR_DELIVERY_DISABLED);
}
}
}
if ($cart->hasData('delivery')) {
if (empty($this->data['labelRouting'])) {
throw new DeliveryException(translate('branch_missing_zip', 'delivery'));
}
$info = $this->getInfo();
if (empty($info['labelRouting'])) {
throw new DeliveryException('Neznámá pobočka.');
}
$currencyContext = ServiceContainer::getService(CurrencyContext::class);
$currency = $this->custom_data['balikobot']['currency'] ?? $currencyContext->getActiveId();
if (
!empty($this->data['labelRouting'])
&& !in_array($info['country'], $this->getCountryByCurrency($currency))
) {
throw new DeliveryException(translate('branch_currency_not_supported', 'delivery'));
}
}
return parent::checkSelected($cart, $payment);
}
public function import()
{
$json = file_get_contents(self::$jsonDelivery);
$data = json_decode_strict($json, true);
if (count($data) > 0) {
sqlGetConnection()->transactional(function () use ($data) {
sqlQuery('UPDATE '.self::$tableName.' SET visible = "N" ');
$separatedCol = [
'id',
'zip',
'street',
'country',
'city',
'name',
'place',
'labelRouting',
'directions',
'url',
];
$excludeColumns = [
'photos',
];
foreach ($data['data'] as $id => $branch) {
$data = [];
foreach ($branch as $title => $value) {
if (in_array($title, $separatedCol)) {
if ($title == 'zip') {
$data[$title] = str_replace(' ', '', $value);
} elseif ($title == 'url') {
if (is_array($value)) {
$data[$title] = serialize($value);
} else {
$data[$title] = $value;
}
} elseif ($title == 'country') {
$data[$title] = strtoupper($value);
} else {
if ($value === []) { // Sulini tam obcas misto prazdnyho stringu maji prazdny objekt
$value = '';
}
$data[$title] = $value;
}
} elseif ($title == 'openingHours') {
// foreach ($value['regular'] as $day => $hours) {
// $formatter = new IntlDateFormatter('cs_CZ', IntlDateFormatter::FULL, IntlDateFormatter::FULL);
// $formatter->setPattern('EEEE');
// $p = $formatter->format(new DateTime($day));
//
// $openingHours[mb_convert_case($p, MB_CASE_TITLE, 'UTF-8')] = $hours;
// }
$data['hours'] = serialize($value['compactShort']);
} elseif (!in_array($title, $excludeColumns)) {
$data['data'][$title] = $value;
}
}
$data['data'] = serialize($data['data']);
$data['visible'] = 'Y';
$this->replaceSQL(self::$tableName, $data);
}
});
return true;
}
return false;
}
protected function getCountryByCurrency($currency): array
{
switch ($currency) {
case 'CZK':
return ['CZ'];
break;
case 'EUR':
return ['SK', 'DE', 'AT', 'FR', 'ES', 'HR', 'IT'];
break;
case 'HUF':
return ['HU'];
break;
case 'RON':
return ['RO'];
break;
case 'PLN':
return ['PL'];
break;
default:
return [];
}
}
public function ZBOXOnly(): bool
{
$vendors = $this->getCustomData()['widget_options']['vendors'] ?? [];
foreach ($vendors as $vendor) {
if (($vendor['group'] ?? '') != 'zbox') {
return false;
}
}
return true;
}
}