423 lines
19 KiB
PHP
423 lines
19 KiB
PHP
<?php
|
|
|
|
use x13allegro\Api\DataProvider\OfferProvider;
|
|
use x13allegro\Api\Model\Command\OfferPublication\OfferPublicationCommand;
|
|
use x13allegro\Api\Model\Command\OfferPublication\PublicationAction;
|
|
use x13allegro\Api\Model\Command\QuantityChange\QuantityChangeCommand;
|
|
use x13allegro\Api\Model\Offers\Enum\SellingModeType;
|
|
use x13allegro\Api\XAllegroApi;
|
|
use x13allegro\Json\JsonMapBuilder;
|
|
|
|
final class XAllegroSyncQuantities extends XAllegroSync
|
|
{
|
|
public static function syncQuantities()
|
|
{
|
|
if (!XAllegroConfiguration::get('QUANITY_CHECK')
|
|
|| !self::checkQuantityAllegroUpdate()
|
|
|| !Configuration::get('PS_STOCK_MANAGEMENT')
|
|
) {
|
|
XAllegroLogger::getInstance()->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;
|
|
}
|
|
}
|