Я использую эти два метода для создания заказов программно в Magento.
Первая создает цитату:
public function prepareCustomerOrder($customerId, array $shoppingCart, array $shippingAddress, array $billingAddress, $shippingMethod, $couponCode = null) { $customerObj = Mage::getModel('customer/customer')->load($customerId); $storeId = $customerObj->getStoreId(); $quoteObj = Mage::getModel('sales/quote')->assignCustomer($customerObj); $storeObj = $quoteObj->getStore()->load($storeId); $quoteObj->setStore($storeObj); // add products to quote foreach($shoppingCart as $part) { $productModel = Mage::getModel('catalog/product'); $productObj = $productModel->setStore($storeId)->setStoreId($storeId)->load($part['PartId']); $productObj->setSkipCheckRequiredOption(true); try{ $quoteItem = $quoteObj->addProduct($productObj); $quoteItem->setPrice(20); $quoteItem->setQty(3); $quoteItem->setQuote($quoteObj); $quoteObj->addItem($quoteItem); } catch (exception $e) { return false; } $productObj->unsSkipCheckRequiredOption(); $quoteItem->checkData(); } // addresses $quoteShippingAddress = new Mage_Sales_Model_Quote_Address(); $quoteShippingAddress->setData($shippingAddress); $quoteBillingAddress = new Mage_Sales_Model_Quote_Address(); $quoteBillingAddress->setData($billingAddress); $quoteObj->setShippingAddress($quoteShippingAddress); $quoteObj->setBillingAddress($quoteBillingAddress); // coupon code if(!empty($couponCode)) $quoteObj->setCouponCode($couponCode); // shipping method an collect $quoteObj->getShippingAddress()->setShippingMethod($shippingMethod); $quoteObj->getShippingAddress()->setCollectShippingRates(true); $quoteObj->getShippingAddress()->collectShippingRates(); $quoteObj->collectTotals(); // calls $address->collectTotals(); $quoteObj->setIsActive(0); $quoteObj->save(); return $quoteObj->getId(); }
А вторая использует эту цитату для создания порядка:
public function createOrder($quoteId, $paymentMethod, $paymentData) { $quoteObj = Mage::getModel('sales/quote')->load($quoteId); // Mage_Sales_Model_Quote $items = $quoteObj->getAllItems(); $quoteObj->reserveOrderId(); // set payment method $quotePaymentObj = $quoteObj->getPayment(); // Mage_Sales_Model_Quote_Payment $quotePaymentObj->setMethod($paymentMethod); $quoteObj->setPayment($quotePaymentObj); // convert quote to order $convertQuoteObj = Mage::getSingleton('sales/convert_quote'); $orderObj = $convertQuoteObj->addressToOrder($quoteObj->getShippingAddress()); $orderPaymentObj = $convertQuoteObj->paymentToOrderPayment($quotePaymentObj); // convert quote addresses $orderObj->setBillingAddress($convertQuoteObj->addressToOrderAddress($quoteObj->getBillingAddress())); $orderObj->setShippingAddress($convertQuoteObj->addressToOrderAddress($quoteObj->getShippingAddress())); // set payment options $orderObj->setPayment($convertQuoteObj->paymentToOrderPayment($quoteObj->getPayment())); if ($paymentData) { $orderObj->getPayment()->setCcNumber($paymentData->ccNumber); $orderObj->getPayment()->setCcType($paymentData->ccType); $orderObj->getPayment()->setCcExpMonth($paymentData->ccExpMonth); $orderObj->getPayment()->setCcExpYear($paymentData->ccExpYear); $orderObj->getPayment()->setCcLast4(substr($paymentData->ccNumber,-4)); } // convert quote items foreach ($items as $item) { // @var $item Mage_Sales_Model_Quote_Item $orderItem = $convertQuoteObj->itemToOrderItem($item); $options = array(); if ($productOptions = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct())) { $options = $productOptions; } if ($addOptions = $item->getOptionByCode('additional_options')) { $options['additional_options'] = unserialize($addOptions->getValue()); } if ($options) { $orderItem->setProductOptions($options); } if ($item->getParentItem()) { $orderItem->setParentItem($orderObj->getItemByQuoteItemId($item->getParentItem()->getId())); } $orderObj->addItem($orderItem); } $orderObj->setCanShipPartiallyItem(false); try { $orderObj->place(); } catch (Exception $e){ Mage::log($e->getMessage()); Mage::log($e->getTraceAsString()); } $orderObj->save(); //$orderObj->sendNewOrderEmail(); return $orderObj->getId(); }
Процесс работает нормально, никаких ошибок и порядок создается. Но общее число равно 0, и в нем нет продуктов, независимо от того, что я ставлю.
Я проследил его, и я могу подтвердить, что строки добавляются в таблицы sales_flat_quote
и sales_flat_quote_item
, так что это нормально. Но при запуске createOrder
и вызова
$items = $quoteObj->getAllItems();
пустой массив всегда возвращается, и я понятия не имею, почему. У меня есть настраиваемые и простые продукты в моем магазине. Это происходит, когда я добавляю простой, когда добавляю настраиваемую ошибку, появляется как метод
$quoteItem = $quoteObj->addProduct($productObj);
возвращает null.
Мне кажется, вы не загружали коллекцию товаров, поэтому корзина всегда возвращалась пустой. Попробуйте эту ссылку, это даст вам более ясную помощь. Создать заказ программно
// this is get only one product, you can refactor the code $this->_product = Mage::getModel('catalog/product')->getCollection() ->addAttributeToFilter('sku', 'Some value here...') ->addAttributeToSelect('*') ->getFirstItem(); // load product data $this->_product->load($this->_product->getId());
Этот код работал для меня,
public function createorder(array $orderdata) { $quoteId = $orderdata['quoteId']; $paymentMethod = $orderdata['paymentMethod']; $paymentData = $orderdata['paymentData']; $quoteObj = Mage::getModel('sales/quote')->load($quoteId); $items = $quoteObj->getAllItems(); $quoteObj->reserveOrderId(); $quotePaymentObj = $quoteObj->getPayment(); $quotePaymentObj->setMethod($paymentMethod); $quoteObj->setPayment($quotePaymentObj); $convertQuoteObj = Mage::getSingleton('sales/convert_quote'); $orderObj = $convertQuoteObj->addressToOrder($quoteObj->getShippingAddress()); $orderPaymentObj = $convertQuoteObj->paymentToOrderPayment($quotePaymentObj); $orderObj->setBillingAddress($convertQuoteObj->addressToOrderAddress($quoteObj->getBillingAddress())); $orderObj->setShippingAddress($convertQuoteObj->addressToOrderAddress($quoteObj->getShippingAddress())); $orderObj->setPayment($convertQuoteObj->paymentToOrderPayment($quoteObj->getPayment())); foreach ($items as $item) { $orderItem = $convertQuoteObj->itemToOrderItem($item); $options = array(); if ($productOptions = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct())) { $options = $productOptions; } if ($addOptions = $item->getOptionByCode('additional_options')) { $options['additional_options'] = unserialize($addOptions->getValue()); } if ($options) { $orderItem->setProductOptions($options); } if ($item->getParentItem()) { $orderItem->setParentItem($orderObj->getItemByQuoteItemId($item->getParentItem()->getId())); } $orderObj->addItem($orderItem); } $quoteObj->collectTotals(); $service = Mage::getModel('sales/service_quote', $quoteObj); $service->submitAll(); $orderObj->setCanShipPartiallyItem(false); try { $last_order_increment_id = Mage::getModel("sales/order")->getCollection()->getLastItem()->getIncrementId(); return $last_order_increment_id; } catch (Exception $e) { Mage::log($e->getMessage()); Mage::log($e->getTraceAsString()); return "Exception:".$e; } }
У меня была такая же проблема, и я попал в API, чтобы найти решение. Я изменил способ загрузки продукта с помощью:
$productEntityId = '123456'; $store_code = 'my_store_code'; $product = Mage::helper('catalog/product')->getProduct($productEntityId,Mage::app()->getStore($store_code)->getId());
Я нашел этот учебник очень полезным:
http://www.classyllama.com/content/unravelling-magentos-collecttotals
Если вы ищете скрипт при создании заказа, это очень хороший старт:
Надеюсь, что это помогает кому-то;)