327 lines
13 KiB
PHP
327 lines
13 KiB
PHP
<?php
|
|
|
|
use x13allegro\Json\JsonMapBuilder;
|
|
use x13allegro\Api\DataProvider\OfferFeesProvider;
|
|
use x13allegro\Api\Model\Command\PriceChange\ModificationType;
|
|
use x13allegro\Api\Model\Command\PriceChange\PriceChangeCommand;
|
|
use x13allegro\Api\Model\Offers\Enum\SellingModeType;
|
|
use x13allegro\Api\Model\Offers\Offer;
|
|
use x13allegro\SyncManager\Offer\Price\SyncPriceEnum;
|
|
|
|
final class XAllegroSyncPrices extends XAllegroSync
|
|
{
|
|
public static function syncPrices()
|
|
{
|
|
if (!self::checkPriceUpdate()) {
|
|
XAllegroLogger::getInstance()->config(['PRICE_UPDATE' => 'DISABLED']);
|
|
return;
|
|
}
|
|
|
|
$auctions = self::getSyncPricesData();
|
|
$context = Context::getContext();
|
|
|
|
foreach ($auctions as $auction)
|
|
{
|
|
if (!self::changeAccount($auction['id_xallegro_account'])) {
|
|
continue;
|
|
}
|
|
|
|
$accountConfiguration = new XAllegroConfigurationAccount($auction['id_xallegro_account']);
|
|
$productCustom = new XAllegroProductCustom($auction['id_xallegro_account'], $auction['id_product']);
|
|
$productCustom->useGlobalAccountsSettings(true);
|
|
$productCustom->setProductAttributeId($auction['id_product_attribute']);
|
|
$productCustom->setOriginalProductPrice(XAllegroProduct::getProductStaticPrice(
|
|
(int)$auction['id_product'],
|
|
(int)$auction['id_product_attribute'],
|
|
$context
|
|
));
|
|
$productCustom->calculatePrice();
|
|
|
|
if (!Validate::isLoadedObject($context->shop) || $context->shop->id != (int)$auction['id_shop']) {
|
|
$context->shop = new Shop($auction['id_shop']);
|
|
}
|
|
|
|
$product_price = XAllegroProduct::calculatePrice($productCustom, $accountConfiguration);
|
|
|
|
Hook::exec(
|
|
'actionX13AllegroProductPriceModifier',
|
|
array(
|
|
'id_product' => (int) $auction['id_product'],
|
|
'id_product_attribute' => (int) $auction['id_product_attribute'],
|
|
'id_xallegro_account' => (int) $auction['id_xallegro_account'],
|
|
'product_price' => &$product_price,
|
|
'auction' => $auction
|
|
)
|
|
);
|
|
|
|
if (!(float)$product_price) {
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
/** @var Offer $offer */
|
|
$offer = (new JsonMapBuilder())->build(self::$api->sale()->offers()->getDetails($auction['id_auction']), Offer::class);
|
|
|
|
// @since 7.0.0
|
|
// backward compatibility
|
|
if (!$auction['selling_mode']) {
|
|
XAllegroAuction::updateAuctionSellingMode($offer->sellingMode->format, $offer->id);
|
|
}
|
|
}
|
|
catch (Exception $ex) {
|
|
if ($ex->getCode() == 404) {
|
|
XAllegroAuction::archiveAuctions([$auction['id_auction']]);
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
// if offer is in AUCTION mode, and price buy now is 0
|
|
// skip update
|
|
if ($offer->sellingMode->format != SellingModeType::BUY_NOW
|
|
&& (!$offer->sellingMode->price || $offer->sellingMode->price->amount == 0)
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
// Update auction price if there is none
|
|
$auction_price = $auction['price_buy_now'];
|
|
if (!(float)$auction_price) {
|
|
$auction_price = $offer->sellingMode->price->amount;
|
|
}
|
|
|
|
// Check for auctions with special prices from Allegro,
|
|
// if there is ongoing campaign with special price
|
|
// for this product and this auction we should not change price
|
|
if ((int) $accountConfiguration->get('AUCTION_CHECK_BADGES', true)) {
|
|
$hasActiveCampaing = false;
|
|
|
|
try {
|
|
$offerCampaings = self::$api->sale()->badges()->getBadges($auction['id_auction']);
|
|
|
|
if (!empty($offerCampaings->badges)) {
|
|
foreach ($offerCampaings->badges as $offerCampaign) {
|
|
if ($offerCampaign->process->status == 'ACTIVE') {
|
|
$hasActiveCampaing = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception $ex) {
|
|
continue;
|
|
}
|
|
|
|
if ($hasActiveCampaing) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if ($auction['account_sync_price'] === null) {
|
|
if ($auction['account_all_sync_price'] === null) {
|
|
$update = (int)$auction['configuration_sync_price'];
|
|
} else {
|
|
$update = (int)$auction['account_all_sync_price'];
|
|
}
|
|
} else {
|
|
$update = (int)$auction['account_sync_price'];
|
|
}
|
|
|
|
$auction_price -= $auction['fees'];
|
|
|
|
// Get fees
|
|
$calculatedFees = 0;
|
|
if (abs($auction_price - $product_price) > 0.000001) {
|
|
$offer->sellingMode->price->amount = $product_price;
|
|
|
|
$auctionCalculateFees = $accountConfiguration->get('AUCTION_CALCULATE_FEES', true);
|
|
if ($auctionCalculateFees == 1 || $auctionCalculateFees == 2 && !$productCustom->hasAnyPriceImpact()) {
|
|
$feesProvider = new OfferFeesProvider(self::$api, self::$account);
|
|
$calculatedFees = $feesProvider->getOfferFees($offer);
|
|
}
|
|
|
|
$product_price += $calculatedFees;
|
|
XAllegroAuction::updateAuctionFees($calculatedFees, $auction['id_auction']);
|
|
}
|
|
|
|
if (($update == SyncPriceEnum::FULL && abs($auction_price - $product_price) > 0.000001)
|
|
|| ($update == SyncPriceEnum::ONLY_UP && (float)$auction_price < (float)$product_price)
|
|
|| ($update == SyncPriceEnum::ONLY_DOWN && (float)$auction_price > (float)$product_price)
|
|
) {
|
|
self::changePrice($auction['id_auction'], (float)$auction_price, (float)$product_price, $calculatedFees);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static function changePrice($id_auction, $auction_price, $product_price, $fees = 0)
|
|
{
|
|
/** @var PriceChangeCommand $object */
|
|
$object = (new JsonMapBuilder('Command/PriceChangeCommand'))->map(new PriceChangeCommand());
|
|
$object->offerCriteria()->offers($id_auction);
|
|
$object->modification->type = ModificationType::FIXED_PRICE;
|
|
$object->modification->price->amount = $product_price;
|
|
|
|
$targetProductPrice = $product_price;
|
|
|
|
if ($auction_price < $product_price) {
|
|
$diff = abs($auction_price - $product_price);
|
|
|
|
if ($auction_price <= 50 && $diff > 100) {
|
|
$object->modification->type = ModificationType::INCREASE_PRICE;
|
|
$object->modification->value->amount = 100;
|
|
|
|
$product_price = $auction_price + 100;
|
|
}
|
|
else if ($auction_price > 50 && $diff > $auction_price) {
|
|
$object->modification->type = ModificationType::INCREASE_PERCENTAGE;
|
|
$object->modification->percentage = 200;
|
|
|
|
$product_price = $auction_price + ($auction_price * 200 / 100);
|
|
}
|
|
}
|
|
|
|
if ($product_price > $targetProductPrice) {
|
|
if ($object->modification->type == ModificationType::INCREASE_PERCENTAGE) {
|
|
$object->modification->type = ModificationType::FIXED_PRICE;
|
|
$object->modification->price->amount = $targetProductPrice;
|
|
}
|
|
|
|
$product_price = $targetProductPrice;
|
|
}
|
|
|
|
$commandId = self::$api->generateUUID();
|
|
|
|
try {
|
|
self::$api
|
|
->sale()
|
|
->commands()
|
|
->priceChange()
|
|
->setCommand($object)
|
|
->executeCommand($commandId);
|
|
|
|
XAllegroLogger::getInstance()
|
|
->account(self::$account->id)
|
|
->offer($id_auction)
|
|
->api('put', 'price-change-command', [
|
|
'commandId' => $commandId,
|
|
'old' => $auction_price,
|
|
'old_with_fees' => $auction_price + $fees,
|
|
'new' => $product_price,
|
|
'fees' => $fees,
|
|
'modification' => $object->modification,
|
|
]);
|
|
|
|
$task = new XAllegroTask();
|
|
$task->id_xallegro_account = self::$account->id;
|
|
$task->id_command = self::$api->getLastUUID();
|
|
$task->id_auction = (float)$id_auction;
|
|
$task->type = XAllegroTask::TYPE_PRICE;
|
|
$task->method = XAllegroTask::METHOD_SYNC;
|
|
$task->value = $product_price;
|
|
$task->add();
|
|
}
|
|
catch (Exception $ex) {
|
|
if ($ex->getCode() == 404) {
|
|
XAllegroAuction::closeAuctions([$id_auction], 'offer-not-found');
|
|
}
|
|
}
|
|
}
|
|
|
|
private static function getSyncPricesData()
|
|
{
|
|
$count = XAllegroAuction::countActiveAuctions();
|
|
if (!$count) {
|
|
return array();
|
|
}
|
|
|
|
$offset = (int)XAllegroConfiguration::get('PRICE_UPDATE_OFFSET');
|
|
$limit = (int)XAllegroConfiguration::get('PRICE_UPDATE_CHUNK');
|
|
|
|
$result = Db::getInstance()->executeS('
|
|
SELECT
|
|
a.`id_xallegro_account`,
|
|
a.`id_auction`,
|
|
a.`id_shop`,
|
|
a.`id_product`,
|
|
a.`id_product_attribute`,
|
|
a.`selling_mode`,
|
|
a.`price_buy_now`,
|
|
a.`fees`,
|
|
xcp_single.`sync_price` as `account_sync_price`,
|
|
xcp_all.`sync_price` as `account_all_sync_price`,
|
|
configuration.`configuration_sync_price`
|
|
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` = "PRICE_UPDATE"
|
|
)
|
|
ELSE xca.`value` END as `configuration_sync_price`
|
|
FROM `' . _DB_PREFIX_ . 'xallegro_configuration_account` xca
|
|
JOIN `' . _DB_PREFIX_ . 'xallegro_account` ac
|
|
ON (ac.`id_xallegro_account` = xca.`id_account`)
|
|
WHERE xca.`name` = "PRICE_UPDATE"
|
|
AND ac.`active` = 1
|
|
) configuration
|
|
ON (configuration.`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`)
|
|
WHERE a.`closed` = 0
|
|
AND a.`id_auction` > 0
|
|
AND a.`id_xallegro_account` > 0
|
|
AND ac.`active` = 1
|
|
AND (
|
|
CASE
|
|
WHEN xcp_single.`sync_price` IS NOT NULL THEN xcp_single.`sync_price`
|
|
WHEN xcp_all.`sync_price` IS NOT NULL THEN xcp_all.`sync_price`
|
|
ELSE configuration.`configuration_sync_price`
|
|
END
|
|
) > 0
|
|
AND ((xt.`type` != "' . pSQL(XAllegroTask::TYPE_PRICE) .'" AND xt.`type` != "' . pSQL(XAllegroTask::TYPE_PUBLICATION) .'")
|
|
OR xt.`id_xallegro_task` IS NULL)
|
|
GROUP BY a.`id_auction`
|
|
ORDER BY a.`id_xallegro_auction`
|
|
LIMIT ' . $offset . ', ' . $limit
|
|
);
|
|
|
|
$offset += $limit;
|
|
XAllegroConfiguration::updateValue('PRICE_UPDATE_OFFSET', ($offset >= $count ? 0 : $offset));
|
|
|
|
return $result ?: [];
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
private static function checkPriceUpdate()
|
|
{
|
|
$accountOption = (int)Db::getInstance()->getValue('
|
|
SELECT COUNT(*)
|
|
FROM `' . _DB_PREFIX_ . 'xallegro_configuration_account`
|
|
WHERE `name` = "PRICE_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_price` > 0'
|
|
);
|
|
|
|
return (int)XAllegroConfiguration::get('PRICE_UPDATE') || $accountOption || $productOption;
|
|
}
|
|
}
|