Magento – Creating Quote Address the right way

magento-1.9quoteshippingshipping-addressshipping-methods

I'm trying to create a quote address programmatically, everything is working fine and the order is created, however this is after 2 workarounds im not sure why i need them, I'll list all the observations I have and hopefully someone can point out what im doing wrong.

My biggest problems is calculating the shipping cost, and the way a shipping address is created, so let's say the basic way to create a quote order is as follows (don't mind the variables) :

// Initializing the Quote Model, all good here
$quote = Mage::getModel('sales/quote')
    ->setStoreId($store_id)
    ->setWebsiteId($website_id)
    ->assignCustomer($customer);

// The shipping address, all good here
$shipping_address = array(
    'prefix' => '',
    'firstname' => $customer->getFirstname(),
    'middlename' => '',
    'lastname' => $customer->getLastname(),
    'suffix' => '',
    'company' => '',
    'street' => array(
        '0' => $d['street'],
        '1' => ''
    ),
    'city' => $d['city'],
    'country_id' => $d['country_id'],
    'region' => $d['region'],
    'postcode' => '0000',
    'telephone' => $customer->getPhone(),
    'fax' => '',
    'vat_id' => '',
    'save_in_address_book' => 1
);

// Adding a product, all good here
$quote->addProduct($product_model, new Varien_Object(
    array(  'qty' => 1,
            'options' => $options
        )
));

// Setting the shipping/billing address
$quote->getShippingAddress()->addData($shipping_address);
$quote->getBillingAddress()->addData($shipping_address);

// Setting the shipping method, all good here as well
$methods = Mage::getSingleton('shipping/config')->getActiveCarriers();
foreach($methods as $_code => $_method){
    // Get the first allowed method of this shipping carrier
    $m = key($_method->getAllowedMethods());
    $shipping_method = $_code . '_' . $m;
}
$shippingAddress->setShippingMethod($shipping_method);

// Collecting the shipping rates, i have no clue what im doing wrong here
$shippingAddress->setWeight(90); // I will have to set his manually, not sure why
$shippingAddress->setFreeMethodWeight(90); // I will have to set this manually, not sure why
$shippingAddress->setShippingMethod($shipping_method);
$shippingAddress->setCollectShippingRates(true);
$shippingAddress->collectShippingRates();

$quote->collectTotals();

Now I want to retrieve the shipping cost, so I just do a $quote->getShippingAddress()->getShippingAmount().

The problem is I have to set the shipping weight as follow for this to work, as in the code block above:

$shippingAddress->setWeight(90);
$shippingAddress->setFreeMethodWeight(90);

This is because for some reason, in

app/code/core/Mage/Sales/Model/Quote/Address.php:913

$request->setPackageWeight($item ? $item->getRowWeight() : $this->getWeight());

The getWeight function returns 0, if i didn't set it explicilty, and it makes sense, since in my code i don't find anywhere it's calculated or modified when im adding the products to fetch the weight from. So this is my first issue, why im setting the weight explicitly, why i need to do so.

The second issue is the $shippingAddress->setFreeMethodWeight(90); line, i have to do this as well, because in

app/code/Mage/Shipping/Model/Carrier/Tablerate.php:138

// Package weight and qty free shipping
$oldWeight = $request->getPackageWeight();
$oldQty = $request->getPackageQty();

$request->setPackageWeight($request->getFreeMethodWeight());
$request->setPackageQty($oldQty - $freeQty);

$result = $this->_getModel('shipping/rate_result');
$rate = $this->getRate($request);

$request->setPackageWeight($oldWeight);
$request->setPackageQty($oldQty);

The getRate function is calculated after setting the package weight to the return value of getFreeMethodWeight, which is null if I didn't set it as above. I have the FreeShipping shipping method disabled, and no Cart Price rules, so I have no idea why the above lines are written this way.

That's pretty much it. Hopefull I was able to explain everything.

Best Answer

First, where do you declare the variable $shippingAddress ?

Since you have to enter the weight manually, can you check if $product->getWeight(); give you 90 ?

If not, maybe the weight is not correctly defined in admin for the current store.

Otherwise, can you try to add the item product to the shipping address like that :

$quote->getShippingAddress()->addData($shipping_address);
$quote->getShippingAddress()->addItem($item);
Related Topic