878 lines
28 KiB
PHP
878 lines
28 KiB
PHP
<?php
|
|
|
|
namespace External\VarioBundle\Synchronizers;
|
|
|
|
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
|
use External\VarioBundle\Exception\SynchronizerException;
|
|
use External\VarioBundle\SoapClient;
|
|
use External\VarioBundle\Util\VarioConfig;
|
|
use External\VarioBundle\Util\VarioHelper;
|
|
use KupShop\KupShopBundle\Context\ContextManager;
|
|
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
|
|
use KupShop\OrderingBundle\Util\Order\OrderItemInfo;
|
|
use Psr\Log\LoggerInterface;
|
|
use Query\Operator;
|
|
use Query\Order;
|
|
|
|
class OrderSynchronizer extends BaseSynchronizer
|
|
{
|
|
protected static $type = 'otDocument';
|
|
protected static $batch = 50;
|
|
protected static $maxBatches = 10;
|
|
protected static bool $createUnregUserFromOrder = false;
|
|
|
|
protected $fields = [
|
|
'Number' => 'document',
|
|
'DocumentItems' => 'items',
|
|
];
|
|
|
|
protected $sentryLogger;
|
|
protected $orderItemInfo;
|
|
protected $contextManager;
|
|
|
|
public function __construct(
|
|
SoapClient $client,
|
|
VarioHelper $helper,
|
|
VarioConfig $config,
|
|
LoggerInterface $logger,
|
|
SentryLogger $sentryLogger,
|
|
OrderItemInfo $orderItemInfo,
|
|
ContextManager $contextManager,
|
|
) {
|
|
parent::__construct($client, $helper, $config, $logger);
|
|
|
|
$this->sentryLogger = $sentryLogger;
|
|
$this->orderItemInfo = $orderItemInfo;
|
|
$this->contextManager = $contextManager;
|
|
}
|
|
|
|
public function getEshopID($objectID)
|
|
{
|
|
$id = $this->helper->getMapping('vario_orders', $objectID);
|
|
if (!$id) {
|
|
return null;
|
|
}
|
|
|
|
return $id;
|
|
}
|
|
|
|
public function sync()
|
|
{
|
|
$this->syncOrdersFromVario();
|
|
$this->syncOrdersToVario();
|
|
}
|
|
|
|
private function syncOrdersFromVario(): void
|
|
{
|
|
$loop = 0;
|
|
do {
|
|
// fetch data
|
|
if ($forceSync = getVal('force_sync')) {
|
|
$items = $this->client->forceObjectData(static::getType(), $forceSync);
|
|
$this->forceEnd = true;
|
|
} else {
|
|
$items = $this->client->getJobsData(static::getType(), static::$batch);
|
|
}
|
|
|
|
$doneJobs = [];
|
|
|
|
foreach ($items as $item) {
|
|
// Log change
|
|
$this->logItem($item);
|
|
|
|
$eshopID = $this->getEshopID($this->getObjectID($item));
|
|
|
|
// faktura, na ktery je packageID
|
|
if ($eshopID === null && $item->Data->DocumentType == 'FV' && !empty($item->Data->Data2)) {
|
|
$this->syncFactorage($item);
|
|
}
|
|
|
|
// eshopID is null
|
|
if ($eshopID === null) {
|
|
$doneJobs[] = $item->Job->ID;
|
|
continue;
|
|
}
|
|
|
|
// delete action
|
|
if ($item->Job->Action == 'acDelete') {
|
|
$this->syncDelete($eshopID);
|
|
$doneJobs[] = $item->Job->ID;
|
|
continue;
|
|
}
|
|
|
|
foreach ($this->fields as $originalField => $syncField) {
|
|
if (!property_exists($item->Data, $originalField)) {
|
|
continue;
|
|
}
|
|
|
|
$value = $item->Data->$originalField;
|
|
$column = $originalField;
|
|
|
|
$method = 'sync'.ucfirst($syncField);
|
|
if (!method_exists($this, $method)) {
|
|
throw new SynchronizerException(
|
|
sprintf('Method %s() for synchronizer type \'%s\' is not defined!', $method, static::getType())
|
|
);
|
|
}
|
|
|
|
call_user_func_array([$this, $method], [$value, $eshopID, $column, $item]);
|
|
}
|
|
|
|
$doneJobs[] = $item->Job->ID;
|
|
}
|
|
|
|
$doneJobs = array_filter($doneJobs);
|
|
|
|
if (!empty($doneJobs)) {
|
|
$this->client->setJobsDone($doneJobs);
|
|
}
|
|
|
|
if (static::$maxBatches !== null && static::$maxBatches <= $loop) {
|
|
$this->forceEnd = true;
|
|
}
|
|
|
|
$loop++;
|
|
} while (count($items) > 0 && $this->forceEnd == false);
|
|
}
|
|
|
|
public function syncDocument($value, $orderId, $column, $item): void
|
|
{
|
|
$order = \Order::get((int) $orderId);
|
|
|
|
$this->syncDocumentStatuses($order, $item->Data);
|
|
}
|
|
|
|
public function syncFactorage($item): void
|
|
{
|
|
$orderNumber = $this->getOriginalNumber($item->Data->OrderNumber);
|
|
// try to find order ID by order_no
|
|
$orderID = $this->selectSQL('orders', ['order_no' => $orderNumber], ['id'])->fetchColumn();
|
|
|
|
if (!$orderID) {
|
|
return;
|
|
}
|
|
|
|
$order = new \Order();
|
|
$order->createFromDB($orderID);
|
|
|
|
$order->setData('varioNumber', $item->Data->Number);
|
|
|
|
$this->syncPackageId($item->Data->Data2, $orderID);
|
|
}
|
|
|
|
protected function syncDocumentStatuses(\Order $order, object $item): void
|
|
{
|
|
}
|
|
|
|
protected function changeOrderStatus(\Order $order, int $status, ?string $emailType = null, ?string $varioStatus = null): void
|
|
{
|
|
if ($order->status != $status) {
|
|
$order->changeStatus($status, null, $emailType !== null ? true : null, null, $emailType);
|
|
$order->logHistory('[Vario] Změna stavu'.($varioStatus ? ': '.$varioStatus : ''));
|
|
}
|
|
}
|
|
|
|
public function syncItems($values, $orderID, $column, $item): void
|
|
{
|
|
if (!$orderID) {
|
|
return;
|
|
}
|
|
|
|
$order = new \Order();
|
|
$order->createFromDB($orderID);
|
|
|
|
$cancelledItems = $this->helper->getOrderAdditionalInfo($orderID, 'cancelled_items');
|
|
|
|
if (!$order->isActive()) {
|
|
return;
|
|
}
|
|
|
|
foreach ($values as $item) {
|
|
// delete cancelled items from order
|
|
if ($this->contains($item->State, 'STORNO')) {
|
|
// item is already cancelled, so skip it
|
|
if (isset($cancelledItems[$this->helper->trimVarioId($item->ID)]) && $cancelledItems[$this->helper->trimVarioId($item->ID)] == true) {
|
|
continue;
|
|
}
|
|
|
|
$itemID = null;
|
|
if (!empty($item->ProductID)) {
|
|
$productID = $this->helper->getMapping('vario_products', $this->helper->trimVarioId($item->ProductID));
|
|
$variantID = null;
|
|
if ($productID && !empty($item->VariantID)) {
|
|
$variantID = $this->helper->getMapping('vario_variations', $this->helper->trimVarioId($item->VariantID));
|
|
if (!$variantID) {
|
|
$variantID = null;
|
|
}
|
|
}
|
|
|
|
if (!$productID) {
|
|
$this->captureOrderItemSyncFailure($orderID, $item);
|
|
continue;
|
|
}
|
|
|
|
$itemID = $this->selectSQL('order_items', ['id_order' => $orderID, 'id_product' => $productID, 'id_variation' => $variantID], ['id'])->fetchColumn();
|
|
} else {
|
|
// try to find item by name
|
|
$itemID = $this->selectSQL('order_items', ['id_order' => $orderID, 'descr' => $item->Description], ['id'])->fetchColumn();
|
|
}
|
|
|
|
if (!$itemID && !($itemID = $this->findOrderItemOnShop($orderID, $item))) {
|
|
$this->captureOrderItemSyncFailure($orderID, $item);
|
|
continue;
|
|
}
|
|
|
|
$orderItem = $this->selectSQL('order_items', ['id' => $itemID])->fetch();
|
|
|
|
// Sanity check
|
|
if ($orderItem['id_order'] != $orderID) {
|
|
$this->captureOrderItemSyncFailure($orderID, $item);
|
|
continue;
|
|
}
|
|
|
|
$price = toDecimal($orderItem['total_price']);
|
|
$vat = toDecimal($orderItem['tax']);
|
|
$itemPrice = $price->addVat($vat);
|
|
|
|
$order->deleteItem($itemID);
|
|
|
|
$cancelledItems[$this->helper->trimVarioId($item->ID)] = true;
|
|
$this->helper->saveOrderAdditionalInfo($orderID, 'cancelled_items', $cancelledItems);
|
|
|
|
$history = $order->getHistory(true);
|
|
$deleteInfo = end($history);
|
|
if ($deleteInfo) {
|
|
$comment = $deleteInfo['comment'].' s cenou '.printPrice($itemPrice);
|
|
$this->updateSQL('orders_history', ['comment' => $comment], ['id' => $deleteInfo['id']]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function findOrderItemOnShop($orderID, $item): ?int
|
|
{
|
|
return null;
|
|
}
|
|
|
|
public function captureOrderItemSyncFailure($orderID, $item): void
|
|
{
|
|
$this->sentryLogger->captureException(
|
|
new SynchronizerException('Failure in order items synchronization! Order ID: '.$orderID),
|
|
[
|
|
'id_order' => $orderID,
|
|
'item' => $item,
|
|
]
|
|
);
|
|
}
|
|
|
|
public function syncPackageId($value, $orderID): void
|
|
{
|
|
if (!$orderID) {
|
|
return;
|
|
}
|
|
|
|
if (empty($value)) {
|
|
$value = null;
|
|
}
|
|
|
|
$packageId = null;
|
|
if ($value) {
|
|
$data = explode(';', $value);
|
|
$packageId = $data[1] ?? null;
|
|
}
|
|
|
|
$this->updateSQL('orders', ['package_id' => $packageId], ['id' => $orderID]);
|
|
}
|
|
|
|
private function contains(string $string, string $word): bool
|
|
{
|
|
if (strpos(strtolower($string), strtolower($word)) !== false) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected function syncOrdersToVario(): void
|
|
{
|
|
if (isDevelopment()) {
|
|
return;
|
|
}
|
|
|
|
$qb = sqlQueryBuilder()->select('o.id')
|
|
->from('orders', 'o')
|
|
->leftJoin('o', 'vario_orders', 'vo', 'vo.id_order = o.id')
|
|
->andWhere(Operator::equals(['o.status_storno' => 0]))
|
|
->andWhere('vo.id_vario IS NULL')
|
|
->andWhere(Operator::not(Operator::equals(['source' => 'import'])))
|
|
->groupBy('o.id');
|
|
|
|
foreach ($qb->execute() as $order) {
|
|
$orderObject = new \Order();
|
|
$orderObject->createFromDB($order['id']);
|
|
|
|
$this->contextManager->activateOrder($orderObject, function () use ($orderObject) {
|
|
$orderObject->fetchItems();
|
|
$this->syncOrder($orderObject);
|
|
});
|
|
}
|
|
}
|
|
|
|
public function syncOrder(\Order $order): bool
|
|
{
|
|
if (isDevelopment()) {
|
|
return true;
|
|
}
|
|
|
|
try {
|
|
$documentObject = $this->createDocumentObject($order);
|
|
|
|
$this->logOrderUpload($order, $documentObject);
|
|
|
|
$varioOrderId = $this->helper->trimVarioId($this->client->createOrUpdateOrder($documentObject));
|
|
|
|
$this->helper->createMapping('vario_orders', $varioOrderId, $order->id);
|
|
|
|
$this->resolveOrder($order, $varioOrderId);
|
|
} catch (\Exception|\Error|\Throwable $e) {
|
|
// try to create missing mapping
|
|
if ($e->getMessage() === 'There is already another Document with this Number') {
|
|
try {
|
|
$this->importMissingOrdersMapping((int) $order->id);
|
|
} catch (\Throwable $e) {
|
|
$this->helper->logException($e, sprintf('[Vario] Chyba při zápisu objednávky: %s', $order->order_no), [
|
|
'orderId' => $order->id,
|
|
'exception' => $e->getMessage(),
|
|
]);
|
|
}
|
|
} else {
|
|
$this->helper->logException($e, sprintf('[Vario] Chyba při zápisu objednávky: %s', $order->order_no), [
|
|
'orderId' => $order->id,
|
|
'exception' => $e->getMessage(),
|
|
]);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function logOrderUpload(\Order $order, \stdClass $documentObject, bool $update = false): void
|
|
{
|
|
if (isDevelopment()) {
|
|
return;
|
|
}
|
|
|
|
$status = 'Uploading';
|
|
if ($update) {
|
|
$status = 'Updating';
|
|
}
|
|
|
|
$this->logger->notice(
|
|
sprintf('VARIO: %s order to Vario, OrderID: %s', $status, $order->id),
|
|
[
|
|
'id_order' => $order->id,
|
|
'Type' => static::getType(),
|
|
'Order' => (array) $documentObject,
|
|
]
|
|
);
|
|
}
|
|
|
|
public function createDocumentObject(\Order $order): \stdClass
|
|
{
|
|
$document = new \stdClass();
|
|
|
|
$customerID = '';
|
|
if (!empty($order->id_user)) {
|
|
$customerID = sqlQueryBuilder()
|
|
->select('id_vario')
|
|
->from('vario_users')
|
|
->where(
|
|
Operator::equals(
|
|
[
|
|
'id_user' => $order->id_user,
|
|
]
|
|
)
|
|
)->execute()->fetchColumn();
|
|
|
|
if (empty($customerID)) {
|
|
$customerID = '';
|
|
}
|
|
|
|
if (!empty($customerID)) {
|
|
// check if user exists
|
|
if (!$this->checkVarioUserExists($customerID)) {
|
|
$customerID = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
if (empty($customerID) && $this->createUnregistredUser()) {
|
|
$customerID = $this->helper->createUnregistredUserFromOrder($order);
|
|
}
|
|
|
|
$document->ID = '';
|
|
$document->Book = $this->getOrderBook($order);
|
|
|
|
$document->OrderNumber = $this->getOrderNumber($order);
|
|
$document->Number = $this->getNumber($order);
|
|
$document->DocumentName = $this->getDocumentName($order);
|
|
$document->DocumentType = 'ZZ';
|
|
$document->Currency = $order->getCurrency();
|
|
$document->DontMakeInvoice = false;
|
|
$document->VarNumber = $order->order_no;
|
|
|
|
$document->Comment = $this->getDocumentComment($order);
|
|
$document->Status = 'Nová';
|
|
$document->Text = $this->getDocumentText($order);
|
|
|
|
$document->Date = $this->formatDateTime($order->date_created, 'Y-m-d\T00:00:00');
|
|
$document->TaxDate = null;
|
|
$document->SettlementDate = $this->formatDateTime($order->date_created, 'Y-m-d\T00:00:00');
|
|
|
|
$document->SettlementMethod = $this->getPaymentName($order);
|
|
$document->Delivery = $this->getDeliveryName($order);
|
|
|
|
$document->PlaceOfSupply = $this->getPlaceOfSupply($order);
|
|
|
|
$document->IO = 1; // smer toku penez
|
|
|
|
$document->Rounding = 0;
|
|
|
|
$document->Payed = 0;
|
|
$document->SettlementLeft = 0;
|
|
|
|
$document->RequestedAdvance = $this->getRequestAdvanced($order);
|
|
$document->AdvancePayed = $this->getAdvancePayed($order);
|
|
|
|
$document->TotalWithoutVAT = $order->total_price_array['value_without_vat']->asFloat();
|
|
$document->TotalWithVAT = $order->total_price_array['value_with_vat']->asFloat();
|
|
$document->Total = $order->total_price_array['value_with_vat']->asFloat();
|
|
|
|
$document->SumRoundingPlace = $this->getOrderSummaryRounding($order);
|
|
$document->VATRoundingPlace = 0.01;
|
|
|
|
$document->Interest = 0;
|
|
|
|
$document->CompanyID = $customerID;
|
|
$document->DeliveryCompanyID = '';
|
|
|
|
if (!empty($order->invoice_firm)) {
|
|
$document->CompanyName = $order->invoice_firm;
|
|
$document->PersonName = $order->invoice_name.' '.$order->invoice_surname;
|
|
} else {
|
|
$document->CompanyName = $order->invoice_name.' '.$order->invoice_surname;
|
|
$document->PersonName = $order->invoice_name.' '.$order->invoice_surname;
|
|
}
|
|
|
|
$document->Addresses = [];
|
|
foreach (['atPrimary', 'atDelivery'] as $address) {
|
|
$document->Addresses[] = $this->createAddressObject($order, $address);
|
|
}
|
|
|
|
$document->IC = $order->invoice_ico;
|
|
$document->DIC = $order->invoice_dic;
|
|
|
|
$document->Telephone = $order->invoice_phone;
|
|
$document->Email = $order->invoice_email;
|
|
|
|
$document->BankName = '';
|
|
$document->BankBranch = '';
|
|
$document->AccountNumber = '';
|
|
$document->BankCode = '';
|
|
$document->SpecificSymbol = '';
|
|
$document->IBAN = '';
|
|
|
|
$document->SalesAgent = $this->getSalesAgent($order);
|
|
$document->Category = '';
|
|
|
|
$document->DueDateDays = $this->getDueDateDays($order);
|
|
$document->PriceGroup = '';
|
|
|
|
$document->PricelistID = $this->getPriceListID($order);
|
|
$document->PricelistName = $this->getPriceListName($order);
|
|
$document->Discount = $this->getDiscount($order);
|
|
|
|
$document->OneDelivery = false;
|
|
$document->Data1 = $order->id_user ? (int) $order->id_user : '';
|
|
$document->Data2 = '';
|
|
$document->Note = $this->getDocumentNote($order);
|
|
$document->UserFields = '';
|
|
|
|
$document->DocumentItems = $this->getDocumentItems($order);
|
|
|
|
return $document;
|
|
}
|
|
|
|
protected function getDocumentItems(\Order $order)
|
|
{
|
|
$itemNumber = 1;
|
|
|
|
$documentItems = [];
|
|
foreach ($order->fetchItems() as $item) {
|
|
$documentItems[] = $this->createItemObject($item, $order, $itemNumber++);
|
|
}
|
|
|
|
return $documentItems;
|
|
}
|
|
|
|
protected function getPriceListID(\Order $order): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function getRequestAdvanced(\Order $order): float
|
|
{
|
|
$payment = $order->getDeliveryType()->getPayment();
|
|
if ($payment && $payment->hasOnlinePayment()) {
|
|
return $order->total_price_array['value_with_vat']->asFloat();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
protected function getAdvancePayed(\Order $order): float
|
|
{
|
|
$payment = $order->getDeliveryType()->getPayment();
|
|
if ($payment && $payment->hasOnlinePayment()) {
|
|
return $order->total_price_array['value_with_vat']->asFloat();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
protected function getPriceListName(\Order $order): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function getDiscount(\Order $order): string
|
|
{
|
|
return '0';
|
|
}
|
|
|
|
protected function getDueDateDays(\Order $order): int
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
protected function getSalesAgent(\Order $order): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function getPlaceOfSupply(\Order $order): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function getDeliveryName(\Order $order): string
|
|
{
|
|
$delivery = $order->getDeliveryType()->getDelivery();
|
|
|
|
if (!empty($delivery->getCustomData()['vario_name'])) {
|
|
return $delivery->getCustomData()['vario_name'];
|
|
}
|
|
|
|
return $delivery->name;
|
|
}
|
|
|
|
protected function getPaymentName(\Order $order): string
|
|
{
|
|
if ($payment = $order->getDeliveryType()->getPayment()) {
|
|
if ($payment instanceof \Dobirka) {
|
|
return 'Dobírka';
|
|
} elseif ($payment instanceof \Prevodem) {
|
|
return 'Bankovním převodem';
|
|
} elseif ($payment instanceof \GoPay) {
|
|
return 'Platba kartou GP';
|
|
}
|
|
|
|
return $payment->getName();
|
|
}
|
|
|
|
return $order->getDeliveryType()->payment;
|
|
}
|
|
|
|
protected function getNumber(\Order $order): string
|
|
{
|
|
return $this->getOrderNumber($order);
|
|
}
|
|
|
|
protected function getOrderNumber(\Order $order): string
|
|
{
|
|
return $order->order_no;
|
|
}
|
|
|
|
private function getOriginalNumber(string $number): string
|
|
{
|
|
$number = explode('-', $number);
|
|
|
|
return end($number);
|
|
}
|
|
|
|
protected function getOrderBook(\Order $order): string
|
|
{
|
|
if ($deliveryType = $order->getDeliveryType()) {
|
|
if ($delivery = $deliveryType->getDelivery()) {
|
|
$bookName = $delivery->getCustomData()['vario_book_name'] ?? null;
|
|
if (!empty($bookName)) {
|
|
return $bookName;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 'Zakázky';
|
|
}
|
|
|
|
private function checkVarioUserExists($varioID)
|
|
{
|
|
if ($this->client->getClient()->GetCustomer($varioID)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
protected function getDocumentName(\Order $order): string
|
|
{
|
|
return 'Zakázka';
|
|
}
|
|
|
|
public function createItemObject($item, \Order $order, $documentOrderNumber): \stdClass
|
|
{
|
|
$itemObject = new \stdClass();
|
|
|
|
if (!empty($item['id_product'])) {
|
|
$product = $this->selectSQL('products', ['id' => $item['id_product']])->fetch();
|
|
if (!($productId = $this->helper->getVarioID('vario_products', $item['id_product']))) {
|
|
$exception = true;
|
|
// if coupon
|
|
if ($product) {
|
|
if (!empty($product['data'])) {
|
|
$data = json_decode($product['data'], true);
|
|
if (($data['generate_coupon'] ?? false) == 'Y') {
|
|
$productId = null;
|
|
$item['id_product'] = null;
|
|
$item['id_variation'] = null;
|
|
$itemName = $item['descr'];
|
|
$exception = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($exception) {
|
|
throw new SynchronizerException(
|
|
sprintf('Mapping for product ID %s was not found!', $item['id_product'])
|
|
);
|
|
}
|
|
}
|
|
$variationId = '';
|
|
if ($item['id_variation'] !== null) {
|
|
if (!($variationId = $this->helper->getVarioID('vario_variations', $item['id_variation']))) {
|
|
throw new SynchronizerException(
|
|
sprintf('Mapping for variation ID %s was not found!', $item['id_variation'])
|
|
);
|
|
}
|
|
}
|
|
|
|
$itemNumber = '';
|
|
$itemName = $itemName ?? null;
|
|
} else {
|
|
$productId = $this->getNonProductItemID($order, $item);
|
|
$variationId = '';
|
|
$itemNumber = '';
|
|
$itemType = $this->orderItemInfo->getItemType($item);
|
|
$itemName = $item['descr'];
|
|
|
|
if ($itemType) {
|
|
$itemNumber = $itemType;
|
|
}
|
|
}
|
|
|
|
$itemObject->ID = '';
|
|
$itemObject->ProductID = $this->prepareVarioID($productId);
|
|
$itemObject->VariantID = $this->prepareVarioID($variationId);
|
|
|
|
$itemObject->DocumentID = '';
|
|
$itemObject->DocumentOrderNumber = $documentOrderNumber;
|
|
$itemObject->Description = $itemName;
|
|
$itemObject->ItemNumber = $itemNumber;
|
|
$itemObject->Quantity = $item['pieces'];
|
|
$itemObject->QuantityUnit = 'Ks';
|
|
$itemObject->GPL = $item['piece_price']['value_without_vat']->asFloat();
|
|
$itemObject->PricePerUnit = $item['piece_price']['value_without_vat']->asFloat();
|
|
$itemObject->PriceWithoutVAT = $item['total_price']['value_without_vat']->asFloat();
|
|
$itemObject->TotalVAT = $item['total_price']['value_vat']->asFloat();
|
|
$itemObject->TotalPrice = $item['total_price']['value_with_vat']->asFloat();
|
|
$itemObject->VATRate = (int) $item['vat'];
|
|
$itemObject->DiscountRate = $item['discount']->asFloat();
|
|
$itemObject->VATType = $this->getVatType($order, $item);
|
|
$itemObject->StoreID = $this->getStoreID($order, $item);
|
|
$itemObject->State = 'Rezervováno';
|
|
$itemObject->OrderID = $order->order_no;
|
|
$itemObject->DeliveryDate = null;
|
|
$itemObject->QuantityGroups = [];
|
|
$itemObject->DeliveryNoteID = '';
|
|
$itemObject->DeliveryNoteItemID = '';
|
|
$itemObject->CommissionID = '';
|
|
$itemObject->CommissionItemID = '';
|
|
$itemObject->Note = '';
|
|
$itemObject->Data1 = '';
|
|
$itemObject->Data2 = '';
|
|
$itemObject->Number1 = 0;
|
|
$itemObject->Number2 = 0;
|
|
$itemObject->AccountCode = '';
|
|
$itemObject->ExternID = '';
|
|
$itemObject->UserFields = '';
|
|
|
|
return $itemObject;
|
|
}
|
|
|
|
public function createAddressObject(\Order $order, $type = 'atPrimary'): \stdClass
|
|
{
|
|
$address = new \stdClass();
|
|
|
|
if ($type == 'atPrimary') {
|
|
$prefix = 'invoice';
|
|
$addressName = 'Fakturační adresa';
|
|
} elseif ($type == 'atDelivery') {
|
|
$prefix = 'delivery';
|
|
$addressName = 'Doručovací adresa';
|
|
} else {
|
|
throw new SynchronizerException('Unknown address type!');
|
|
}
|
|
|
|
$userName = $order->{$prefix.'_name'}.' '.$order->{$prefix.'_surname'};
|
|
if (!empty($order->{$prefix.'_firm'})) {
|
|
$userName = $order->{$prefix.'_firm'}."\n".$userName;
|
|
}
|
|
|
|
$street = $userName."\n".$order->{$prefix.'_street'};
|
|
$city = $order->{$prefix.'_city'};
|
|
$zip = $order->{$prefix.'_zip'};
|
|
|
|
$address->ID = '';
|
|
$address->AddressType = $type;
|
|
$address->AddressName = $addressName;
|
|
$address->Street = $street;
|
|
$address->City = $city;
|
|
$address->ZIP = $zip;
|
|
|
|
$address->Country = $order->{$prefix.'_country'};
|
|
|
|
$address->CountryISO = $order->{$prefix.'_country'};
|
|
$address->Address = '';
|
|
$address->UseOnDocuments = true;
|
|
if ($type == 'atDelivery') {
|
|
$address->UseOnDocuments = false;
|
|
}
|
|
|
|
return $address;
|
|
}
|
|
|
|
public function importMissingOrdersMapping(?int $orderId = null): int
|
|
{
|
|
$qb = sqlQueryBuilder()->select('o.id, o.order_no, o.date_created')
|
|
->from('orders', 'o')
|
|
->leftJoin('o', 'vario_orders', 'vo', 'vo.id_order = o.id')
|
|
->andWhere('vo.id_vario IS NULL AND o.order_no NOT LIKE \'OLD%\'');
|
|
|
|
if ($orderId) {
|
|
$qb->andWhere(Operator::equals(['o.id' => $orderId]));
|
|
}
|
|
|
|
$fixed = 0;
|
|
foreach ($qb->execute() as $item) {
|
|
$datetime = new \DateTime($item['date_created']);
|
|
$date = $datetime->format('Y-m-d');
|
|
|
|
$varioOrders = $this->client->getClient()->GetDocumentsByCriteria1(null, 'ZZ', $datetime->format('Y-m-d\TH:00:00'), $date.'\T23:59:59');
|
|
foreach ($varioOrders as $varioOrder) {
|
|
try {
|
|
$order = new \Order();
|
|
$order->createFromDB($item['id']);
|
|
|
|
$orderNumber = $this->getOriginalNumber($varioOrder->OrderNumber);
|
|
if ($orderNumber === $item['order_no']) {
|
|
try {
|
|
$this->helper->createMapping('vario_orders', $this->helper->trimVarioId($varioOrder->ID), $item['id']);
|
|
$order->logHistory('Objednávka odeslána do Varia');
|
|
$fixed++;
|
|
} catch (UniqueConstraintViolationException $e) {
|
|
continue;
|
|
}
|
|
}
|
|
} catch (\Throwable $e) {
|
|
$this->sentryLogger->captureException($e);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $fixed;
|
|
}
|
|
|
|
private function getOrderSummaryRounding(\Order $order): float
|
|
{
|
|
switch ($order->getCurrency()) {
|
|
case 'CZK':
|
|
return 1.00;
|
|
case 'EUR':
|
|
return 0.01;
|
|
}
|
|
|
|
return 0.01;
|
|
}
|
|
|
|
protected function getNonProductItemID(\Order $order, $item): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function getStoreID(\Order $order, $item): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function getVatType(\Order $order, $item): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function getDocumentComment(\Order $order): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function getDocumentText(\Order $order): string
|
|
{
|
|
$comment = $order->note_user;
|
|
if (!empty($comment)) {
|
|
return html_entity_decode($comment);
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
public function getDocumentNote(\Order $order): string
|
|
{
|
|
return '';
|
|
}
|
|
|
|
protected function formatDateTime(\DateTimeInterface $datetime, $format = 'Y-m-d\TH:i:s'): string
|
|
{
|
|
return $datetime->format($format);
|
|
}
|
|
|
|
protected function resolveOrder(\Order $order, string $varioOrderId): void
|
|
{
|
|
$order->logHistory(sprintf('[Vario] Objednávka odeslána do Varia; VarioID: %s', $varioOrderId));
|
|
}
|
|
|
|
protected function createUnregistredUser(): bool
|
|
{
|
|
return self::$createUnregUserFromOrder;
|
|
}
|
|
}
|