177 lines
6.1 KiB
PHP
177 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace KupShop\PreordersBundle\Service;
|
|
|
|
use KupShop\KupShopBundle\Context\CurrencyContext;
|
|
use KupShop\OrderingBundle\Util\Purchase\PurchaseUtil;
|
|
use KupShop\PreordersBundle\Entity\UserPreorder;
|
|
use KupShop\UserAddressesBundle\Util\UserAddressesUtil;
|
|
use Query\Operator as Op;
|
|
|
|
class OrderCreator
|
|
{
|
|
public function __construct(
|
|
private readonly CurrencyContext $currencyContext,
|
|
private readonly PurchaseUtil $purchaseUtil,
|
|
private readonly PreorderUtil $listUtil,
|
|
private readonly DynamicContexts $contextsService,
|
|
private readonly ?UserAddressesUtil $userAddressesUtil,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @param array $itemsToAdd map of [id_preorder_item => number_of_pieces]
|
|
*
|
|
* @throws \Throwable
|
|
*/
|
|
public function createOrder(UserPreorder $userPreorder, array $itemsToAdd): \Order
|
|
{
|
|
return sqlGetConnection()->transactional(
|
|
fn () => $this->contextsService->withBasePrices(
|
|
$userPreorder->getPreorder(),
|
|
fn () => $this->handleOrderCreation($userPreorder, $itemsToAdd),
|
|
),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @throws \Doctrine\DBAL\Driver\Exception|\Doctrine\DBAL\Exception
|
|
*/
|
|
private function handleOrderCreation(UserPreorder $userPreorder, array $itemsToAdd): \Order
|
|
{
|
|
$products = $this->getProductsToAdd($itemsToAdd);
|
|
$productList = $this->listUtil->getPreorderProductList($products);
|
|
|
|
$purchaseState = PreorderUtil::toPurchaseState(
|
|
$productList->getProducts(),
|
|
'preorder_piece_price',
|
|
);
|
|
|
|
$purchaseState->setCustomData([
|
|
'order' => $this->getOrderFields($userPreorder),
|
|
]);
|
|
|
|
$order = $this->purchaseUtil->createOrderFromPurchaseState($purchaseState);
|
|
$this->decrementPiecesInPreorder($userPreorder, $products);
|
|
|
|
return $order;
|
|
}
|
|
|
|
/**
|
|
* @throws \Doctrine\DBAL\Driver\Exception
|
|
* @throws \Exception
|
|
*/
|
|
private function getProductsToAdd(array $preorderItemsToAdd): array
|
|
{
|
|
$preorderItemsIds = array_keys($preorderItemsToAdd);
|
|
|
|
$items = sqlQueryBuilder()
|
|
->select('pi.id',
|
|
'pi.id_product',
|
|
'pi.id_variation',
|
|
'pi.pieces AS pieces_total',
|
|
'pi.pieces_sent',
|
|
'pi.piece_price')
|
|
->from('preorders_items', 'pi')
|
|
->where(Op::inIntArray($preorderItemsIds, 'pi.id'))
|
|
->execute()
|
|
->fetchAllAssociative();
|
|
|
|
foreach ($items as &$item) {
|
|
$item['pieces'] = $preorderItemsToAdd[$item['id']];
|
|
}
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* @throws \Doctrine\DBAL\Exception
|
|
*/
|
|
private function decrementPiecesInPreorder(UserPreorder $userPreorder, array $items): void
|
|
{
|
|
$mappedIds = [];
|
|
foreach ($items as $toAddItems) {
|
|
$mappedIds[(int) $toAddItems['id']] = $toAddItems;
|
|
}
|
|
|
|
foreach ($userPreorder->getItems() as $item) {
|
|
if (!array_key_exists((int) $item['id'], $mappedIds)) {
|
|
continue;
|
|
}
|
|
$toAddItem = $mappedIds[(int) $item['id']];
|
|
|
|
$userPreorder->setItem(
|
|
$item['id'],
|
|
null,
|
|
null,
|
|
null,
|
|
min((int) $item['pieces_sent'] + $toAddItem['pieces'], (int) $item['pieces'])
|
|
);
|
|
}
|
|
}
|
|
|
|
private function getOrderFields(UserPreorder $userPreorder): array
|
|
{
|
|
$user = $userPreorder->getUser();
|
|
$preorderData = $userPreorder->getCustomData();
|
|
|
|
$customData = [
|
|
'preorders' => [
|
|
'id_preorder_date' => $userPreorder->preorderDateId,
|
|
],
|
|
];
|
|
|
|
$data = [
|
|
'id_user' => $user->id,
|
|
'status' => findModule(\Modules::B2B_PREORDERS, 'order_status', 0),
|
|
'invoice_name' => $user->name ?? '',
|
|
'invoice_surname' => $user->surname ?? '',
|
|
'invoice_firm' => $user->firm ?? '',
|
|
'invoice_ico' => $user->ico ?? '',
|
|
'invoice_dic' => $user->dic ?? '',
|
|
'invoice_street' => $user->street ?? '',
|
|
'invoice_city' => $user->city ?? '',
|
|
'invoice_zip' => $user->zip ?? '',
|
|
'invoice_country' => $user->country ?? '',
|
|
'invoice_phone' => $user->phone ?? '',
|
|
'invoice_email' => $user->email ?? '',
|
|
'invoice_state' => $user->state ?? '',
|
|
'invoice_custom_address' => $user->invoice_custom_address ?? '',
|
|
'delivery_name' => $user->delivery_name ?? '',
|
|
'delivery_surname' => $user->delivery_surname ?? '',
|
|
'delivery_firm' => $user->delivery_firm ?? '',
|
|
'delivery_street' => $user->delivery_street ?? '',
|
|
'delivery_city' => $user->delivery_city ?? '',
|
|
'delivery_zip' => $user->delivery_zip ?? '',
|
|
'delivery_country' => $user->delivery_country ?? '',
|
|
'delivery_state' => $user->delivery_state ?? '',
|
|
'delivery_custom_address' => $user->delivery_custom_address ?? '',
|
|
'delivery_type' => 'Doprava',
|
|
'delivery_complete' => 0,
|
|
'currency' => $preorderData['currency'] ?? $user->getUserCurrency(),
|
|
'currency_rate' => $this->currencyContext->getAll()[$user->getUserCurrency()]->getRate(),
|
|
'note_user' => '',
|
|
'date_created' => date('Y-m-d H:i:s'),
|
|
'date_updated' => date('Y-m-d H:i:s'),
|
|
'note_admin' => json_encode($customData),
|
|
];
|
|
|
|
// Replace delivery fields with user address if set
|
|
if ($this->userAddressesUtil && isset($preorderData['user_address'])) {
|
|
if ($address = $this->userAddressesUtil->getDeliveryAddress($preorderData['user_address'])) {
|
|
$addressData = $address->getAddressArray();
|
|
|
|
foreach ($data as $key => &$value) {
|
|
if (!str_starts_with($key, 'delivery_')) {
|
|
continue;
|
|
}
|
|
|
|
$value = $addressData[$key] ?? $value;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
}
|