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