Magento – Convert quote to order generating empty order

magento-1onepage-checkoutpaymentquotesales-order

I'm changing the Magento to not save automatically orders as pending at checkout. I want to save only orders that were paid, and if it fails back to the cart with an error message in the payment.

I got the Magento not save the order as pending, but now need to save as complete in case of success. So I'm trying to save the quote with the code below.

    $convert = Mage::getModel('sales/convert_quote');

    $quoteModelInstance = Mage::getSingleton('checkout/session')->getQuote();
    $customerModelInstance = Mage::getSingleton('customer/session');
    $paymentModelInstance = $convert->paymentToOrderPayment($quoteModelInstance->getPayment());

    $order = Mage::getModel('sales/order');
    $order->setQuote($quoteModelInstance);
    $order->setCustomer($customerModelInstance);
    $order->setPayment($paymentModelInstance);
    $order->setShipping($customerModelInstance->getShippingRelatedInfo());

    try {
        $order->save();
    } catch (Exception $e) {
        Mage::logException($e);
    }

On $quoteModelInstance variable I have:

Array
(
    [entity_id] => 1587
    [store_id] => 1
    [created_at] => 2015-02-23 18:58:43
    [updated_at] => 2015-02-24 11:19:30
    [converted_at] => 
    [is_active] => 1
    [is_virtual] => 0
    [is_multi_shipping] => 0
    [items_count] => 1
    [items_qty] => 50.0000
    [orig_order_id] => 0
    [store_to_base_rate] => 1.0000
    [store_to_quote_rate] => 1.0000
    [base_currency_code] => BRL
    [store_currency_code] => BRL
    [quote_currency_code] => BRL
    [grand_total] => 1.0000
    [base_grand_total] => 1.0000
    [checkout_method] => 
    [customer_id] => 10
    [customer_tax_class_id] => 3
    [customer_group_id] => 1
    [customer_email] => eduardo@hefer.com.br
    [customer_prefix] => 
    [customer_firstname] => Eduardo
    [customer_middlename] => 
    [customer_lastname] => Dias
    [customer_suffix] => 
    [customer_dob] => 1991-02-24 00:00:00
    [complemento] => 
    [numero] => 
    [bairro] => 
    [customer_note] => 
    [customer_note_notify] => 1
    [customer_is_guest] => 0
    [remote_ip] => 177.64.172.10
    [applied_rule_ids] => 1
    [reserved_order_id] => 
    [password_hash] => 
    [coupon_code] => 
    [global_currency_code] => BRL
    [base_to_global_rate] => 1.0000
    [base_to_quote_rate] => 1.0000
    [customer_taxvat] => 
    [customer_gender] => 1
    [subtotal] => 1.0000
    [base_subtotal] => 1.0000
    [subtotal_with_discount] => 1.0000
    [base_subtotal_with_discount] => 1.0000
    [is_changed] => 1
    [trigger_recollect] => 0
    [ext_shipping_info] => 
    [gift_message_id] => 
    [is_persistent] => 0
    [interest] => 
    [base_interest] => 
    [agillitas_vet] => 0.0200
    [x_forwarded_for] => 
)

And in $quoteModelInstance->getPayment():

Array
(
    [payment_id] => 295
    [quote_id] => 1587
    [created_at] => 2015-02-24 11:18:58
    [updated_at] => 2015-02-24 11:19:27
    [method] => Query_Cielo_Dc
    [cc_type] => visa
    [cc_number_enc] => 
    [cc_last4] => 
    [cc_cid_enc] => 
    [cc_owner] => 
    [cc_exp_month] => 11
    [cc_exp_year] => 2023
    [cc_ss_owner] => 
    [cc_ss_start_month] => 0
    [cc_ss_start_year] => 0
    [po_number] => 
    [additional_data] => 
    [cc_ss_issue] => 
    [additional_information] => Array
        (
        )

    [paypal_payer_id] => 
    [paypal_payer_status] => 
    [paypal_correlation_id] => 
)

This generated the request, but did not save all the data, see image below.
Wrong order id and empty order data

I tried this way too:

    $quote = Mage::getSingleton('checkout/session')->getQuote();
    $convert = Mage::getModel('sales/convert_quote');
    $convert->paymentToOrderPayment($quote->getPayment());

    $order = $convert->toOrder($quote);
    $order->save();

But returned this error:

Fatal error: Call to a member function getMethodInstance() on a
non-object in
/public/dev/app/code/core/Mage/Payment/Model/Observer.php on line 46


EDIT 1:
I got to save the order with this code:

$quote = Mage::getSingleton('checkout/session')->getQuote();
$quote->collectTotals()
    ->getPayment()->setMethod('purchaseorder');

$service = Mage::getModel('sales/service_quote', $quote);
$service->submitAll();
$order = $service->getOrder();
$order->save();

If I use another method of payment which has form, I lose the data. I need to get the data placed by the customer on payment method.

Best Answer

One general remark here: You're trying to set the full customer session object (Mage::getSingleton('customer/session')) as the quote's customer. You should do Mage::getSingleton('customer/session')->getCustomer().

As for the whole process, I have been doing this in the past as follows:

$quote = Mage::getSingleton('checkout/session')->getQuote();
$quote->assignCustomer(Mage::getSingleton('customer/session')->getCustomer());

$quote->collectTotals()
    ->getPayment()->setMethod('purchaseorder');

$convert = Mage::getModel('sales/convert_quote');
$order = $convert->toOrder($quote)
    ->setBillingAddress(
        $convert->addressToOrderAddress($quote->getBillingAddress())
    )
    ->setShippingAddress(
        $convert->addressToOrderAddress($quote->getShippingAddress())
    )
    ->setPayment(
        $convert->paymentToOrderPayment($quote->getPayment())
    );

foreach ($quote->getAllItems() as $quoteItem) {
    $orderItem = $convert->itemToOrderItem($quoteItem);
    if ($quoteItem->getParentItem()) {
        $orderItem->setParentItem(
            $order->getItemByQuoteItemId($quoteItem->getParentItem()->getId())
        );
    }
    $order->addItem($orderItem);
}

$order->save();

I'm manually setting the payment method on the quote to 'purchaseorder'. You should see if this works for you too and/or fits your needs.

Related Topic