<?php
declare(strict_types=1);
namespace Iwv\IwvDatevV6\Service;
use Doctrine\DBAL\Connection;
use Iwv\IwvDatevV6\Helper\ArrayHelper;
use Iwv\IwvDatevV6\Service\VariablesExporterExt\VariablesExporterConfig;
use Iwv\IwvVariablesHelper\Services\VariablesExporterServiceAbstract;
use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionDefinition;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
class VariablesExporterService extends VariablesExporterServiceAbstract
{
/** @var Connection */
protected $connection;
/** @var EntityRepositoryInterface */
protected $stateMachineHistoryRepository;
/** @var EntitySearchResult */
protected $loadedOrdersDB;
/** @var Context */
protected $context;
/** @var VariablesExporterConfig */
protected $variablesExporterConfig;
public function __construct(
Connection $connection,
EntityRepositoryInterface $orderRepository,
EntityRepositoryInterface $stateMachineHistoryRepository
) {
$this->connection = $connection;
$this->orderRepository = $orderRepository;
$this->stateMachineHistoryRepository = $stateMachineHistoryRepository;
parent::__construct($connection);
}
/**
* @param Criteria $criteria
* @param Context $context
* @return EntitySearchResult
*/
public function loadLatestOrders(Criteria $criteria, VariablesExporterConfig $variablesExporterConfig, Context $context): EntitySearchResult
{
$this->variablesExporterConfig = $variablesExporterConfig;
$associations = [
'lineItems',
'transactions',
'transactions.paymentMethod',
'transactions.paymentMethod.translations',
'transactions.stateMachineState',
'orderCustomer.customer',
'orderCustomer.customer.group',
'deliveries',
'deliveries.stateMachineState',
'salesChannel.currency',
];
if ($this->variablesExporterConfig->loadField('order_delivery_states')) {
$associations[] = 'deliveries.stateMachineState.toStateMachineHistoryEntries';
}
$criteria->addAssociations($associations);
if ($this->variablesExporterConfig->loadField('order_delivery_states')) {
$criteria->getAssociation('deliveries.stateMachineState.toStateMachineHistoryEntries')->setLimit(1)->addSorting(new FieldSorting('createdAt', FieldSorting::DESCENDING));
}
$criteria->getAssociation('transactions')->addSorting(new FieldSorting('createdAt', FieldSorting::DESCENDING));
$this->context = $context;
$this->loadedOrdersDB = $this->orderRepository->search($criteria, $this->context);
return $this->loadedOrdersDB;
}
/**
* @param string $orderId
* @param array $settingsArray [paymentStates]
* @return array
* @throws \Exception
*/
public function getLatestOrderVariables(string $orderId, array $settingsArray): array
{
$variablesArray = [];
/** @var OrderEntity $orderDB */
$orderDB = $this->loadedOrdersDB->get($orderId);
if (!$orderDB) {
return $variablesArray;
}
$transactions = $orderDB->getTransactions();
$hasTransactions = $transactions && $transactions->first();
$paymentMethod = $paymentMethodName = '';
if ($hasTransactions) {
$customFields = $transactions->first()->getCustomFields();
$paymentCodeArray = explode("\\", $transactions->first()->getPaymentMethod()->getHandlerIdentifier());
$paymentMethod = end($paymentCodeArray);
$paymentCustomFields = $transactions->first()->getPaymentMethod()->getCustomFields();
if ($paymentCustomFields) {
$variablesArray = array_merge($variablesArray, ArrayHelper::arrayFlat($paymentCustomFields, 'payment_method_cf', '_'));
}
$paymentMethodName = $transactions->first()->getPaymentMethod()->getTranslated() && isset($transactions->first()->getPaymentMethod()->getTranslated()['name']) ? $transactions->first()->getPaymentMethod()->getTranslated()['name'] : '';
if ($customFields) {
$variablesArray = array_merge($variablesArray, ArrayHelper::arrayFlat($customFields, 'order_transaction_cf', '.', $this->variablesExporterConfig->loadField('order_transaction_cf_export') === 'deep_load'));
$variablesArray = array_merge($variablesArray, ArrayHelper::arrayFlat($customFields, 'order_transaction_cf', '_', $this->variablesExporterConfig->loadField('order_transaction_cf_export') === 'deep_load'));
}
if (isset($settingsArray['paymentsErloes'][$transactions->first()->getPaymentMethod()->getId()])) {
$variablesArray['{payment_datev_konto}'] = $settingsArray['paymentsErloes'][$transactions->first()->getPaymentMethod()->getId()]['counterAccount'];
} elseif (isset($settingsArray['paymentsErloes']['default'])) {
$variablesArray['{payment_datev_konto}'] = $settingsArray['paymentsErloes']['default']['counterAccount'];
}
}
$variablesArray['{payment_method_cf_datev_gegenkonto}'] = $variablesArray['{payment_datev_konto}'] ?? '';
$variablesArray['{order_number}'] = $orderDB->getOrderNumber();
$variablesArray['{order_date}'] = $orderDB->getOrderDateTime()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d');
$variablesArray['{order_affiliate_code}'] = $orderDB->getAffiliateCode();
$variablesArray['{order_payment_status}'] = $hasTransactions && $orderDB->getTransactions()->first()->getStateMachineState() ? $orderDB->getTransactions()->first()->getStateMachineState()->getTechnicalName() : '';
$variablesArray['{order_status}'] = $orderDB->getStateMachineState() ? $orderDB->getStateMachineState()->getTechnicalName() : '';
$variablesArray['{order_delivery_status}'] = $orderDB->getDeliveries() && $orderDB->getDeliveries()->first() && $orderDB->getDeliveries()->first()->getStateMachineState() ? $orderDB->getDeliveries()->first()->getStateMachineState()->getTechnicalName() : '';
$variablesArray['{order_customer_comment}'] = $orderDB->getCustomerComment() ?: '';
$variablesArray['{payment_method}'] = $paymentMethod;
$variablesArray['{payment_method_name}'] = $paymentMethodName;
$variablesArray['{customer_number}'] = $orderDB->getOrderCustomer()->getCustomerNumber();
$variablesArray['{customer_email}'] = $orderDB->getOrderCustomer()->getEmail();
$customerGroupDB = $orderDB->getOrderCustomer()->getCustomer() ? $orderDB->getOrderCustomer()->getCustomer()->getGroup() : '';
$variablesArray['{customer_group_id}'] = $customerGroupDB ? $customerGroupDB->getId() : '';
$variablesArray['{customer_group_name}'] = $customerGroupDB ? ($customerGroupDB->getTranslated()['name'] ?? $customerGroupDB->getName()) : '';
$variablesArray['{sales_channel_currency}'] = $orderDB->getSalesChannel()->getCurrency()->getIsoCode();
$variablesArray['{sales_channel_name}'] = $orderDB->getSalesChannel()->getName();;
$variablesArray['{sales_channel_id}'] = $orderDB->getSalesChannelId();
$variablesArray['{order_delivery_date}'] = $orderDB->getDeliveries() && $orderDB->getDeliveries()->last() ? $orderDB->getDeliveries()->last()->getShippingDateEarliest()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d') : '';
/* order custom fields */
if ($this->variablesExporterConfig->loadField('order_cf_export') && ($orderCustomFields = $orderDB->getCustomFields())) {
foreach ($orderCustomFields as $pdcfKey => $pdcf) {
if (is_string($pdcf) || is_numeric($pdcf)) {
$variablesArray['{order_cf_' . $pdcfKey . '}'] = $pdcf;
} elseif (is_bool($pdcf)) {
$variablesArray['{order_cf_' . $pdcfKey . '}'] = $pdcf ? '1' : '0';
}
}
$variablesArray = array_merge($variablesArray, ArrayHelper::arrayFlat($orderCustomFields, 'order_cf', '.', $this->variablesExporterConfig->loadField('order_cf_export') === 'deep_load'));
}
/* customer group custom fields */
if ($this->variablesExporterConfig->loadField('customer_group_cf_export') && ($customFields = $customerGroupDB && $customerGroupDB->getCustomFields() ? $customerGroupDB->getCustomFields() : false)) {
foreach ($customFields as $pdcfKey => $pdcf) {
if (is_string($pdcf) || is_numeric($pdcf)) {
$variablesArray['{customer_group_cf_' . $pdcfKey . '}'] = $pdcf;
} elseif (is_bool($pdcf)) {
$variablesArray['{customer_group_cf_' . $pdcfKey . '}'] = $pdcf ? '1' : '0';
}
}
// $variablesArray = array_merge($variablesArray, ArrayHelper::arrayFlat($orderCustomFields, 'order_cf', '.', $this->variablesExporterConfig->loadField('order_cf_export') === 'deep_load'));
}
/* customer custom fields */
if ($orderDB->getOrderCustomer() && $orderDB->getOrderCustomer()->getCustomer() && ($customFields = $orderDB->getOrderCustomer()->getCustomer()->getCustomFields())) {
foreach ($customFields as $pdcfKey => $pdcf) {
if (is_string($pdcf) || is_numeric($pdcf)) {
$variablesArray['{customer_cf_' . $pdcfKey . '}'] = $pdcf;
} elseif (is_bool($pdcf)) {
$variablesArray['{customer_cf_' . $pdcfKey . '}'] = $pdcf ? '1' : '0';
}
}
}
if ($this->variablesExporterConfig->loadField('payment_states_export') || isset($settingsArray['paymentRowLegacyExport'])) {
foreach (
($orderDB->getTransactions() ? $this->stateMachineHistoryRepository->search((new Criteria)
->addFilter(new EqualsFilter('entityName', OrderTransactionDefinition::ENTITY_NAME))
->addFilter(new EqualsAnyFilter('entityId.id', $orderDB->getTransactions()->getIds()))
->addFilter(new EqualsAnyFilter('transitionActionName', $settingsArray['paymentStates']['selectStates']))
->addSorting(new FieldSorting('createdAt', FieldSorting::DESCENDING)), $this->context) : []) as $transactionDate
) {
if (isset($settingsArray['paymentStates']['paid'][$transactionDate->getTransitionActionName()]) && empty($variablesArray['{payment_date}'])) {
$variablesArray['{payment_date}'] = $transactionDate->getCreatedAt()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d');
}
if (isset($settingsArray['paymentStates']['refunded'][$transactionDate->getTransitionActionName()]) && empty($variablesArray['{refunded_date}'])) {
$variablesArray['{refunded_date}'] = $transactionDate->getCreatedAt()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d');
}
}
}
/* delivery states */
if ($orderDB->getDeliveries() && $orderDB->getDeliveries()->first()) {
/** @var \Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity $deliveryDB */
$variablesArray['{order_delivery_state}'] = $orderDB->getDeliveries()->first()->getStateMachineState()->getTechnicalName();
foreach ($orderDB->getDeliveries() as $deliveryDB) {
if (empty($variablesArray['{order_tracking_id}']) && ($trackingIds = implode(', ', $deliveryDB->getTrackingCodes()))) {
$variablesArray['{order_tracking_id}'] = $trackingIds;
}
if ($this->variablesExporterConfig->loadField('order_delivery_states')) {
if ($deliveryDB->getStateMachineState()->getTechnicalName() === 'shipped') {
$variablesArray['{order_shipped_date}'] = $deliveryDB->getStateMachineState()->getToStateMachineHistoryEntries() && $deliveryDB->getStateMachineState()->getToStateMachineHistoryEntries()->first() ? $deliveryDB->getStateMachineState()->getToStateMachineHistoryEntries()->first()->getCreatedAt()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d') : ($deliveryDB->getUpdatedAt() ? $deliveryDB->getUpdatedAt()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d') : ($deliveryDB->getCreatedAt() ? $deliveryDB->getCreatedAt()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d') : ''));
break 1;
} elseif ($deliveryDB->getStateMachineState()->getTechnicalName() === 'shipped_partially') {
$variablesArray['{order_shipped_date}'] = $deliveryDB->getStateMachineState()->getToStateMachineHistoryEntries() && $deliveryDB->getStateMachineState()->getToStateMachineHistoryEntries()->first() ? $deliveryDB->getStateMachineState()->getToStateMachineHistoryEntries()->first()->getCreatedAt()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d') : ($deliveryDB->getUpdatedAt() ? $deliveryDB->getUpdatedAt()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d') : ($deliveryDB->getCreatedAt() ? $deliveryDB->getCreatedAt()->setTimezone(new \DateTimeZone($this->variablesExporterConfig->exportTimeZone))->format('Y-m-d') : ''));
}
}
}
}
/* sw635 compatibility fix */
$query = 'SELECT platform,special FROM magnalister_orders WHERE current_orders_id = ?';
$params = [$orderDB->getId()];
if (isset($settingsArray['hasPluginMagnalister']) && $settingsArray['hasPluginMagnalister'] && ($q = method_exists($this->connection, 'fetchAssociative') ? $this->connection->fetchAssociative($query, $params) : $this->connection->fetchAssoc($query, $params))) {
$variablesArray['{channel_name}'] = $q['platform'];
$variablesArray['{channel_order_number}'] = $q['special'];
}
$variablesArray['{currency_factor_order_total}'] = $this->formatPrice($orderDB->getAmountTotal() / $orderDB->getCurrencyFactor());
return array_merge($this->getOrderPluginVariables($orderDB)['entityVars'], $variablesArray);
}
/**
*
* @param float $price
* @return string
*/
protected function formatPrice($price): string
{
return number_format($price, 2, ',', '');
}
/**
* @param OrderEntity $orderDB
* @return array[]
*/
public function getOrderPluginVariables(OrderEntity $orderDB): array
{
$entityVars = [];
foreach ($this->pluginVariables as $plugin) {
$entityVars = array_merge($entityVars, $plugin->getVariablesFromOrderDB($orderDB));
}
$entityVars['{order_transaction_id}'] = ($entityVars['{paypal_payment_id}'] ?? '') ?: ($entityVars['{payone_transaction_id}'] ?: ($entityVars['{mollie_third_party_payment_id}'] ?: ($entityVars['{klarna_order_id}'] ?: ($entityVars['{easycredit_transaction_id}'] ?: ($entityVars['{swag_amazon_pay_charge_id}'] ?: '')))));
return [
'entityVars' => $entityVars,
];
}
}