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; } }