Posting in the Magento forums has been disabled pending the implementation of a new and improved forum solution which should better serve the community.

For new questions please post at magento.stackexchange.com, the community-run support site for the Magento community. We will be providing updates on the new forum solution soon. For questions or concerns please email community@magento.com.

Magento Forum

How do I call product attributes from a quote / shipping module? 
 
Auriferous
Jr. Member
 
Total Posts:  26
Joined:  2008-05-22
 

I have added the dimensions attribute in the fedex shipping request and then created length width and height attributes. Now I need to access these attributes in from fedex.php.  I have tried a few things but not having much success. I dumped the $request variable and its puts out pages and pages of information in which I have seen the values that I need however I cant seem to retrieve only 1 value at a time. Here is the code:

public function setRequest(Mage_Shipping_Model_Rate_Request $request)
    
{  
        
  
          
exit(var_dump($request->getQuote()));

What I need to do is retrieve the dimensions for each product as well as the qty of each product then use a few lines of code and combine all the items to be shipped and there total volume or box size needed.

Any ideas how to accomplish this? I was preferring to do all the customizing in just one file rather then changing a bunch of core files.

Thanks in advance!

 
Magento Community Magento Community
Magento Community
Magento Community
 
rrobinson
Jr. Member
 
Avatar
Total Posts:  15
Joined:  2008-05-19
Portland, Or
 

Without seeing the dump I’m going to take a guess that you added the dimension attributes to the product and
the attributes are actually named ‘width’, ‘length’ and ‘height’

$items $quote->getItemsCollection()
                             ->
getItems();

foreach( 
$items as $item )
{
    $product 
$item->getProduct();
    
// note that if the product data does not exist in
    // in your item, can't tell without seeing the dump
    // but it should.
    // comment out the previous line and use the
    // following line to retrieve the product
    // $product = Mage::getModel('catalog/product')->load( $item->getProductId() );   

    
$height $product->getHeight();
    
$width $product->getWidth();
    
$length $product->getLength();
    
$price $product->getPrice();

    
//whatever you want to do here with the data
}
 
Magento Community Magento Community
Magento Community
Magento Community
 
Auriferous
Jr. Member
 
Total Posts:  26
Joined:  2008-05-22
 

Thanks mucho rrobinson!

I had to do a lot of finagling but got things to work. I probably could find a better way to go about things but I had to do something quick. We sell Electronics and they can vary a lot in size and weight. We were doing ok shipping auto receivers and smaller items but then when we got an order for a 49 lb and 35x35x18 mobile satellite unit to ship from OC California to Miami FL the bill was 750 bucks for the method chosen and they only payed 250 (by our previous quote which didn’t factor in the dimensions)

I decided to get rid of the actual dimensions of Length Width and Height as product attributes and just replace these with “Volume” in cubic inches. Our erp system has this field and it seems the way to go if your going to try to estimate multiple items in one shipping box. For instance if someone bought a receiver, a cable adapter, and a remote they would all go in the same box. If would be some tricky logic trying to find the most optimal box size to fit all of these items. So I just decided multiply line item quantity by line item cubic inches and then sum all totals for a grand total volume of all products being shipped and then find the cube root and send these dimensions in the API request.

So here is the code I came up with in fedex.php:

public function setRequest(Mage_Shipping_Model_Rate_Request $request)
    
{      
    
// BEGIN CUSTOM CODE
     
        
$items $items Mage::getSingleton('checkout/session')->getQuote()->getItemsCollection()->getItems();         
        
$totalvolume 0;
        foreach( 
$items as $item )
        
{    
            
// Get quanity for each Item and multiply by volume
            
$qty =  $item->getQty();
            
$product Mage::getModel('catalog/product')->load$item->getProductId() );            
            
$volume $product->getVolume();
            
// Create default value for volume should value be missing
            
if($volume 1){
            
// Default volume - Size for single item (6x7x11)
            
$volume 462 $qty;
            
}
            $totalvolume 
=     ($totalvolume + ($volume $qty));    
        

         
// TEST OUTPUT
         // exit(var_dump($totalvolume)); 
            
            // Find cube root of total volume as 'x' 
            //-> This will be used for all dimensions
            
$c $totalvolume;
            
$count 0;
                
$x 3;
                do 
{
                $x 
ceil($x - (pow($x,3) - $c)/(3*pow($x,2)));
                
$count++;
                
while($count 50);
    
        
$this->_request $request;

        
$r = new Varien_Object();
        
// Set dimensions -> Just use length for all (cubed)
        
$r->setLength($x);
    
// END CUSTOM CODE
        
if ($request->getLimitMethod()) {
            $r
->setService($request->getLimitMethod());
        
}

        
if ($request->getFedexAccount()) {
            $account 
$request->getFedexAccount();
        
else {
            $account 
$this->getConfigData('account');
        
}

$payment $xml->addChild('Payment');
            
$payment->addChild('PayorType''SENDER');    
                    
    
// BEGIN CUSTOM CODE
            // Add dimensions for more acurate quotes 
            
$dimensions $xml->addChild('Dimensions');
            
$dimensions->addChild('Length'$r->getLength());
            
$dimensions->addChild('Width'$r->getLength());
            
$dimensions->addChild('Height'$r->getLength());            
            
$dimensions->addChild('Units''IN');    
    
// END CUSTOM CODE
                
        
$declaredValue $xml->addChild('DeclaredValue');
            
$declaredValue->addChild('Value'$r->getValue());
 
Magento Community Magento Community
Magento Community
Magento Community
 
rrobinson
Jr. Member
 
Avatar
Total Posts:  15
Joined:  2008-05-19
Portland, Or
 

Nice solution, I’m sure posting your code will help someone else out in the future.
In fact I can see where I may run across the same requirements.
Definitely bookmarking this thread.

I have a question on your solution.
Have you checked to see if the product is already in the item?
A quick $item->getProduct() call should do it.

It would be interesting to know if it’s there at that point and may save some execution time
by not having to ‘load’ the product.

Thanks for sharing!

 
Magento Community Magento Community
Magento Community
Magento Community
 
Auriferous
Jr. Member
 
Total Posts:  26
Joined:  2008-05-22
 

I tried that but i believe I kept coming up with a NULL result. If I dump getQuote() I end up with about 30,000 lines in the result. Much of which looks to be data duplicated over and over again. I have seen product information in this dump but can’t seem to extract it. Most of my background is in coldfusion and I’m just getting to know php. Working with classes has got me a bit flustered. The Quote/Order/Shipping systems seem very complex and intertwined. I’m sure there is a better way to go about this but it seemed the quickest and simplest to load the product. Feel free to play around a bit and find a better way of going about it. I know its kind of rough but its gets the job done. I tested a shipping quote from Magento against our fedex shipping manager and it came out exactly the same down to the penny.

I just realized there was one other things I changed in fedex.php. In the XML response there is a discount price and a list price returned. Magento has made the system to use the discount price. We have an account where we get a substantial shipping discount and I didn’t want to pass all of this along but rather set my own discount. Here is the code where the XML is parsed into variables:

// Test Dump XML Response
                       // exit(var_dump($responseBody));
        return $this->_parseXmlResponse($responseBody);
    
}

    
protected function _parseXmlResponse($response)
    
{
        $costArr 
= array();
        
$priceArr = array();
        
$errorTitle 'Unable to retrieve quotes';
        if (
strlen(trim($response))>0{
            
if (strpos(trim($response), '<?xml')===0{
                $xml 
simplexml_load_string($response);
                if (
is_object($xml)) {
                    
if (is_object($xml->Error) && is_object($xml->Error->Message)) {
                        $errorTitle 
= (string)$xml->Error->Message;
                    
elseif (is_object($xml->SoftError) && is_object($xml->SoftError->Message)) {
                        $errorTitle 
= (string)$xml->SoftError->Message;
                    
else {
                        $errorTitle 
'Unknown error';
                    
}
                    $allowedMethods 
explode(","$this->getConfigData('allowed_methods'));
                    foreach (
$xml->Entry as $entry{
                        
if (in_array((string)$entry->Service$allowedMethods)) {
                                             
// BEGIN CUSTOM CODE
// Change  DiscountedCharges to ListCharges
// OLD $costArr[(string)$entry->Service] = (string)$entry->EstimatedCharges->DiscountedCharges->NetCharge;
                            
$costArr[(string)$entry->Service] = (string)$entry->EstimatedCharges->ListCharges->NetCharge;
// Again change  DiscountedCharges to ListCharges
                            
$priceArr[(string)$entry->Service] $this->getMethodPrice((string)$entry->EstimatedCharges->ListCharges->NetCharge, (string)$entry->Service);
                                         
// END CUSTOM CODE
                        
}
                    }
                    asort
($priceArr);
                
}
            } 
else {
                $errorTitle 
'Response is in the wrong format';
            
}
        }
 
Magento Community Magento Community
Magento Community
Magento Community
 
rrobinson
Jr. Member
 
Avatar
Total Posts:  15
Joined:  2008-05-19
Portland, Or
 

Right on! Thanks.

The thousands of entries you see are really just references to the same data.
It’s not really duplicated. ( I know it doesn’t help much knowing that )

I’m working on a couple of coldfusion projects myself, one using fusebox.

If this is your first php project you’ve definitely taken on the task. This is absolutely
classes taken to the extreme. But get this under your belt and everything else will
be gravy.

 
Magento Community Magento Community
Magento Community
Magento Community
 
beautifugarbage
Jr. Member
 
Total Posts:  20
Joined:  2008-11-04
 

hey Guys… great post!… super helpful!!
I have a quick question though, I am trying to do exactly what you describe here, our client sells clothing, and it seems that the shipping quotes returned from the shipping API are not ver accurate, and this relates to the issue you describe above, where the product dimensions have a greater impact on the shipping price than the weight…

I am interested to know if you are using the FedEx shipping API or another shipping API??

also is the code you posted above the ONLY code you modified in order to add dimensions to products??
would you be able to tell me which files these were that you edited??

Thanks very much for your help!… again great helpful posting!

thanks in advance!

 
Magento Community Magento Community
Magento Community
Magento Community
 
clickcomkyle
Jr. Member
 
Total Posts:  28
Joined:  2008-08-07
 

thank you! this was extremely helpful.

i used
$product->getMyCustomAttribute()
to impliment different shipping information on a per-product basis. should work great now! thanks!

 
Magento Community Magento Community
Magento Community
Magento Community
 
Auriferous
Jr. Member
 
Total Posts:  26
Joined:  2008-05-22
 
LiFTED - 05 December 2008 02:43 PM

hey Guys… great post!… super helpful!!
I have a quick question though, I am trying to do exactly what you describe here, our client sells clothing, and it seems that the shipping quotes returned from the shipping API are not ver accurate, and this relates to the issue you describe above, where the product dimensions have a greater impact on the shipping price than the weight…

I am interested to know if you are using the FedEx shipping API or another shipping API??

also is the code you posted above the ONLY code you modified in order to add dimensions to products??
would you be able to tell me which files these were that you edited??

Thanks very much for your help!… again great helpful posting!

thanks in advance!

fedex.php is the only file that I changed. I also added a product attribute called “volume” (labeled it cubic inches for users to understand)

The idea is that the Fedex charges the same price for a package based on the volume and the weight without regard to the actual dimensions. So if you are shipping multiple items in the same package you can get a pretty close idea of the size box you will need to enclose all the items. The one major assumption is that all of your items are of similar size and shapes.. If it were for a 8’ 2x4 and a bock of nails then i might not be as accurate.. but then you would most likely ship the items separately. Its not perfect but has been working out great for us!

 
Magento Community Magento Community
Magento Community
Magento Community
 
quanza
Sr. Member
 
Avatar
Total Posts:  97
Joined:  2008-12-02
Tokyo, Japan
 

If anyone’s curious, turns out you can get the weight for an entire order with:

$request->getPackageWeight();

Beats having to cycle through all the items and their quantities.

 
Magento Community Magento Community
Magento Community
Magento Community
 
xondeo
Member
 
Total Posts:  40
Joined:  2009-04-08
 

I’m wondering if somebody knows where could i attack the code of magento to get the following condition:

I have three custom attributes per item:
Height
Width
Length

Now it could be calculated the volumetric weight so: (height*width*length)/6000

If volumetric weigth is > than Weight, then volumetric weight will replace the value of the Weight.
So ALL shipping methods would use the volumetric weight if this happends…

Any ideas? grin

 
Magento Community Magento Community
Magento Community
Magento Community
 
nwd37210
Jr. Member
 
Total Posts:  17
Joined:  2009-12-28
 

I’ve been testing this out and it’s pretty close to working.

It works well for single items but the prices are too high when I get quotes for multiple items. What can I do to get this script to generate a quote per package instead of per order? I’ve already switched this setting in the admin. Our packages are always shipped in separate boxes.

Thanks,

 
Magento Community Magento Community
Magento Community
Magento Community
 
Will Josefi Gazin
Jr. Member
 
Total Posts:  4
Joined:  2009-10-05
 

To access a custom field in shipping module you need to add the field in your config.xml

<global>
        <
sales>
            <
quote>
                <
item>
                    <
product_attributes>
                           <
mycustomfield/>
                    </
product_attributes>
                </
item>
            </
quote>
 
Magento Community Magento Community
Magento Community
Magento Community
 
davekpbm
Jr. Member
 
Total Posts:  4
Joined:  2010-04-05
 

I used Auriferous’ code above just to see how it worked, and it does. But I am wondering if anyone knows how to use the data from the height, width, and length attributes that I have for each item. I could certainly go through the trouble to create a volume for every item, but it would be nice to use the data we already have.

 
Magento Community Magento Community
Magento Community
Magento Community
 
DirectLowVoltage
Jr. Member
 
Total Posts:  30
Joined:  2009-02-19
 
davekpbm - 05 August 2010 12:50 PM

I used Auriferous’ code above just to see how it worked, and it does. But I am wondering if anyone knows how to use the data from the height, width, and length attributes that I have for each item. I could certainly go through the trouble to create a volume for every item, but it would be nice to use the data we already have.

// Get quanity for each Item and multiply by volume
            $qty =  $item->getQty();
            
$product Mage::getModel('catalog/product')->load$item->getProductId() );
.
.
.
change
$volume $product->getVolume();
to
$height $product->getHeight();
$width $product->getWidth();
$length $product->getLength();
$volume $height $lenght $width
.
.
.
// Create default value for volume should value be missing
            if($volume 1){
            
// Default volume - Size for single item (6x7x11)
            
$volume 462 $qty;

This should work… if your attributes are height,width,length

 
Magento Community Magento Community
Magento Community
Magento Community
 
deanbeasley
Jr. Member
 
Total Posts:  5
Joined:  2008-12-08
 

does this actually get the quatity in the basket? I am after code that retrieves the qty in the basket not whats in stock

 
Magento Community Magento Community
Magento Community
Magento Community
Magento Community
Magento Community
Back to top