config(['QUANTITY_ALLEGRO_UPDATE' => 'DISABLED']); return; } foreach (self::getSyncQuantitiesData() as $auction) { if (!self::changeAccount($auction['id_xallegro_account'])) { continue; } // @since 7.0.0 // backward compatibility if (!$auction['selling_mode']) { try { $item = (new OfferProvider(self::$api, true))->getOfferDetails($auction['id_auction']); XAllegroAuction::updateAuctionSellingMode($item->sellingMode->format, $item->id); $auction['selling_mode'] = $item->sellingMode->format; } catch (Exception $ex) { continue; } } // if offer is in AUCTION mode if ($auction['selling_mode'] == SellingModeType::AUCTION) { $auction['stock_quantity'] = min(1, $auction['stock_quantity']); } self::changeQuantity( $auction['id_auction'], $auction['stock_quantity'], $auction['quantity'], $auction['threshold'], XAllegroTask::METHOD_SYNC ); } } /** * @param array $params * @return void */ public static function hookSyncQuantities(array $params) { $result = Db::getInstance()->executeS(' SELECT DISTINCT(a.`id_auction`), a.`selling_mode`, a.`id_xallegro_account`, a.`quantity` FROM `' . _DB_PREFIX_ . 'xallegro_auction` a JOIN `' . _DB_PREFIX_ . 'xallegro_account` ac ON (a.`id_xallegro_account` = ac.`id_xallegro_account`) INNER JOIN ( SELECT xca.`id_account`, CASE WHEN xca.`value` = "' . pSQL(XAllegroConfigurationAccount::GLOBAL_OPTION) . '" THEN ( SELECT xc.`value` FROM `' . _DB_PREFIX_ . 'xallegro_configuration` xc WHERE xc.`name` = "QUANITY_ALLEGRO_UPDATE" ) ELSE xca.`value` END as `configuration_sync_quantity` FROM `' . _DB_PREFIX_ . 'xallegro_configuration_account` xca JOIN `' . _DB_PREFIX_ . 'xallegro_account` ac ON (ac.`id_xallegro_account` = xca.`id_account`) WHERE xca.`name` = "QUANITY_ALLEGRO_UPDATE" AND ac.`active` = 1 ) configurationQuantity ON (configurationQuantity.`id_account` = a.`id_xallegro_account`) LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_custom_product` xcp_all ON (a.`id_product` = xcp_all.`id_product` AND xcp_all.`id_xallegro_account` = 0) LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_custom_product` xcp_single ON (a.`id_product` = xcp_single.`id_product` AND a.`id_xallegro_account` = xcp_single.`id_xallegro_account`) LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_task` xt ON (a.`id_auction` = xt.`id_auction`) LEFT JOIN `' . _DB_PREFIX_ . 'stock_available` sa ON (a.`id_product` = sa.`id_product` AND a.`id_product_attribute` = sa.`id_product_attribute`) WHERE a.`id_product` = ' . (int)$params['id_product'] . ' AND a.`id_product_attribute` = ' . (int)$params['id_product_attribute'] . ' AND a.`id_auction` > 0 AND a.`closed` = 0 AND a.`archived` = 0 AND ac.`active` = 1 AND ( CASE WHEN xcp_single.`sync_quantity_allegro` IS NOT NULL THEN xcp_single.`sync_quantity_allegro` WHEN xcp_all.`sync_quantity_allegro` IS NOT NULL THEN xcp_all.`sync_quantity_allegro` ELSE configurationQuantity.`configuration_sync_quantity` END ) > 0' . (!(bool)XAllegroConfiguration::get('QUANITY_ALLEGRO_OOS') ? '' : ' AND (sa.`out_of_stock` = 0 OR (sa.`out_of_stock` = 2 AND ( SELECT IFNULL(`value`, 0) FROM `' . _DB_PREFIX_ . 'configuration` WHERE `name` = "PS_ORDER_OUT_OF_STOCK" AND (`id_shop` = a.`id_shop` OR `id_shop` IS NULL) AND (`id_shop_group` = a.`id_shop_group` OR `id_shop_group` IS NULL) ) = 0 ) )') . ' AND ((xt.`type` != "' . pSQL(XAllegroTask::TYPE_QUANTITY) .'" AND xt.`type` != "' . pSQL(XAllegroTask::TYPE_PUBLICATION) .'") OR xt.`id_xallegro_task` IS NULL) ORDER BY a.`id_xallegro_account` ASC' ); if (!$result) { return; } foreach ($result as $auction) { if (!self::changeAccount($auction['id_xallegro_account'])) { continue; } // @since 7.0.0 // backward compatibility if (!$auction['selling_mode']) { try { $item = (new OfferProvider(self::$api, true))->getOfferDetails($auction['id_auction']); XAllegroAuction::updateAuctionSellingMode($item->sellingMode->format, $item->id); $auction['selling_mode'] = $item->sellingMode->format; } catch (Exception $ex) { continue; } } // if offer is in AUCTION mode if ($auction['selling_mode'] == SellingModeType::AUCTION) { $params['quantity'] = min(1, $params['quantity']); } $accountConfiguration = new XAllegroConfigurationAccount($auction['id_xallegro_account']); self::changeQuantity( $auction['id_auction'], $params['quantity'], $auction['quantity'], (int)$accountConfiguration->get('CLOSE_AUCTION_TRESHOLD', true), XAllegroTask::METHOD_HOOK ); } } /** * @return array * @throws PrestaShopDatabaseException */ private static function getSyncQuantitiesData() { if ((bool)XAllegroConfiguration::get('QUANITY_ALLEGRO_VALUE_MAX')) { $stockCompare = 'LEAST(IF(a.`selling_mode` = "AUCTION", LEAST(1, sa.`quantity`), sa.`quantity`), ' . (int)XAllegroConfiguration::get('QUANITY_ALLEGRO_VALUE_MAX') . ') '; $valueMaxCompare = ' OR a.`quantity` > ' . (int)XAllegroConfiguration::get('QUANITY_ALLEGRO_VALUE_MAX'); } else { $stockCompare = 'IF(a.`selling_mode` = "AUCTION", LEAST(1, sa.`quantity`), sa.`quantity`) '; $valueMaxCompare = ''; } $stockCompare .= ((bool)XAllegroConfiguration::get('QUANITY_ALLEGRO_ALWAYS_MAX') ? '!=' : '<') . ' a.`quantity`' . $valueMaxCompare; $result = Db::getInstance()->executeS(' SELECT DISTINCT(a.`id_auction`), a.`selling_mode`, a.`quantity`, a.`id_xallegro_account`, IF(a.`selling_mode` = "AUCTION", LEAST(1, sa.`quantity`), sa.`quantity`) as `stock_quantity`, IFNULL(configurationThreshold.`threshold`, 0) as `threshold` FROM `' . _DB_PREFIX_ . 'xallegro_auction` a JOIN `' . _DB_PREFIX_ . 'xallegro_account` ac ON (a.`id_xallegro_account` = ac.`id_xallegro_account`) INNER JOIN ( SELECT xca.`id_account`, CASE WHEN xca.`value` = "' . pSQL(XAllegroConfigurationAccount::GLOBAL_OPTION) . '" THEN ( SELECT xc.`value` FROM `' . _DB_PREFIX_ . 'xallegro_configuration` xc WHERE xc.`name` = "QUANITY_ALLEGRO_UPDATE" ) ELSE xca.`value` END as `configuration_sync_quantity` FROM `' . _DB_PREFIX_ . 'xallegro_configuration_account` xca JOIN `' . _DB_PREFIX_ . 'xallegro_account` ac ON (ac.`id_xallegro_account` = xca.`id_account`) WHERE xca.`name` = "QUANITY_ALLEGRO_UPDATE" AND ac.`active` = 1 ) configurationQuantity ON (configurationQuantity.`id_account` = a.`id_xallegro_account`) LEFT JOIN ( SELECT xca.`id_account`, CASE WHEN xca.`value` = "" OR xca.`value` = 0 THEN ( SELECT COALESCE(SUM(xc.`value`), 0) FROM `' . _DB_PREFIX_ . 'xallegro_configuration` xc WHERE xc.`name` = "CLOSE_AUCTION_TRESHOLD" ) ELSE COALESCE(SUM(xca.`value`), 0) END as `threshold` FROM `' . _DB_PREFIX_ . 'xallegro_configuration_account` xca JOIN `' . _DB_PREFIX_ . 'xallegro_account` ac ON (ac.`id_xallegro_account` = xca.`id_account`) WHERE xca.`name` = "CLOSE_AUCTION_TRESHOLD" AND ac.`active` = 1 GROUP BY xca.`id_account` ) configurationThreshold ON (configurationThreshold.`id_account` = a.`id_xallegro_account`) LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_custom_product` xcp_all ON (a.`id_product` = xcp_all.`id_product` AND xcp_all.`id_xallegro_account` = 0) LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_custom_product` xcp_single ON (a.`id_product` = xcp_single.`id_product` AND a.`id_xallegro_account` = xcp_single.`id_xallegro_account`) LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_task` xt ON (a.`id_auction` = xt.`id_auction`) JOIN `' . _DB_PREFIX_ . 'shop` s ON (s.`id_shop` = a.`id_shop`) JOIN `' . _DB_PREFIX_ . 'shop_group` sg ON (sg.`id_shop_group` = s.`id_shop_group`) LEFT JOIN `' . _DB_PREFIX_ . 'stock_available` sa ON a.`id_product` = sa.`id_product` AND a.`id_product_attribute` = sa.`id_product_attribute` AND ((sg.`share_stock` = 1 AND sa.`id_shop` = 0 AND sa.`id_shop_group` = s.`id_shop_group`) OR (sg.`share_stock` = 0 AND sa.`id_shop` = s.`id_shop` AND sa.`id_shop_group` = 0)) WHERE a.`closed` = 0 AND a.`archived` = 0 AND a.`id_auction` > 0 AND a.`id_xallegro_account` > 0 AND ac.`active` = 1 AND ( CASE WHEN xcp_single.`sync_quantity_allegro` IS NOT NULL THEN xcp_single.`sync_quantity_allegro` WHEN xcp_all.`sync_quantity_allegro` IS NOT NULL THEN xcp_all.`sync_quantity_allegro` ELSE configurationQuantity.`configuration_sync_quantity` END ) > 0 AND (' . $stockCompare . ' OR (IF(a.`selling_mode` = "AUCTION", LEAST(1, sa.`quantity`), sa.`quantity`) < configurationThreshold.`threshold`))' . (!(bool)XAllegroConfiguration::get('QUANITY_ALLEGRO_OOS') ? '' : ' AND (sa.`out_of_stock` = 0 OR (sa.`out_of_stock` = 2 AND ( SELECT IFNULL(`value`, 0) FROM `' . _DB_PREFIX_ . 'configuration` WHERE `name` = "PS_ORDER_OUT_OF_STOCK" AND (`id_shop` = a.`id_shop` OR `id_shop` IS NULL) AND (`id_shop_group` = a.`id_shop_group` OR `id_shop_group` IS NULL) ) = 0 ) )') . ' AND ((xt.`type` != "' . pSQL(XAllegroTask::TYPE_QUANTITY) .'" AND xt.`type` != "' . pSQL(XAllegroTask::TYPE_PUBLICATION) .'") OR xt.`id_xallegro_task` IS NULL) GROUP BY a.`id_auction` ORDER BY a.`id_xallegro_account` ASC LIMIT ' . (int)XAllegroConfiguration::get('QUANITY_ALLEGRO_UPDATE_CHUNK') ); return $result ?: []; } /** * @param int|float $id_auction * @param int $stock_quantity * @param int $auction_quantity * @param int $threshold * @param string $method */ private static function changeQuantity($id_auction, $stock_quantity, $auction_quantity, $threshold, $method) { $forcedClosing = false; if ($threshold) { // if qty is lower than threshold, we need to force auction to close if ($stock_quantity < $threshold && $stock_quantity > 0) { $stock_quantity = 0; $forcedClosing = true; } } // jesli ilosc w magazynie jest dodatnia robimy aktualizację if ($stock_quantity > 0) { // jesli ilosc na aukcji jest mniejsza niż w sklepie i ustawione jest trzymanie maksymalnych stanow magazynowych // lub ilosc na aukcji jest większa niż w sklepie if (($auction_quantity < $stock_quantity && (bool)XAllegroConfiguration::get('QUANITY_ALLEGRO_ALWAYS_MAX')) || ((bool)XAllegroConfiguration::get('QUANITY_ALLEGRO_VALUE_MAX') && $auction_quantity > (int)XAllegroConfiguration::get('QUANITY_ALLEGRO_VALUE_MAX')) || $auction_quantity > $stock_quantity) { if ((bool)XAllegroConfiguration::get('QUANITY_ALLEGRO_VALUE_MAX')) { $stock_quantity = min($stock_quantity, (int)XAllegroConfiguration::get('QUANITY_ALLEGRO_VALUE_MAX')); } $stock_quantity = min( $stock_quantity, XAllegroApi::QUANTITY_MAX ); if ($auction_quantity == XAllegroApi::QUANTITY_MAX && $stock_quantity == XAllegroApi::QUANTITY_MAX) { return; } /** @var QuantityChangeCommand $object */ $object = (new JsonMapBuilder('Command/QuantityChangeCommand'))->map(new QuantityChangeCommand()); $object->offerCriteria()->offers($id_auction); $object->modification->value = (int)$stock_quantity; $commandId = self::$api->generateUUID(); try { self::$api ->sale() ->commands() ->quantityChange() ->setCommand($object) ->executeCommand($commandId); XAllegroLogger::getInstance() ->env($method) ->account(self::$account->id) ->offer($id_auction) ->api('put', 'quantity-change-command', "commandId: $commandId; old: $auction_quantity; new: $stock_quantity"); $task = new XAllegroTask(); $task->id_xallegro_account = self::$account->id; $task->id_command = $commandId; $task->id_auction = (float)$id_auction; $task->type = XAllegroTask::TYPE_QUANTITY; $task->method = $method; $task->value = (int)$stock_quantity; $task->add(); } catch (Exception $ex) { if ($ex->getCode() == 404) { XAllegroAuction::closeAuctions([$id_auction], 'offer-not-found'); } } } } // jesli ilosc w magazynie jest zerowa - konczymy aukcje else { /** @var OfferPublicationCommand $object */ $object = (new JsonMapBuilder('Command/OfferPublicationCommand'))->map(new OfferPublicationCommand()); $object->publication->action = PublicationAction::END; $object->offerCriteria()->offers($id_auction); $commandId = self::$api->generateUUID(); try { self::$api ->sale() ->commands() ->offerPublication() ->setCommand($object) ->executeCommand($commandId); XAllegroLogger::getInstance() ->env($method) ->account(self::$account->id) ->offer($id_auction) ->api('put', 'publication-command', "commandId: $commandId; currentAuctionQty: $auction_quantity; currentStockQty: $stock_quantity; forcedClosing: $forcedClosing; END"); $task = new XAllegroTask(); $task->id_xallegro_account = self::$account->id; $task->id_command = $commandId; $task->id_auction = (float)$id_auction; $task->type = XAllegroTask::TYPE_PUBLICATION; $task->method = $method; $task->value = PublicationAction::END; $task->add(); } catch (Exception $ex) { if ($ex->getCode() == 404) { XAllegroAuction::closeAuctions([$id_auction], 'offer-not-found'); } } } } /** * @return bool */ private static function checkQuantityAllegroUpdate() { $accountOption = (int)Db::getInstance()->getValue(' SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'xallegro_configuration_account` WHERE `name` = "QUANITY_ALLEGRO_UPDATE" AND `value` != "' . pSQL(XAllegroConfigurationAccount::GLOBAL_OPTION) . '" AND `value` > 0' ); $productOption = (int)Db::getInstance()->getValue(' SELECT COUNT(*) FROM `' . _DB_PREFIX_ . 'xallegro_custom_product` WHERE `sync_quantity_allegro` > 0' ); return (int)XAllegroConfiguration::get('QUANITY_ALLEGRO_UPDATE') || $accountOption || $productOption; } }