12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Sales\Model\AdminOrder;
- use Magento\Customer\Api\AddressMetadataInterface;
- use Magento\Customer\Model\Metadata\Form as CustomerForm;
- use Magento\Framework\Api\ExtensibleDataObjectConverter;
- use Magento\Framework\App\ObjectManager;
- use Magento\Quote\Model\Quote\Address;
- use Magento\Quote\Model\Quote\Item;
- use Magento\Sales\Api\Data\OrderAddressInterface;
- use Magento\Sales\Model\Order;
- use Magento\Store\Model\StoreManagerInterface;
- use Psr\Log\LoggerInterface;
- /**
- * Order create model
- * @api
- * @SuppressWarnings(PHPMD.TooManyFields)
- * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- * @since 100.0.2
- */
- class Create extends \Magento\Framework\DataObject implements \Magento\Checkout\Model\Cart\CartInterface
- {
- /**
- * Xml default email domain path
- */
- const XML_PATH_DEFAULT_EMAIL_DOMAIN = 'customer/create_account/email_domain';
- /**
- * Quote session object
- *
- * @var \Magento\Backend\Model\Session\Quote
- */
- protected $_session;
- /**
- * Quote customer wishlist model object
- *
- * @var \Magento\Wishlist\Model\Wishlist
- */
- protected $_wishlist;
- /**
- * Sales Quote instance
- *
- * @var \Magento\Quote\Model\Quote
- */
- protected $_cart;
- /**
- * Catalog Compare List instance
- *
- * @var \Magento\Catalog\Model\Product\Compare\ListCompare
- */
- protected $_compareList;
- /**
- * Re-collect quote flag
- *
- * @var boolean
- */
- protected $_needCollect;
- /**
- * Re-collect cart flag
- *
- * @var boolean
- */
- protected $_needCollectCart = false;
- /**
- * Collect (import) data and validate it flag
- *
- * @var boolean
- */
- protected $_isValidate = false;
- /**
- * Array of validate errors
- *
- * @var array
- */
- protected $_errors = [];
- /**
- * Quote associated with the model
- *
- * @var \Magento\Quote\Model\Quote
- */
- protected $_quote;
- /**
- * Core registry
- *
- * @var \Magento\Framework\Registry
- */
- protected $_coreRegistry = null;
- /**
- * @var \Psr\Log\LoggerInterface
- */
- protected $_logger;
- /**
- * Core event manager proxy
- *
- * @var \Magento\Framework\Event\ManagerInterface
- */
- protected $_eventManager = null;
- /**
- * @var \Magento\Sales\Model\Config
- */
- protected $_salesConfig;
- /**
- * @var \Magento\Framework\ObjectManagerInterface
- */
- protected $_objectManager;
- /**
- * @var \Magento\Framework\DataObject\Copy
- */
- protected $_objectCopyService;
- /**
- * @var \Magento\Framework\Message\ManagerInterface
- */
- protected $messageManager;
- /**
- * @var Product\Quote\Initializer
- */
- protected $quoteInitializer;
- /**
- * @var \Magento\Customer\Api\CustomerRepositoryInterface
- */
- protected $customerRepository;
- /**
- * @var \Magento\Customer\Api\AddressRepositoryInterface
- */
- protected $addressRepository;
- /**
- * @var \Magento\Customer\Api\Data\AddressInterfaceFactory
- */
- protected $addressFactory;
- /**
- * @var \Magento\Customer\Model\Metadata\FormFactory
- */
- protected $_metadataFormFactory;
- /**
- * @var \Magento\Customer\Api\GroupRepositoryInterface
- */
- protected $groupRepository;
- /**
- * @var \Magento\Framework\App\Config\ScopeConfigInterface
- */
- protected $_scopeConfig;
- /**
- * @var \Magento\CatalogInventory\Api\StockRegistryInterface
- */
- protected $stockRegistry;
- /**
- * @var \Magento\Sales\Model\AdminOrder\EmailSender
- */
- protected $emailSender;
- /**
- * @var \Magento\Quote\Model\Quote\Item\Updater
- */
- protected $quoteItemUpdater;
- /**
- * @var \Magento\Framework\DataObject\Factory
- */
- protected $objectFactory;
- /**
- * @var \Magento\Customer\Api\AccountManagementInterface
- */
- protected $accountManagement;
- /**
- * @var \Magento\Customer\Api\Data\CustomerInterfaceFactory
- */
- protected $customerFactory;
- /**
- * Constructor
- *
- * @var \Magento\Customer\Model\Customer\Mapper
- */
- protected $customerMapper;
- /**
- * @var \Magento\Quote\Api\CartRepositoryInterface
- */
- protected $quoteRepository;
- /**
- * @var \Magento\Quote\Api\CartManagementInterface
- */
- protected $quoteManagement;
- /**
- * @var \Magento\Framework\Api\DataObjectHelper
- */
- protected $dataObjectHelper;
- /**
- * @var \Magento\Sales\Api\OrderManagementInterface
- */
- protected $orderManagement;
- /**
- * @var \Magento\Quote\Model\QuoteFactory
- */
- protected $quoteFactory;
- /**
- * Serializer interface instance.
- *
- * @var \Magento\Framework\Serialize\Serializer\Json
- */
- private $serializer;
- /**
- * @var ExtensibleDataObjectConverter
- */
- private $dataObjectConverter;
- /**
- * @var StoreManagerInterface
- */
- private $storeManager;
- /**
- * @param \Magento\Framework\ObjectManagerInterface $objectManager
- * @param \Magento\Framework\Event\ManagerInterface $eventManager
- * @param \Magento\Framework\Registry $coreRegistry
- * @param \Magento\Sales\Model\Config $salesConfig
- * @param \Magento\Backend\Model\Session\Quote $quoteSession
- * @param \Psr\Log\LoggerInterface $logger
- * @param \Magento\Framework\DataObject\Copy $objectCopyService
- * @param \Magento\Framework\Message\ManagerInterface $messageManager
- * @param Product\Quote\Initializer $quoteInitializer
- * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
- * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository
- * @param \Magento\Customer\Api\Data\AddressInterfaceFactory $addressFactory
- * @param \Magento\Customer\Model\Metadata\FormFactory $metadataFormFactory
- * @param \Magento\Customer\Api\GroupRepositoryInterface $groupRepository
- * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
- * @param EmailSender $emailSender
- * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
- * @param Item\Updater $quoteItemUpdater
- * @param \Magento\Framework\DataObject\Factory $objectFactory
- * @param \Magento\Quote\Api\CartRepositoryInterface $quoteRepository
- * @param \Magento\Customer\Api\AccountManagementInterface $accountManagement
- * @param \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory
- * @param \Magento\Customer\Model\Customer\Mapper $customerMapper
- * @param \Magento\Quote\Api\CartManagementInterface $quoteManagement
- * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
- * @param \Magento\Sales\Api\OrderManagementInterface $orderManagement
- * @param \Magento\Quote\Model\QuoteFactory $quoteFactory
- * @param array $data
- * @param \Magento\Framework\Serialize\Serializer\Json|null $serializer
- * @param ExtensibleDataObjectConverter|null $dataObjectConverter
- * @param StoreManagerInterface $storeManager
- * @SuppressWarnings(PHPMD.ExcessiveParameterList)
- */
- public function __construct(
- \Magento\Framework\ObjectManagerInterface $objectManager,
- \Magento\Framework\Event\ManagerInterface $eventManager,
- \Magento\Framework\Registry $coreRegistry,
- \Magento\Sales\Model\Config $salesConfig,
- \Magento\Backend\Model\Session\Quote $quoteSession,
- \Psr\Log\LoggerInterface $logger,
- \Magento\Framework\DataObject\Copy $objectCopyService,
- \Magento\Framework\Message\ManagerInterface $messageManager,
- Product\Quote\Initializer $quoteInitializer,
- \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
- \Magento\Customer\Api\AddressRepositoryInterface $addressRepository,
- \Magento\Customer\Api\Data\AddressInterfaceFactory $addressFactory,
- \Magento\Customer\Model\Metadata\FormFactory $metadataFormFactory,
- \Magento\Customer\Api\GroupRepositoryInterface $groupRepository,
- \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
- \Magento\Sales\Model\AdminOrder\EmailSender $emailSender,
- \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry,
- \Magento\Quote\Model\Quote\Item\Updater $quoteItemUpdater,
- \Magento\Framework\DataObject\Factory $objectFactory,
- \Magento\Quote\Api\CartRepositoryInterface $quoteRepository,
- \Magento\Customer\Api\AccountManagementInterface $accountManagement,
- \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory,
- \Magento\Customer\Model\Customer\Mapper $customerMapper,
- \Magento\Quote\Api\CartManagementInterface $quoteManagement,
- \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
- \Magento\Sales\Api\OrderManagementInterface $orderManagement,
- \Magento\Quote\Model\QuoteFactory $quoteFactory,
- array $data = [],
- \Magento\Framework\Serialize\Serializer\Json $serializer = null,
- ExtensibleDataObjectConverter $dataObjectConverter = null,
- StoreManagerInterface $storeManager = null
- ) {
- $this->_objectManager = $objectManager;
- $this->_eventManager = $eventManager;
- $this->_coreRegistry = $coreRegistry;
- $this->_salesConfig = $salesConfig;
- $this->_session = $quoteSession;
- $this->_logger = $logger;
- $this->_objectCopyService = $objectCopyService;
- $this->quoteInitializer = $quoteInitializer;
- $this->messageManager = $messageManager;
- $this->customerRepository = $customerRepository;
- $this->addressRepository = $addressRepository;
- $this->addressFactory = $addressFactory;
- $this->_metadataFormFactory = $metadataFormFactory;
- $this->customerFactory = $customerFactory;
- $this->groupRepository = $groupRepository;
- $this->_scopeConfig = $scopeConfig;
- $this->emailSender = $emailSender;
- $this->stockRegistry = $stockRegistry;
- $this->quoteItemUpdater = $quoteItemUpdater;
- $this->objectFactory = $objectFactory;
- $this->quoteRepository = $quoteRepository;
- $this->accountManagement = $accountManagement;
- $this->customerMapper = $customerMapper;
- $this->quoteManagement = $quoteManagement;
- $this->dataObjectHelper = $dataObjectHelper;
- $this->orderManagement = $orderManagement;
- $this->quoteFactory = $quoteFactory;
- $this->serializer = $serializer ?: ObjectManager::getInstance()
- ->get(\Magento\Framework\Serialize\Serializer\Json::class);
- parent::__construct($data);
- $this->dataObjectConverter = $dataObjectConverter ?: ObjectManager::getInstance()
- ->get(ExtensibleDataObjectConverter::class);
- $this->storeManager = $storeManager ?: ObjectManager::getInstance()->get(StoreManagerInterface::class);
- }
- /**
- * Set validate data in import data flag
- *
- * @param boolean $flag
- * @return $this
- */
- public function setIsValidate($flag)
- {
- $this->_isValidate = (bool)$flag;
- return $this;
- }
- /**
- * Return is validate data in import flag
- *
- * @return boolean
- * @SuppressWarnings(PHPMD.BooleanGetMethodName)
- */
- public function getIsValidate()
- {
- return $this->_isValidate;
- }
- /**
- * Retrieve quote item
- *
- * @param int|\Magento\Quote\Model\Quote\Item $item
- * @return \Magento\Quote\Model\Quote\Item|false
- */
- protected function _getQuoteItem($item)
- {
- if ($item instanceof \Magento\Quote\Model\Quote\Item) {
- return $item;
- } elseif (is_numeric($item)) {
- return $this->getSession()->getQuote()->getItemById($item);
- }
- return false;
- }
- /**
- * Initialize data for price rules
- *
- * @return $this
- */
- public function initRuleData()
- {
- $this->_coreRegistry->register(
- 'rule_data',
- new \Magento\Framework\DataObject(
- [
- 'store_id' => $this->_session->getStore()->getId(),
- 'website_id' => $this->_session->getStore()->getWebsiteId(),
- 'customer_group_id' => $this->getCustomerGroupId()
- ]
- )
- );
- return $this;
- }
- /**
- * Set collect totals flag for quote
- *
- * @param bool $flag
- * @return $this
- */
- public function setRecollect($flag)
- {
- $this->_needCollect = $flag;
- return $this;
- }
- /**
- * Recollect totals for customer cart.
- *
- * Set recollect totals flag for quote.
- *
- * @return $this
- */
- public function recollectCart()
- {
- if ($this->_needCollectCart === true) {
- $this->getCustomerCart()->collectTotals();
- $this->quoteRepository->save($this->getCustomerCart());
- }
- $this->setRecollect(true);
- return $this;
- }
- /**
- * Quote saving
- *
- * @return $this
- */
- public function saveQuote()
- {
- if (!$this->getQuote()->getId()) {
- return $this;
- }
- if ($this->_needCollect) {
- $this->getQuote()->collectTotals();
- }
- $this->quoteRepository->save($this->getQuote());
- return $this;
- }
- /**
- * Retrieve session model object of quote
- *
- * @return \Magento\Backend\Model\Session\Quote
- */
- public function getSession()
- {
- return $this->_session;
- }
- /**
- * Retrieve quote object model
- *
- * @return \Magento\Quote\Model\Quote
- */
- public function getQuote()
- {
- if (!$this->_quote) {
- $this->_quote = $this->getSession()->getQuote();
- }
- return $this->_quote;
- }
- /**
- * Set quote object
- *
- * @param \Magento\Quote\Model\Quote $quote
- * @return $this
- */
- public function setQuote(\Magento\Quote\Model\Quote $quote)
- {
- $this->_quote = $quote;
- return $this;
- }
- /**
- * Initialize creation data from existing order
- *
- * @param \Magento\Sales\Model\Order $order
- * @return $this
- * @throws \Magento\Framework\Exception\LocalizedException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- public function initFromOrder(\Magento\Sales\Model\Order $order)
- {
- $session = $this->getSession();
- $session->setData($order->getReordered() ? 'reordered' : 'order_id', $order->getId());
- $session->setCurrencyId($order->getOrderCurrencyCode());
- /* Check if we edit guest order */
- $session->setCustomerId($order->getCustomerId() ?: false);
- $session->setStoreId($order->getStoreId());
- /* Initialize catalog rule data with new session values */
- $this->initRuleData();
- foreach ($order->getItemsCollection($this->_salesConfig->getAvailableProductTypes(), true) as $orderItem) {
- /* @var $orderItem \Magento\Sales\Model\Order\Item */
- if (!$orderItem->getParentItem()) {
- $qty = $orderItem->getQtyOrdered();
- if (!$order->getReordered()) {
- $qty -= max($orderItem->getQtyShipped(), $orderItem->getQtyInvoiced());
- }
- if ($qty > 0) {
- $item = $this->initFromOrderItem($orderItem, $qty);
- if (is_string($item)) {
- throw new \Magento\Framework\Exception\LocalizedException(__($item));
- }
- }
- }
- }
- $shippingAddress = $order->getShippingAddress();
- if ($shippingAddress) {
- $shippingAddress->setSameAsBilling($this->isAddressesAreEqual($order));
- }
- $this->_initBillingAddressFromOrder($order);
- $this->_initShippingAddressFromOrder($order);
- $quote = $this->getQuote();
- if (!$quote->isVirtual() && $this->getShippingAddress()->getSameAsBilling()) {
- $this->setShippingAsBilling(1);
- }
- $this->setShippingMethod($order->getShippingMethod());
- $quote->getShippingAddress()->setShippingDescription($order->getShippingDescription());
- $orderCouponCode = $order->getCouponCode();
- if ($orderCouponCode) {
- $quote->setCouponCode($orderCouponCode);
- }
- if ($quote->getCouponCode()) {
- $quote->collectTotals();
- }
- $this->_objectCopyService->copyFieldsetToTarget('sales_copy_order', 'to_edit', $order, $quote);
- $this->_eventManager->dispatch('sales_convert_order_to_quote', ['order' => $order, 'quote' => $quote]);
- if (!$order->getCustomerId()) {
- $quote->setCustomerIsGuest(true);
- }
- if ($session->getUseOldShippingMethod(true)) {
- /*
- * if we are making reorder or editing old order
- * we need to show old shipping as preselected
- * so for this we need to collect shipping rates
- */
- $this->collectShippingRates();
- } else {
- /*
- * if we are creating new order then we don't need to collect
- * shipping rates before customer hit appropriate button
- */
- $this->collectRates();
- }
- $quote->getShippingAddress()->unsCachedItemsAll();
- $quote->setTotalsCollectedFlag(false);
- $this->quoteRepository->save($quote);
- return $this;
- }
- /**
- * Copy billing address from order
- *
- * @param \Magento\Sales\Model\Order $order
- * @return void
- */
- protected function _initBillingAddressFromOrder(\Magento\Sales\Model\Order $order)
- {
- $this->getQuote()->getBillingAddress()->setCustomerAddressId('');
- $this->_objectCopyService->copyFieldsetToTarget(
- 'sales_copy_order_billing_address',
- 'to_order',
- $order->getBillingAddress(),
- $this->getQuote()->getBillingAddress()
- );
- }
- /**
- * Copy shipping address from order
- *
- * @param \Magento\Sales\Model\Order $order
- * @return void
- */
- protected function _initShippingAddressFromOrder(\Magento\Sales\Model\Order $order)
- {
- $orderShippingAddress = $order->getShippingAddress();
- $quoteShippingAddress = $this->getQuote()->getShippingAddress()->setCustomerAddressId(
- ''
- )->setSameAsBilling(
- $orderShippingAddress && $orderShippingAddress->getSameAsBilling()
- );
- $this->_objectCopyService->copyFieldsetToTarget(
- 'sales_copy_order_shipping_address',
- 'to_order',
- $orderShippingAddress,
- $quoteShippingAddress
- );
- }
- /**
- * Initialize creation data from existing order Item
- *
- * @param \Magento\Sales\Model\Order\Item $orderItem
- * @param int $qty
- * @return \Magento\Quote\Model\Quote\Item|string|$this
- */
- public function initFromOrderItem(\Magento\Sales\Model\Order\Item $orderItem, $qty = null)
- {
- if (!$orderItem->getId()) {
- return $this;
- }
- $product = $this->_objectManager->create(
- \Magento\Catalog\Model\Product::class
- )->setStoreId(
- $this->getSession()->getStoreId()
- )->load(
- $orderItem->getProductId()
- );
- if ($product->getId()) {
- $product->setSkipCheckRequiredOption(true);
- $buyRequest = $orderItem->getBuyRequest();
- if (is_numeric($qty)) {
- $buyRequest->setQty($qty);
- }
- $item = $this->getQuote()->addProduct($product, $buyRequest);
- if (is_string($item)) {
- return $item;
- }
- if ($additionalOptions = $orderItem->getProductOptionByCode('additional_options')) {
- $item->addOption(
- new \Magento\Framework\DataObject(
- [
- 'product' => $item->getProduct(),
- 'code' => 'additional_options',
- 'value' => $this->serializer->serialize($additionalOptions)
- ]
- )
- );
- }
- $this->_eventManager->dispatch(
- 'sales_convert_order_item_to_quote_item',
- ['order_item' => $orderItem, 'quote_item' => $item]
- );
- return $item;
- }
- return $this;
- }
- /**
- * Retrieve customer wishlist model object
- *
- * @param bool $cacheReload pass cached wishlist object and get new one
- * @return \Magento\Wishlist\Model\Wishlist|false Return false if customer ID is not specified
- */
- public function getCustomerWishlist($cacheReload = false)
- {
- if ($this->_wishlist !== null && !$cacheReload) {
- return $this->_wishlist;
- }
- $customerId = (int)$this->getSession()->getCustomerId();
- if ($customerId) {
- $this->_wishlist = $this->_objectManager->create(\Magento\Wishlist\Model\Wishlist::class);
- $this->_wishlist->loadByCustomerId($customerId, true);
- $this->_wishlist->setStore(
- $this->getSession()->getStore()
- )->setSharedStoreIds(
- $this->getSession()->getStore()->getWebsite()->getStoreIds()
- );
- } else {
- $this->_wishlist = false;
- }
- return $this->_wishlist;
- }
- /**
- * Retrieve customer cart quote object model
- *
- * @return \Magento\Quote\Model\Quote
- */
- public function getCustomerCart()
- {
- if ($this->_cart !== null) {
- return $this->_cart;
- }
- $this->_cart = $this->quoteFactory->create();
- $customerId = (int)$this->getSession()->getCustomerId();
- $storeId = (int)$this->getSession()->getStoreId();
- if ($customerId) {
- try {
- $this->_cart = $this->quoteRepository->getForCustomer($customerId, [$storeId]);
- } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
- $this->_cart->setStore($this->getSession()->getStore());
- $customerData = $this->customerRepository->getById($customerId);
- $this->_cart->assignCustomer($customerData);
- $this->quoteRepository->save($this->_cart);
- }
- }
- return $this->_cart;
- }
- /**
- * Retrieve customer compare list model object
- *
- * @return \Magento\Catalog\Model\Product\Compare\ListCompare
- */
- public function getCustomerCompareList()
- {
- if ($this->_compareList !== null) {
- return $this->_compareList;
- }
- $customerId = (int)$this->getSession()->getCustomerId();
- if ($customerId) {
- $this->_compareList = $this->_objectManager->create(
- \Magento\Catalog\Model\Product\Compare\ListCompare::class
- );
- } else {
- $this->_compareList = false;
- }
- return $this->_compareList;
- }
- /**
- * Retrieve current customer group ID.
- *
- * @return int
- */
- public function getCustomerGroupId()
- {
- $groupId = $this->getQuote()->getCustomerGroupId();
- if (!$groupId) {
- $groupId = $this->getSession()->getCustomerGroupId();
- }
- return $groupId;
- }
- /**
- * Move quote item to another items list
- *
- * @param int|\Magento\Quote\Model\Quote\Item $item
- * @param string $moveTo
- * @param int $qty
- * @return $this
- * @throws \Magento\Framework\Exception\LocalizedException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
- */
- public function moveQuoteItem($item, $moveTo, $qty)
- {
- $item = $this->_getQuoteItem($item);
- if ($item) {
- $removeItem = false;
- $moveTo = explode('_', $moveTo);
- switch ($moveTo[0]) {
- case 'order':
- $info = $item->getBuyRequest();
- $info->setOptions($this->_prepareOptionsForRequest($item))->setQty($qty);
- $product = $this->_objectManager->create(
- \Magento\Catalog\Model\Product::class
- )->setStoreId(
- $this->getQuote()->getStoreId()
- )->load(
- $item->getProduct()->getId()
- );
- $product->setSkipCheckRequiredOption(true);
- $newItem = $this->getQuote()->addProduct($product, $info);
- if (is_string($newItem)) {
- throw new \Magento\Framework\Exception\LocalizedException(__($newItem));
- }
- $product->unsSkipCheckRequiredOption();
- $newItem->checkData();
- $this->_needCollectCart = true;
- break;
- case 'cart':
- $cart = $this->getCustomerCart();
- if ($cart && $item->getOptionByCode('additional_options') === null) {
- //options and info buy request
- $product = $this->_objectManager->create(
- \Magento\Catalog\Model\Product::class
- )->setStoreId(
- $this->getQuote()->getStoreId()
- )->load(
- $item->getProduct()->getId()
- );
- $info = $item->getOptionByCode('info_buyRequest');
- if ($info) {
- $info = new \Magento\Framework\DataObject(
- $this->serializer->unserialize($info->getValue())
- );
- $info->setQty($qty);
- $info->setOptions($this->_prepareOptionsForRequest($item));
- } else {
- $info = new \Magento\Framework\DataObject(
- [
- 'product_id' => $product->getId(),
- 'qty' => $qty,
- 'options' => $this->_prepareOptionsForRequest($item)
- ]
- );
- }
- $cartItem = $cart->addProduct($product, $info);
- if (is_string($cartItem)) {
- throw new \Magento\Framework\Exception\LocalizedException(__($cartItem));
- }
- $cartItem->setPrice($item->getProduct()->getPrice());
- $this->_needCollectCart = true;
- $removeItem = true;
- }
- break;
- case 'wishlist':
- $wishlist = null;
- if (!isset($moveTo[1])) {
- $wishlist = $this->_objectManager->create(
- \Magento\Wishlist\Model\Wishlist::class
- )->loadByCustomerId(
- $this->getSession()->getCustomerId(),
- true
- );
- } else {
- $wishlist = $this->_objectManager->create(
- \Magento\Wishlist\Model\Wishlist::class
- )->load($moveTo[1]);
- if (!$wishlist->getId() || $wishlist->getCustomerId() != $this->getSession()->getCustomerId()
- ) {
- $wishlist = null;
- }
- }
- if (!$wishlist) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __('We can\'t find this wish list.')
- );
- }
- $wishlist->setStore(
- $this->getSession()->getStore()
- )->setSharedStoreIds(
- $this->getSession()->getStore()->getWebsite()->getStoreIds()
- );
- if ($wishlist->getId() && $item->getProduct()->isVisibleInSiteVisibility()) {
- $info = $item->getBuyRequest();
- $info->setOptions(
- $this->_prepareOptionsForRequest($item)
- )->setQty(
- $qty
- )->setStoreId(
- $this->getSession()->getStoreId()
- );
- $wishlist->addNewItem($item->getProduct(), $info);
- $removeItem = true;
- }
- break;
- case 'remove':
- $removeItem = true;
- break;
- default:
- break;
- }
- if ($removeItem) {
- $this->getQuote()->deleteItem($item);
- }
- $this->setRecollect(true);
- }
- return $this;
- }
- /**
- * Handle data sent from sidebar
- *
- * @param array $data
- * @return $this
- * @throws \Magento\Framework\Exception\LocalizedException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- * @SuppressWarnings(PHPMD.UnusedLocalVariable)
- */
- public function applySidebarData($data)
- {
- if (isset($data['add_order_item'])) {
- foreach ($data['add_order_item'] as $orderItemId => $value) {
- /* @var $orderItem \Magento\Sales\Model\Order\Item */
- $orderItem = $this->_objectManager->create(\Magento\Sales\Model\Order\Item::class)->load($orderItemId);
- $item = $this->initFromOrderItem($orderItem);
- if (is_string($item)) {
- throw new \Magento\Framework\Exception\LocalizedException(__($item));
- }
- }
- }
- if (isset($data['add_cart_item'])) {
- foreach ($data['add_cart_item'] as $itemId => $qty) {
- $item = $this->getCustomerCart()->getItemById($itemId);
- if ($item) {
- $this->moveQuoteItem($item, 'order', $qty);
- $this->removeItem($itemId, 'cart');
- }
- }
- }
- if (isset($data['add_wishlist_item'])) {
- foreach ($data['add_wishlist_item'] as $itemId => $qty) {
- $item = $this->_objectManager->create(
- \Magento\Wishlist\Model\Item::class
- )->loadWithOptions(
- $itemId,
- 'info_buyRequest'
- );
- if ($item->getId()) {
- $this->addProduct($item->getProduct(), $item->getBuyRequest()->toArray());
- }
- }
- }
- if (isset($data['add'])) {
- foreach ($data['add'] as $productId => $qty) {
- $this->addProduct($productId, ['qty' => $qty]);
- }
- }
- if (isset($data['remove'])) {
- foreach ($data['remove'] as $itemId => $from) {
- $this->removeItem($itemId, $from);
- }
- }
- if (isset($data['empty_customer_cart']) && (int)$data['empty_customer_cart'] == 1) {
- $this->getCustomerCart()->removeAllItems()->collectTotals();
- $this->quoteRepository->save($this->getCustomerCart());
- }
- $this->recollectCart();
- return $this;
- }
- /**
- * Remove item from some of customer items storage (shopping cart, wishlist etc.)
- *
- * @param int $itemId
- * @param string $from
- * @return $this
- */
- public function removeItem($itemId, $from)
- {
- switch ($from) {
- case 'quote':
- $this->removeQuoteItem($itemId);
- break;
- case 'cart':
- $cart = $this->getCustomerCart();
- if ($cart) {
- $cart->removeItem($itemId);
- $this->_needCollectCart = true;
- }
- break;
- case 'wishlist':
- $wishlist = $this->getCustomerWishlist();
- if ($wishlist) {
- $item = $this->_objectManager->create(\Magento\Wishlist\Model\Item::class)->load($itemId);
- $item->delete();
- }
- break;
- case 'compared':
- $this->_objectManager->create(
- \Magento\Catalog\Model\Product\Compare\Item::class
- )->load($itemId)->delete();
- break;
- }
- return $this;
- }
- /**
- * Remove quote item
- *
- * @param int $item
- * @return $this
- */
- public function removeQuoteItem($item)
- {
- $this->getQuote()->removeItem($item);
- $this->setRecollect(true);
- return $this;
- }
- /**
- * Add product to current order quote
- * $product can be either product id or product model
- * $config can be either buyRequest config, or just qty
- *
- * @param int|\Magento\Catalog\Model\Product $product
- * @param array|float|int|\Magento\Framework\DataObject $config
- * @return $this
- * @throws \Magento\Framework\Exception\LocalizedException
- */
- public function addProduct($product, $config = 1)
- {
- if (!is_array($config) && !$config instanceof \Magento\Framework\DataObject) {
- $config = ['qty' => $config];
- }
- $config = new \Magento\Framework\DataObject($config);
- if (!$product instanceof \Magento\Catalog\Model\Product) {
- $productId = $product;
- $product = $this->_objectManager->create(
- \Magento\Catalog\Model\Product::class
- )->setStore(
- $this->getSession()->getStore()
- )->setStoreId(
- $this->getSession()->getStoreId()
- )->load(
- $product
- );
- if (!$product->getId()) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __('We could not add a product to cart by the ID "%1".', $productId)
- );
- }
- }
- $item = $this->quoteInitializer->init($this->getQuote(), $product, $config);
- if (is_string($item)) {
- throw new \Magento\Framework\Exception\LocalizedException(__($item));
- }
- $item->checkData();
- $this->setRecollect(true);
- return $this;
- }
- /**
- * Add multiple products to current order quote
- *
- * @param array $products
- * @return $this
- */
- public function addProducts(array $products)
- {
- foreach ($products as $productId => $config) {
- $config['qty'] = isset($config['qty']) ? (double)$config['qty'] : 1;
- try {
- $this->addProduct($productId, $config);
- } catch (\Magento\Framework\Exception\LocalizedException $e) {
- $this->messageManager->addErrorMessage($e->getMessage());
- } catch (\Exception $e) {
- return $e;
- }
- }
- return $this;
- }
- /**
- * Update quantity of order quote items
- *
- * @param array $items
- * @return $this
- * @throws \Exception|\Magento\Framework\Exception\LocalizedException
- */
- public function updateQuoteItems($items)
- {
- if (!is_array($items)) {
- return $this;
- }
- try {
- foreach ($items as $itemId => $info) {
- if (!empty($info['configured'])) {
- $item = $this->getQuote()->updateItem($itemId, $this->objectFactory->create($info));
- $info['qty'] = (double)$item->getQty();
- } else {
- $item = $this->getQuote()->getItemById($itemId);
- if (!$item) {
- continue;
- }
- $info['qty'] = (double)$info['qty'];
- }
- $this->quoteItemUpdater->update($item, $info);
- if ($item && !empty($info['action'])) {
- $this->moveQuoteItem($item, $info['action'], $item->getQty());
- }
- }
- } catch (\Magento\Framework\Exception\LocalizedException $e) {
- $this->recollectCart();
- throw $e;
- } catch (\Exception $e) {
- $this->_logger->critical($e);
- }
- $this->recollectCart();
- return $this;
- }
- /**
- * Parse additional options and sync them with product options
- *
- * @param \Magento\Quote\Model\Quote\Item $item
- * @param string $additionalOptions
- * @return array
- * @throws \Magento\Framework\Exception\LocalizedException
- *
- * @deprecated 101.0.0
- */
- protected function _parseOptions(\Magento\Quote\Model\Quote\Item $item, $additionalOptions)
- {
- $productOptions = $this->_objectManager->get(
- \Magento\Catalog\Model\Product\Option\Type\DefaultType::class
- )->setProduct(
- $item->getProduct()
- )->getProductOptions();
- $newOptions = [];
- $newAdditionalOptions = [];
- foreach (explode("\n", $additionalOptions) as $_additionalOption) {
- if (strlen(trim($_additionalOption))) {
- try {
- if (strpos($_additionalOption, ':') === false) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __('There is an error in one of the option rows.')
- );
- }
- list($label, $value) = explode(':', $_additionalOption, 2);
- } catch (\Exception $e) {
- throw new \Magento\Framework\Exception\LocalizedException(
- __('There is an error in one of the option rows.')
- );
- }
- $label = trim($label);
- $value = trim($value);
- if (empty($value)) {
- continue;
- }
- if (array_key_exists($label, $productOptions)) {
- $optionId = $productOptions[$label]['option_id'];
- $option = $item->getProduct()->getOptionById($optionId);
- $group = $this->_objectManager->get(
- \Magento\Catalog\Model\Product\Option::class
- )->groupFactory(
- $option->getType()
- )->setOption(
- $option
- )->setProduct(
- $item->getProduct()
- );
- $parsedValue = $group->parseOptionValue($value, $productOptions[$label]['values']);
- if ($parsedValue !== null) {
- $newOptions[$optionId] = $parsedValue;
- } else {
- $newAdditionalOptions[] = ['label' => $label, 'value' => $value];
- }
- } else {
- $newAdditionalOptions[] = ['label' => $label, 'value' => $value];
- }
- }
- }
- return ['options' => $newOptions, 'additional_options' => $newAdditionalOptions];
- }
- /**
- * Assign options to item
- *
- * @param \Magento\Quote\Model\Quote\Item $item
- * @param array $options
- * @return $this
- *
- * @deprecated 101.0.0
- */
- protected function _assignOptionsToItem(\Magento\Quote\Model\Quote\Item $item, $options)
- {
- $optionIds = $item->getOptionByCode('option_ids');
- if ($optionIds) {
- foreach (explode(',', $optionIds->getValue()) as $optionId) {
- $item->removeOption('option_' . $optionId);
- }
- $item->removeOption('option_ids');
- }
- if ($item->getOptionByCode('additional_options')) {
- $item->removeOption('additional_options');
- }
- $item->save();
- if (!empty($options['options'])) {
- $item->addOption(
- new \Magento\Framework\DataObject(
- [
- 'product' => $item->getProduct(),
- 'code' => 'option_ids',
- 'value' => implode(',', array_keys($options['options']))
- ]
- )
- );
- foreach ($options['options'] as $optionId => $optionValue) {
- $item->addOption(
- new \Magento\Framework\DataObject(
- [
- 'product' => $item->getProduct(),
- 'code' => 'option_' . $optionId,
- 'value' => $optionValue
- ]
- )
- );
- }
- }
- if (!empty($options['additional_options'])) {
- $item->addOption(
- new \Magento\Framework\DataObject(
- [
- 'product' => $item->getProduct(),
- 'code' => 'additional_options',
- 'value' => $this->serializer->serialize($options['additional_options'])
- ]
- )
- );
- }
- return $this;
- }
- /**
- * Prepare options array for info buy request
- *
- * @param \Magento\Quote\Model\Quote\Item $item
- * @return array
- */
- protected function _prepareOptionsForRequest($item)
- {
- $newInfoOptions = [];
- $optionIds = $item->getOptionByCode('option_ids');
- if ($optionIds) {
- foreach (explode(',', $optionIds->getValue()) as $optionId) {
- $option = $item->getProduct()->getOptionById($optionId);
- $optionValue = $item->getOptionByCode('option_' . $optionId)->getValue();
- $group = $this->_objectManager->get(
- \Magento\Catalog\Model\Product\Option::class
- )->groupFactory(
- $option->getType()
- )->setOption(
- $option
- )->setQuoteItem(
- $item
- );
- $newInfoOptions[$optionId] = $group->prepareOptionValueForRequest($optionValue);
- }
- }
- return $newInfoOptions;
- }
- /**
- * Return valid price
- *
- * @param float|int $price
- * @return float|int
- */
- protected function _parseCustomPrice($price)
- {
- $price = $this->_objectManager->get(\Magento\Framework\Locale\FormatInterface::class)->getNumber($price);
- $price = $price > 0 ? $price : 0;
- return $price;
- }
- /**
- * Retrieve order quote shipping address
- *
- * @return \Magento\Quote\Model\Quote\Address
- */
- public function getShippingAddress()
- {
- return $this->getQuote()->getShippingAddress();
- }
- /**
- * Return Customer (Checkout) Form instance
- *
- * @param \Magento\Customer\Api\Data\CustomerInterface $customer
- * @return CustomerForm
- */
- protected function _createCustomerForm(\Magento\Customer\Api\Data\CustomerInterface $customer)
- {
- $customerForm = $this->_metadataFormFactory->create(
- \Magento\Customer\Api\CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
- 'adminhtml_checkout',
- $this->customerMapper->toFlatArray($customer),
- false,
- CustomerForm::IGNORE_INVISIBLE
- );
- return $customerForm;
- }
- /**
- * Set and validate Quote address
- *
- * All errors added to _errors
- *
- * @param \Magento\Quote\Model\Quote\Address $address
- * @param array $data
- * @return $this
- */
- protected function _setQuoteAddress(\Magento\Quote\Model\Quote\Address $address, array $data)
- {
- $isAjax = !$this->getIsValidate();
- // Region is a Data Object, so it is represented by an array. validateData() doesn't understand arrays, so we
- // need to merge region data with address data. This is going to be removed when we switch to use address Data
- // Object instead of the address model.
- // Note: if we use getRegion() here it will pull region from db using the region_id
- $data = isset($data['region']) && is_array($data['region']) ? array_merge($data, $data['region']) : $data;
- $addressForm = $this->_metadataFormFactory->create(
-
- AddressMetadataInterface::ENTITY_TYPE_ADDRESS,
- 'adminhtml_customer_address',
- $data,
- $isAjax,
- CustomerForm::DONT_IGNORE_INVISIBLE,
- []
- );
- // prepare request
- // save original request structure for files
- if ($address->getAddressType() == \Magento\Quote\Model\Quote\Address::TYPE_SHIPPING) {
- $requestData = ['order' => ['shipping_address' => $data]];
- $requestScope = 'order/shipping_address';
- } else {
- $requestData = ['order' => ['billing_address' => $data]];
- $requestScope = 'order/billing_address';
- }
- $request = $addressForm->prepareRequest($requestData);
- $addressData = $addressForm->extractData($request, $requestScope);
- if ($this->getIsValidate()) {
- $errors = $addressForm->validateData($addressData);
- if ($errors !== true) {
- if ($address->getAddressType() == \Magento\Quote\Model\Quote\Address::TYPE_SHIPPING) {
- $typeName = __('Shipping Address: ');
- } else {
- $typeName = __('Billing Address: ');
- }
- foreach ($errors as $error) {
- $this->_errors[] = $typeName . $error;
- }
- $address->setData($addressForm->restoreData($addressData));
- } else {
- $address->setData($addressForm->compactData($addressData));
- }
- } else {
- $address->addData($addressForm->restoreData($addressData));
- }
- return $this;
- }
- /**
- * Set shipping address into quote
- *
- * @param \Magento\Quote\Model\Quote\Address|array $address
- * @return $this
- */
- public function setShippingAddress($address)
- {
- if (is_array($address)) {
- $shippingAddress = $this->_objectManager->create(
- \Magento\Quote\Model\Quote\Address::class
- )->setData(
- $address
- )->setAddressType(
- \Magento\Quote\Model\Quote\Address::TYPE_SHIPPING
- );
- if (!$this->getQuote()->isVirtual()) {
- $this->_setQuoteAddress($shippingAddress, $address);
- }
- /**
- * save_in_address_book is not a valid attribute and is filtered out by _setQuoteAddress,
- * that is why it should be added after _setQuoteAddress call
- */
- $saveInAddressBook = (int)(!empty($address['save_in_address_book']));
- $shippingAddress->setData('save_in_address_book', $saveInAddressBook);
- }
- if ($address instanceof \Magento\Quote\Model\Quote\Address) {
- $shippingAddress = $address;
- }
- $this->setRecollect(true);
- $this->getQuote()->setShippingAddress($shippingAddress);
- return $this;
- }
- /**
- * Set shipping address to be same as billing
- *
- * @param bool $flag If true - don't save in address book and actually copy data across billing and shipping
- * addresses
- * @return $this
- */
- public function setShippingAsBilling($flag)
- {
- if ($flag) {
- $tmpAddress = clone $this->getBillingAddress();
- $tmpAddress->unsAddressId()->unsAddressType();
- $data = $tmpAddress->getData();
- $data['save_in_address_book'] = 0;
- // Do not duplicate address (billing address will do saving too)
- $this->getShippingAddress()->addData($data);
- }
- $this->getShippingAddress()->setSameAsBilling($flag);
- $this->setRecollect(true);
- return $this;
- }
- /**
- * Retrieve quote billing address
- *
- * @return \Magento\Quote\Model\Quote\Address
- */
- public function getBillingAddress()
- {
- return $this->getQuote()->getBillingAddress();
- }
- /**
- * Set billing address into quote
- *
- * @param array $address
- * @return $this
- */
- public function setBillingAddress($address)
- {
- if (!is_array($address)) {
- return $this;
- }
- $billingAddress = $this->_objectManager->create(Address::class)
- ->setData($address)
- ->setAddressType(Address::TYPE_BILLING);
- $this->_setQuoteAddress($billingAddress, $address);
- /**
- * save_in_address_book is not a valid attribute and is filtered out by _setQuoteAddress,
- * that is why it should be added after _setQuoteAddress call
- */
- $saveInAddressBook = (int)(!empty($address['save_in_address_book']));
- $billingAddress->setData('save_in_address_book', $saveInAddressBook);
- $quote = $this->getQuote();
- if (!$quote->isVirtual() && $this->getShippingAddress()->getSameAsBilling()) {
- $address['save_in_address_book'] = 0;
- $this->setShippingAddress($address);
- }
- // not assigned billing address should be saved as new
- // but if quote already has the billing address it won't be overridden
- if (empty($billingAddress->getCustomerAddressId())) {
- $billingAddress->setCustomerAddressId(null);
- $quote->getBillingAddress()->setCustomerAddressId(null);
- }
- $quote->setBillingAddress($billingAddress);
- return $this;
- }
- /**
- * Set shipping method
- *
- * @param string $method
- * @return $this
- */
- public function setShippingMethod($method)
- {
- $this->getShippingAddress()->setShippingMethod($method);
- $this->setRecollect(true);
- return $this;
- }
- /**
- * Empty shipping method and clear shipping rates
- *
- * @return $this
- */
- public function resetShippingMethod()
- {
- $this->getShippingAddress()->setShippingMethod(false);
- $this->getShippingAddress()->removeAllShippingRates();
- return $this;
- }
- /**
- * Collect shipping data for quote shipping address
- *
- * @return $this
- */
- public function collectShippingRates()
- {
- $store = $this->getQuote()->getStore();
- $this->storeManager->setCurrentStore($store);
- $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
- $this->collectRates();
- return $this;
- }
- /**
- * Calculate totals
- *
- * @return void
- */
- public function collectRates()
- {
- $this->getQuote()->collectTotals();
- }
- /**
- * Set payment method into quote
- *
- * @param string $method
- * @return $this
- */
- public function setPaymentMethod($method)
- {
- $this->getQuote()->getPayment()->setMethod($method);
- return $this;
- }
- /**
- * Set payment data into quote
- *
- * @param array $data
- * @return $this
- */
- public function setPaymentData($data)
- {
- if (!isset($data['method'])) {
- $data['method'] = $this->getQuote()->getPayment()->getMethod();
- }
- $this->getQuote()->getPayment()->importData($data);
- return $this;
- }
- /**
- * Add coupon code to the quote
- *
- * @param string $code
- * @return $this
- */
- public function applyCoupon($code)
- {
- $code = trim((string)$code);
- $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
- if (empty($code)) {
- $this->getQuote()->getShippingAddress()->setFreeShipping(0);
- }
- $this->getQuote()->setCouponCode($code);
- $this->setRecollect(true);
- return $this;
- }
- /**
- * Add account data to quote
- *
- * @param array $accountData
- * @return $this
- */
- public function setAccountData($accountData)
- {
- $customer = $this->getQuote()->getCustomer();
- if (empty($accountData['email'])) {
- $accountData['email'] = $customer->getEmail();
- }
- $form = $this->_createCustomerForm($customer);
- // emulate request
- $request = $form->prepareRequest($accountData);
- $data = $form->extractData($request);
- $data = $form->restoreData($data);
- $customer = $this->customerFactory->create();
- $this->dataObjectHelper->populateWithArray(
- $customer,
- $data,
- \Magento\Customer\Api\Data\CustomerInterface::class
- );
- $this->getQuote()->updateCustomerData($customer);
- $data = [];
- $customerData = $this->customerMapper->toFlatArray($customer);
- foreach ($form->getAttributes() as $attribute) {
- $code = sprintf('customer_%s', $attribute->getAttributeCode());
- $data[$code] = isset($customerData[$attribute->getAttributeCode()])
- ? $customerData[$attribute->getAttributeCode()]
- : null;
- }
- if (isset($data['customer_group_id'])) {
- $customerGroup = $this->groupRepository->getById($data['customer_group_id']);
- $data['customer_tax_class_id'] = $customerGroup->getTaxClassId();
- $this->setRecollect(true);
- }
- $this->getQuote()->addData($data);
- return $this;
- }
- /**
- * Parse data retrieved from request
- *
- * @param array $data
- * @return $this
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- public function importPostData($data)
- {
- if (is_array($data)) {
- $this->addData($data);
- } else {
- return $this;
- }
- if (isset($data['account'])) {
- $this->setAccountData($data['account']);
- }
- if (isset($data['comment'])) {
- $this->getQuote()->addData($data['comment']);
- if (empty($data['comment']['customer_note_notify'])) {
- $this->getQuote()->setCustomerNoteNotify(false);
- } else {
- $this->getQuote()->setCustomerNoteNotify(true);
- }
- }
- if (isset($data['billing_address'])) {
- $this->setBillingAddress($data['billing_address']);
- }
- if (isset($data['shipping_address'])) {
- $this->setShippingAddress($data['shipping_address']);
- }
- if (isset($data['shipping_method'])) {
- $this->setShippingMethod($data['shipping_method']);
- }
- if (isset($data['payment_method'])) {
- $this->setPaymentMethod($data['payment_method']);
- }
- if (isset($data['coupon']['code'])) {
- $this->applyCoupon($data['coupon']['code']);
- }
- return $this;
- }
- /**
- * Check whether we need to create new customer (for another website) during order creation
- *
- * @param \Magento\Store\Model\Store $store
- * @return bool
- */
- protected function _customerIsInStore($store)
- {
- $customer = $this->getQuote()->getCustomer();
- return $customer->getWebsiteId() == $store->getWebsiteId()
- || $this->accountManagement->isCustomerInStore($customer->getWebsiteId(), $store->getId());
- }
- /**
- * Set and validate Customer data. Return the updated Data Object merged with the account data
- *
- * @param \Magento\Customer\Api\Data\CustomerInterface $customer
- * @return \Magento\Customer\Api\Data\CustomerInterface
- */
- protected function _validateCustomerData(\Magento\Customer\Api\Data\CustomerInterface $customer)
- {
- $form = $this->_createCustomerForm($customer);
- // emulate request
- $request = $form->prepareRequest(['order' => $this->getData()]);
- $data = $form->extractData($request, 'order/account');
- $validationResults = $this->accountManagement->validate($customer);
- if (!$validationResults->isValid()) {
- $errors = $validationResults->getMessages();
- if (is_array($errors)) {
- foreach ($errors as $error) {
- $this->_errors[] = $error;
- }
- }
- }
- $data = $form->restoreData($data);
- foreach ($data as $key => $value) {
- if ($value !== null) {
- unset($data[$key]);
- }
- }
- $this->dataObjectHelper->populateWithArray(
- $customer,
- $data,
- \Magento\Customer\Api\Data\CustomerInterface::class
- );
- return $customer;
- }
- /**
- * Prepare customer data for order creation.
- *
- * Create customer if not created using data from customer form.
- * Create customer billing/shipping address if necessary using data from customer address forms.
- * Set customer data to quote.
- *
- * @return $this
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function _prepareCustomer()
- {
- if ($this->getQuote()->getCustomerIsGuest()) {
- return $this;
- }
- /** @var $store \Magento\Store\Model\Store */
- $store = $this->getSession()->getStore();
- $customer = $this->getQuote()->getCustomer();
- if ($customer->getId() && !$this->_customerIsInStore($store)) {
- /** Create a new customer record if it is not available in the specified store */
- /** Unset customer ID to ensure that new customer will be created */
- $customer->setId(null)
- ->setStoreId($store->getId())
- ->setWebsiteId($store->getWebsiteId())
- ->setCreatedAt(null);
- $customer = $this->_validateCustomerData($customer);
- } else if (!$customer->getId()) {
- /** Create new customer */
- $customerBillingAddressDataObject = $this->getBillingAddress()->exportCustomerAddress();
- $customer->setSuffix($customerBillingAddressDataObject->getSuffix())
- ->setFirstname($customerBillingAddressDataObject->getFirstname())
- ->setLastname($customerBillingAddressDataObject->getLastname())
- ->setMiddlename($customerBillingAddressDataObject->getMiddlename())
- ->setPrefix($customerBillingAddressDataObject->getPrefix())
- ->setStoreId($store->getId())
- ->setWebsiteId($store->getWebsiteId())
- ->setEmail($this->_getNewCustomerEmail());
- $customer = $this->_validateCustomerData($customer);
- }
- $this->getQuote()->setCustomer($customer);
- if ($this->getBillingAddress()->getSaveInAddressBook()) {
- $this->_prepareCustomerAddress($this->getQuote()->getCustomer(), $this->getBillingAddress());
- $address = $this->getBillingAddress()->setCustomerId($this->getQuote()->getCustomer()->getId());
- $this->setBillingAddress($address);
- }
- if (!$this->getQuote()->isVirtual() && $this->getShippingAddress()->getSaveInAddressBook()) {
- $this->_prepareCustomerAddress($this->getQuote()->getCustomer(), $this->getShippingAddress());
- $address = $this->getShippingAddress()->setCustomerId($this->getQuote()->getCustomer()->getId());
- $this->setShippingAddress($address);
- }
- $this->getBillingAddress()->setCustomerId($customer->getId());
- $this->getQuote()->updateCustomerData($this->getQuote()->getCustomer());
- $customer = $this->getQuote()->getCustomer();
- $origAddresses = $customer->getAddresses(); // save original addresses
- $customer->setAddresses([]);
- $customerData = $this->customerMapper->toFlatArray($customer);
- $customer->setAddresses($origAddresses); // restore original addresses
- foreach ($this->_createCustomerForm($customer)->getUserAttributes() as $attribute) {
- if (isset($customerData[$attribute->getAttributeCode()])) {
- $quoteCode = sprintf('customer_%s', $attribute->getAttributeCode());
- $this->getQuote()->setData($quoteCode, $customerData[$attribute->getAttributeCode()]);
- }
- }
- return $this;
- }
- /**
- * Create customer address and save it in the quote so that it can be used to persist later.
- *
- * @param \Magento\Customer\Api\Data\CustomerInterface $customer
- * @param \Magento\Quote\Model\Quote\Address $quoteCustomerAddress
- * @return void
- * @throws \InvalidArgumentException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- protected function _prepareCustomerAddress($customer, $quoteCustomerAddress)
- {
- // Possible that customerId is null for new customers
- $quoteCustomerAddress->setCustomerId($customer->getId());
- $customerAddress = $quoteCustomerAddress->exportCustomerAddress();
- $quoteAddressId = $quoteCustomerAddress->getCustomerAddressId();
- $addressType = $quoteCustomerAddress->getAddressType();
- if ($quoteAddressId) {
- /** Update existing address */
- $existingAddressDataObject = $this->addressRepository->getById($quoteAddressId);
- /** Update customer address data */
- $this->dataObjectHelper->mergeDataObjects(
- get_class($existingAddressDataObject),
- $existingAddressDataObject,
- $customerAddress
- );
- $customerAddress = $existingAddressDataObject;
- } elseif ($addressType == \Magento\Quote\Model\Quote\Address::ADDRESS_TYPE_SHIPPING) {
- try {
- $billingAddressDataObject = $this->accountManagement->getDefaultBillingAddress($customer->getId());
- } catch (\Exception $e) {
- /** Billing address does not exist. */
- }
- $isShippingAsBilling = $quoteCustomerAddress->getSameAsBilling();
- if (isset($billingAddressDataObject) && $isShippingAsBilling) {
- /** Set existing billing address as default shipping */
- $customerAddress = $billingAddressDataObject;
- $customerAddress->setIsDefaultShipping(true);
- }
- }
- switch ($addressType) {
- case \Magento\Quote\Model\Quote\Address::ADDRESS_TYPE_BILLING:
- if ($customer->getDefaultBilling() === null) {
- $customerAddress->setIsDefaultBilling(true);
- }
- break;
- case \Magento\Quote\Model\Quote\Address::ADDRESS_TYPE_SHIPPING:
- if ($customer->getDefaultShipping() === null) {
- $customerAddress->setIsDefaultShipping(true);
- }
- break;
- default:
- throw new \InvalidArgumentException('Customer address type is invalid.');
- }
- $this->getQuote()->setCustomer($customer);
- $this->getQuote()->addCustomerAddress($customerAddress);
- }
- /**
- * Prepare item options
- *
- * @return $this
- */
- protected function _prepareQuoteItems()
- {
- foreach ($this->getQuote()->getAllItems() as $item) {
- $options = [];
- $productOptions = $item->getProduct()->getTypeInstance()->getOrderOptions($item->getProduct());
- if ($productOptions) {
- $productOptions['info_buyRequest']['options'] = $this->_prepareOptionsForRequest($item);
- $options = $productOptions;
- }
- $addOptions = $item->getOptionByCode('additional_options');
- if ($addOptions) {
- $options['additional_options'] = $this->serializer->unserialize($addOptions->getValue());
- }
- $item->setProductOrderOptions($options);
- }
- return $this;
- }
- /**
- * Create new order
- *
- * @return \Magento\Sales\Model\Order
- */
- public function createOrder()
- {
- $this->_prepareCustomer();
- $this->_validate();
- $quote = $this->getQuote();
- $this->_prepareQuoteItems();
- $orderData = [];
- if ($this->getSession()->getOrder()->getId()) {
- $oldOrder = $this->getSession()->getOrder();
- $originalId = $oldOrder->getOriginalIncrementId();
- if (!$originalId) {
- $originalId = $oldOrder->getIncrementId();
- }
- $orderData = [
- 'original_increment_id' => $originalId,
- 'relation_parent_id' => $oldOrder->getId(),
- 'relation_parent_real_id' => $oldOrder->getIncrementId(),
- 'edit_increment' => $oldOrder->getEditIncrement() + 1,
- 'increment_id' => $originalId . '-' . ($oldOrder->getEditIncrement() + 1)
- ];
- $quote->setReservedOrderId($orderData['increment_id']);
- }
- $order = $this->quoteManagement->submit($quote, $orderData);
- if ($this->getSession()->getOrder()->getId()) {
- $oldOrder = $this->getSession()->getOrder();
- $oldOrder->setRelationChildId($order->getId());
- $oldOrder->setRelationChildRealId($order->getIncrementId());
- $oldOrder->save();
- $this->orderManagement->cancel($oldOrder->getEntityId());
- $order->save();
- }
- if ($this->getSendConfirmation()) {
- $this->emailSender->send($order);
- }
- $this->_eventManager->dispatch('checkout_submit_all_after', ['order' => $order, 'quote' => $quote]);
- return $order;
- }
- /**
- * Validate quote data before order creation
- *
- * @return $this
- * @throws \Magento\Framework\Exception\LocalizedException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- * @SuppressWarnings(PHPMD.NPathComplexity)
- */
- protected function _validate()
- {
- if (!$this->getSession()->getStore()->getId()) {
- throw new \Magento\Framework\Exception\LocalizedException(__('Please select a store'));
- }
- $items = $this->getQuote()->getAllItems();
- if (count($items) === 0) {
- $this->_errors[] = __('Please specify order items.');
- }
- foreach ($items as $item) {
- /** @var \Magento\Quote\Model\Quote\Item $item */
- $messages = $item->getMessage(false);
- if ($item->getHasError() && is_array($messages) && !empty($messages)) {
- $this->_errors = array_merge($this->_errors, $messages);
- }
- }
- if (!$this->getQuote()->isVirtual()) {
- if (!$this->getQuote()->getShippingAddress()->getShippingMethod()) {
- $this->_errors[] = __('The shipping method is missing. Select the shipping method and try again.');
- }
- }
- if (!$this->getQuote()->getPayment()->getMethod()) {
- $this->_errors[] = __("The payment method isn't selected. Enter the payment method and try again.");
- } else {
- $method = $this->getQuote()->getPayment()->getMethodInstance();
- if (!$method->isAvailable($this->getQuote())) {
- $this->_errors[] = __('This payment method is not available.');
- } else {
- try {
- $method->validate();
- } catch (\Magento\Framework\Exception\LocalizedException $e) {
- $this->_errors[] = $e->getMessage();
- }
- }
- }
- if (!empty($this->_errors)) {
- /** @var LoggerInterface $logger */
- $logger = ObjectManager::getInstance()->get(LoggerInterface::class);
- foreach ($this->_errors as $error) {
- $logger->error($error);
- $this->messageManager->addErrorMessage($error);
- }
- throw new \Magento\Framework\Exception\LocalizedException(__('Validation is failed.'));
- }
- return $this;
- }
- /**
- * Retrieve new customer email.
- *
- * @return string
- */
- protected function _getNewCustomerEmail()
- {
- return $this->getData('account/email');
- }
- /**
- * Checks id shipping and billing addresses are equal.
- *
- * @param Order $order
- * @return bool
- */
- private function isAddressesAreEqual(Order $order)
- {
- $shippingAddress = $order->getShippingAddress();
- $billingAddress = $order->getBillingAddress();
- $shippingData = $this->dataObjectConverter->toFlatArray($shippingAddress, [], OrderAddressInterface::class);
- $billingData = $this->dataObjectConverter->toFlatArray($billingAddress, [], OrderAddressInterface::class);
- unset(
- $shippingData['address_type'],
- $shippingData['entity_id'],
- $billingData['address_type'],
- $billingData['entity_id']
- );
- return $shippingData == $billingData;
- }
- }
|