first commit

This commit is contained in:
2024-11-11 18:46:54 +01:00
commit a630d17338
25634 changed files with 4923715 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
<?php
use x13allegro\Api\XAllegroApi;
abstract class XAllegroSync
{
/** @var int */
protected static $current_allegro_account = null;
/** @var XAllegroApi */
protected static $api;
/** @var XAllegroAccount */
protected static $account;
/**
* @param int $id_xallegro_account
* @return bool
*/
protected static function changeAccount($id_xallegro_account)
{
// @todo Refactoring from static!!!
//if (self::$api instanceof XAllegroApi && self::$current_allegro_account == (int)$id_xallegro_account) {
// return true;
//}
self::$current_allegro_account = (int)$id_xallegro_account;
try {
self::$account = new XAllegroAccount(self::$current_allegro_account);
self::$api = new XAllegroApi(self::$account);
if (!self::$account->active) {
return false;
}
}
catch (Exception $ex) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,159 @@
<?php
use x13allegro\Api\Model\Order\Fulfillment;
use x13allegro\Api\Model\Order\Enum\CheckoutFormStatus;
use x13allegro\Component\Logger\Log;
use x13allegro\Component\Logger\LogType;
use x13allegro\Json\JsonMapBuilder;
use x13allegro\Repository\FulfillmentStatusRepository;
use x13allegro\SyncManager\Order\OrderController;
final class XAllegroSyncFulfillmentStatus extends XAllegroSync
{
/**
* @param int $orderId
* @param string $fulfillmentStatus
* @param bool $ajaxController
* @return array|false
*/
public static function sendFulfillmentStatus($orderId, $fulfillmentStatus, $ajaxController = false)
{
$error = '';
$order = new Order($orderId);
/** @var XAllegroOrder $allegroOrder */
$allegroOrder = XAllegroOrder::getByOrderId($order->id);
if (!Validate::isLoadedObject($order)) {
$error = 'Nie można znaleźć zamówienia w bazie danych.';
}
else if (!$allegroOrder) {
$error = 'To zamówienie nie jest powiązane z Allegro.';
}
else if ($allegroOrder->fulfillment_status == $fulfillmentStatus) {
$error = 'To zamówienie posiada już status: ' . FulfillmentStatusRepository::{$fulfillmentStatus}()->getValue();
}
else if (!self::changeAccount($allegroOrder->id_xallegro_account)) {
$error = 'Wystąpił błąd podczas połączenia z API Allegro.';
}
if (!empty($error)) {
Log::instance()
->order($order->id)
->error(LogType::ORDER_FULFILLMENT_STATUS_SEND(), $error);
if ($ajaxController) {
return [
'status' => false,
'orderId' => $order->id,
'message' => $error
];
}
return false;
}
if (in_array($allegroOrder->event_type, FulfillmentStatusRepository::getUnsupportedEvents())) {
Log::instance()
->order($order->id)
->error(LogType::ORDER_FULFILLMENT_STATUS_SEND(), 'Unsupported Event');
return [
'status' => false,
'orderId' => $order->id,
'message' => 'Dla tego zamówienia nie jest możliwa zmiana statusu Allegro.'
];
}
try {
/** @var Fulfillment $fulfillment */
$fulfillment = (new JsonMapBuilder('Fulfillment'))->map(new Fulfillment());
$fulfillment->status = $fulfillmentStatus;
$fulfillment->shipmentSummary->lineItemsSent = 'ALL';
self::$api->order()->checkoutForms($allegroOrder->checkout_form)->setOrderStatus($allegroOrder->checkout_form_content->revision, $fulfillment);
$allegroOrder->fulfillment_status = $fulfillmentStatus;
$allegroOrder->save();
Log::instance()
->account(self::$api->getAccount()->id)
->order($order->id)
->logDatabase()
->info(LogType::ORDER_FULFILLMENT_STATUS_SEND(), ['status' => $fulfillmentStatus]);
}
catch (Exception $ex) {
// revision for this order is outdated
// try to update order
if ($ex->getCode() == 409) {
try {
$checkoutForm = self::$api->order()->checkoutForms($allegroOrder->checkout_form)->getCheckoutForm();
switch ($checkoutForm->status) {
case CheckoutFormStatus::READY_FOR_PROCESSING:
$action = 'readyForProcessing';
break;
case CheckoutFormStatus::CANCELLED:
$action = 'cancelled';
break;
default:
throw new UnexpectedValueException("Unexpected checkoutForm.status: {$checkoutForm->status}");
}
Db::getInstance()->execute('START TRANSACTION');
Log::instance()
->account(self::$api->getAccount()->id)
->order($order->id)
->logDatabase()
->info(LogType::ORDER_REVISION_UPDATE(), ['checkoutForm.id' => $allegroOrder->checkout_form]);
(new OrderController($allegroOrder, self::$account, $checkoutForm))->execute($action);
Log::instance()->info(LogType::ORDER_REVISION_UPDATE_FINISH());
Db::getInstance()->execute('COMMIT');
return [
'status' => true,
'orderId' => $order->id,
'revisionReload' => true
];
}
catch (Exception $ex) {
Db::getInstance()->execute('ROLLBACK');
Log::instance()
->account(self::$api->getAccount()->id)
->order($order->id)
->logDatabase()
->error(LogType::ORDER_REVISION_UPDATE(), (string)$ex);
return [
'status' => false,
'orderId' => $order->id,
'message' => (string)$ex
];
}
}
else {
Log::instance()
->account(self::$api->getAccount()->id)
->order($order->id)
->logDatabase()
->error(LogType::ORDER_FULFILLMENT_STATUS_SEND(), (string)$ex);
return [
'status' => false,
'orderId' => $order->id,
'message' => (string)$ex
];
}
}
return [
'status' => true,
'orderId' => $order->id,
'revisionReload' => false
];
}
}

View File

@@ -0,0 +1,78 @@
<?php
use x13allegro\Api\Model\Order\Invoice;
use x13allegro\Api\XAllegroApi;
use x13allegro\Component\Logger\Log;
use x13allegro\Component\Logger\LogType;
use x13allegro\Exception\ModuleException;
use x13allegro\Json\JsonMapBuilder;
final class XAllegroSyncInvoice
{
/**
* @param int $orderId
* @param string $invoiceFile
* @param string $invoiceFileName
* @param string $invoiceNumber
* @return bool
* @throws UnexpectedValueException|ModuleException
*/
public static function uploadOrderInvoice($orderId, $invoiceFile, $invoiceFileName, $invoiceNumber = '')
{
$allegroOrder = XAllegroOrder::getByOrderId($orderId);
if (!$allegroOrder) {
return false;
}
/** @var Invoice $invoice */
$invoice = (new JsonMapBuilder('Invoice'))->map(new Invoice());
$invoice->invoiceNumber = $invoiceNumber;
$invoice->file->name = $invoiceFileName;
$api = new XAllegroApi(new XAllegroAccount($allegroOrder->id_xallegro_account));
$resourceInvoices = $api->order()->checkoutForms($allegroOrder->checkout_form)->invoices();
$resultInvoice = $resourceInvoices->createInvoiceFile($invoice);
$resourceInvoices->uploadInvoiceFile($resultInvoice->id, $invoiceFile);
Log::instance()
->account($api->getAccount()->id)
->order($orderId)
->logDatabase()
->info(LogType::ORDER_INVOICE_UPLOAD(), [
'checkoutForm.id' => $allegroOrder->checkout_form,
'invoice.id' => $resultInvoice->id,
'invoice.file.name' => $invoiceFileName
]);
return true;
}
/**
* @param Order $order
* @param Context $context
* @return array
* @throws UnexpectedValueException|PrestaShopException
*/
public static function getPrestaShopInvoice(Order $order, Context $context)
{
/** @var OrderInvoice[] $orderInvoiceList */
$orderInvoiceList = $order->getInvoicesCollection()->getResults();
if (empty($orderInvoiceList)) {
throw new UnexpectedValueException('Brak dokumentów wygenerowanych przez PrestaShop.');
}
/** @see src/Adapter/PDF/OrderInvoicePdfGenerator.php */
Hook::exec('actionPDFInvoiceRender', ['order_invoice_list' => $orderInvoiceList]);
$pfd = new PDF($orderInvoiceList, PDF::TEMPLATE_INVOICE, $context->smarty);
$invoiceFile = $pfd->render(false);
return [
'invoiceFile' => $invoiceFile,
'invoiceFileName' => $pfd->filename,
'invoiceNumber' => $orderInvoiceList[0]->getInvoiceNumberFormatted($context->language->id)
];
}
}

View File

@@ -0,0 +1,327 @@
<?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.`archived` = 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;
}
}

View File

@@ -0,0 +1,422 @@
<?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;
}
}

View File

@@ -0,0 +1,259 @@
<?php
use x13allegro\Adapter\DbAdapter;
use x13allegro\Api\Model\Order\CarrierOperator;
use x13allegro\Api\Model\Order\ParcelTrackingNumber;
use x13allegro\Api\Model\Order\Enum\FulfillmentStatus;
use x13allegro\Component\Logger\Log;
use x13allegro\Component\Logger\LogType;
use x13allegro\Json\JsonMapBuilder;
final class XAllegroSyncShipping extends XAllegroSync
{
public static function syncShipping()
{
if (!XAllegroConfiguration::get('IMPORT_ORDERS')
|| !XAllegroConfiguration::get('ORDER_ALLEGRO_SEND_SHIPPING')
) {
return;
}
foreach (self::getSyncShipping(true) as $order) {
self::sendShippingNumber($order['id_order'], 'sync');
}
}
/**
* @param int $id_order
* @param string $method
* @return array
*/
public static function sendShippingNumber($id_order, $method)
{
$error = '';
$order = new Order((int)$id_order);
/** @var XAllegroOrder $allegroOrder */
$allegroOrder = XAllegroOrder::getByOrderId($order->id);
$package_info = array_values(XAllegroCarrier::getPackageInfo($order->id));
$order_carrier = new OrderCarrier((int)$package_info[0]['id_order_carrier']);
if (!self::changeAccount($allegroOrder->id_xallegro_account)) {
return array(
'result' => false,
'message' => 'Wystąpił błąd podczas połączenia z API Allegro'
);
}
if (!Validate::isLoadedObject($order)) {
$error = 'Nie można znaleźć zamówienia w bazie danych.';
}
else if (!$allegroOrder || empty($package_info)) {
$error = 'To zamówienie nie jest powiązane z Allegro.';
}
else if (!Validate::isLoadedObject($order_carrier)) {
$error = 'Identyfikator przewoźnika jest nieprawidłowy.';
}
else if (!$package_info[0]['id_operator']) {
$error = 'Nie powiązano operatora do tego przewoźnika.';
}
else if (!$order_carrier->tracking_number) {
$error = 'Nie uzupełniono numeru śledzenia dla tego przewożnika.';
}
else if ($package_info[0]['id_operator'] == CarrierOperator::OTHER()->getKey() && empty($package_info[0]['operator_name'])) {
$error = 'Wybierając przewoźnika "Inny", należy podać jego nazwę.';
}
if (!empty($error)) {
if ($method == 'sync') {
Log::instance()
->account(self::$api->getAccount()->id)
->order($order->id)
->logDatabase()
->error(LogType::ORDER_SHIPPING_TRACKING_NUMBER(), $error);
}
return array(
'result' => false,
'message' => $error
);
}
$hookResult = Hook::exec(
'actionX13AllegroTrackingNumberModifier',
array(
'order' => $order,
'order_carrier' => &$order_carrier,
'id_xallegro_account' => $allegroOrder->id_xallegro_account,
),
null,
true // return as array
);
if (is_array($hookResult)) {
foreach ($hookResult as $module) {
if (isset($module['skip']) && $module['skip']) {
return array(
'result' => true,
'message' => 'Pominięto wysłanie numeru śledzenia.'
);
}
}
}
try {
/** @var ParcelTrackingNumber $ptn */
$ptn = (new JsonMapBuilder('ParcelTrackingNumber'))->map(new ParcelTrackingNumber());
$ptn->waybill = trim($order_carrier->tracking_number);
$ptn->carrierId = $package_info[0]['id_operator'];
$ptn->carrierName = $package_info[0]['operator_name'];
if (empty($allegroOrder->checkout_form_content->lineItems->items)) {
$checkoutForm = self::$api->order()->checkoutForms($allegroOrder->checkout_form)->getCheckoutForm();
$allegroOrder->checkout_form_content->lineItems->items = $checkoutForm->lineItems;
}
foreach ($allegroOrder->checkout_form_content->lineItems->items as $item) {
$ptn->lineItem($item->id);
}
self::$api->order()->checkoutForms($allegroOrder->checkout_form)->addTrackingNumber($ptn);
XAllegroCarrier::updatePackageInfo(
$order_carrier->id,
$order->id,
$package_info[0]['id_operator'],
$package_info[0]['operator_name'],
$order_carrier->tracking_number
);
XAllegroCarrier::markAsSend($order->id);
Log::instance()
->account(self::$api->getAccount()->id)
->order($order->id)
->logDatabase()
->info(LogType::ORDER_SHIPPING_TRACKING_NUMBER());
$changeFulfillmentStatus = XAllegroConfiguration::get('ORDER_ALLEGRO_SHIPPING_STATUS');
$fulfillmentStatus = XAllegroConfiguration::get('ORDER_ALLEGRO_SHIPPING_STATUS_FULFILLMENT');
if ($changeFulfillmentStatus && FulfillmentStatus::isValidKey($fulfillmentStatus)) {
XAllegroSyncFulfillmentStatus::sendFulfillmentStatus($order->id, $fulfillmentStatus);
}
}
catch (Exception $ex) {
Log::instance()
->account(self::$api->getAccount()->id)
->order($order->id)
->logDatabase()
->error(LogType::ORDER_SHIPPING_TRACKING_NUMBER(), (string)$ex);
// manage only when there is 4xx error
if ($ex->getCode() < 500) {
XAllegroCarrier::markAsError($order->id);
}
return array(
'result' => false,
'message' => (string)$ex
);
}
return array(
'result' => true,
'message' => 'Numer śledzenia został wysłany do Allegro.'
);
}
/**
* @param bool $checkBlockedStates
* @param int $offset
* @return array
*/
public static function getSyncShipping($checkBlockedStates = false, $offset = 0)
{
$orderStates = false;
if ($checkBlockedStates) {
$orderStates = json_decode(XAllegroConfiguration::get('BLOCK_ORDER_SEND_SHIPPING_STATUS'), true);
}
$result = Db::getInstance()->executeS('
SELECT o.`id_order`, xac.`id_xallegro_account`
FROM `' . _DB_PREFIX_ . 'orders` o
JOIN `' . _DB_PREFIX_ . 'xallegro_order` xo
ON (o.`id_order` = xo.`id_order`)
JOIN `' . _DB_PREFIX_ . 'xallegro_account` xac
ON (xo.`id_xallegro_account` = xac.`id_xallegro_account`)
LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_carrier` xc
ON (xo.`delivery_method` = xc.`id_fields_shipment`)
LEFT JOIN `' . _DB_PREFIX_ . 'order_carrier` oc
ON (o.`id_order` = oc.`id_order`)
LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_carrier_package_info` xcp
ON (o.`id_order` = xcp.`id_order`)
WHERE xo.`delivery_method` IS NOT NULL
AND xo.`delivery_method` NOT LIKE "0"
AND ((xc.`id_operator` IS NOT NULL
AND xc.`id_operator` != "")
OR (xcp.`id_operator` IS NOT NULL
AND xcp.`id_operator` != ""))
AND (oc.`tracking_number` IS NOT NULL
AND oc.`tracking_number` != "")
AND (xcp.`send_enabled` = 1 OR xcp.`send_enabled` IS NULL)
AND (xcp.`id_order_carrier` IS NULL
OR xcp.`send` = 0
OR replace(xcp.`tracking_number`, " ", "") COLLATE ' . pSQL(DbAdapter::getColumnCollation('xallegro_carrier_package_info', 'tracking_number')) . ' NOT LIKE replace(oc.`tracking_number`, " ", ""))
AND xac.`active` = 1'
. (is_array($orderStates) && !empty($orderStates) ? ' AND o.`current_state` NOT IN (' . implode(',', array_map('intval', $orderStates)) . ')' : '') . '
GROUP BY o.`id_order`
LIMIT ' . ($offset ? ($offset * (int)XAllegroConfiguration::get('IMPORT_ORDERS_CHUNK')) . ', ' : '') . (int)XAllegroConfiguration::get('IMPORT_ORDERS_CHUNK')
);
if (!$result) {
return array();
}
return $result;
}
/**
* @param bool $checkBlockedStates
* @return int
*/
public static function getCountSyncShipping($checkBlockedStates = false)
{
$orderStates = false;
if ($checkBlockedStates) {
$orderStates = json_decode(XAllegroConfiguration::get('BLOCK_ORDER_SEND_SHIPPING_STATUS'), true);
}
return (int)Db::getInstance()->getValue('
SELECT COUNT(o.`id_order`)
FROM `' . _DB_PREFIX_ . 'orders` o
JOIN `' . _DB_PREFIX_ . 'xallegro_order` xo
ON (o.`id_order` = xo.`id_order`)
JOIN `' . _DB_PREFIX_ . 'xallegro_account` xac
ON (xo.`id_xallegro_account` = xac.`id_xallegro_account`)
LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_carrier` xc
ON (xo.`delivery_method` = xc.`id_fields_shipment`)
LEFT JOIN `' . _DB_PREFIX_ . 'order_carrier` oc
ON (o.`id_order` = oc.`id_order`)
LEFT JOIN `' . _DB_PREFIX_ . 'xallegro_carrier_package_info` xcp
ON (o.`id_order` = xcp.`id_order`)
WHERE xo.`delivery_method` IS NOT NULL
AND xo.`delivery_method` NOT LIKE "0"
AND ((xc.`id_operator` IS NOT NULL
AND xc.`id_operator` != "")
OR (xcp.`id_operator` IS NOT NULL
AND xcp.`id_operator` != ""))
AND (oc.`tracking_number` IS NOT NULL
AND oc.`tracking_number` != "")
AND (xcp.`send_enabled` = 1 OR xcp.`send_enabled` IS NULL)
AND (xcp.`id_order_carrier` IS NULL
OR xcp.`send` = 0
OR replace(xcp.`tracking_number`, " ", "") COLLATE ' . pSQL(DbAdapter::getColumnCollation('xallegro_carrier_package_info', 'tracking_number')) . ' NOT LIKE replace(oc.`tracking_number`, " ", ""))
AND xac.`active` = 1'
. (is_array($orderStates) && !empty($orderStates) ? ' AND o.`current_state` NOT IN (' . implode(',', array_map('intval', $orderStates)) . ')' : '') . '
GROUP BY o.`id_order`'
);
}
}

View File

@@ -0,0 +1,60 @@
<?php
use x13allegro\Api\Model\Offers\Enum\PublicationStatus;
final class XAllegroSyncStatuses extends XAllegroSync
{
/**
* @param int $lastAuctionId
* @param array $close_auctions
* @return bool
*/
public static function syncAuctionStatuses($lastAuctionId, array &$close_auctions = null)
{
$result = Db::getInstance()->executeS('
SELECT a.`id_xallegro_auction`, a.`id_xallegro_account`, a.`id_auction`, a.`quantity`
FROM `'._DB_PREFIX_.'xallegro_auction` a
JOIN `'._DB_PREFIX_.'xallegro_account` ac
ON a.`id_xallegro_account` = ac.`id_xallegro_account`
WHERE a.`id_xallegro_auction` > ' . (int)$lastAuctionId . '
AND a.`id_xallegro_account` > 0
AND ac.`active` = 1
LIMIT 200'
);
if (!$result) {
return false;
}
foreach ($result as $auction)
{
if (!self::changeAccount($auction['id_xallegro_account'])) {
continue;
}
$lastAuctionId = $auction['id_xallegro_auction'];
try {
$offer = self::$api->sale()->offers()->getDetails($auction['id_auction']);
}
catch (Exception $ex) {
if ($ex->getCode() == 404) {
XAllegroAuction::archiveAuctions([$auction['id_auction']]);
}
continue;
}
// synchronize local quantity
if ($auction['quantity'] != $offer->stock->available) {
XAllegroAuction::updateAuctionQuantity($offer->stock->available, $offer->id);
}
if ($offer->publication->status == PublicationStatus::ENDED) {
$close_auctions[] = $auction['id_auction'];
}
}
return $lastAuctionId;
}
}

View File

@@ -0,0 +1,260 @@
<?php
use x13allegro\Api\DataProvider\OfferProvider;
use x13allegro\Api\Exception\InvalidArgumentException;
use x13allegro\Api\Model\Offers\OfferTags;
use x13allegro\Json\JsonMapBuilder;
final class XAllegroSyncTasks extends XAllegroSync
{
public static function checkTasks()
{
foreach (XAllegroTask::getTasks() as $task)
{
if (!self::changeAccount($task['id_xallegro_account'])) {
continue;
}
switch ($task['type'])
{
case XAllegroTask::TYPE_PUBLICATION:
self::checkPublicationTask($task);
break;
case XAllegroTask::TYPE_QUANTITY:
self::checkQuantityTask($task);
break;
case XAllegroTask::TYPE_PRICE:
self::checkPriceTask($task);
break;
default:
throw new InvalidArgumentException('Invalid Task type');
}
}
}
/**
* @param $task
*/
private static function checkPublicationTask($task)
{
$code = $task['method'] . '-publication-command';
try {
$result = self::$api
->sale()
->commands()
->offerPublication()
->tasks($task['id_command']);
foreach ($result->tasks as $taskResult)
{
if ($taskResult->status == XAllegroTask::STATUS_SUCCESS)
{
$type = 'SUCCESS';
if ($task['value'] == 'ACTIVATE')
{
XAllegroAuction::activeAuctions(array($task['id_auction']), $code);
$tags = json_decode($task['tags']);
if (!empty($tags))
{
/** @var OfferTags $offerTags */
$offerTags = (new JsonMapBuilder('OfferTags'))->map(new OfferTags());
foreach ($tags as $tag) {
$offerTags->tag($tag);
}
self::$api->sale()->offers()->tags($task['id_auction'], $offerTags);
XAllegroLogger::getInstance()
->setType('POST')
->setCode('ASSIGN_TAGS')
->setAuction($task['id_auction'])
->setAccount($task['id_xallegro_account'])
->setMessage($tags)
->log();
}
}
else {
XAllegroAuction::closeAuctions(array($task['id_auction']), $code);
}
}
else if ($taskResult->status == XAllegroTask::STATUS_FAIL) {
$type = 'ERROR';
}
else {
continue;
}
self::clearTask($taskResult, $task['id_xallegro_task'], $type, $code);
}
}
catch (Exception $ex) {
if ($ex->getCode() == 404 || $ex->getCode() == 409)
{
$taskResult = new StdClass();
$taskResult->message = (string)$ex;
self::clearTask($taskResult, $task['id_xallegro_task'], 'DELETE', $code);
}
}
}
/**
* @param array $task
*/
private static function checkQuantityTask($task)
{
$code = $task['method'] . '-quantity-change-command';
try {
$result = self::$api
->sale()
->commands()
->quantityChange()
->tasks($task['id_command']);
foreach ($result->tasks as $taskResult)
{
if ($taskResult->status == XAllegroTask::STATUS_SUCCESS)
{
$type = 'SUCCESS';
try {
$offer = (new OfferProvider(self::$api, true))->getOfferDetails($task['id_auction']);
XAllegroAuction::updateAuctionQuantity($offer->stock->available, $task['id_auction']);
}
catch (Exception $ex) {}
}
else if ($taskResult->status == XAllegroTask::STATUS_FAIL) {
$type = 'ERROR';
}
else {
$type = 'DELETE';
$now = new DateTime();
$expire = new DateTime($taskResult->scheduledAt);
$interval = $now->diff($expire);
if ($interval->days == 0 && $interval->h <= 2) {
continue;
}
}
self::clearTask($taskResult, $task['id_xallegro_task'], $type, $code);
}
}
catch (Exception $ex) {
if ($ex->getCode() == 404 || $ex->getCode() == 409)
{
$taskResult = new StdClass();
$taskResult->message = (string)$ex;
self::clearTask($taskResult, $task['id_xallegro_task'], 'DELETE', $code);
}
}
}
private static function checkPriceTask($task)
{
$code = $task['method'] . '-price-change-command';
try {
$result = self::$api
->sale()
->commands()
->priceChange()
->tasks($task['id_command']);
foreach ($result->tasks as $taskResult)
{
if ($taskResult->status == XAllegroTask::STATUS_SUCCESS) {
$type = 'SUCCESS';
XAllegroAuction::updateAuctionPrice($task['value'], $task['id_auction']);
}
else if ($taskResult->status == XAllegroTask::STATUS_FAIL) {
$type = 'ERROR';
}
else {
$type = 'DELETE';
$now = new DateTime();
$expire = new DateTime($taskResult->scheduledAt);
$interval = $now->diff($expire);
if ($interval->days == 0 && $interval->h <= 2) {
continue;
}
}
self::clearTask($taskResult, $task['id_xallegro_task'], $type, $code);
}
}
catch (Exception $ex) {
if ($ex->getCode() == 404 || $ex->getCode() == 409)
{
$taskResult = new StdClass();
$taskResult->message = (string)$ex;
self::clearTask($taskResult, $task['id_xallegro_task'], 'DELETE', $code);
}
}
}
/**
* @param StdClass $taskResult
* @param int $taskId
* @param string $loggerType
* @param string $loggerCode
*/
private static function clearTask(StdClass $taskResult, $taskId, $loggerType, $loggerCode)
{
$task = new XAllegroTask($taskId);
$message = $taskResult->message;
$code = 'DEFAULT';
if (isset($taskResult->errors) && !empty($taskResult->errors)) {
$message = ($taskResult->errors[0]->userMessage ?: $taskResult->errors[0]->message);
$code = $taskResult->errors[0]->code;
}
XAllegroLogger::getInstance()
->setType($loggerType)
->setCode($loggerCode)
->setAuction((float)$task->id_auction)
->setAccount($task->id_xallegro_account)
->setMessage(array(
'type' => $task->type,
'method' => $task->method,
'value' => $task->value,
'message' => $message,
'scheduledAt' => isset($taskResult->scheduledAt) ? $taskResult->scheduledAt : false,
'code' => $code
))
->log();
// aukcji nie znaleziono, zamykamy ją w systemie
if ($code == 'NotFoundException'
|| $code == 'PublicationValidationException.IllegalChangeInactiveOffer'
|| $code == 'NOT_FOUND'
|| $code == 'OFFER_NOT_FOUND'
|| $code == 'OFFER_DOES_NOT_EXIST'
) {
Db::getInstance()->update('xallegro_auction', ['closed' => 1], 'id_auction = '.(float)$task->id_auction);
XAllegroLogger::getInstance()
->setType('LOCAL_DB')
->setCode('not-found-auction')
->setAuction((float)$task->id_auction)
->setAccount($task->id_xallegro_account)
->setMessage('Auction closed due to its unavailability on Allegro')
->log();
}
$task->delete();
}
}