3528 lines
121 KiB
PHP
3528 lines
121 KiB
PHP
<?php
|
|
|
|
use KupShop\CatalogBundle\Section\SectionFinder;
|
|
use KupShop\ElninoBundle\Email\ReturnReclamationEmail;
|
|
use KupShop\ElninoBundle\Translations\AbraComplementTypeTranslation;
|
|
use KupShop\ElninoBundle\Translations\AbraDamagesTranslation;
|
|
use KupShop\ElninoBundle\Translations\AbraModelsTranslation;
|
|
use KupShop\ElninoBundle\Translations\AbraScentsTranslation;
|
|
use KupShop\ElninoBundle\Translations\AbraSeriesTranslation;
|
|
use KupShop\ElninoBundle\Translations\AbraUnitsTranslation;
|
|
use KupShop\I18nBundle\Translations\ParametersListTranslation;
|
|
use KupShop\I18nBundle\Translations\ParametersTranslation;
|
|
use KupShop\I18nBundle\Translations\ProducersTranslation;
|
|
use KupShop\I18nBundle\Translations\SectionsTranslation;
|
|
use KupShop\KupShopBundle\Config;
|
|
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
|
|
use KupShop\KupShopBundle\Util\LegacyUrlGenerator;
|
|
use KupShop\KupShopBundle\Util\Locale\LanguageSwitcher;
|
|
use KupShop\KupShopBundle\Util\Price\PriceCalculator;
|
|
use KupShop\KupShopBundle\Util\System\PathFinder;
|
|
use KupShop\OrderingBundle\Util\Order\OrderItemInfo;
|
|
use PhpAmqpLib\Message\AMQPMessage;
|
|
use Query\Operator;
|
|
|
|
require_once __DIR__.'/class.Abra.php';
|
|
|
|
class AbraElninoBase extends AbraBase
|
|
{
|
|
public const CHARGE_BALNE = 2;
|
|
|
|
public $syncTimeout = 180; // Sync incoming changes max for 3 minutes
|
|
|
|
protected $main_table = 'products';
|
|
|
|
protected $settings = [
|
|
'lang' => 'cs',
|
|
'web' => null,
|
|
'queue' => null,
|
|
'rabbit_server' => 'rabbitmq.elsvc.net',
|
|
];
|
|
|
|
public static $ABRA_UIDS = [
|
|
'StoreCard' => 'product',
|
|
'ReceivedOrder' => 'order',
|
|
'ReceivedOrderRow' => 'order',
|
|
'Category' => 'ignore',
|
|
'Brand' => 'producer',
|
|
'SeriesBrand' => 'serie',
|
|
'Parameter' => 'parameters',
|
|
'ParameterValue' => 'parameters_values',
|
|
'ParameterAssortmentGroup' => 'parameters_sections',
|
|
'ParameterStoreCard' => 'parameters_products',
|
|
'AssortmentGroup' => 'ignore',
|
|
'ComplementModel' => 'complement_model',
|
|
'ComplementTypeSC' => 'complement_type',
|
|
'Model' => 'model',
|
|
'Damage' => 'damage',
|
|
'Picture' => 'picture',
|
|
];
|
|
|
|
public static $PRODUCT_FIELDS = [
|
|
// Base
|
|
'Code' => 'code',
|
|
'StoreMenuItem_ID' => 'ignore',
|
|
'Quantity' => 'in_store',
|
|
'X_LimitWEB' => 'elnino_in_store_decrement',
|
|
'X_WEBGroup' => 'ignore',
|
|
'VOC_PLN' => 'price',
|
|
'ID' => 'delete',
|
|
'EAN' => 'ean',
|
|
'X_VATRate' => 'vat',
|
|
'Brand_ID' => 'producer_id',
|
|
'SeriesBrand_ID' => 'id_serie',
|
|
'ComplementModel_ID' => 'id_complement_model',
|
|
|
|
// Popis
|
|
'X_Name_Mark' => 'product_line', // Parametr Produktová řada
|
|
'Annotation' => 'short_descr',
|
|
'Description' => 'long_descr',
|
|
|
|
// Flagy
|
|
'X_Gift' => 'flag_G', // Flag Dárek
|
|
'X_Action' => 'flag_A', // Flag Akce
|
|
'X_Sample' => 'ignore', // Flag Vzorek
|
|
'X_Tester' => 'flag_T', // Flag Tester
|
|
'X_Spatter' => 'ignore', // Flag Odstrik
|
|
'X_Set' => 'flag_S', // Flag Set
|
|
'Quantity_ToDelivery' => 'to_deliver', // Flag Na ceste + parametry
|
|
'X_VOEU' => 'region',
|
|
|
|
// Parametry
|
|
'X_SortCosmeticsPL' => 'category', // Kategorie produktu + parametr
|
|
'X_Size' => 'size', // Parametr Velikost
|
|
'Weight' => 'weight', // Parametr Váha
|
|
'X_Damage' => 'damage', // Parameter Poškození
|
|
'X_sexB' => 'sex', // Parametr Pohlaví
|
|
'X_Constitution_PL' => 'constitution', // Parametr Složení
|
|
'X_ShadePL' => 'shade', // Parametr Odstín
|
|
|
|
// Ignores
|
|
'StoreAssortmentGroup_ID' => 'ignore',
|
|
'UnitSize_ID' => 'ignore',
|
|
'SETtype' => 'ignore',
|
|
'Name2' => 'ignore',
|
|
// '' => 'ignore',
|
|
|
|
'X_SETtype' => 'ignore',
|
|
'X_SortCosmetics' => 'ignore',
|
|
'X_SortCosmeticsEN' => 'ignore',
|
|
'X_LimitX_SortCosmeticsENWEB' => 'ignore',
|
|
'X_Note2EN' => 'ignore',
|
|
'X_Note2' => 'ignore',
|
|
'X_ShadeEN' => 'ignore',
|
|
'X_Shade' => 'ignore',
|
|
'X_Constitution_EN' => 'ignore',
|
|
'X_Constitution' => 'ignore',
|
|
'X_Constitution_DE' => 'ignore',
|
|
'X_ShadeDE' => 'ignore',
|
|
'X_Note2DE' => 'ignore',
|
|
'X_EU' => 'ignore',
|
|
'X_IDpar' => 'ignore',
|
|
'X_WEB_Transfer' => 'figure',
|
|
'X_WEB' => 'ignore',
|
|
'Depth' => 'ignore',
|
|
'Height' => 'ignore',
|
|
'Width' => 'ignore',
|
|
'Size' => 'ignore',
|
|
'X_Damage_ID' => 'ignore',
|
|
|
|
// Prices
|
|
'MOC_EUR_GR' => 'ignore',
|
|
'MOC_EUR_PE' => 'ignore',
|
|
'VOC_CZK' => 'ignore',
|
|
'MOC_CZK_KZ' => 'ignore',
|
|
'MOC_CZK_PC' => 'ignore',
|
|
'MOC_CZK_PE' => 'ignore',
|
|
'VOC_EUR' => 'ignore',
|
|
'MOC_CZK_SP' => 'ignore',
|
|
'MOC_CZK_PV' => 'ignore',
|
|
'MOC_CHF' => 'ignore',
|
|
'MOC_CHF_PA' => 'ignore',
|
|
'MOC_BGN' => 'ignore',
|
|
'MOC_EUR_UA' => 'ignore',
|
|
'NAK_CZK_ES' => 'ignore',
|
|
];
|
|
|
|
public static $PICTURE_FIELDS = [
|
|
'StoreCard_ID' => 'id_product',
|
|
'PictureType' => 'type',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $SECTION_FIELDS = [
|
|
'Name' => 'name',
|
|
'Code' => 'ignore',
|
|
'Parent_ID' => 'parent_id',
|
|
'Parent2_ID' => 'ignore',
|
|
'NamePlural' => 'ignore', // Disable plural sync
|
|
'PosIndex' => 'position',
|
|
'AlternativeName' => 'plural',
|
|
'X_Description' => 'descr',
|
|
'X_Activate' => 'figure',
|
|
'Replacement_ID' => 'replacement',
|
|
'ReplacementType' => 'ignore',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $ORDER_FIELDS = [
|
|
'Status_Confirmed' => 'ignore',
|
|
'Status_Closed' => 'ignore',
|
|
'Status_Storno' => 'ignore',
|
|
'Status_Authorization' => 'ignore',
|
|
'UnitPriceWithoutVAT' => 'price',
|
|
'Quantity' => 'quantity',
|
|
'Status' => 'status',
|
|
'Note_Expedition' => 'note_expedition',
|
|
'PackageNumber' => 'ignore',
|
|
];
|
|
|
|
public static $PRODUCER_FIELDS = [
|
|
'Text' => 'name',
|
|
'Posindex' => 'position',
|
|
'X_Description' => 'descr',
|
|
'X_Activate' => 'active',
|
|
'ONDELETE' => 'delete',
|
|
|
|
'Parent_ID' => 'ignore',
|
|
'Replacement_ID' => 'replacement',
|
|
];
|
|
|
|
public static $SERIES_FIELDS = [
|
|
'Name' => 'name',
|
|
'Brand_ID' => 'producer',
|
|
'Sex' => 'sex',
|
|
'X_Description' => 'descr',
|
|
'X_Activate' => 'active',
|
|
'Replacement_ID' => 'ignore',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $PARAMETERS_FIELDS = [
|
|
'Code' => 'id',
|
|
'Name' => 'name',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $PARAMETERS_VALUES_FIELDS = [
|
|
'Parameter_ID' => 'id_parameter',
|
|
'Name' => 'name',
|
|
'Position' => 'position',
|
|
'CDN_ID' => 'ignore',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $PARAMETERS_PRODUCTS_FIELDS = [
|
|
'StoreCard_ID' => 'id_product',
|
|
'ParameterValue_ID' => 'param_value_id',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $PARAMETERS_SECTIONS_FIELDS = [
|
|
'Parameter_ID' => 'id_parameter',
|
|
'StoreAssortmentGroup_ID' => 'id_section',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $COMPLEMENT_MODEL_FIELDS = [
|
|
'Name' => 'name',
|
|
'Code' => 'ignore',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $COMPLEMENT_TYPE_FIELDS = [
|
|
'Name' => 'name',
|
|
'Code' => 'ignore',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $DAMAGE_FIELDS = [
|
|
'Code' => 'code',
|
|
'Name' => 'name',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $UNITSIZE_FIELDS = [
|
|
'Code' => 'code',
|
|
'Name' => 'name',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $MODEL_FIELDS = [
|
|
'SeriesBrand_ID' => 'id_serie',
|
|
'StoreAssortmentGroup_ID' => 'id_category',
|
|
'ComplementModel_ID' => 'id_complement_model',
|
|
'X_Description' => 'descr',
|
|
'X_SEO_URL' => 'ignore',
|
|
'X_Activate' => 'ignore',
|
|
'Replacement_ID' => 'replacement',
|
|
'ONDELETE' => 'delete',
|
|
];
|
|
|
|
public static $GET_ALL_TYPES = [
|
|
'Brand' => [
|
|
'batch' => 100,
|
|
],
|
|
'SeriesBrand' => [
|
|
'batch' => 500,
|
|
],
|
|
'AssortmentGroup' => [
|
|
'batch' => 500,
|
|
],
|
|
'Parameter' => [
|
|
'batch' => 1000,
|
|
],
|
|
'ParameterValue' => [
|
|
'batch' => 1000,
|
|
],
|
|
'ParameterAssortmentGroup' => [
|
|
'batch' => 1000,
|
|
],
|
|
'Scent' => [
|
|
'batch' => 1000,
|
|
],
|
|
'ComplementModel' => [
|
|
'batch' => 1000,
|
|
],
|
|
'ComplementTypeSC' => [
|
|
'batch' => 1000,
|
|
],
|
|
'Model' => [
|
|
'batch' => 500,
|
|
],
|
|
'ElementScentModel' => [
|
|
'batch' => 1000,
|
|
],
|
|
'Damage' => [
|
|
'batch' => 1000,
|
|
],
|
|
'UnitSize' => [
|
|
'batch' => 1000,
|
|
],
|
|
'StoreCard' => [
|
|
'batch' => 100,
|
|
],
|
|
'ParameterStoreCard' => [
|
|
'batch' => 1000,
|
|
],
|
|
'Picture' => [
|
|
'batch' => 1000,
|
|
],
|
|
'SecondaryAssortmentGroup' => [
|
|
'batch' => 1000,
|
|
],
|
|
];
|
|
|
|
protected $lang;
|
|
protected $site;
|
|
|
|
public static $MAX_DISCOUNT = 85;
|
|
|
|
/**
|
|
* [ABRA_UID => [Array of fields to sync]].
|
|
*/
|
|
public static $TRANSLATION_FIELDS = [
|
|
'AssortmentGroup' => [
|
|
'Name',
|
|
'X_Description',
|
|
],
|
|
'Damage' => [
|
|
'Name',
|
|
],
|
|
'Brand' => [
|
|
// 'Text', - same in all languages
|
|
'X_Description',
|
|
],
|
|
'UnitSize' => [
|
|
'Code',
|
|
'Name',
|
|
],
|
|
'ComplementTypeSC' => [
|
|
'Name',
|
|
],
|
|
'Parameter' => [
|
|
'Name',
|
|
],
|
|
'ParameterValue' => [
|
|
'Name',
|
|
],
|
|
'SeriesBrand' => [
|
|
'X_Description',
|
|
],
|
|
'Model' => [
|
|
'X_Description',
|
|
],
|
|
];
|
|
public static $SECONDARY_ASSORTMENT_GROUP_FIELDS;
|
|
public static $SCENT_FIELDS;
|
|
|
|
public static $ENABLED_STORES = [1, 6, 8];
|
|
|
|
protected $languageContext;
|
|
|
|
public function __construct($settings = null)
|
|
{
|
|
ini_set('memory_limit', '512M');
|
|
parent::__construct($settings);
|
|
|
|
$this->languageContext = ServiceContainer::getService(\KupShop\KupShopBundle\Context\LanguageContext::class);
|
|
}
|
|
|
|
public function getOneDataBlock($type, $index, $batch)
|
|
{
|
|
$selection = null;
|
|
$filter = null;
|
|
if (isset($_GET['filter']) && !empty($_GET['filter'])) {
|
|
$filter = explode(',', $_GET['filter']);
|
|
$filter = array_map(function ($value) { return "'".$value."'"; }, $filter);
|
|
$filter = join(',', $filter);
|
|
$selection = 'SELECTION';
|
|
}
|
|
|
|
return $this->client->weGetObjectType($type, $index, $batch, $selection, $filter, $this->settings['web'], $this->settings['lang']);
|
|
}
|
|
|
|
protected $translations = [
|
|
'Sets' => 'Kazety',
|
|
'Testers' => 'Testery',
|
|
'pcs' => 'ks',
|
|
'Shade' => 'Odstín',
|
|
'tester' => 'tester',
|
|
'Sections' => 'Sortiment',
|
|
];
|
|
|
|
protected $batch_size = 100;
|
|
|
|
public function resetProductCache()
|
|
{
|
|
return;
|
|
}
|
|
|
|
public function getOrderStatus(Order $order)
|
|
{
|
|
$result = $this->client->__call('weGetAttribute', [
|
|
$this->settings['web'],
|
|
'ReceivedOrders',
|
|
'ExternalNumber',
|
|
$order->order_no,
|
|
'X_Status',
|
|
'integer',
|
|
]);
|
|
|
|
return $result;
|
|
}
|
|
|
|
// Sync functions
|
|
protected $rabbitConnection;
|
|
protected $rabbitChannel;
|
|
|
|
public function syncTranslations($type, $params)
|
|
{
|
|
if (!isset(static::$TRANSLATION_FIELDS[$type]) && $type != 'all') {
|
|
throw new RuntimeException(sprintf('Translations field mapping is not defined for UID \'%s\'!', $type));
|
|
}
|
|
|
|
if ($type == 'all') {
|
|
$types = array_keys(static::$TRANSLATION_FIELDS);
|
|
} else {
|
|
$types = [$type];
|
|
}
|
|
|
|
// 76940 - should have translations
|
|
foreach ($this->languageContext->getSupported() as $language) {
|
|
// do not import default language
|
|
if ($language->getId() != $this->languageContext->getDefaultId()) {
|
|
// option to select language to sync
|
|
if (isset($_GET['language']) && $language->getId() != $_GET['language']) {
|
|
continue;
|
|
}
|
|
|
|
echo "<br>Starting language {$language->getId()}<br>";
|
|
flush();
|
|
|
|
// set language
|
|
$this->lang = $language->getId();
|
|
$this->settings['lang'] = $language->getId();
|
|
foreach ($types as $syncType) {
|
|
// ugly filter set
|
|
if ($filter = $this->getTranslationsFilter($syncType)) {
|
|
$_GET['filter'] = $filter;
|
|
}
|
|
|
|
// run sync
|
|
$this->getAllData($syncType, $params);
|
|
}
|
|
|
|
echo "<br>Ended language {$language->getId()}<br>";
|
|
flush();
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getTranslationsFilter($type)
|
|
{
|
|
if (isset(static::$TRANSLATION_FIELDS[$type])) {
|
|
$filter = [];
|
|
foreach (static::$TRANSLATION_FIELDS[$type] as $filterField) {
|
|
$filter[] = $filterField;
|
|
}
|
|
$filter[] = 'LastID';
|
|
if (!empty($filter)) {
|
|
return join(',', $filter);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function saveTranslationObject($translation_class, array $idArray, array $values)
|
|
{
|
|
$idArray = array_merge(['id_language' => $this->lang], $idArray);
|
|
$translation_service = ServiceContainer::getService($translation_class);
|
|
$translation_service->saveSingleObject($idArray['id_language'], $idArray['id_object'], $values);
|
|
}
|
|
|
|
public function isTranslationsSync()
|
|
{
|
|
if (!findModule(Modules::TRANSLATIONS)) {
|
|
return false;
|
|
}
|
|
|
|
return (bool) ((isset($_GET['sync_translations']) || ($this->languageContext->getDefaultId() != $this->lang)) && $this->lang != '');
|
|
}
|
|
|
|
public function translationFieldSupported($field)
|
|
{
|
|
if (isset(static::$TRANSLATION_FIELDS[$this->type]) && in_array($field, static::$TRANSLATION_FIELDS[$this->type])) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function syncProducts()
|
|
{
|
|
$startTime = microtime(true);
|
|
try {
|
|
if (!$this->rabbitChannel) {
|
|
// Connect
|
|
$this->rabbitConnection = new PhpAmqpLib\Connection\AMQPStreamConnection($this->settings['rabbit_server'], 5672, 'wpj', 'SbyAMozJ03tPo5EA8rVU', 'main');
|
|
$this->rabbitChannel = $this->rabbitConnection->channel();
|
|
$this->rabbitChannel->basic_qos(null, 200, null);
|
|
$this->rabbitChannel->basic_consume($this->settings['queue'], '', false, false, true, false, [$this, 'process_message']);
|
|
}
|
|
|
|
while (count($this->rabbitChannel->callbacks) && (microtime(true) - $startTime) < $this->syncTimeout) {
|
|
$this->rabbitChannel->wait(null, false, 3);
|
|
}
|
|
var_dump('Messages still pending');
|
|
|
|
// Mark more messages pending
|
|
return true;
|
|
} catch (PhpAmqpLib\Exception\AMQPTimeoutException $e) {
|
|
var_dump('No more messages');
|
|
} catch (Exception $e) {
|
|
$this->log(['syncProducts exception' => $e->getMessage(), 'queue' => $this->settings['queue']]);
|
|
// Clear
|
|
try {
|
|
$this->rabbitChannel->close();
|
|
} catch (Exception $e) {
|
|
}
|
|
|
|
try {
|
|
$this->rabbitConnection->close();
|
|
} catch (Exception $e) {
|
|
}
|
|
|
|
$this->rabbitConnection = null;
|
|
$this->rabbitChannel = null;
|
|
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param AMQPMessage $msg
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
public function process_message($msg)
|
|
{
|
|
$type = $msg->get_properties()['type'] ?? 'abra';
|
|
if ($type === 'claims.v2') {
|
|
$type = 'claims'; // Elnino začalo posílat type=claims.v2 místo claims, a pak se diví, že se jim neposílají emaily, omgwtf
|
|
}
|
|
|
|
$body = json_decode($msg->body);
|
|
|
|
// $this->log(['change' => $body->data, 'queue' => $this->settings['queue']]);
|
|
|
|
try {
|
|
// ignore unknown message types
|
|
if (method_exists($this, "process_message_{$type}")) {
|
|
$this->{"process_message_{$type}"}($body);
|
|
}
|
|
} catch (Exception $e) {
|
|
$this->log(['exception' => $e->getMessage(), 'queue' => $this->settings['queue']]);
|
|
|
|
// Cancel receiving messages
|
|
$msg->delivery_info['channel']->basic_nack($msg->delivery_info['delivery_tag'], false, true);
|
|
$msg->delivery_info['channel']->basic_cancel($msg->delivery_info['delivery_tag']);
|
|
|
|
throw $e;
|
|
}
|
|
|
|
// Skip ACK if in development mode
|
|
if (!isLocalDevelopment()) {
|
|
$logAck = array_search($this->settings['web'], ['kosmetika-zdravi.cz', 'europarfemy.cz']) !== false;
|
|
if ($logAck) {
|
|
$this->log(['msg ack' => json_encode($body), 'queue' => $this->settings['queue']]);
|
|
}
|
|
$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
|
|
}
|
|
}
|
|
|
|
public function process_message_abra($body)
|
|
{
|
|
$this->processChange($body->data);
|
|
}
|
|
|
|
public function process_message_claims($data)
|
|
{
|
|
if (!$data) {
|
|
var_dump('Claims empty');
|
|
|
|
return;
|
|
}
|
|
|
|
if (($data->shop ?? 'nic') != ($this->settings['claims'] ?? 'neco')) {
|
|
var_dump('Claim not for us - '.$data->shop);
|
|
|
|
return;
|
|
}
|
|
|
|
/** @var ReturnReclamationEmail $email */
|
|
$email = ServiceContainer::getService(ReturnReclamationEmail::class);
|
|
$email->setData($data);
|
|
$email->sendEmail($email->getEmail());
|
|
}
|
|
|
|
public function processChange($change, $index = null)
|
|
{
|
|
$change = explode($this->separator, $change);
|
|
|
|
$last_change = $change[3];
|
|
|
|
if (empty($change[1])) {
|
|
var_dump('Prázdný kód: '.print_r($change, true));
|
|
|
|
return $last_change;
|
|
}
|
|
|
|
if (empty(static::$ABRA_UIDS[$change[1]])) {
|
|
var_dump('Nepodporovaný CLSID typ změny: '.print_r($change, true));
|
|
|
|
return $last_change;
|
|
}
|
|
|
|
$type = static::$ABRA_UIDS[$change[1]];
|
|
$this->type = $change[1];
|
|
$method = "sync_{$type}";
|
|
|
|
$this->lang = strtolower(trim($change[7] ?? 'all'));
|
|
$this->site = strtolower(trim($change[6] ?? 'all'));
|
|
|
|
if ($this->lang == 'all') {
|
|
$this->lang = '';
|
|
}
|
|
|
|
if ($this->site == 'all') {
|
|
$this->site = '';
|
|
}
|
|
|
|
// Skip if change not for us
|
|
if (!$this->isMessageForUs($change[3], $change[2], $change[4], $change[5])) {
|
|
// $this->log(['Not for us' => $change[0]]);
|
|
|
|
return $last_change;
|
|
}
|
|
|
|
// Check for run-away transaction
|
|
if (sqlGetConnection()->getTransactionNestingLevel() > 0) {
|
|
throw new Exception('Transaction level non-zero! '.sqlGetConnection()->getTransactionNestingLevel());
|
|
}
|
|
|
|
// if ($index && $level > 1)
|
|
// $last_change = $index;
|
|
|
|
if ($change[2] !== 'LastID') {
|
|
$this->$method($change[3], $change[2], $change[4], $change[5]);
|
|
}
|
|
|
|
return $last_change;
|
|
}
|
|
|
|
public function isMessageForUs($code, $field, $value, $value2)
|
|
{
|
|
$messageLevel = $this->getMessageLevel();
|
|
if (is_null($messageLevel)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function sync_product($code, $field, $value, $value2 = null)
|
|
{
|
|
if (!isset(static::$PRODUCT_FIELDS[$field])) {
|
|
var_dump('Nedefinovaná položka synchronizace:', $field, $value, $value2);
|
|
|
|
return;
|
|
}
|
|
|
|
if (empty($code)) {
|
|
var_dump('Empty code', $field, $value, $value2);
|
|
|
|
return;
|
|
}
|
|
|
|
if ($code[0] == '0') {
|
|
var_dump('Nulový kód '.$code);
|
|
|
|
return;
|
|
}
|
|
|
|
// Preskocit Vialky
|
|
if (($code == '999998' || $code == '999999') && $field === 'X_Activate') {
|
|
return;
|
|
}
|
|
|
|
$id = $this->getMappingFromAbra('product', $code);
|
|
|
|
if (!$id) {
|
|
// if ($column == 'price' || $column == 'in_store')
|
|
// return;
|
|
|
|
// Create Product
|
|
$vat_id = null;
|
|
getVat($vat_id);
|
|
|
|
$this->insertSQL('products', [
|
|
'id' => $code,
|
|
'code' => $code,
|
|
'title' => $code,
|
|
'vat' => $vat_id,
|
|
'figure' => 'Y',
|
|
'campaign' => 'N',
|
|
'date_added' => date('Y-m-d H:i:s'),
|
|
]);
|
|
// maxscale tady zlobi. Kdyz mu nasetuju IDcko natvrdo, nevrati mi ho v sqlInsertId()
|
|
$id = $code;
|
|
|
|
// Add "Novinka - datum" parametr
|
|
try {
|
|
$data = ['id_product' => $id, 'id_parameter' => 35, 'value_float' => time()];
|
|
$this->insertSQL('parameters_products', $data);
|
|
} catch (Exception $e) {
|
|
}
|
|
$this->setMappingFromAbra('product', $id, $code);
|
|
}
|
|
|
|
$this->sync_products_switch($code, $field, $value, $value2, $id);
|
|
}
|
|
|
|
public function sync_products_switch($code, $field, $value, $value2, $id)
|
|
{
|
|
$value = trim($value);
|
|
|
|
$column = static::$PRODUCT_FIELDS[$field];
|
|
|
|
switch ($column) {
|
|
case 'id_category':
|
|
$id_section = $this->getMappingFromAbra('section', $value);
|
|
if (!$id_section) {
|
|
if ($value > 0) {
|
|
echo 'Unknown section ID: '.$value;
|
|
}
|
|
// throw new Exception('Unknown section ID: '.$value);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->deleteSQL('products_in_sections', ['id_product' => $id]);
|
|
|
|
sqlQuery('REPLACE INTO products_in_sections (id_product, id_section)
|
|
VALUES (:id_product, :id_section)', ['id_product' => $id, 'id_section' => $id_section]);
|
|
|
|
return;
|
|
|
|
case 'category_param':
|
|
// Create parameter
|
|
$data = ['id_product' => $id, 'id_parameter' => 28];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
$data['value_list'] = $this->findParameterValue(28, $value);
|
|
$this->insertSQL('parameters_products', $data);
|
|
|
|
$this->scheduleProductTitleUpdate($id);
|
|
|
|
return;
|
|
|
|
case 'unit':
|
|
if ($value != 'ks') {
|
|
echo 'Unknown unit: '.$value;
|
|
// throw new Exception('Unknown unit: '.$value);
|
|
}
|
|
|
|
return;
|
|
|
|
case 'price':
|
|
$value = $this->preparePriceFromAbra($value);
|
|
|
|
$actual = returnSQLResult('SELECT price FROM products WHERE id=:id', ['id' => $id]);
|
|
|
|
if ($value != $actual && $actual > 0) {
|
|
$diff = floor((1 - ($value / $actual)) * 100);
|
|
|
|
if ($diff > 5 && $diff <= $this::$MAX_DISCOUNT) {
|
|
$data = ['id_product' => $id, 'id_parameter' => 34];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
$data = ['id_product' => $id, 'id_parameter' => 36];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
// Oznacit jako 'Zlevneno'
|
|
$data = ['id_product' => $id, 'id_parameter' => 34];
|
|
$data['value_float'] = $diff;
|
|
$this->insertSQL('parameters_products', $data);
|
|
|
|
// Oznacit jako 'Zlevneno - datum'
|
|
$data = ['id_product' => $id, 'id_parameter' => 36];
|
|
$data['value_float'] = time();
|
|
$this->insertSQL('parameters_products', $data);
|
|
|
|
$data = ['id_product' => $id, 'flag' => 'Z'];
|
|
$this->updateProductFlag($data, true);
|
|
} elseif ($diff < -1) {
|
|
$data = ['id_product' => $id, 'flag' => 'Z'];
|
|
$this->updateProductFlag($data, false);
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
case 'producer':
|
|
$value = $this->findProducer($value);
|
|
break;
|
|
|
|
case 'producer_id':
|
|
if ($value == $this->abraNull) {
|
|
$id_producer = null;
|
|
} else {
|
|
$id_producer = $this->getMappingFromAbra('producer', $value);
|
|
}
|
|
$this->updateSQL('products', ['producer' => $id_producer], ['id' => $id]);
|
|
|
|
$this->scheduleProductTitleUpdate($id);
|
|
|
|
return;
|
|
|
|
case 'figure':
|
|
$msgLevel = $this->getMessageLevel();
|
|
$productLevel = returnSQLResult('SELECT figure_level FROM products WHERE id=:id', ['id' => $id]);
|
|
|
|
if ($msgLevel < $productLevel) {
|
|
return false;
|
|
}
|
|
|
|
// On delete, revert to zero
|
|
if ($value === '' || $value === 'DEL') {
|
|
$msgLevel = 0;
|
|
}
|
|
|
|
$value = $this->parseBool($value);
|
|
|
|
$this->updateSQL('products', ['figure' => $value ? 'Y' : 'N', 'figure_level' => $msgLevel], ['id' => $id]);
|
|
$this->scheduleProductTitleUpdate($id);
|
|
|
|
return;
|
|
|
|
case 'delete':
|
|
$column = 'figure';
|
|
$value = $value > 0 ? 'Y' : 'O';
|
|
break;
|
|
|
|
case 'sex':
|
|
$data = ['id_product' => $id, 'id_parameter' => 18];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
switch ($value) {
|
|
case 'M':
|
|
$value = 16;
|
|
break;
|
|
case 'W':
|
|
$value = 17;
|
|
break;
|
|
case 'U':
|
|
$value = 22;
|
|
break;
|
|
case 'K':
|
|
$value = 23;
|
|
break;
|
|
case 'B':
|
|
$value = 24;
|
|
break;
|
|
default:
|
|
throw new Exception('Nedefinované pohlaví: '.$value);
|
|
}
|
|
|
|
$data['value_list'] = $value;
|
|
$this->insertSQL('parameters_products', $data);
|
|
|
|
$this->scheduleProductTitleUpdate($id);
|
|
|
|
return;
|
|
|
|
case 'size':
|
|
$data = ['id_product' => $id, 'id_parameter' => 20];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
if (preg_match('/([0-9,]+)(\w+)?/i', $value, $matches)) {
|
|
$value = $this->preparePriceFromAbra($matches[1]);
|
|
$data['value_float'] = $value;
|
|
if (!empty($matches[2])) {
|
|
$data['unit'] = $matches[2];
|
|
}
|
|
$this->insertSQL('parameters_products', $data);
|
|
}
|
|
|
|
$this->scheduleProductTitleUpdate($id);
|
|
|
|
return;
|
|
|
|
case 'size_value':
|
|
// Value can be "3x10" !!
|
|
$value_string = $value;
|
|
$this->preparePrice($value);
|
|
|
|
if ($value2 == $this->abraNull || $value2 == '') {
|
|
$value2 = null;
|
|
}
|
|
|
|
$this->updateSQL('products', ['size_value' => $value, 'size_unit' => $value2], ['id' => $id]);
|
|
|
|
// This has to be from text representation.
|
|
sqlQuery("UPDATE products p
|
|
LEFT JOIN abra_units au ON p.size_unit = au.id_abra
|
|
SET p.size = CONCAT(REPLACE(:size_value, '.', ','), ' ', IFNULL(au.code,''))
|
|
WHERE p.id=:id", ['id' => $id, 'size_value' => $value_string]);
|
|
|
|
$this->scheduleProductTitleUpdate($id);
|
|
break;
|
|
|
|
case 'weight':
|
|
$data = ['id_product' => $id, 'id_parameter' => 21];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
$value = $this->preparePriceFromAbra($value);
|
|
if (!empty($value)) {
|
|
$data['value_float'] = $value;
|
|
$this->insertSQL('parameters_products', $data);
|
|
}
|
|
|
|
return;
|
|
|
|
case 'region':
|
|
$data = ['id_product' => $id, 'id_parameter' => 26];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
switch ($value) {
|
|
case '1':
|
|
$value = 19;
|
|
break;
|
|
case '2':
|
|
$value = 20;
|
|
break;
|
|
case '4':
|
|
$value = 21;
|
|
break;
|
|
}
|
|
$data['value_list'] = $value;
|
|
$this->insertSQL('parameters_products', $data);
|
|
|
|
return;
|
|
|
|
case 'product_line':
|
|
$data = ['id_product' => $id, 'id_parameter' => 27];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
$value = $this->findParameterValue(27, $value);
|
|
$data['value_list'] = $value;
|
|
$this->insertSQL('parameters_products', $data);
|
|
|
|
$this->scheduleProductTitleUpdate($id);
|
|
|
|
return;
|
|
|
|
case 'flag_S':
|
|
if ($value == '') {
|
|
$value = 'Ne';
|
|
} elseif ($value == 'Kazeta') {
|
|
$value = 'Ano';
|
|
} else {
|
|
throw new Exception("Neznámý set: {$value}");
|
|
}
|
|
|
|
// no break
|
|
case 'flag_G':
|
|
case 'flag_A':
|
|
case 'flag_T':
|
|
$flag = substr($column, 5);
|
|
$value = $this->parseBool($value);
|
|
|
|
$data = ['id_product' => $id, 'flag' => $flag];
|
|
$this->updateProductFlag($data, $value);
|
|
|
|
return;
|
|
|
|
case 'vat':
|
|
$value = $this->findVAT($value);
|
|
break;
|
|
|
|
case 'in_store':
|
|
$value2 = strtolower($value2);
|
|
|
|
if (!$value2) {
|
|
var_dump('Neni cislo skladu!!!');
|
|
|
|
return;
|
|
}
|
|
|
|
if (!in_array($value2, static::$ENABLED_STORES)) {
|
|
var_dump("Ignorace skladu {$value2} !!!");
|
|
|
|
return;
|
|
}
|
|
|
|
$value = intval($value);
|
|
|
|
$storeFields = 'in_store_'.join(', in_store_', static::$ENABLED_STORES);
|
|
$store = sqlFetchAssoc(sqlQuery('SELECT FIND_IN_SET(\'N\', campaign) AS new, in_store, '.$storeFields.' FROM products WHERE id=:id', ['id' => $id]));
|
|
|
|
$actual = $store['in_store'];
|
|
|
|
$store['in_store_'.$value2] = $value;
|
|
|
|
// sum all stores for in_store field
|
|
$value = 0;
|
|
foreach (static::$ENABLED_STORES as $storeNumber) {
|
|
$value += $store['in_store_'.$storeNumber] ?? 0;
|
|
}
|
|
$store['in_store'] = $value;
|
|
|
|
if ($value > $actual && !$store['new']) {
|
|
// Oznacit jako 'Nove naskladneno'
|
|
$data = ['id_product' => $id, 'id_parameter' => 31];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
$data['value_float'] = time();
|
|
$this->insertSQL('parameters_products', $data);
|
|
|
|
// Add "Nove naskladneno" flag
|
|
$data['flag'] = 'R';
|
|
$this->updateProductFlag($data, true);
|
|
|
|
// Remove "Na ceste" flag
|
|
$data['flag'] = 'C';
|
|
$this->updateProductFlag($data, false);
|
|
}
|
|
unset($store['new']);
|
|
|
|
$this->updateSQL('products', $store, ['id' => $id]);
|
|
|
|
$this->scheduleProductTitleUpdate($id);
|
|
|
|
return;
|
|
|
|
case 'to_deliver':
|
|
$date = DateTime::createFromFormat('j.n.Y', $value2);
|
|
|
|
// Quantity
|
|
$data = ['id_product' => $id, 'id_parameter' => 32];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
if ($date && $value) {
|
|
$data['value_float'] = intval($value);
|
|
$this->insertSQL('parameters_products', $data);
|
|
}
|
|
|
|
// Date
|
|
$data = ['id_product' => $id, 'id_parameter' => 33];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
|
|
if ($date && $value) {
|
|
$data['value_float'] = $date->getTimestamp();
|
|
$this->insertSQL('parameters_products', $data);
|
|
}
|
|
|
|
// Flag
|
|
$data['flag'] = 'C';
|
|
$this->updateProductFlag($data, $date && $value);
|
|
|
|
return;
|
|
|
|
case 'ean':
|
|
$this->prepareNull($value);
|
|
break;
|
|
|
|
case 'ignore':
|
|
return;
|
|
|
|
case 'short_descr':
|
|
break;
|
|
|
|
case 'elnino_in_store_decrement':
|
|
break;
|
|
|
|
default:
|
|
$this->sync_products_common($code, $field, $value, $value2, $id);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->updateSQL('products', [$column => $value], ['id' => $id]);
|
|
|
|
return;
|
|
}
|
|
|
|
protected function sync_products_common($code, $field, $value, $value2 = null, $id = null)
|
|
{
|
|
$column = static::$PRODUCT_FIELDS[$field];
|
|
|
|
switch ($column) {
|
|
case 'id_section':
|
|
case 'id_complement_model':
|
|
case 'id_serie':
|
|
$value = $this->parseNullable($value);
|
|
$this->updateSQL('abra_products', [$column => $value], ['id_product' => $id]);
|
|
$this->scheduleUpdateCommon($id);
|
|
break;
|
|
|
|
case 'id_complement_type':
|
|
case 'name2':
|
|
if ($value == $this->abraNull) {
|
|
$value = null;
|
|
}
|
|
$this->updateSQL($this->main_table, [$column => $value], ['id' => $id]);
|
|
$this->scheduleUpdateCommon($id);
|
|
break;
|
|
|
|
case 'size_value':
|
|
// Value can be "3x10" !!
|
|
$value_string = $value;
|
|
$tmpArr = explode('x', $value);
|
|
if (count($tmpArr) > 1) {
|
|
$value = floatval(trim($tmpArr[0])) * floatval(trim($tmpArr[1]));
|
|
} else {
|
|
$this->preparePrice($value);
|
|
}
|
|
|
|
if ($value2 == $this->abraNull || $value2 == '') {
|
|
$value2 = null;
|
|
}
|
|
|
|
$this->updateSQL($this->main_table, ['size_value' => $value, 'size_unit' => $value2], ['id' => $id]);
|
|
|
|
// This has to be from text representation.
|
|
sqlQuery("UPDATE {$this->main_table} p
|
|
LEFT JOIN abra_units au ON p.size_unit = au.id_abra
|
|
SET p.size = CONCAT(REPLACE(:size_value, '.', ','), ' ', IFNULL(au.code,''))
|
|
WHERE p.id=:id", ['id' => $id, 'size_value' => $value_string]);
|
|
|
|
$this->scheduleUpdateCommon($id);
|
|
break;
|
|
|
|
case 'damage':
|
|
$value = $this->parseNullable($value);
|
|
|
|
$this->updateSQL($this->main_table, ['damage' => $value], ['id' => $id]);
|
|
$this->scheduleUpdateCommon($id);
|
|
break;
|
|
|
|
case 'constitution':
|
|
$this->updateSQL($this->main_table, ['set' => $value], ['id' => $id]);
|
|
$this->scheduleUpdateCommon($id);
|
|
break;
|
|
|
|
case 'shade':
|
|
$this->updateSQL($this->main_table, ['shade' => $value], ['id' => $id]);
|
|
$this->scheduleUpdateCommon($id);
|
|
break;
|
|
|
|
case 'annotation':
|
|
$this->updateSQL($this->main_table, ['annotation' => $value], ['id' => $id]);
|
|
$this->scheduleUpdateCommon($id, true);
|
|
break;
|
|
|
|
default:
|
|
var_dump('Nedefinovaná položka synchronizace: '.$field);
|
|
}
|
|
}
|
|
|
|
public function sync_section($code, $field, $value)
|
|
{
|
|
$id = $this->getMappingFromAbra('section', $code);
|
|
|
|
if (!$id) {
|
|
// Create Product
|
|
$vat_id = null;
|
|
getVat($vat_id);
|
|
$this->insertSQL('sections', ['name' => $value]);
|
|
$id = sqlInsertId();
|
|
|
|
$this->insertSQL('sections_relation', ['id_section' => $id, 'id_topsection' => null, 'position' => 999]);
|
|
|
|
$this->setMappingFromAbra('section', $id, $code);
|
|
}
|
|
|
|
$column = static::$SECTION_FIELDS[$field];
|
|
|
|
// translations sync
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'descr':
|
|
$blocks = ServiceContainer::getService(\KupShop\I18nBundle\Translations\BlocksTranslation::class);
|
|
$idRootBlock = $this->selectSQL('sections', ['id' => $id], ['id_block'])->fetchColumn();
|
|
if ($idRootBlock) {
|
|
$objectID = $this->selectSQL('blocks', ['id_parent' => $idRootBlock, 'id_root' => $idRootBlock], ['id'])->fetchColumn();
|
|
$blocks->saveSingleObject($this->lang, $objectID, ['content' => $value]);
|
|
}
|
|
break;
|
|
default:
|
|
$this->saveTranslationObject(SectionsTranslation::class, ['id_object' => $id], [$column => $value]);
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'parent_id':
|
|
$parent_id = $this->getMappingFromAbra('section', $value);
|
|
if (!$parent_id) {
|
|
if ($value > 0) {
|
|
echo 'Unknown section ID: '.$value;
|
|
}
|
|
// throw new Exception('Unknown section ID: '.$value);
|
|
|
|
break;
|
|
}
|
|
|
|
sqlQuery('DELETE FROM sections_relation WHERE id_section=:id', ['id' => $id]);
|
|
|
|
sqlQuery('INSERT INTO sections_relation (id_section, id_topsection)
|
|
VALUES (:id, :parent_id)', ['id' => $id, 'parent_id' => $parent_id, 'position' => 999]);
|
|
|
|
MenuSectionTree::invalidateCache();
|
|
|
|
return;
|
|
|
|
case 'position':
|
|
sqlQuery('UPDATE '.getTableName('sections_relation').'
|
|
SET position=:position
|
|
WHERE id_section=:id', ['id' => $id, 'position' => $value]);
|
|
|
|
return;
|
|
|
|
case 'descr':
|
|
/** @var \KupShop\ContentBundle\Util\Block $blockService */
|
|
$blockService = ServiceContainer::getService(\KupShop\ContentBundle\Util\Block::class);
|
|
|
|
$blockService->insertFirstBlock('sections', $id, $value);
|
|
|
|
return;
|
|
|
|
case 'figure':
|
|
$this->updateSQL('sections', ['figure' => ($value == 'Ano' ? 'Y' : 'N')], ['id' => $id]);
|
|
|
|
return;
|
|
|
|
case 'ignore':
|
|
return;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('sections', ['id' => $id]);
|
|
|
|
return;
|
|
|
|
case 'replacement':
|
|
$id_new = $this->getMappingFromAbra('section', $value);
|
|
if ($id && $id_new) {
|
|
$this->createRewrite(\KupShop\ElninoBundle\Util\Rewrite::TYPE_CATEGORY, $id_new, [
|
|
's' => 'category',
|
|
'IDcat' => $id,
|
|
]);
|
|
}
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Section: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
|
|
default:
|
|
$this->updateSQL('sections', [$column => $value], ['id' => $id]);
|
|
}
|
|
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, $id);
|
|
}
|
|
|
|
// Always update only one section
|
|
public function getSectionIDs($abra_id, $sex)
|
|
{
|
|
if (!$abra_id) {
|
|
return null;
|
|
}
|
|
|
|
$sections = sqlFetchAll(sqlQuery('SELECT abs.id_section AS id, sr.id_topsection
|
|
FROM abra_sections abs
|
|
LEFT JOIN sections_relation sr ON sr.id_section = abs.id_section
|
|
WHERE id_abra=:code
|
|
ORDER BY abs.id_section',
|
|
['code' => $abra_id]
|
|
));
|
|
|
|
if (empty($sections)) {
|
|
var_dump('unknown section: '.$abra_id);
|
|
|
|
return null;
|
|
}
|
|
|
|
return array_map(function ($x) {
|
|
return $x['id'];
|
|
}, $sections);
|
|
}
|
|
|
|
public function sync_producer($code, $field, $value)
|
|
{
|
|
$id = $this->getMappingFromAbra('producer', $code);
|
|
|
|
if (!$id) {
|
|
// Create Product
|
|
$vat_id = null;
|
|
getVat($vat_id);
|
|
$max_position = returnSQLResult('SELECT MAX(position) FROM producers');
|
|
$this->insertSQL('producers', ['name' => $code, 'position' => $max_position + 1]);
|
|
$id = sqlInsertId();
|
|
|
|
$this->setMappingFromAbra('producer', $id, $code);
|
|
}
|
|
|
|
if (empty(static::$PRODUCER_FIELDS[$field])) {
|
|
return;
|
|
}
|
|
|
|
$column = static::$PRODUCER_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'descr':
|
|
$blocks = ServiceContainer::getService(\KupShop\I18nBundle\Translations\BlocksTranslation::class);
|
|
$idRootBlock = $this->selectSQL('producers', ['id' => $id], ['id_block'])->fetchColumn();
|
|
if ($idRootBlock) {
|
|
$objectID = $this->selectSQL('blocks', ['id_parent' => $idRootBlock, 'id_root' => $idRootBlock, 'position' => 1], ['id'])->fetchColumn();
|
|
} else {
|
|
// create empty block
|
|
$service = $this->getBlockUtil();
|
|
$objectID = $service->insertFirstBlock('producers', $id, '');
|
|
}
|
|
|
|
if ($objectID) {
|
|
$blocks->saveSingleObject($this->lang, $objectID, ['content' => $value]);
|
|
}
|
|
break;
|
|
default:
|
|
$this->saveTranslationObject(ProducersTranslation::class, ['id_object' => $id], [$column => $value]);
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
return;
|
|
|
|
case 'position':
|
|
// $this->updateSQL('producers', ['position' => $value], ['id' => $id]);
|
|
return;
|
|
|
|
case 'descr':
|
|
$blockUtil = $this->getBlockUtil();
|
|
$blockUtil->insertFirstBlock('producers', $id, $value);
|
|
|
|
return;
|
|
|
|
case 'active':
|
|
$this->updateSQL('producers', ['active' => ($value == 'Ano' ? 'Y' : 'N')], ['id' => $id]);
|
|
break;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('producers', ['id' => $id]);
|
|
break;
|
|
|
|
case 'replacement':
|
|
$id_new = $this->getMappingFromAbra('producer', $value);
|
|
if ($id && $id_new) {
|
|
$this->createRewrite(\KupShop\ElninoBundle\Util\Rewrite::TYPE_PRODUCER, $id_new, [
|
|
's' => 'category',
|
|
'IDpd' => $id,
|
|
]);
|
|
}
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Producer: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
|
|
default:
|
|
$this->updateSQL('producers', [$column => $value], ['id' => $id]);
|
|
}
|
|
|
|
$this->scheduleProductTitleUpdate(null, null, null, $id);
|
|
}
|
|
|
|
public function sync_parameters($code, $field, $value)
|
|
{
|
|
$id = $this->getMappingFromAbra('parameter', $code);
|
|
|
|
if (!$id) {
|
|
$this->insertSQL('parameters', ['value_type' => 'list']);
|
|
$id = sqlInsertId();
|
|
|
|
$this->setMappingFromAbra('parameter', $id, $code);
|
|
}
|
|
|
|
$column = static::$PARAMETERS_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
$this->saveTranslationObject(ParametersTranslation::class, ['id_object' => $id], [$column => $value]);
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
break;
|
|
|
|
case 'name':
|
|
$value = str_replace(' Ano x Ne', '', $value);
|
|
|
|
$this->updateSQL('parameters', ['name' => $value], ['id' => $id]);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Parameters: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('parameters', ['id' => $id]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function sync_parameters_values($code, $field, $value)
|
|
{
|
|
$id = $this->getMappingFromAbra('parameters_value', $code);
|
|
|
|
if (!$id && $value) {
|
|
$id_parameter = $this->getMappingFromAbra('parameter', $value);
|
|
|
|
$this->insertSQL('parameters_list', ['id_parameter' => $id_parameter, 'value' => '', 'description' => '']);
|
|
$id = sqlInsertId();
|
|
|
|
$this->setMappingFromAbra('parameters_value', $id, $code);
|
|
}
|
|
|
|
$column = static::$PARAMETERS_VALUES_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'name':
|
|
$this->saveTranslationObject(ParametersListTranslation::class, ['id_object' => $id], ['value' => $value]);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
break;
|
|
|
|
case 'name':
|
|
$this->updateSQL('parameters_list', ['value' => $value], ['id' => $id]);
|
|
break;
|
|
|
|
case 'position':
|
|
$this->updateSQL('parameters_list', ['position' => $value], ['id' => $id]);
|
|
break;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('parameters_list', ['id' => $id]);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Parameters Values: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
public function sync_parameters_products($code, $field, $value)
|
|
{
|
|
$id = $this->getMappingFromAbra('parameters_product', $code);
|
|
|
|
$column = static::$PARAMETERS_PRODUCTS_FIELDS[$field];
|
|
|
|
if (!$id) {
|
|
// Only create if having valid product ID
|
|
if ($column != 'id_product' || !$value) {
|
|
var_dump('Nejde vytvorit parametr, nemám produkt');
|
|
|
|
return;
|
|
}
|
|
|
|
if ($this->main_table === 'products') {
|
|
$id_product = $this->getMappingFromAbra('product', $value);
|
|
} else {
|
|
$id_variation = $this->getMappingFromAbra('product', $value);
|
|
$id_product = returnSQLResult('SELECT id_product FROM products_variations WHERE id=:id', [
|
|
'id' => $id_variation,
|
|
]);
|
|
}
|
|
if (!$id_product) {
|
|
var_dump("Neexistujici produkt {$value}");
|
|
|
|
return;
|
|
}
|
|
|
|
$id_parameter = $this->getMappingFromAbra('parameter', '1');
|
|
|
|
$values = ['id_parameter' => $id_parameter, 'id_product' => $id_product];
|
|
if (isset($id_variation)) {
|
|
$values['id_variation'] = $id_variation;
|
|
}
|
|
$this->insertSQL('parameters_products', $values);
|
|
|
|
$id = sqlInsertId();
|
|
|
|
$this->setMappingFromAbra('parameters_product', $id, $code);
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
break;
|
|
|
|
case 'id_product':
|
|
if (empty($value)) {
|
|
return;
|
|
}
|
|
|
|
if ($this->main_table === 'products') {
|
|
$id_product = $this->getMappingFromAbra('product', $value);
|
|
} else {
|
|
$id_variation = $this->getMappingFromAbra('product', $value);
|
|
$id_product = returnSQLResult('SELECT id_product FROM products_variations WHERE id=:id', [
|
|
'id' => $id_variation,
|
|
]);
|
|
}
|
|
|
|
if (is_null($id_product)) {
|
|
var_dump("Neexistujici produkt {$value}");
|
|
break;
|
|
}
|
|
|
|
$values = ['id_product' => $id_product];
|
|
if (isset($id_variation)) {
|
|
$values['id_variation'] = $id_variation;
|
|
}
|
|
$this->updateSQL('parameters_products', $values, ['id' => $id]);
|
|
break;
|
|
|
|
case 'param_value_id':
|
|
if (empty($value)) {
|
|
return;
|
|
}
|
|
|
|
$id_value = $this->getMappingFromAbra('parameters_value', $value);
|
|
$id_parameter = returnSQLResult('SELECT id_parameter FROM parameters_list WHERE id=:id', ['id' => $id_value]);
|
|
$this->updateSQL('parameters_products', ['value_list' => $id_value, 'id_parameter' => $id_parameter], ['id' => $id]);
|
|
break;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('parameters_products', ['id' => $id]);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Parameters Products: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
public function sync_parameters_sections($code, $field, $value)
|
|
{
|
|
$ids = $this->getMappingFromAbraMultiple('parameters_section', $code);
|
|
|
|
if (count($ids) <= 0) {
|
|
// insert new abra row or rows
|
|
switch ($field) {
|
|
case 'AssortmentGroup_ID':
|
|
foreach ($this->getMappingFromAbraMultiple('section', $value) as $sectionID) {
|
|
$this->insertSQL('abra_parameters_sections', ['id_abra' => $code, 'id_section' => $sectionID]);
|
|
}
|
|
break;
|
|
case 'Parameter_ID':
|
|
$parameterID = $this->getMappingFromAbra('parameter', $value);
|
|
$this->insertSQL('abra_parameters_sections', ['id_abra' => $code, 'id_parameter' => $parameterID]);
|
|
break;
|
|
}
|
|
} else {
|
|
// update existing rows (or insert new combinations of abra_id and kupshop id_section)
|
|
switch ($field) {
|
|
case 'AssortmentGroup_ID':
|
|
foreach ($this->getMappingFromAbraMultiple('section', $value) as $sectionID) {
|
|
$row = sqlQueryBuilder()->select('*')->from('abra_parameters_sections')
|
|
->where('id_abra=:id_abra AND id_section=:id_section')
|
|
->setParameters(['id_abra' => $code, 'id_section' => $sectionID])
|
|
->setMaxResults(1)->execute()->fetch();
|
|
// combination of abra_id and kupshop id_section does not exists, so create it
|
|
if (!$row) {
|
|
// find existing abra row
|
|
$row = sqlQueryBuilder()->select('*')->from('abra_parameters_sections')
|
|
->where('id_abra=:id_abra')
|
|
->setParameters(['id_abra' => $code])
|
|
->setMaxResults(1)->execute()->fetch();
|
|
if ($row && isset($row['id_parameter'])) {
|
|
// duplicate existing abra row
|
|
$this->insertSQL('abra_parameters_sections', ['id_abra' => $code, 'id_section' => $sectionID, 'id_parameter' => $row['id_parameter']]);
|
|
} else {
|
|
// create new abra row
|
|
$this->insertSQL('abra_parameters_sections', ['id_abra' => $code, 'id_section' => $sectionID]);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 'Parameter_ID':
|
|
$parameterID = $this->getMappingFromAbra('parameter', $value);
|
|
$this->updateSQL('abra_parameters_sections', ['id_parameter' => $parameterID], ['id_abra' => $code]);
|
|
break;
|
|
case 'ONDELETE':
|
|
// remove related rows (parameters_sections)
|
|
foreach ($this->getMappingFromAbraMultiple('parameters_section', $code) as $parametersSectionsID) {
|
|
$this->deleteSQL('parameters_sections', ['id' => $parametersSectionsID]);
|
|
}
|
|
// remove abra_parameters_sections rows
|
|
$this->deleteSQL('abra_parameters_sections', ['id_abra' => $code]);
|
|
|
|
return;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// when $field IS NOT 'ONDELETE', update kupshop parameters_sections table
|
|
$abraSelection = sqlQueryBuilder()->select('*')->from('abra_parameters_sections')
|
|
->where('id_abra=:id_abra')->setParameter('id_abra', $code)
|
|
->execute()->fetchAll();
|
|
foreach ($abraSelection as $abraRow) {
|
|
// update/insert only if id_section and id_parameter is present
|
|
if (isset($abraRow['id_section']) && isset($abraRow['id_parameter'])) {
|
|
// update existing kupshop parameters_sections row or insert new one
|
|
if (isset($abraRow['id_parameters_section'])) {
|
|
$this->updateSQL('parameters_sections', ['id_section' => $abraRow['id_section'], 'id_parameter' => $abraRow['id_parameter']], ['id' => $abraRow['id_parameters_section']]);
|
|
} else {
|
|
$this->insertSQL('parameters_sections', ['id_section' => $abraRow['id_section'], 'id_parameter' => $abraRow['id_parameter']]);
|
|
$id = sqlInsertId();
|
|
$this->updateSQL('abra_parameters_sections', ['id_parameters_section' => $id], ['id_abra' => $code, 'id_section' => $abraRow['id_section'], 'id_parameter' => $abraRow['id_parameter']]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public function sync_complement_model($code, $field, $value)
|
|
{
|
|
$id = returnSQLResult('SELECT id_abra FROM abra_complement_models WHERE id_abra=:code', ['code' => $code]);
|
|
|
|
if (!$id) {
|
|
$this->insertSQL('abra_complement_models', ['id_abra' => $code]);
|
|
$id = $code;
|
|
}
|
|
|
|
$column = static::$COMPLEMENT_MODEL_FIELDS[$field];
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
break;
|
|
|
|
case 'name':
|
|
$this->updateSQL('abra_complement_models', ['name' => $value], ['id_abra' => $id]);
|
|
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, null, $id);
|
|
break;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('abra_complement_models', ['id_abra' => $id]);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Complement Model: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
public function sync_complement_type($code, $field, $value)
|
|
{
|
|
$id = returnSQLResult('SELECT id_abra FROM abra_complement_types WHERE id_abra=:code', ['code' => $code]);
|
|
|
|
if (!$id) {
|
|
$this->insertSQL('abra_complement_types', ['id_abra' => $code]);
|
|
$id = $code;
|
|
}
|
|
|
|
$column = static::$COMPLEMENT_TYPE_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
$this->saveTranslationObject(AbraComplementTypeTranslation::class, ['id_object' => $id], [$column => $value]);
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, null, null, $id);
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
break;
|
|
|
|
case 'name':
|
|
$this->updateSQL('abra_complement_types', ['name' => $value], ['id_abra' => $id]);
|
|
break;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('abra_complement_types', ['id_abra' => $id]);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Complement Type: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
}
|
|
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, null, null, $id);
|
|
}
|
|
|
|
public function sync_model($code, $field, $value)
|
|
{
|
|
$abra_model = sqlFetchAssoc($this->selectSQL('abra_models', ['id_abra' => $code]));
|
|
|
|
if (!$abra_model) {
|
|
$this->insertSQL('abra_models', ['id_abra' => $code]);
|
|
}
|
|
|
|
if (empty(static::$MODEL_FIELDS[$field])) {
|
|
return;
|
|
}
|
|
|
|
$column = static::$MODEL_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
$this->saveTranslationObject(AbraModelsTranslation::class, ['id_object' => $code], [$column => $value]);
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, $code);
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
break;
|
|
|
|
case 'id_serie':
|
|
$value = $this->parseNullable($value);
|
|
$this->updateSQL('abra_models', ['id_serie' => $value], ['id_abra' => $code]);
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, $code);
|
|
break;
|
|
|
|
case 'id_complement_model':
|
|
$value = $this->parseNullable($value);
|
|
$this->updateSQL('abra_models', ['id_complement_model' => $value], ['id_abra' => $code]);
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, $code);
|
|
break;
|
|
|
|
case 'descr':
|
|
$this->updateSQL('abra_models', ['descr' => $value], ['id_abra' => $code]);
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, $code);
|
|
break;
|
|
|
|
case 'id_category':
|
|
$value = $this->parseNullable($value);
|
|
$this->updateSQL('abra_models', ['id_section' => $value], ['id_abra' => $code]);
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, $code);
|
|
|
|
return;
|
|
|
|
case 'delete':
|
|
// Move all variations away from this model products
|
|
sqlQuery('UPDATE products_variations pv
|
|
JOIN products p ON pv.id_product = p.id
|
|
SET pv.id_product = 0
|
|
WHERE p.id_model = :id_model', ['id_model' => $code]);
|
|
$this->deleteSQL('abra_models', ['id_abra' => $code]);
|
|
|
|
// no break
|
|
case 'replacement':
|
|
$abra_model_new = $this->selectSQL('abra_models', ['id_abra' => $value])->fetch();
|
|
if ($abra_model && $abra_model_new) {
|
|
$this->createRewrite(\KupShop\ElninoBundle\Util\Rewrite::TYPE_MODEL, $abra_model_new['old_kupshop_id'], [
|
|
's' => 'product',
|
|
'IDmodel' => $abra_model['old_kupshop_id'],
|
|
]);
|
|
}
|
|
|
|
return;
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Model: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
public function sync_serie($code, $field, $value)
|
|
{
|
|
$id = $this->getMappingFromAbra('serie', $code);
|
|
|
|
if (!$id) {
|
|
// Create Product
|
|
$this->insertSQL('abra_series', ['id_abra' => $code]);
|
|
$id = sqlInsertId();
|
|
}
|
|
|
|
if (empty(static::$SERIES_FIELDS[$field])) {
|
|
return;
|
|
}
|
|
|
|
$column = static::$SERIES_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
$this->saveTranslationObject(AbraSeriesTranslation::class, ['id_object' => $code], [$column => $value]);
|
|
$this->scheduleProductTitleUpdate(null, null, $id);
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
return;
|
|
|
|
case 'producer':
|
|
$id_producer = $this->getMappingFromAbra('producer', $value);
|
|
$this->updateSQL('abra_series', ['id_producer' => $id_producer ?: null], ['id_serie' => $id]);
|
|
break;
|
|
|
|
case 'active':
|
|
$active = $value == 'Ano' ? 'Y' : 'N';
|
|
$this->updateSQL('abra_series', ['active' => $active], ['id_serie' => $id]);
|
|
break;
|
|
|
|
case 'delete':
|
|
$products = sqlQueryBuilder()
|
|
->select('p.id', 'pv.id as id_variation')
|
|
->fromProducts()
|
|
->joinVariationsOnProducts()
|
|
->where('p.id_serie = :id_serie')
|
|
->setParameter('id_serie', $id);
|
|
|
|
foreach ($products as $product) {
|
|
$this->scheduleProductTitleUpdate($product['id'], $product['id_variation']);
|
|
}
|
|
|
|
$this->deleteSQL('abra_series', ['id_serie' => $id]);
|
|
break;
|
|
|
|
case 'descr':
|
|
$this->handleTranslatedText(['table' => 'abra_series', 'field' => $column, 'where' => ['id_serie' => $id]], $value);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Serie: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
|
|
default:
|
|
$this->updateSQL('abra_series', [$column => $value], ['id_serie' => $id]);
|
|
}
|
|
|
|
$this->scheduleProductTitleUpdate(null, null, $id);
|
|
}
|
|
|
|
public function sync_damage($code, $field, $value)
|
|
{
|
|
$id = returnSQLResult('SELECT id_abra FROM abra_damages WHERE id_abra=:code', ['code' => $code]);
|
|
|
|
if (!$id) {
|
|
$this->insertSQL('abra_damages', ['id_abra' => $code]);
|
|
$id = $code;
|
|
}
|
|
|
|
$column = static::$DAMAGE_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
default:
|
|
$this->saveTranslationObject(AbraDamagesTranslation::class, ['id_object' => $id], [$column => $value]);
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
break;
|
|
|
|
case 'code':
|
|
$this->updateSQL('abra_damages', ['code' => $value], ['id_abra' => $id]);
|
|
break;
|
|
|
|
case 'name':
|
|
$this->updateSQL('abra_damages', ['name' => $value], ['id_abra' => $id]);
|
|
break;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('abra_damages', ['id_abra' => $id]);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Damage: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
public static $PICTURE_TYPES = [
|
|
'1' => 'nothing',
|
|
'2' => 'Y',
|
|
'3' => 'nothing',
|
|
'4' => 'nothing',
|
|
'5' => 'N',
|
|
'6' => 'nothing',
|
|
'default' => 'ignore',
|
|
];
|
|
|
|
// 550949495~|~Picture~|~StoreCard_ID~|~171467~|~71203~|~~|~all~|~all
|
|
|
|
// 563980919~|~Picture~|~StoreCard_ID~|~173141~|~71602~|~~|~all~|~all
|
|
// 563980920~|~Picture~|~PictureType~|~173141~|~4~|~~|~all~|~all
|
|
public function sync_picture($code, $field, $value)
|
|
{
|
|
$row = sqlFetchAssoc($this->selectSQL('abra_pictures', ['id_abra' => $code]));
|
|
$column = static::$PICTURE_FIELDS[$field];
|
|
|
|
if (!$row) {
|
|
$this->setMappingFromAbra('picture', null, $code);
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'id_product':
|
|
$id_product = returnSQLResult('SELECT id FROM products WHERE code=:code', ['code' => $value]);
|
|
|
|
if (!$id_product) {
|
|
return;
|
|
}
|
|
|
|
$this->updateSQL('abra_pictures', ['id_abra_product' => $value], ['id_abra' => $code]);
|
|
|
|
$product = sqlFetchArray(sqlQuery('SELECT apr.id_product, ap.id_picture
|
|
FROM abra_pictures ap
|
|
JOIN abra_products apr ON apr.id_abra = ap.id_abra_product
|
|
WHERE ap.id_abra=:id_abra',
|
|
['id_abra' => $code]));
|
|
|
|
$this->scheduleProductTitleUpdate($product['id_product']);
|
|
break;
|
|
case 'type':
|
|
$product = sqlFetchArray(sqlQuery('SELECT apr.id_product, ap.id_picture
|
|
FROM abra_pictures ap
|
|
JOIN abra_products apr ON apr.id_abra = ap.id_abra_product
|
|
WHERE ap.id_abra=:id_abra',
|
|
['id_abra' => $code]));
|
|
|
|
$type = null;
|
|
if (isset(static::$PICTURE_TYPES[$value])) {
|
|
switch (static::$PICTURE_TYPES[$value]) {
|
|
case 'ignore':
|
|
return false;
|
|
case 'nothing':
|
|
break;
|
|
case 'coty_video':
|
|
$pathFinder = PathFinder::getService();
|
|
$videosDir = $pathFinder->getDataDir().'photos/shared/videos/'.mb_substr('00'.$code, -2);
|
|
@mkdir($videosDir, 0777, true);
|
|
$videoName = $code.'_'.$value.'.mp4';
|
|
if (file_exists($videosDir.'/'.$videoName)) {
|
|
$this->updateSQL('abra_pictures', ['type' => $value], ['id_abra' => $code]);
|
|
} else {
|
|
$downloader = new Downloader();
|
|
if ($downloader->copyRemoteFile(trim('https://test:test@server23.elnino.cz:81/?id='.$code), $videosDir.'/'.$videoName)) {
|
|
$this->updateSQL('abra_pictures', ['type' => $value], ['id_abra' => $code]);
|
|
}
|
|
}
|
|
|
|
return;
|
|
default:
|
|
$type = static::$PICTURE_TYPES[$value];
|
|
}
|
|
} elseif (isset(static::$PICTURE_TYPES['default'])) {
|
|
switch (static::$PICTURE_TYPES['default']) {
|
|
case 'ignore':
|
|
return false;
|
|
case 'nothing':
|
|
break;
|
|
default:
|
|
$type = static::$PICTURE_TYPES['default'];
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
if (!file_exists($this->getPhotoPath($code, null)['path'])) {
|
|
if (!empty($row['id_picture'])) {
|
|
sqlQuery('DELETE FROM photos WHERE id = :id', ['id' => $row['id_picture']]);
|
|
}
|
|
$row['id_picture'] = null;
|
|
}
|
|
|
|
if (!$row['id_picture']) {
|
|
sqlGetConnection()->transactional(function () use ($code, &$product, $type) {
|
|
// download if photo no exists already
|
|
if (!$this->photoExists($code)) {
|
|
$id = $this->downloadPhoto($code);
|
|
} else {
|
|
$id = $this->getPhotoId($code);
|
|
}
|
|
if (!$id) {
|
|
$this->deleteSQL('abra_pictures', ['id_abra' => $code]);
|
|
|
|
return false;
|
|
// throw new Exception("Chyba stahovani fotky: ".$code);
|
|
}
|
|
|
|
$product['id_picture'] = $id;
|
|
|
|
$this->updateSQL('abra_pictures', ['id_picture' => $id], ['id_abra' => $code]);
|
|
if ($type && !empty($product['id_product'])) {
|
|
sqlQuery("INSERT IGNORE INTO photos_products_relation (id_photo, id_product, show_in_lead, active)
|
|
VALUES (:id_picture, :id_product, :show_in_lead , 'Y')",
|
|
['id_picture' => $id, 'id_product' => $product['id_product'], 'show_in_lead' => $type]);
|
|
}
|
|
|
|
// 360
|
|
if ($type == 'G') {
|
|
for ($i = 2; $i <= 24; $i++) {
|
|
// download if photo no exists already
|
|
if (!$this->photoExists($code, $i)) {
|
|
$photoId = $this->downloadPhoto($code, $i);
|
|
} else {
|
|
$photoId = $this->getPhotoId($code, $i);
|
|
}
|
|
|
|
if (!$photoId) {
|
|
throw new Exception("Neco s fotkama - prerusilo stahovani rady 360° fotek. Picture_code: {$code}, frame: {$i}");
|
|
}
|
|
|
|
$this->updateSQL('photos', ['parent' => $id], ['id' => $photoId]);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
if ($type && !empty($product['id_product'])) {
|
|
$productPhotoRelation = $this->selectSQL(
|
|
'photos_products_relation',
|
|
[
|
|
'id_photo' => $product['id_picture'],
|
|
'id_product' => $product['id_product'],
|
|
]
|
|
)->fetch();
|
|
if ($productPhotoRelation) {
|
|
$this->updateSQL(
|
|
'photos_products_relation',
|
|
[
|
|
'show_in_lead' => $type,
|
|
'position' => $value ?? $productPhotoRelation['position'] ?? null,
|
|
],
|
|
[
|
|
'id_photo' => $product['id_picture'],
|
|
'id_product' => $product['id_product'],
|
|
]
|
|
);
|
|
} elseif ($product['id_product']) {
|
|
sqlQuery("INSERT IGNORE INTO photos_products_relation (id_photo, id_product, show_in_lead, active, position)
|
|
VALUES (:id_picture, :id_product, :show_in_lead , 'Y', :position)",
|
|
[
|
|
'id_picture' => $row['id_picture'],
|
|
'id_product' => $product['id_product'],
|
|
'show_in_lead' => $type,
|
|
'position' => $value ?? null,
|
|
]);
|
|
}
|
|
}
|
|
|
|
$this->updateSQL('abra_pictures', ['type' => $value], ['id_abra' => $code]);
|
|
$this->scheduleProductTitleUpdate($product['id_product']);
|
|
break;
|
|
case 'delete':
|
|
$row = sqlQueryBuilder()->select('apr.id_product, api.id_picture, ph.source, ph.image_2')
|
|
->from('abra_pictures', 'api')
|
|
->leftJoin('api', 'abra_products', 'apr', 'apr.id_abra=api.id_abra_product')
|
|
->leftJoin('api', 'photos', 'ph', 'ph.id=api.id_picture')
|
|
->where(\Query\Operator::equals(['api.id_abra' => $code]))
|
|
->setMaxResults(1)->execute()->fetch();
|
|
|
|
if (!empty($row['id_picture'])) {
|
|
// this also removes photos_products_relation and abra_pictures (both have ON DELETE CASCADE)
|
|
sqlQueryBuilder()->delete('photos')
|
|
->where(\Query\Operator::equals(['id' => $row['id_picture']]))->execute();
|
|
if (!empty($row['source']) && !empty($row['image_2'])) {
|
|
$cfg = Config::get();
|
|
@unlink($cfg['Path']['photos'].$row['source'].$row['image_2']);
|
|
}
|
|
} else {
|
|
sqlQueryBuilder()->delete('abra_pictures')
|
|
->where(\Query\Operator::equals(['id_abra' => $code]))->execute();
|
|
}
|
|
|
|
$this->scheduleProductTitleUpdate($row['id_product']);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Section: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param null $frame
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getPhotoId($code, $frame = null)
|
|
{
|
|
$name = $code.'.jpg';
|
|
if ($frame) {
|
|
$name = $code.'_'.$frame.'.jpg';
|
|
}
|
|
|
|
$photo = $this->selectSQL('photos', ['image_2' => $name])->fetch();
|
|
if ($photo) {
|
|
return $photo['id'];
|
|
} else {
|
|
return $this->savePhotoToDb($code, $frame);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param int $frame
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function photoExists($code, $frame = null)
|
|
{
|
|
if (file_exists($this->getPhotoPath($code, $frame)['path'])) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getPhotoPath($code, $frame)
|
|
{
|
|
$dir = intval($code) % 100;
|
|
$dir = sprintf('%1$02d', $dir);
|
|
|
|
$name = $code.'.jpg';
|
|
if ($frame) {
|
|
$name = $code.'_'.$frame.'.jpg';
|
|
}
|
|
$pathFinder = PathFinder::getService();
|
|
|
|
return [
|
|
'dir' => $dir,
|
|
'path' => $pathFinder->getDataDir().'photos/shared/'.$dir.'/'.$name,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param int|null $frame
|
|
*
|
|
* @return bool|string|null
|
|
*/
|
|
public function downloadPhoto($id, $frame = null)
|
|
{
|
|
$downloader = new Downloader();
|
|
|
|
$query = $id;
|
|
if ($frame) {
|
|
$query .= '&frame='.$frame;
|
|
}
|
|
|
|
$photo = $downloader->downloadImage(trim('https://test:test@server23.elnino.cz:81/?id='.$query));
|
|
|
|
$this->uploadPhoto($photo, $this->getPhotoPath($id, $frame));
|
|
|
|
return $this->savePhotoToDb($id, $frame);
|
|
}
|
|
|
|
public function savePhotoToDb($id, $frame)
|
|
{
|
|
$dir = intval($id) % 100;
|
|
$dir = sprintf('%1$02d', $dir);
|
|
|
|
$descr = $id;
|
|
if ($frame) {
|
|
$descr .= '_'.$frame;
|
|
$id .= '_'.$frame;
|
|
}
|
|
|
|
$this->insertSQL('photos', [
|
|
'descr' => $descr,
|
|
'source' => "shared/{$dir}/",
|
|
'image_2' => $id.'.jpg',
|
|
]);
|
|
|
|
return sqlInsertId();
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
public function uploadPhoto($photo, $dest)
|
|
{
|
|
$pathFinder = PathFinder::getService();
|
|
$dir = $pathFinder->getDataDir().'photos/shared/';
|
|
|
|
if (!file_exists($dir)) {
|
|
mkdir($dir, 0777);
|
|
}
|
|
if (!file_exists($dir.$dest['dir'])) {
|
|
mkdir($dir.$dest['dir'], 0777);
|
|
}
|
|
|
|
return rename($photo['tmp_name'], $dest['path']);
|
|
}
|
|
|
|
public function sync_unitsize($code, $field, $value)
|
|
{
|
|
$id = returnSQLResult('SELECT id_abra FROM abra_units WHERE id_abra=:code', ['code' => $code]);
|
|
|
|
if (!$id) {
|
|
$this->insertSQL('abra_units', ['id_abra' => $code]);
|
|
$id = $code;
|
|
}
|
|
|
|
$column = static::$UNITSIZE_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
$this->saveTranslationObject(AbraUnitsTranslation::class, ['id_object' => $id], [$column => $value]);
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'ignore':
|
|
break;
|
|
|
|
case 'code':
|
|
$this->updateSQL('abra_units', ['code' => $value], ['id_abra' => $id]);
|
|
break;
|
|
|
|
case 'name':
|
|
$this->updateSQL('abra_units', ['name' => $value], ['id_abra' => $id]);
|
|
break;
|
|
|
|
case 'delete':
|
|
$this->deleteSQL('abra_units', ['id_abra' => $id]);
|
|
break;
|
|
|
|
case null:
|
|
var_dump('Unit: Nedefinovaná položka synchronizace: '.$field);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
public function sync_order($code, $field, $value, $value2)
|
|
{
|
|
if (!isset(static::$ORDER_FIELDS[$field])) {
|
|
var_dump('Nedefinovaná položka synchronizace:', $field, $value, $value2);
|
|
|
|
return;
|
|
}
|
|
|
|
$column = static::$ORDER_FIELDS[$field];
|
|
|
|
if ($column == 'quantity' || $column == 'price') {
|
|
list($code, $id_product) = explode('~', $code);
|
|
}
|
|
|
|
$id = $this->getMappingFromAbra('order', $code);
|
|
|
|
if (!$id) {
|
|
var_dump("Neznámá objednávka: {$code}");
|
|
|
|
return false;
|
|
}
|
|
|
|
$value = trim($value);
|
|
|
|
$order = new Order();
|
|
$order->createFromDB($id);
|
|
|
|
switch ($column) {
|
|
case 'status':
|
|
// Cancel order
|
|
if ($value == 6) {
|
|
$order->storno(false, null, true);
|
|
|
|
return true;
|
|
} // Confirm order
|
|
elseif ($value == 1) {
|
|
$status = 3;
|
|
} // Complete order
|
|
elseif ($value == 4) {
|
|
$status = 1;
|
|
} // Complete order
|
|
elseif ($value == 9) {
|
|
$status = 2;
|
|
} // Ignore everything else
|
|
else {
|
|
return false;
|
|
}
|
|
|
|
$order->changeStatus($status, translate('abra_order_status_change', 'abra'), false);
|
|
break;
|
|
|
|
case 'quantity':
|
|
$data = ['id_order' => $id, 'id_product' => $id_product];
|
|
$items = sqlQuery('SELECT id FROM order_items WHERE id_order=:id_order AND id_product=:id_product',
|
|
$data);
|
|
|
|
if (sqlNumRows($items) != 1) {
|
|
return;
|
|
}
|
|
// throw new Exception("Nelze najít změněnou položku objednávky: ".print_r($data, true));
|
|
|
|
$item_id = sqlFetchAssoc($items)['id'];
|
|
$order->updateItem($item_id, $this->preparePriceFromAbra($value));
|
|
|
|
break;
|
|
|
|
case 'price':
|
|
$data = ['id_order' => $id, 'id_product' => $id_product];
|
|
$items = sqlQuery('SELECT id FROM order_items WHERE id_order=:id_order AND id_product=:id_product',
|
|
$data);
|
|
|
|
if (sqlNumRows($items) != 1) {
|
|
return;
|
|
}
|
|
// throw new Exception("Nelze najít změněnou položku objednávky: ".print_r($data, true));
|
|
|
|
$item_id = sqlFetchAssoc($items)['id'];
|
|
$order->updateItemPrice($item_id, toDecimal($this->preparePriceFromAbra($value)));
|
|
|
|
break;
|
|
|
|
case 'note_expedition':
|
|
$noteExpedition = translate('abra_order_error', 'abra');
|
|
$order->logHistory("{$noteExpedition}:<br>{$value}");
|
|
break;
|
|
|
|
case 'ignore':
|
|
break;
|
|
|
|
default:
|
|
throw new Exception('Nedefinovany sloupec: '.$column);
|
|
}
|
|
}
|
|
|
|
public function sync_ignore($code, $field, $value, $value2 = null)
|
|
{
|
|
}
|
|
|
|
// Orders
|
|
public function syncOrder($id)
|
|
{
|
|
// Ignore order for now if sync failed
|
|
$cacheId = 'order-sync-failed-'.$id;
|
|
|
|
if (getCache($cacheId)) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$this->log(['Sync order', 'id' => $id]);
|
|
|
|
parent::syncOrder($id);
|
|
} catch (RuntimeException $e) {
|
|
$this->notifyOrderError($e, $id);
|
|
|
|
return;
|
|
}
|
|
|
|
// Pokud by se stala chyba, vylitla by exception. Tady vím, že je to OK
|
|
$this->log(['Sync order' => 'success', 'id' => $id]);
|
|
}
|
|
|
|
public function notifyOrderError($e, $id)
|
|
{
|
|
// Send notification email to shop owners
|
|
$cacheId = 'order-sync-failed-'.$id;
|
|
|
|
if (getCache($cacheId)) {
|
|
return;
|
|
}
|
|
|
|
$order = new Order();
|
|
$order->createFromDB($id);
|
|
setCache($cacheId, $id, 1800);
|
|
|
|
global $dbcfg;
|
|
SendMail('info@kupshop.cz', 'joe@wpj.cz, abra@it-pro.cz, '.$dbcfg->order_shopkeeper_mail, "Chyba synchronizace objednávky {$order->order_no}", "Nelze odeslat do Abry objednávku číslo {$order->order_no}.\n\nChyba: {$e->getMessage()}");
|
|
}
|
|
|
|
public function getOrder($id)
|
|
{
|
|
$order = new Order();
|
|
$order->createFromDB($id, true, true, true);
|
|
|
|
return $this->contextManager->activateOrder($order, function () use ($order) {
|
|
$delivery = null;
|
|
$payment = null;
|
|
$id_delivery_type = null;
|
|
if (findModule('eshop_delivery')) {
|
|
$delivery_type = $order->getDeliveryType();
|
|
$id_delivery_type = $delivery_type->id;
|
|
$delivery = $this->getMappingToAbra('delivery', $delivery_type->id_delivery) ?: null;
|
|
$payment = $this->getMappingToAbra('payment', $delivery_type->id_payment) ?: null;
|
|
|
|
if ($delivery == 'CZ' && $order->delivery_country == 'PL') {
|
|
$delivery = 'PL';
|
|
}
|
|
}
|
|
|
|
$user_abra_id = getVal('elnino_abra_id',
|
|
sqlFetchAssoc($this->selectSQL('users', ['id' => $order->id_user], ['elnino_abra_id'])), 519194);
|
|
|
|
$sync_order = [
|
|
// Header
|
|
'WEBsource' => $this->settings['web'],
|
|
'DocumentNumber' => $order->order_no,
|
|
'WEBnote' => $this->prepareTextForOrder($order->note_user),
|
|
'Currency' => $order->currency,
|
|
'PaymentCode' => $payment,
|
|
'TransportCode' => $delivery,
|
|
'Amount' => $this->preparePriceToAbra($order->total_price),
|
|
|
|
'Department' => null,
|
|
'Points' => null,
|
|
'SMS' => ($id_delivery_type && $id_delivery_type != 3) ? 'A' : 'N',
|
|
'DocumentID' => $order->id,
|
|
'Status' => 0,
|
|
'CustomerServiceNote' => null,
|
|
|
|
// Customer
|
|
'Code' => $user_abra_id,
|
|
'Email' => null,
|
|
'PhoneNumber' => null,
|
|
|
|
// Invoice address
|
|
'adName' => null,
|
|
'adFirstName' => null,
|
|
'adLastName' => null,
|
|
'adStreet' => null,
|
|
'adCity' => null,
|
|
'adPostCode' => null,
|
|
'adCountryCode' => null,
|
|
|
|
// Delivery address
|
|
'amName' => null,
|
|
'amFirstName' => null,
|
|
'amLastName' => null,
|
|
'amStreet' => null,
|
|
'amCity' => null,
|
|
'amPostCode' => null,
|
|
|
|
'OrgIdentNumber' => null,
|
|
'VATIdentNumber' => null,
|
|
'CH_Kanton' => null,
|
|
'CH_Recipient' => null,
|
|
|
|
'Rows' => $this->getOrderRows($order),
|
|
];
|
|
|
|
return $sync_order;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param $order Order
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getOrderRows($order)
|
|
{
|
|
$orderItemInfo = ServiceContainer::getService(OrderItemInfo::class);
|
|
|
|
$order->fetchItems();
|
|
|
|
$isKOZA = array_search($this->settings['web'], ['kosmetika-zdravi.cz', 'spleticna.si', 'lijepa.hr', 'europarfemy.cz', 'parfimo.ch', 'parfimo.it', 'parfumcity.cz', 'parfumcity.ch', 'profumicitta.it', 'parfimo.de', 'parfimo.at', 'eglamour.de']) !== false;
|
|
|
|
$rows = [];
|
|
|
|
$priceType = 'value_without_vat_no_rounding';
|
|
if ($isKOZA) {
|
|
$priceType = 'value_with_vat_no_rounding';
|
|
}
|
|
|
|
$delivery = null;
|
|
foreach ($order->items as $item) {
|
|
$store = 1;
|
|
$item['descr'] = $this->prepareTextForOrder($item['descr']);
|
|
if ($item['id_product']) {
|
|
$code = $this->getMappingToAbra('product', $item['id_product']);
|
|
} else {
|
|
$code = '';
|
|
}
|
|
|
|
$itemType = $orderItemInfo->getItemType($item);
|
|
if ($code) {
|
|
$type = 3;
|
|
$name = '';
|
|
$price = $item['piece_price'][$priceType];
|
|
$quantity = $item['pieces'];
|
|
$vat = $item['vat'];
|
|
} else {
|
|
if ($itemType == OrderItemInfo::TYPE_DELIVERY) {
|
|
$delivery = $item;
|
|
continue;
|
|
}
|
|
|
|
if ($itemType == OrderItemInfo::TYPE_COUPON) {
|
|
$itemNote = $item['note'];
|
|
if (!empty($itemNote['discount']['cv'])) {
|
|
$item['descr'] .= ' ('.$itemNote['discount']['cv'].')';
|
|
}
|
|
|
|
if (!$this->selectSQL('discounts_coupons', ['id_discount' => $itemNote['discount']['id']])->fetch()) {
|
|
$itemType = OrderItemInfo::TYPE_DISCOUNT;
|
|
}
|
|
|
|
if (($couponData = $this->getDiscountItemValues($item)) && $itemType == OrderItemInfo::TYPE_COUPON) {
|
|
$rowPrice = $couponData['coupon_price'];
|
|
|
|
$this->processOrderItemToRows($rows, $item, [
|
|
'type' => 1,
|
|
'code' => '',
|
|
'quantity' => '1',
|
|
'price' => $this->preparePriceToAbra($couponData['residue']),
|
|
'name' => translate_shop('abra_not_used_discount', 'abra'),
|
|
'vat' => 25,
|
|
]);
|
|
} else {
|
|
$rowPrice = $item['total_price'][$priceType];
|
|
}
|
|
} else {
|
|
$rowPrice = $item['total_price'][$priceType];
|
|
}
|
|
|
|
$type = 3;
|
|
$code = $this->getNonProductCode($itemType);
|
|
if ($itemType == OrderItemInfo::TYPE_CHARGE) {
|
|
$chargeId = ($item['note']['id_charge'] ?? false);
|
|
if ($chargeId == self::CHARGE_BALNE) {
|
|
$code = '999904';
|
|
}
|
|
}
|
|
$name = $item['descr'];
|
|
$price = $rowPrice;
|
|
$quantity = 1;
|
|
$vat = $item['vat'];
|
|
}
|
|
|
|
if ($this->settings['web'] == 'perfumy-hurtownia.pl') {
|
|
$price = roundPrice($price);
|
|
}
|
|
|
|
$price = $this->preparePriceToAbra($price);
|
|
|
|
// Detect used store
|
|
if ($item['id_product']
|
|
&& array_search($this->settings['web'], [
|
|
'europarfemy.cz', 'kosmetika-zdravi.cz', 'spleticna.si', 'parfumcity.cz', 'parfumcity.ch', 'parfimo.ch', 'wholesale-perfumes.eu',
|
|
]) !== false
|
|
) {
|
|
$elnino_store = $item['note']['elnino_store'] ?? 1;
|
|
if ($elnino_store) {
|
|
$store = intval($elnino_store);
|
|
}
|
|
}
|
|
|
|
if ($isKOZA) {
|
|
$row = sqlFetchAll(sqlQuery('SELECT data, campaign, price FROM products WHERE id=:id', ['id' => $item['id_product']]));
|
|
|
|
$campaign = [];
|
|
|
|
if (isset($row[0])) {
|
|
if (!empty($row[0]['campaign'])) {
|
|
$campaign = explodeFlags($row[0]['campaign']);
|
|
}
|
|
}
|
|
|
|
if (isset($campaign['G'])) {
|
|
$price = calcPrice($row[0]['price'], $vat);
|
|
$price = $this->preparePriceToAbra($price->printFloatValue(2));
|
|
|
|
$this->processOrderItemToRows($rows, $item, [
|
|
'type' => 3,
|
|
'code' => $code,
|
|
'quantity' => $quantity,
|
|
'price' => $price,
|
|
'name' => $name,
|
|
'store' => $store,
|
|
'vat' => $vat,
|
|
]);
|
|
|
|
$code = '999990';
|
|
$price = '-'.$price;
|
|
$type = 3;
|
|
$name = $item['descr'];
|
|
$store = 1;
|
|
}
|
|
}
|
|
|
|
$this->processOrderItemToRows($rows, $item, [
|
|
'type' => $type,
|
|
'code' => $code,
|
|
'quantity' => $quantity,
|
|
'price' => $price,
|
|
'name' => $name,
|
|
'store' => $store,
|
|
'vat' => $vat,
|
|
]);
|
|
}
|
|
|
|
// sleva na dopravu
|
|
if (findModule(Modules::DELIVERY_TYPES)) {
|
|
$deliveryType = $order->getDeliveryType();
|
|
$priceUtil = ServiceContainer::getService(\KupShop\KupShopBundle\Util\Price\PriceUtil::class);
|
|
$currency = $priceUtil->getCurrencyById($order->currency);
|
|
$originalDeliveryPrice = $deliveryType->getPrice();
|
|
if ($currency) {
|
|
$originalDeliveryPrice = PriceCalculator::convert($originalDeliveryPrice, $currency);
|
|
}
|
|
if ($currency->getId() == 'EUR' && !empty($deliveryType->price_eur)) {
|
|
$originalDeliveryPrice = toDecimal($deliveryType->price_eur);
|
|
if (!empty($deliveryType->payment_price_eur)) {
|
|
$originalDeliveryPrice = $originalDeliveryPrice->add(toDecimal($deliveryType->payment_price_eur));
|
|
}
|
|
$originalDeliveryPrice = new \KupShop\KupShopBundle\Util\Price\Price($originalDeliveryPrice, $priceUtil->getCurrencyById('EUR'), 0);
|
|
}
|
|
|
|
if ($delivery === null) {
|
|
if ($deliveryDiscount = $this->getDeliveryDiscount($originalDeliveryPrice, null, $currency)) {
|
|
$this->processOrderItemToRows($rows, null, [
|
|
'type' => 3,
|
|
'code' => 999918,
|
|
'quantity' => 1,
|
|
'price' => $this->preparePriceToAbra($deliveryDiscount->printFloatValue(2)),
|
|
'name' => translate_shop('abra_delivery_discount', 'abra'),
|
|
'store' => 1,
|
|
'vat' => 0,
|
|
]);
|
|
}
|
|
$deliveryPrice = $originalDeliveryPrice->getPriceWithVat();
|
|
$deliveryName = $deliveryType->name;
|
|
} else {
|
|
$deliveryPrice = $delivery['total_price'][$priceType];
|
|
if ($deliveryDiscount = $this->getDeliveryDiscount($originalDeliveryPrice, $delivery['total_price'][$priceType], $currency)) {
|
|
$this->processOrderItemToRows($rows, null, [
|
|
'type' => 3,
|
|
'code' => 999918,
|
|
'quantity' => 1,
|
|
'price' => $this->preparePriceToAbra($deliveryDiscount->printFloatValue(2)),
|
|
'name' => translate_shop('abra_delivery_discount', 'abra'),
|
|
'store' => 1,
|
|
'vat' => 0,
|
|
]);
|
|
$deliveryPrice = $originalDeliveryPrice->getPriceWithVat();
|
|
}
|
|
$deliveryName = $delivery['descr'];
|
|
}
|
|
|
|
if ($deliveryPrice->isPositive()) {
|
|
$this->processOrderItemToRows($rows, null, [
|
|
'type' => 3,
|
|
'code' => $this->getNonProductCode(OrderItemInfo::TYPE_DELIVERY),
|
|
'quantity' => 1,
|
|
'price' => $this->preparePriceToAbra($deliveryPrice->printFloatValue(2)),
|
|
'name' => $deliveryName,
|
|
'store' => 1,
|
|
'vat' => 0,
|
|
]);
|
|
}
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
|
|
protected function getDiscountItemValues($item)
|
|
{
|
|
$itemNote = $item['note'];
|
|
if (isset($itemNote['discount']) && ($itemNote['discount']['unit'] ?? false) == 'price') {
|
|
$couponPrice = toDecimal($itemNote['discount']['discount']);
|
|
$residue = $couponPrice->add($item['total_price']['value_with_vat']);
|
|
if ($residue->isPositive()) {
|
|
return [
|
|
'coupon_price' => $couponPrice->mul(DecimalConstants::negativeOne()),
|
|
'residue' => $residue,
|
|
];
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
protected function processOrderItemToRows(&$rows, $item, $rowData)
|
|
{
|
|
// "3~|~002002~|~1~|~168,5~|~",
|
|
$rows[] = join($this->separator, [
|
|
$rowData['type'],
|
|
$rowData['code'],
|
|
$rowData['quantity'],
|
|
$rowData['price'],
|
|
$rowData['name'],
|
|
$rowData['store'] ?? 1,
|
|
$rowData['vat'],
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @param $deliveryPriceOriginal \KupShop\KupShopBundle\Util\Price\Price
|
|
* @param $deliveryPrice Decimal|null
|
|
*
|
|
* @return Decimal|null
|
|
*/
|
|
public function getDeliveryDiscount($deliveryPriceOriginal, $deliveryPrice, $currency)
|
|
{
|
|
$deliveryPriceOriginal = $deliveryPriceOriginal->getPriceWithVat();
|
|
|
|
if ($deliveryPrice === null) {
|
|
if ($deliveryPriceOriginal->isZero()) {
|
|
return null;
|
|
}
|
|
|
|
return $deliveryPriceOriginal->mul(DecimalConstants::negativeOne());
|
|
}
|
|
|
|
$deliveryPrice = roundPrice($deliveryPrice, null, 'DB', null, $currency);
|
|
$deliveryDiscount = $deliveryPrice->sub($deliveryPriceOriginal);
|
|
if (!$deliveryDiscount->isNegative()) {
|
|
$deliveryDiscount = null;
|
|
}
|
|
|
|
if ($deliveryDiscount) {
|
|
$diff = DecimalConstants::one()->sub($deliveryPrice->div($deliveryPriceOriginal))->mul(DecimalConstants::hundred())->asFloat();
|
|
if ($diff <= 0.1) {
|
|
$deliveryDiscount = null;
|
|
}
|
|
}
|
|
|
|
return $deliveryDiscount;
|
|
}
|
|
|
|
protected function getNonProductCode($itemType)
|
|
{
|
|
switch ($itemType) {
|
|
case OrderItemInfo::TYPE_DELIVERY:
|
|
$deliveryPriceCodes = [
|
|
'kosmetika-zdravi.cz' => 999802,
|
|
'parfumcity.cz' => 999803,
|
|
'europarfemy.cz' => 999804,
|
|
'parfumcity.ch' => 999807,
|
|
'parfimo.ch' => 999808,
|
|
'parfimo.it' => 999811,
|
|
'spleticna.si' => 999812,
|
|
'lijepa.hr' => 999813,
|
|
'profumicitta.it' => 999814,
|
|
'parfimo.de' => 999809,
|
|
'parfimo.at' => 999817,
|
|
'eglamour.de' => 999819,
|
|
];
|
|
|
|
return $deliveryPriceCodes[$this->settings['web']] ?? 999920;
|
|
break;
|
|
case OrderItemInfo::TYPE_DISCOUNT:
|
|
return 999944;
|
|
break;
|
|
case OrderItemInfo::TYPE_GIFT:
|
|
return 999990;
|
|
break;
|
|
case OrderItemInfo::TYPE_COUPON:
|
|
return 999919;
|
|
break;
|
|
case OrderItemInfo::TYPE_CHARGE:
|
|
return 999905;
|
|
break;
|
|
default:
|
|
return 999944; // fallback, pokud se nepodari urcit typ polozky
|
|
}
|
|
}
|
|
|
|
// Delayed processing functions
|
|
public function fixProductsTitles()
|
|
{
|
|
// $this->scheduleProductTitleUpdate(11972, 1444);
|
|
// return $this->updateScheduledProducts();
|
|
|
|
$products = sqlQueryBuilder()
|
|
->select('p.id', 'pv.id as id_variation', 'p.id_model')
|
|
->fromProducts()
|
|
->joinVariationsOnProducts()
|
|
->orderBy('p.id')
|
|
->addOrderBy('pv.id')
|
|
->execute();
|
|
foreach ($products as $index => $product) {
|
|
if (isset(static::$abraKozaV2)) {
|
|
$this->scheduleProductTitleUpdate($product['id'], null, null, null, null, $product['id_model']);
|
|
} else {
|
|
$this->scheduleProductTitleUpdate($product['id'], $product['id_variation']);
|
|
}
|
|
}
|
|
|
|
while (($remaining = returnSQLResult('SELECT COUNT(*) FROM abra_delayed_update')) > 0) {
|
|
var_dump("Updating delayed update, {$remaining} items left");
|
|
$this->updateScheduledProducts();
|
|
}
|
|
|
|
$this->finalizeSync();
|
|
}
|
|
|
|
public function scheduleProductTitleUpdate($product_id = null, $variation_id = null, $serie_id = null, $brand_id = null, $section_id = null, $model_id = null, $complement_model_id = null, $complement_type_id = null)
|
|
{
|
|
if (!is_null($product_id) && $product_id > 0) {
|
|
$this->saveDelayedUpdate($product_id, 'product');
|
|
}
|
|
|
|
if (!is_null($variation_id)) {
|
|
$this->saveDelayedUpdate($variation_id, 'variation');
|
|
}
|
|
|
|
if (!is_null($serie_id)) {
|
|
$this->saveDelayedUpdate($serie_id, 'serie');
|
|
}
|
|
|
|
if (!is_null($brand_id)) {
|
|
$this->saveDelayedUpdate($brand_id, 'brand');
|
|
}
|
|
|
|
if (!is_null($section_id)) {
|
|
$this->saveDelayedUpdate($section_id, 'section');
|
|
}
|
|
|
|
if (!is_null($model_id)) {
|
|
$this->saveDelayedUpdate($model_id, 'model');
|
|
}
|
|
|
|
if (!is_null($complement_model_id)) {
|
|
$this->saveDelayedUpdate($complement_model_id, 'complement_model');
|
|
}
|
|
|
|
if (!is_null($complement_type_id)) {
|
|
$this->saveDelayedUpdate($complement_type_id, 'complement_type');
|
|
}
|
|
}
|
|
|
|
public function saveDelayedUpdate($id, $type)
|
|
{
|
|
sqlQuery('INSERT IGNORE INTO abra_delayed_update (related_id, type) VALUES (:id, :type)', ['id' => $id, 'type' => $type]);
|
|
}
|
|
|
|
public function getDelayedUpdate($type, $limit = 500)
|
|
{
|
|
$data = sqlQueryBuilder()->select('*')->from('abra_delayed_update')
|
|
->where(\Query\Operator::equals(['type' => $type]))
|
|
->setMaxResults($limit)
|
|
->execute();
|
|
|
|
return sqlFetchAll($data, ['related_id' => 'id']);
|
|
}
|
|
|
|
public function deleteDelayedUpdate(array $ids)
|
|
{
|
|
sqlQueryBuilder()->delete('abra_delayed_update')
|
|
->where(\Query\Operator::inIntArray($ids, 'id'))
|
|
->execute();
|
|
}
|
|
|
|
public function updateScheduledProducts()
|
|
{
|
|
$this->collectUpdatedProducts();
|
|
|
|
// Update products
|
|
if ($product_list = $this->getDelayedUpdate('product')) {
|
|
$productIds = array_keys($product_list);
|
|
$products = sqlQuery('
|
|
SELECT p.id, p.id_model, p.size, p.shade, s.name AS section_name, pr.name AS producer_name, abs.name AS serie_name,
|
|
abcm.name AS complement_model_name, p.name2, abs.sex, ap.id_section, s.id as id_section_shop, pr.id AS id_producer,
|
|
abs.id_serie AS id_serie, GROUP_CONCAT(p.campaign SEPARATOR \',\') AS campaign, abm.descr AS long_descr,
|
|
abd.name AS damage_name, abct.name AS complement_type_name, ap.id_serie, ap.id_section, ap.id_complement_model, abs.id_producer, abs.id_serie AS id_serie_kupshop
|
|
FROM products AS p
|
|
LEFT JOIN abra_models AS abm ON abm.id_abra = p.id_model
|
|
LEFT JOIN abra_products ap ON p.id = ap.id_product
|
|
LEFT JOIN abra_complement_types AS abct ON abct.id_abra = p.id_complement_type
|
|
LEFT JOIN abra_damages AS abd ON abd.id_abra = p.damage
|
|
LEFT JOIN abra_sections AS absec ON absec.id_abra = ap.id_section
|
|
LEFT JOIN sections AS s ON s.id = absec.id_section
|
|
LEFT JOIN abra_series AS abs ON abs.id_abra = ap.id_serie
|
|
LEFT JOIN abra_complement_models AS abcm ON abcm.id_abra = ap.id_complement_model
|
|
LEFT JOIN producers AS pr ON pr.id = abs.id_producer
|
|
WHERE p.id IN (:id_products)
|
|
GROUP BY p.id',
|
|
['id_products' => $productIds],
|
|
['id_products' => \Doctrine\DBAL\Connection::PARAM_INT_ARRAY]
|
|
);
|
|
|
|
foreach ($products as $product) {
|
|
try {
|
|
$this->updateProduct($product);
|
|
} catch (Exception $e) {
|
|
exception_handler($e);
|
|
}
|
|
}
|
|
|
|
$this->recalcInStore(\Query\Operator::inIntArray($productIds, 'p.id'));
|
|
|
|
$this->deleteDelayedUpdate($product_list);
|
|
}
|
|
}
|
|
|
|
public function hideIncompleteProducts()
|
|
{
|
|
$SQL = sqlQuery('UPDATE products p
|
|
LEFT JOIN photos_products_relation AS ppr ON ppr.id_product = p.id
|
|
LEFT JOIN parameters_products pp ON pp.id_parameter = 22 AND pp.id_product = p.id
|
|
SET p.figure = \'O\'
|
|
WHERE p.figure = \'Y\' AND (p.ean IS NULL OR p.ean = 0 /*OR ppr.id_photo IS NULL*/ OR p.price <= 0
|
|
OR (FIND_IN_SET("S", p.campaign) > 0 AND (p.set IS NULL OR p.set = "")))');
|
|
|
|
var_dump(['Skryto produktů bez EANu /*nebo obrázků*/ nebo nulovou cenou nebo setů bez popisu', sqlAffectedRows($SQL)]);
|
|
|
|
$SQL = sqlQuery('UPDATE products p
|
|
LEFT JOIN photos_products_relation AS ppr ON ppr.id_product = p.id
|
|
LEFT JOIN parameters_products pp ON pp.id_parameter = 22 AND pp.id_product = p.id
|
|
SET p.figure = \'Y\'
|
|
WHERE p.figure = \'O\' AND p.ean IS NOT NULL AND p.ean != 0 /*AND ppr.id_photo IS NOT NULL*/ AND p.price > 0
|
|
AND (FIND_IN_SET("S", p.campaign) <= 0 OR NOT (p.set IS NULL OR p.set = ""))');
|
|
|
|
var_dump(['Zobrazeno produktů v "prodej ukončen" s EANem/*, obrázkem*/ a cenou a setů s popisem', sqlAffectedRows($SQL)]);
|
|
}
|
|
|
|
/**
|
|
* @param $product array
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
public function updateProduct($product)
|
|
{
|
|
if (empty($product['id_model'])) {
|
|
// Update model
|
|
$product['name2'] = $product['name2'] ?: '';
|
|
|
|
$model = sqlFetchAssoc($this->selectSQL('abra_models', [
|
|
'id_serie' => $product['id_serie'],
|
|
'id_section' => $product['id_section'],
|
|
'id_complement_model' => $product['id_complement_model'],
|
|
], ['id_abra']));
|
|
|
|
if ($model) {
|
|
$this->updateSQL('products', ['id_model' => $model['id_abra']], ['id' => $product['id']]);
|
|
}
|
|
}
|
|
|
|
// Update variation title
|
|
$flags = explodeFlags($product['campaign']);
|
|
$campaign = $this->getCampaignsNames(
|
|
array_filter($flags, function ($k) {
|
|
return in_array($k, ['V', 'T', 'O', 'S']);
|
|
}, ARRAY_FILTER_USE_KEY)
|
|
);
|
|
|
|
// Kategorie + Vyrobce + Rada + Doplnek modelu + Doplnek typu produktu + Name2 + velikost + odstín + poškození + (vzorek/odstřik/tester/kazeta)
|
|
$attributes = [
|
|
// $product['producer_name'], // Vyrobce je uz vsude zobrazeny, tak ho vynechat
|
|
$product['serie_name'],
|
|
$product['complement_model_name'],
|
|
$product['complement_type_name'],
|
|
$product['name2'],
|
|
|
|
$product['shade'],
|
|
$product['section_name'],
|
|
$product['sex'],
|
|
$product['size'],
|
|
$product['damage_name'],
|
|
join(' ', $campaign),
|
|
];
|
|
|
|
$title = join(' ', array_filter($attributes));
|
|
// preskocit Vialky
|
|
if (!($product['id'] == '999998' || $product['id'] == '999999')) {
|
|
$this->updateSQL('products', ['title' => $title], ['id' => $product['id']]);
|
|
}
|
|
|
|
// update section
|
|
$sectionFinder = ServiceContainer::getService(SectionFinder::class);
|
|
$sectionFinder->setProductSections($product['id'], $product['id_section_shop'] ? [$product['id_section_shop']] : []);
|
|
|
|
// Update sex
|
|
$data = ['id_product' => $product['id'], 'id_parameter' => 18];
|
|
$this->deleteSQL('parameters_products', $data);
|
|
switch ($product['sex']) {
|
|
case 'M':
|
|
$value = 16;
|
|
break;
|
|
case '':
|
|
case 'W':
|
|
$value = 17;
|
|
break;
|
|
case 'U':
|
|
$value = 22;
|
|
break;
|
|
case 'K':
|
|
$value = 23;
|
|
break;
|
|
case 'B':
|
|
$value = 24;
|
|
break;
|
|
default:
|
|
throw new Exception('Nedefinované pohlaví: '.$product['sex']);
|
|
}
|
|
$data['value_list'] = $value;
|
|
$this->insertSQL('parameters_products', $data);
|
|
}
|
|
|
|
public function updateModel($model)
|
|
{
|
|
if (empty($model['id_serie']) || empty($model['id_section'])) {
|
|
$this->updateSQL('products', ['figure' => 'O'], ['id_model' => $model['id']]);
|
|
|
|
return false;
|
|
}
|
|
|
|
$data = $this->generateModelTitle($model);
|
|
|
|
$this->updateSQL(
|
|
'abra_models',
|
|
[
|
|
'short_title' => $data['short_title'],
|
|
'id_serie' => $model['id_serie'],
|
|
],
|
|
['id_abra' => $model['id']]
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
public function generateModelTitle($values)
|
|
{
|
|
// Kategorie + Vyrobce + Rada + Doplnek modelu
|
|
$attributes = [
|
|
$values['producer_name'],
|
|
$values['serie_name'],
|
|
$values['complement_model_name'],
|
|
];
|
|
|
|
$short_title = join(' ', array_filter($attributes));
|
|
$title = join(' ', [$values['section_name'], $short_title]);
|
|
|
|
return [
|
|
'title' => $title,
|
|
'short_title' => $short_title,
|
|
];
|
|
}
|
|
|
|
public function finalizeSync()
|
|
{
|
|
$this->updateScheduledProducts();
|
|
|
|
$this->hideIncompleteProducts();
|
|
}
|
|
|
|
/**
|
|
* Returns how specific current message is
|
|
* Returns one of:
|
|
* null - message is not for us
|
|
* 1 - message is global
|
|
* 2 - message is for our language
|
|
* 3 - message is for our site
|
|
* 4 - message is for our language + site.
|
|
*
|
|
* @return int|null
|
|
*/
|
|
public function getMessageLevel()
|
|
{
|
|
// Site does not match, not message for us
|
|
if ($this->site and $this->site != $this->settings['web']) {
|
|
return null;
|
|
}
|
|
|
|
// Language does not match, not message for us
|
|
$supportedLanguages = $this->languageContext->getSupported();
|
|
if ($this->lang && !isset($supportedLanguages[$this->lang])) {
|
|
return null;
|
|
}
|
|
|
|
if ($this->site and $this->lang) {
|
|
return 4;
|
|
}
|
|
|
|
if ($this->site) {
|
|
return 3;
|
|
}
|
|
|
|
if ($this->lang) {
|
|
return 2;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
public function handleTranslatedText($object, $value)
|
|
{
|
|
$level = $this->getMessageLevel();
|
|
|
|
if ($value == 'DEL') {
|
|
$level = 0;
|
|
$value = '';
|
|
}
|
|
|
|
// Update level
|
|
$this->updateSQL($object['table'], [$object['field'] => $value/* "{$object['field']}_level" => $level */], $object['where']);
|
|
}
|
|
|
|
public function log($data)
|
|
{
|
|
// Do not log in development
|
|
if (isDevelopment()) {
|
|
return;
|
|
}
|
|
|
|
/** @var Symfony\Bridge\Monolog\Logger $logger */
|
|
$logger = ServiceContainer::getService('logger');
|
|
$logger->notice('Abra Elnino Log: '.print_r($data, true));
|
|
}
|
|
|
|
protected function collectUpdatedProducts()
|
|
{
|
|
// Schedule serie update on brand update
|
|
if ($brand = $this->getDelayedUpdate('brand')) {
|
|
$series = sqlQueryBuilder()->select('id_serie as id')
|
|
->from('abra_series')
|
|
->where(\Query\Operator::inIntArray(array_keys($brand), 'id_producer'))
|
|
->execute();
|
|
|
|
foreach ($series as $serie) {
|
|
$this->scheduleProductTitleUpdate(null, null, $serie['id']);
|
|
}
|
|
|
|
$this->deleteDelayedUpdate($brand);
|
|
}
|
|
|
|
// Schedule product update on serie update
|
|
if ($serie = $this->getDelayedUpdate('serie')) {
|
|
$products = sqlQueryBuilder()->select('p.id');
|
|
if (isset(static::$abraKozaV2)) {
|
|
$products->addSelect('p.id_model');
|
|
}
|
|
$products = $products
|
|
->from('abra_series', 'asr')
|
|
->join('asr', 'abra_models', 'am', 'am.id_serie = asr.id_abra')
|
|
->join('am', 'products', 'p', 'am.id_abra = p.id_model')
|
|
->where(\Query\Operator::inIntArray(array_keys($serie), 'asr.id_serie'))
|
|
->execute();
|
|
|
|
foreach ($products as $product) {
|
|
$this->scheduleProductTitleUpdate($product['id'], null, null, null, null, $product['id_model'] ?? null);
|
|
}
|
|
|
|
$this->deleteDelayedUpdate($serie);
|
|
}
|
|
|
|
// Schedule product update on section update
|
|
if ($section = $this->getDelayedUpdate('section')) {
|
|
$products = sqlQueryBuilder()->select('p.id')
|
|
->fromProducts()
|
|
->joinSectionsOnProducts()
|
|
->where(\Query\Operator::inIntArray(array_keys($section), 'ps.id_section'))
|
|
->execute();
|
|
|
|
foreach ($products as $product) {
|
|
$this->scheduleProductTitleUpdate($product['id']);
|
|
}
|
|
|
|
$this->deleteDelayedUpdate($section);
|
|
}
|
|
|
|
// Schedule product update on complement_model update
|
|
if ($complementModel = $this->getDelayedUpdate('complement_model')) {
|
|
$models = sqlQueryBuilder()->select('id_abra')
|
|
->from('abra_models')
|
|
->where(\Query\Operator::inStringArray(array_keys($complementModel), 'id_complement_model'))
|
|
->execute();
|
|
|
|
foreach ($models as $model) {
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, $model['id_abra']);
|
|
}
|
|
|
|
$this->deleteDelayedUpdate($complementModel);
|
|
}
|
|
|
|
// Schedule product update on model update
|
|
if ($model = $this->getDelayedUpdate('model')) {
|
|
$products = sqlQueryBuilder()->select('p.id')
|
|
->fromProducts()
|
|
->where(\Query\Operator::inIntArray(array_keys($model), 'p.id_model'))
|
|
->execute();
|
|
|
|
foreach ($products as $product) {
|
|
$this->scheduleProductTitleUpdate($product['id']);
|
|
}
|
|
|
|
if (!isset(static::$abraKozaV2)) {
|
|
$this->deleteDelayedUpdate($model);
|
|
}
|
|
}
|
|
|
|
// Schedule product update on complement_type update
|
|
if ($complementType = $this->getDelayedUpdate('complement_type')) {
|
|
$products = sqlQueryBuilder()->select('id')
|
|
->from('products')
|
|
->where(\Query\Operator::inIntArray(array_keys($complementType), 'id_complement_type'))
|
|
->execute();
|
|
|
|
foreach ($products as $product) {
|
|
$this->scheduleProductTitleUpdate($product['id']);
|
|
}
|
|
|
|
$this->deleteDelayedUpdate($complementType);
|
|
}
|
|
}
|
|
|
|
public function getCampaignsNames($flags)
|
|
{
|
|
$cfg = Config::get();
|
|
|
|
if (!is_array($flags)) {
|
|
$flags = explodeFlags($flags);
|
|
}
|
|
|
|
$campaign = [];
|
|
foreach ($cfg['Products']['Flags'] as $flag => $name) {
|
|
if (array_key_exists($flag, $flags)) {
|
|
$campaign[] = $name['singular'];
|
|
}
|
|
}
|
|
|
|
return $campaign;
|
|
}
|
|
|
|
protected function scheduleUpdateCommon($id, $force_product = false)
|
|
{
|
|
if ($this->main_table == 'products') {
|
|
$this->scheduleProductTitleUpdate($id);
|
|
} else {
|
|
$idProduct = null;
|
|
if ($force_product) {
|
|
$idProduct = $this->selectSQL('products_variations', ['id' => $id], ['id_product'])->fetchColumn();
|
|
}
|
|
$this->scheduleProductTitleUpdate($idProduct, $id);
|
|
}
|
|
}
|
|
|
|
public function recalcInStore($spec = null)
|
|
{
|
|
/*
|
|
* UPDATE `products`
|
|
JOIN (
|
|
SELECT p.id, COALESCE(SUM(GREATEST(pv.in_store, 0)), p.in_store) in_store
|
|
FROM `products` p
|
|
LEFT JOIN `products_variations` pv ON pv.id_product=p.id AND pv.figure = 'Y'
|
|
GROUP BY p.id
|
|
) AS sums ON products.id=sums.id
|
|
SET products.in_store=sums.in_store WHERE products.in_store != sums.in_store
|
|
*/
|
|
|
|
$sums = sqlQueryBuilder()->select('p.id', 'COALESCE(SUM(GREATEST(pv.in_store, 0)), p.in_store) in_store')
|
|
->from('products', 'p')
|
|
->leftJoin('p', 'products_variations', 'pv', 'pv.id_product=p.id AND pv.figure = \'Y\'')
|
|
->groupBy('p.id');
|
|
|
|
if ($spec) {
|
|
$sums->andWhere($spec);
|
|
}
|
|
|
|
sqlQuery("UPDATE products
|
|
JOIN ({$sums->getSQL()}) AS sums ON products.id=sums.id
|
|
SET products.in_store=sums.in_store WHERE products.in_store != sums.in_store",
|
|
$sums->getParameters(), $sums->getParameterTypes());
|
|
}
|
|
|
|
public function sync_secondary_assortment_group($code, $field, $value)
|
|
{
|
|
$column = static::$SECONDARY_ASSORTMENT_GROUP_FIELDS[$field];
|
|
|
|
$secondaryAssortmentGroup = sqlQueryBuilder()->select('*')->from('abra_secondary_assortment_group')
|
|
->where(\Query\Operator::equals(['id_abra' => $code]))
|
|
->setMaxResults(1)->execute()->fetch();
|
|
|
|
if (!$secondaryAssortmentGroup) {
|
|
$this->insertSQL('abra_secondary_assortment_group', ['id_abra' => $code]);
|
|
}
|
|
|
|
$id_product = $secondaryAssortmentGroup['id_product'] ?? null;
|
|
switch ($column) {
|
|
case 'abra_section_id':
|
|
$this->updateSQL('abra_secondary_assortment_group', ['id_abra_section' => $value], ['id_abra' => $code]);
|
|
break;
|
|
case 'abra_product_id':
|
|
$id_product = returnSQLResult('SELECT ap.id_product FROM abra_products ap
|
|
WHERE ap.id_abra=:id_abra', ['id_abra' => $value]);
|
|
$this->updateSQL('abra_secondary_assortment_group', ['id_product' => $id_product], ['id_abra' => $code]);
|
|
break;
|
|
case 'delete':
|
|
$this->deleteSQL('abra_secondary_assortment_group', ['id_abra' => $code]);
|
|
break;
|
|
}
|
|
if (!empty($id_product) && $id_product !== '0') {
|
|
$this->scheduleProductTitleUpdate($id_product);
|
|
}
|
|
}
|
|
|
|
public function sync_scent($code, $field, $value)
|
|
{
|
|
// var_dump('sc: ' . $code . $field . $value);
|
|
$row = sqlQueryBuilder()->select('id_abra, name')->from('abra_scents')
|
|
->where('id_abra=:code')
|
|
->setParameter('code', $code)
|
|
->setMaxResults(1)->execute()->fetch();
|
|
|
|
if (!$row) {
|
|
// insert abra_scent
|
|
$this->insertSQL('abra_scents', ['id_abra' => $code, 'name' => $value]);
|
|
}
|
|
|
|
$column = static::$SCENT_FIELDS[$field];
|
|
|
|
if ($this->isTranslationsSync()) {
|
|
if (!$this->translationFieldSupported($field)) {
|
|
return;
|
|
}
|
|
|
|
$this->saveTranslationObject(AbraScentsTranslation::class, ['id_object' => $code], [$column => $value]);
|
|
|
|
return;
|
|
}
|
|
|
|
switch ($column) {
|
|
case 'name':
|
|
// update abra_scent
|
|
$this->updateSQL('abra_scents', ['name' => $value], ['id_abra' => $code]);
|
|
break;
|
|
|
|
case 'delete':
|
|
// remove abra_scent
|
|
sqlQueryBuilder()->delete('abra_scents')->where('id_abra=:id')->setParameter('id', $code)->execute();
|
|
|
|
echo 'Scent removed; ';
|
|
break;
|
|
}
|
|
}
|
|
|
|
public function sync_product_scent($code, $field, $value)
|
|
{
|
|
$row = sqlQueryBuilder()->select('*')->from('abra_products_scents')
|
|
->where('id_abra=:code')
|
|
->setParameter('code', $code)
|
|
->setMaxResults(1)->execute()->fetch();
|
|
|
|
try {
|
|
switch ($field) {
|
|
case 'Model_ID':
|
|
if (!$value) {
|
|
return;
|
|
}
|
|
$this->updateProductsScents($code, 'id_model', $value, $row);
|
|
break;
|
|
case 'Scent_ID':
|
|
$this->updateProductsScents($code, 'id_scent', $value, $row);
|
|
break;
|
|
case 'Element':
|
|
$this->updateProductsScents($code, 'element', $value, $row);
|
|
break;
|
|
case 'Part':
|
|
$this->updateProductsScents($code, 'part', $value, $row);
|
|
break;
|
|
case 'ONDELETE':
|
|
if ($row && $row['id_scent'] > 0 && $row['id_model'] > 0) {
|
|
// remove abra_products_scents
|
|
$this->deleteSQL('abra_products_scents', ['id_abra' => $row['id_abra']]);
|
|
}
|
|
break;
|
|
}
|
|
} catch (Exception $e) {
|
|
// kdyz je slozka vune, ktera nema preklad, neprijde jeji objekt -> cizi klic selze.
|
|
$sentry = getRaven();
|
|
$sentry->captureException($e);
|
|
}
|
|
}
|
|
|
|
public function updateProductsScents($code, $fieldName, $value, &$row)
|
|
{
|
|
// update field
|
|
$conn = sqlGetConnection();
|
|
try {
|
|
$conn->beginTransaction();
|
|
if ($row) {
|
|
$this->updateSQL('abra_products_scents', [$fieldName => $value], ['id_abra' => $code]);
|
|
} else {
|
|
$this->insertSQL('abra_products_scents', [$fieldName => $value, 'id_abra' => $code]);
|
|
$row = true;
|
|
}
|
|
$conn->commit();
|
|
} catch (\Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException $e) {
|
|
$conn->rollBack();
|
|
|
|
if ($fieldName == 'id_scent') {
|
|
$this->insertSQL('abra_scents', ['id_abra' => $value, 'name' => '']);
|
|
|
|
return $this->updateProductsScents($code, $fieldName, $value, $row);
|
|
} else {
|
|
$sentry = getRaven();
|
|
$sentry->captureException($e);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
$id_model = returnSQLResult('SELECT id_model FROM abra_products_scents WHERE id_abra=:code', ['code' => $code]);
|
|
if ($id_model) {
|
|
$this->scheduleProductTitleUpdate(null, null, null, null, null, $id_model);
|
|
}
|
|
}
|
|
|
|
protected function createRewrite($rewriteType, $relatedId, array $urlParams)
|
|
{
|
|
if (findModule(Modules::DB_REWRITE)) {
|
|
if (!$relatedId) {
|
|
return;
|
|
}
|
|
|
|
$languageSwitcher = ServiceContainer::getService(LanguageSwitcher::class);
|
|
$legacyUrlGenerator = ServiceContainer::getService(LegacyUrlGenerator::class);
|
|
$rewrite = ServiceContainer::getService(\KupShop\RewriteBundle\Util\Rewrite::class);
|
|
|
|
foreach ($this->languageContext->getSupported() as $language) {
|
|
$url = $languageSwitcher->switchLanguage(
|
|
$language->getId(),
|
|
function () use ($legacyUrlGenerator, $urlParams) {
|
|
return $legacyUrlGenerator->generate($urlParams);
|
|
}
|
|
);
|
|
|
|
$rewrite->addRewrite($url, $rewriteType, $relatedId);
|
|
}
|
|
}
|
|
}
|
|
|
|
private $blockUtil;
|
|
|
|
protected function getBlockUtil(): KupShop\ContentBundle\Util\Block
|
|
{
|
|
if ($this->blockUtil) {
|
|
return $this->blockUtil;
|
|
}
|
|
|
|
return $this->blockUtil = ServiceContainer::getService(\KupShop\ContentBundle\Util\Block::class);
|
|
}
|
|
|
|
public function getOrdersToSync(): \Query\QueryBuilder
|
|
{
|
|
return sqlQueryBuilder()
|
|
->select('o.id')
|
|
->from('orders', 'o')
|
|
->leftJoin('o', 'abra_orders', 'ao', 'o.id=ao.id_order')
|
|
->where('ao.id_abra IS NULL AND o.date_created < DATE_SUB(NOW(), INTERVAL 30 SECOND)')
|
|
->andWhere(Operator::not(Operator::equals(['o.source' => 'returns'])));
|
|
}
|
|
}
|
|
|
|
if (empty($subclass)) {
|
|
class AbraElnino extends AbraElninoBase
|
|
{
|
|
}
|
|
}
|