Post by 12oclocker » Sat Feb 20, 2010 1:54 am

I've noticed the USPS Shipping model calculates based on weight,
but putting in my package dimensions has no effect whatsoever for "USPS Flat Rate Boxes"
I want to be able to support SMALL, MED, and LARGE flat rate boxes for various customers, and I looked up the various flat rate box sizes and set my product dimensions to exceed the correct Flat Rate Boxes accordingly,
Problem is during checkout, All of the flat rate box options appear! obviously a customer is going to select the cheapest flat rate box option, and thus their order will not fit into the box,
Anyone have any idea's how to fix this? I'd really like to offer the customers some cheaper shipping methods,
Thanks Guys!
Last edited by i2Paq on Sun Feb 21, 2010 6:58 pm, edited 1 time in total.
Reason: Topic moved

Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by Qphoria » Sat Feb 20, 2010 4:05 am

This unfortunately opens a seemingly endless can of worms....
If you have 3 products with dimensions:
5x5x5
5x5x6
5x4x5

Technically if you flip around the width and height, all 3 items would fit into a 15x15x15 box perfectly
But how do you calculate that? a normal calculation function wouldn't catch that

Or if you had non-cubic shapes like blisterpacks where the top of the item is thin but gets fatter. Putting them in a "69" position would fit the box right, but not "66" or "99"

The way that it is done now is to pass the MAX dimensions of your biggest box. This may mean that the customer pays a bit more. So one alternative is to take the average on a "win-some" / "lose-some" basis.

I just haven't found a good way to make it perfect.

In my UPS module I added a Max Weight per box, which could then divide the weight across multiple boxes. But it still assumes the dimensions are the average or max size of the boxes I'm using.

Ideas?

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by 12oclocker » Sun Feb 21, 2010 3:55 am

...The way that it is done now is to pass the MAX dimensions of your biggest box. This may mean that the customer pays a bit more. So one alternative is to take the average on a "win-some" / "lose-some" basis....
It's not doing it that way for my USPS Module? I've tried entering 99x99x99 and it still give my customers the "SMALL Flat Rate Box" option.
I would at least be happy if it would go from my Largest Box dimension. Or if it would do a Girth, or cubic calculation.
Do you have a custom module available which is giving this feature your talking about?

Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by 12oclocker » Sun Feb 21, 2010 8:28 am

... The way that it is done now is to pass the MAX dimensions of your biggest box....
that would be good enough, but it does not seem to do that.
I notice there are dimensions you can enter directly in the USPS module,
but what I want to do is use the dimensions in my products, so I left the dimensions in the USPS module blank.
Any ideas?

I'm looking at the code in "catalog\model\shipping\usps.php"...

I see this...
$weight = $this->cart->getWeight();

I also see this...
$xml .= ' <Width>' . $this->config->get('usps_width') . '</Width>';
$xml .= ' <Length>' . $this->config->get('usps_length') . '</Length>';
$xml .= ' <Height>' . $this->config->get('usps_height') . '</Height>';

so it is using the info from the USPS config, and not my actual product sizes, I think I'm going to customize the module for my needs, but I'd rather not re-invent the wheel, if you want to get on this with me let me know, you seem very knowledgeable on this opencart stuff. I'm just now jumping in. Looks like a pretty easy feature to add though.

Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by 12oclocker » Sun Feb 21, 2010 11:09 am

Ok, I just finished a custom Cubic Flat Rate calculator modification, it WORKS GREAT!!
You only need to mod two files with a few lines of code, and then you have SMART Flat Rate Box calculations!
Works for Domestic and International Flat Rate Box Calculations!
You would enable any Flat Rate Boxes you want to use, and if you go over the cubic space that box allows, the Flat Rate Box will be REMOVED from the customers list of available shipping methods at checkout.

here is how it works....
//Small Flat Rate Box: 5.375” x 8.625” x 1.625” [75.33 cubic space]
//Med Flat Rate Box: 11" X 8.5" X 5.5" [514.25 cubic space]
//Large Flat Rate Box: 12” x 12” x 5.5” [792 cubic space]

so if I have a product and 3 of them would fit into a SMALL flat rate box,
I would set my dimensions to something like 5x5x1 [25 cubic space], then exactly 3 of them would fit into the small flat rate box. anything more than that and the "Small Flat Rate Box" option would be removed!
And this works with any mixing matching of any product. It gets the CubicSpace of the entire cart to do the calculations.

//to make the modification, this is what you need to do....
modify: system\library\cart.php
add this function just below the "getWeight()" function...

Code: Select all

  	public function getCubic() {
		$cubic = 0;
    	foreach ($this->getProducts() as $product) {
      		$cubic += ($product['length'] * $product['width'] * $product['height']) * $product['quantity'];
    	}	
		return $cubic;
	}
//next modify: catalog\model\shipping\usps.php
//search for this string "usps_domestic_"
//modify the containing IF statement to look like the code I have below...
//note: I have commented the modifications so you will know what they are

Code: Select all

				if (isset($data['RateV3Response'][1]) || isset($data['IntlRateResponse'][0])) 
				{
					//added by 12oClocker 2-20-2010
					//Small Flat Rate Box: 5.375” x 8.625” x 1.625” [75.33]
					//Med Flat Rate Box: 11" X 8.5" X 5.5" [514.25]
					//Large Flat Rate Box: 12” x 12” x 5.5” [792]
					$cubic = $this->cart->getCubic(); //get cart cubic space needed	
					
					if ($address['iso_code_2'] == 'US') 
					{ 
						$response = $data['RateV3Response'][1];
						
						foreach (array(0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 16, 17, 18, 19, 22, 23, 25, 27, 28) as $sevice) 
						{
							//flat rate disable checker
							$flatOK = 1;
							if($cubic > 75.33 && $sevice == 28){$flatOK = 0;}//Small Flat Rate Disable Check
							if($cubic > 514.25 && $sevice == 17){$flatOK = 0;}//Med Flat Rate Disable Check
							if($cubic > 792 && $sevice == 22){$flatOK = 0;}//Large Flat Rate Disable Check
							
							if (isset($response[$sevice]) && $this->config->get('usps_domestic_' . $sevice) && $flatOK) {
								$quote_data[$sevice] = array(
									'id'           => 'usps.' . $sevice,
									'title'        => $response[$sevice]['MailService'],
									'cost'         => $this->currency->format($response[$sevice]['Rate'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'), FALSE),
									'tax_class_id' => 0,
									'text'         => $this->currency->format($response[$sevice]['Rate'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'))
								);							
							}
						}
					} else {
						$response = $data['IntlRateResponse'][0];
						
						foreach (array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 21) as $sevice) 
						{
							//flat rate disable checker
							$flatOK = 1;
							if($cubic > 75.33 && $sevice == 16){$flatOK = 0;}//Small Flat Rate Disable Check
							if($cubic > 514.25 && $sevice == 9){$flatOK = 0;}//Med Flat Rate Disable Check
							if($cubic > 792 && $sevice == 11){$flatOK = 0;}//Large Flat Rate Disable Check
							
							if (isset($response[$sevice]) && $this->config->get('usps_international_' . $sevice) && $flatOK) {
								$quote_data[$sevice] = array(
									'id'           => 'usps.' . $sevice,
									'title'        => $response[$sevice]['SvcDescription'],
									'cost'         => $this->currency->format($response[$sevice]['Postage'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'), FALSE),
									'tax_class_id' => 0,
									'text'         => $this->currency->format($response[$sevice]['Postage'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'))
								);							
							}
						}
					}
				}
here is an alt version of the usps.php code if you just want to show he cheapest Flat Rate method avaliable...

Code: Select all

				if (isset($data['RateV3Response'][1]) || isset($data['IntlRateResponse'][0])) 
				{
					//added by 12oclocker 2-20-2010
					//Small Flat Rate Box: 5.375” x 8.625” x 1.625” [75.33]
					//Med Flat Rate Box: 11" X 8.5" X 5.5" [514.25]
					//Large Flat Rate Box: 12” x 12” x 5.5” [792]
					$cubic = $this->cart->getCubic();
					$flbox = 0;//figure out what the best flat rate box option is
					if($cubic < 75.33){$flbox = 1;}//Small Flat Rate Disable Check
					else if($cubic < 514.25){$flbox = 2;}//Med Flat Rate Disable Check
					else if($cubic < 792){$flbox = 3;}//Large Flat Rate Disable Check						
					
					if ($address['iso_code_2'] == 'US') 
					{ 
						$response = $data['RateV3Response'][1];
						
						foreach (array(0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 16, 17, 18, 19, 22, 23, 25, 27, 28) as $sevice) 
						{
							//flat rate disable checker
							$flatOK = 1;
							if($flbox != 1 && $sevice == 28){$flatOK = 0;}//Small Flat Rate Disable Check
							if($flbox != 2 && $sevice == 17){$flatOK = 0;}//Med Flat Rate Disable Check
							if($flbox != 3 && $sevice == 22){$flatOK = 0;}//Large Flat Rate Disable Check							
							
							if (isset($response[$sevice]) && $this->config->get('usps_domestic_' . $sevice) && $flatOK) {
								$quote_data[$sevice] = array(
									'id'           => 'usps.' . $sevice,
									'title'        => $response[$sevice]['MailService'],
									'cost'         => $this->currency->format($response[$sevice]['Rate'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'), FALSE),
									'tax_class_id' => 0,
									'text'         => $this->currency->format($response[$sevice]['Rate'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'))
								);							
							}
						}
					} else {
						$response = $data['IntlRateResponse'][0];
						
						foreach (array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 21) as $sevice) 
						{
							//flat rate disable checker
							$flatOK = 1;
							if($flbox != 1 && $sevice == 16){$flatOK = 0;}//Small Flat Rate Disable Check
							if($flbox != 2 && $sevice == 9){$flatOK = 0;}//Med Flat Rate Disable Check
							if($flbox != 3 && $sevice == 11){$flatOK = 0;}//Large Flat Rate Disable Check
							
							if (isset($response[$sevice]) && $this->config->get('usps_international_' . $sevice) && $flatOK) {
								$quote_data[$sevice] = array(
									'id'           => 'usps.' . $sevice,
									'title'        => $response[$sevice]['SvcDescription'],
									'cost'         => $this->currency->format($response[$sevice]['Postage'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'), FALSE),
									'tax_class_id' => 0,
									'text'         => $this->currency->format($response[$sevice]['Postage'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'))
								);							
							}
						}
					}
				}

Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by 12oclocker » Sun Feb 21, 2010 10:10 pm

I just realized my fix works for INCHES only, since I hard coded that into the source, if someone wants to modify my source changes and add a 'convert' function for the GetCubic, to make it revert to inches no matter what type of measurement is selected, that will solve the issue if you are using a different measurement system.

Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by srunyon1 » Tue Mar 02, 2010 12:06 pm

Hi this looks Great!!!
I am some what of a PHP hack and I'm having problems with where and what to update.
Can you give me a few lines above and a few lines below each change? or the complete .php files?
I think I've got it right in the cart.php but my usps.php keeps bombing.
thanks
Steve

Active Member

Posts

Joined
Thu Jan 28, 2010 3:03 pm

Post by srunyon1 » Tue Mar 02, 2010 12:27 pm

ok now I got it not bombing but it will only give me envelope..even though my products are about med box size.
In the USPS module I have listed.

First-Class
Priority Mail
Express Mail Hold for Pickup
Express Mail PO to Addressee
Parcel Post
Bound Printed Matter
Media Mail
Library
First-Class Postcard Stamped
Express Mail Flat-Rate Envelope
Priority Mail Flat-Rate Envelope
Priority Mail Regular Flat-Rate Box
Priority Mail Keys and IDs
First-Class Keys and IDs
Priority Mail Flat-Rate Large Box
Express Mail Sunday/Holiday
Express Mail Flat-Rate Envelope Sunday/Holiday
Express Mail Flat-Rate Envelope Hold For Pickup
Priority Mail Small Flat-Rate Box

if I select just small, regular and Large. it fails..
does this work for multiple sized products.. say the customer orders two items one small and one large does it take that into consideration?
also do you know how to change the service types? Express mail package seems to be missing..
thanks!
Steve

Active Member

Posts

Joined
Thu Jan 28, 2010 3:03 pm

Post by 12oclocker » Fri Mar 05, 2010 10:03 am

...does this work for multiple sized products.. say the customer orders two items one small and one large does it take that into consideration?
also do you know how to change the service types? Express mail package seems to be missing...
yes it works for all that stuff, I did another update to my code the other day, so it will always just show the BEST avaliable flat rate option, and Express mail is enable-able as well, I will post up my source files for you tonight.

Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by srunyon1 » Sat Mar 06, 2010 12:14 pm

I switched to live USPS and it really works well for my needs.. thanks!!!

Active Member

Posts

Joined
Thu Jan 28, 2010 3:03 pm

Post by 12oclocker » Sun Mar 07, 2010 6:44 am

Can you post a link to it, I find threads talking about it, but thats it.
Thanks ;)

Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by Daniel » Sun Mar 07, 2010 10:21 am

if you can come up with a 3d bin packing algorithm you will have the god feature no one else has managed to do with a shopping cart system.

OpenCart®
Project Owner & Developer.


User avatar
Administrator

Posts

Joined
Fri Nov 03, 2006 6:57 pm

Active Member

Posts

Joined
Thu Jan 28, 2010 3:03 pm

Post by Qphoria » Mon Mar 08, 2010 2:22 pm

noo.. i don't have that feature either on my usps module. Daniel is right.. even better would be a common class that all live rate modules could utilize

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am

Post by 12oclocker » Fri Mar 12, 2010 7:38 am

Daniel wrote:if you can come up with a 3d bin packing algorithm you will have the god feature no one else has managed to do with a shopping cart system.
The cubic space code so far has been working great for me, I've probably shipped 50 packages since, and not one problem, everything has fit, and it does a great job of calculating the free space in the box.

Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by zaccaz » Wed Apr 14, 2010 2:42 am

Has anyone else gotten this running smoothly? It looks like the perfect solution, but I can't seem to get it to work. I made the code changes but now I get a completely blank (white) page at checkout (specifically at shipping selection).

Newbie

Posts

Joined
Thu Jan 28, 2010 3:21 pm

Post by padred123 » Thu Apr 22, 2010 5:41 am

This is great! I was going to do this but I'm kinda happy someone beat me to it. :P I Did find one flaw though..
It won't work if the cart dimensions add up larger than a large box. I added the line below so it will at least use a large box. I'm a novice/intermediate programmer and new to opencart but I'm thinking of a way to make it add multiple boxes to the shipping total if the dimensions exceed a large box. Any Ideas?? I will report back if I figure it out.

Add this:

Code: Select all

                   else if($cubic > 792){$flbox = 3;}
Result:

Code: Select all

                if (isset($data['RateV3Response'][1]) || isset($data['IntlRateResponse'][0]))
                {
                   //added by 12oclocker 2-20-2010
                   //Small Flat Rate Box: 5.375” x 8.625” x 1.625” [75.33]
                   //Med Flat Rate Box: 11" X 8.5" X 5.5" [514.25]
                   //Large Flat Rate Box: 12” x 12” x 5.5” [792]
                   $cubic = $this->cart->getCubic();
                   $flbox = 0;//figure out what the best flat rate box option is
                   if($cubic < 75.33){$flbox = 1;}//Small Flat Rate Disable Check
                   else if($cubic < 514.25){$flbox = 2;}//Med Flat Rate Disable Check
                   else if($cubic < 792){$flbox = 3;}//Large Flat Rate Disable Check                  
                   else if($cubic > 792){$flbox = 3;}
                   if ($address['iso_code_2'] == 'US')
                   {
                      $response = $data['RateV3Response'][1];
                      
                      foreach (array(0, 1, 2, 3, 4, 5, 6, 7, 12, 13, 16, 17, 18, 19, 22, 23, 25, 27, 28) as $sevice)
                      {
                         //flat rate disable checker
                         $flatOK = 1;
                         if($flbox != 1 && $sevice == 28){$flatOK = 0;}//Small Flat Rate Disable Check
                         if($flbox != 2 && $sevice == 17){$flatOK = 0;}//Med Flat Rate Disable Check
                         if($flbox != 3 && $sevice == 22){$flatOK = 0;}//Large Flat Rate Disable Check                     

                         if (isset($response[$sevice]) && $this->config->get('usps_domestic_' . $sevice) && $flatOK) {
                            $quote_data[$sevice] = array(
                               'id'           => 'usps.' . $sevice,
                               'title'        => $response[$sevice]['MailService'],
                               'cost'         => $this->currency->format($response[$sevice]['Rate'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'), FALSE),
                               'tax_class_id' => 0,
                               'text'         => $this->currency->format($response[$sevice]['Rate'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'))
                            );                     
                         }
                      }
                   } else {
                      $response = $data['IntlRateResponse'][0];
                      
                      foreach (array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 21) as $sevice)
                      {
                         //flat rate disable checker
                         $flatOK = 1;
                         if($flbox != 1 && $sevice == 16){$flatOK = 0;}//Small Flat Rate Disable Check
                         if($flbox != 2 && $sevice == 9) {$flatOK = 0;}//Med Flat Rate Disable Check
                         if($flbox != 3 && $sevice == 11){$flatOK = 0;}//Large Flat Rate Disable Check
                         
                         if (isset($response[$sevice]) && $this->config->get('usps_international_' . $sevice) && $flatOK) {
                            $quote_data[$sevice] = array(
                               'id'           => 'usps.' . $sevice,
                               'title'        => $response[$sevice]['SvcDescription'],
                               'cost'         => $this->currency->format($response[$sevice]['Postage'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'), FALSE),
                               'tax_class_id' => 0,
                               'text'         => $this->currency->format($response[$sevice]['Postage'], '', $this->currency->getValue($this->currency->getCode()) / $this->currency->getValue('USD'))
                            );                     
                         }
                      }
                   }
                

New member

Posts

Joined
Wed Mar 24, 2010 6:05 am

Post by 12oclocker » Tue Jul 20, 2010 1:33 am

...It won't work if the cart dimensions add up larger than a large box. I added the line below so it will at least use a large box.....
The code is not flawed, If the cart dimensions add up larger than a Large Flat Rate box, than your products will probably Not fit in that box, so why would you want to display it? It's omitted on purpose, you're going to want to use a different box, probably your own, or one of the USPS non-flat rate boxes (they do have larger ones than the 'Large Flat Rate' that are weight based) Trust me, I've been using this code for hundreds of orders, and have not had a single problem yet. The idea is to enable other USPS services as well as the Flat Rate box services. This code basically will enable or disable any flat rate box service (small, med, or large) as it see's fit. The flat rate services sometimes offer a cost saving advantage over the weight based, thus the reason it was written.

...New Version...
I updated the Flat Rate Box code to work with opencart v1.4.8b
You must have your products set to Inches, and Pounds to use this code.
Works for Small, Medium, and Large Flate Rate Boxes.
I have also implemented a Minimum Shipping charge of $4.90 for International orders in this code, if you dont like that feature, just comment it out.
TODO: add a check for weight limits of the flat rate boxes, I've never ran into this being an issue yet, as unless your shipping rocks or lead blocks, or other really heavy objects.

to install....
Rename file: "\catalog\model\shipping\usps.php" to something else
upload the new file attached

Attachments

USPS Flat Rate Box calculator


Active Member

Posts

Joined
Fri Feb 19, 2010 10:50 am

Post by mjwillyone » Thu Aug 05, 2010 10:33 pm

This is a very helpful, since I am working on a site where the owner wants utilize flat-rate shipping.

I assume that this uses the USPS module in OpenCart and that the owner will need to get an account with the USPS before any of this will work correctly. Is that correct?

Thank you very much,
Mike

Owner/President
MyDataWorks.net


New member

Posts

Joined
Wed Jan 27, 2010 11:24 pm

Post by Qphoria » Thu Aug 05, 2010 11:52 pm

mjwillyone wrote:This is a very helpful, since I am working on a site where the owner wants utilize flat-rate shipping.

I assume that this uses the USPS module in OpenCart and that the owner will need to get an account with the USPS before any of this will work correctly. Is that correct?

Thank you very much,
Mike
This is not for flat-rate shipping. This is for calculating rates supporting the "flat-rate boxes" that usps provides. You will of course need a USPS shipping account and rates will still be weight based, just ranged for the usps flat-rate boxes. Not to be confused with generic Flat rate shipping.

Image


User avatar
Administrator

Posts

Joined
Tue Jul 22, 2008 3:02 am
Who is online

Users browsing this forum: No registered users and 26 guests