Magento, where art thou documentation? Where art thou support for community code and problem solutions?
Laments to the nature of Varien's views "Open Source" aside, the UPS shipping module has one glaring bug: The UPS API doesn't handle weights of zero (or, perhaps, as I havent verified this, Magento's UPS module code doesn't properly take into account that some products may have weight of zero).
(It would seem handy if we could set a shipping method per product. If only.)
Now, before I get into details on a work around to this issue, you should know that if you do not want products considered in shipping calculations, you should be using Virtual products. These act like simple products but are not calculated in the shipping. I have not tested how these interact with Bundled or Grouped products.
You should also consider using Promotions (Shopping Cart price rules) to give items meeting certain criteria free shipping (You can then give those products a weight to avoid the zero-weight issue).
Now, without further pontification (yay, big words),
here's the fix:
(p.s. – this is done using Magento version 1.3.2.4)
1) We are COPYING: app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php and pasting it here:code/local/Mage/Usa/Model/Shipping/Carrier/Ups.php We do this so we overwrite the core code, without actually changing the core code (best practices). Make sure any edits are done to the Ups.php found in your "local" folder rather than the "core" folder.
2) What we want to do is test if a product has a weight of zero. If it does, we flag it, and tell UPS that we have a weight of .05. Pretending our product has some weight prevents UPS from returning a response we can't use. We then test for this flag later in the code to determine if we should reset the cost of the shipping to zero (since presumably, no weight = no cost – Apologies if this does not work with your business logic).
Code added to Ups.php:
01.
//Line 50
02.
protected
$_isZeroWeight
= false;
03.
04.
//Line 155ish
05.
if
(
$weight
== 0) {
06.
$weight
= .05;
07.
$this
->_isZeroWeight = true;
08.
}
09.
10.
//Line 295ish
11.
else
if
(
$this
->_isZeroWeight == true) {
12.
foreach
(
$priceArr
as
$method
=>
$price
) {
13.
$rate
= Mage::getModel(
'shipping/rate_result_method'
);
14.
$rate
->setCarrier(
'ups'
);
15.
$rate
->setCarrierTitle(
$this
->getConfigData(
'title'
));
16.
$rate
->setMethod(
$method
);
17.
$method_arr
=
$this
->getCode(
'method'
,
$method
);
18.
$rate
->setMethodTitle(Mage::helper(
'usa'
)->__(
$method_arr
));
19.
$rate
->setCost(0);
20.
$rate
->setPrice(0);
21.
$result
->append(
$rate
);
22.
}
23.
}
Now, here is the full code. I suggest you go by this to see how the changes relate to the rest of the code:
001.
<?php
002.
/**
003.
* Magento
004.
*
005.
* NOTICE OF LICENSE
006.
*
007.
* This source file is subject to the Open Software License (OSL 3.0)
008.
* that is bundled with this package in the file LICENSE.txt.
009.
* It is also available through the world-wide-web at this URL:
011.
* If you did not receive a copy of the license and are unable to
012.
* obtain it through the world-wide-web, please send an email
013.
* to license@magentocommerce.com so we can send you a copy immediately.
014.
*
015.
* DISCLAIMER
016.
*
017.
* Do not edit or add to this file if you wish to upgrade Magento to newer
018.
* versions in the future. If you wish to customize Magento for your
019.
* needs please refer to http://www.magentocommerce.com for more information.
020.
*
021.
* @category Mage
022.
* @package Mage_Usa
023.
* @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
024.
* @license http://opensource.org/licenses/osl-3.0.php ; Open Software License (OSL 3.0)
025.
*/
026.
027.
/**
028.
* UPS shipping rates estimation
029.
*
030.
* @category Mage
031.
* @package Mage_Usa
032.
* @author Magento Core Team <core@magentocommerce.com>
033.
*/
034.
class
Mage_Usa_Model_Shipping_Carrier_Ups
035.
extends
Mage_Usa_Model_Shipping_Carrier_Abstract
036.
implements
Mage_Shipping_Model_Carrier_Interface
037.
{
038.
039.
protected
$_code
=
'ups'
;
040.
041.
protected
$_request
= null;
042.
043.
protected
$_result
= null;
044.
045.
protected
$_xmlAccessRequest
= null;
046.
047.
protected
$_defaultCgiGatewayUrl
=
'http://www.ups.com:80/using/services/rave/qcostcgi.cgi'
;
048.
049.
protected
$_isZeroWeight
= false;
050.
051.
public
function
collectRates(Mage_Shipping_Model_Rate_Request
$request
)
052.
{
053.
if
(!
$this
->getConfigFlag(
'active'
)) {
054.
return
false;
055.
}
056.
057.
$this
->setRequest(
$request
);
058.
059.
$this
->_result =
$this
->_getQuotes();
060.
$this
->_updateFreeMethodQuote(
$request
);
061.
062.
return
$this
->getResult();
063.
}
064.
065.
public
function
setRequest(Mage_Shipping_Model_Rate_Request
$request
)
066.
{
067.
$this
->_request =
$request
;
068.
069.
$r
=
new
Varien_Object();
070.
071.
if
(
$request
->getLimitMethod()) {
072.
$r
->setAction(
$this
->getCode(
'action'
,
'single'
));
073.
$r
->setProduct(
$request
->getLimitMethod());
074.
}
else
{
075.
$r
->setAction(
$this
->getCode(
'action'
,
'all'
));
076.
$r
->setProduct(
'GND'
.
$this
->getConfigData(
'dest_type'
));
077.
}
078.
079.
if
(
$request
->getUpsPickup()) {
080.
$pickup
=
$request
->getUpsPickup();
081.
}
else
{
082.
$pickup
=
$this
->getConfigData(
'pickup'
);
083.
}
084.
$r
->setPickup(
$this
->getCode(
'pickup'
,
$pickup
));
085.
086.
if
(
$request
->getUpsContainer()) {
087.
$container
=
$request
->getUpsContainer();
088.
}
else
{
089.
$container
=
$this
->getConfigData(
'container'
);
090.
}
091.
$r
->setContainer(
$this
->getCode(
'container'
,
$container
));
092.
093.
if
(
$request
->getUpsDestType()) {
094.
$destType
=
$request
->getUpsDestType();
095.
}
else
{
096.
$destType
=
$this
->getConfigData(
'dest_type'
);
097.
}
098.
$r
->setDestType(
$this
->getCode(
'dest_type'
,
$destType
));
099.
100.
if
(
$request
->getOrigCountry()) {
101.
$origCountry
=
$request
->getOrigCountry();
102.
}
else
{
103.
$origCountry
= Mage::getStoreConfig(
'shipping/origin/country_id'
,
$this
->getStore());
104.
}
105.
106.
$r
->setOrigCountry(Mage::getModel(
'directory/country'
)->load(
$origCountry
)->getIso2Code());
107.
108.
if
(
$request
->getOrigRegionCode()) {
109.
$origRegionCode
=
$request
->getOrigRegionCode();
110.
}
else
{
111.
$origRegionCode
= Mage::getStoreConfig(
'shipping/origin/region_id'
,
$this
->getStore());
112.
if
(
is_numeric
(
$origRegionCode
)) {
113.
$origRegionCode
= Mage::getModel(
'directory/region'
)->load(
$origRegionCode
)->getCode();
114.
}
115.
}
116.
$r
->setOrigRegionCode(
$origRegionCode
);
117.
118.
if
(
$request
->getOrigPostcode()) {
119.
$r
->setOrigPostal(
$request
->getOrigPostcode());
120.
}
else
{
121.
$r
->setOrigPostal(Mage::getStoreConfig(
'shipping/origin/postcode'
,
$this
->getStore()));
122.
}
123.
124.
if
(
$request
->getOrigCity()) {
125.
$r
->setOrigCity(
$request
->getOrigCity());
126.
}
else
{
127.
$r
->setOrigCity(Mage::getStoreConfig(
'shipping/origin/city'
,
$this
->getStore()));
128.
}
129.
130.
if
(
$request
->getDestCountryId()) {
131.
$destCountry
=
$request
->getDestCountryId();
132.
}
else
{
133.
$destCountry
= self::USA_COUNTRY_ID;
134.
}
135.
136.
//for UPS, puero rico state for US will assume as puerto rico country
137.
if
(
$destCountry
==self::USA_COUNTRY_ID && (
$request
->getDestPostcode()==
'00912'
||
$request
->getDestRegionCode()==self::PUERTORICO_COUNTRY_ID)) {
138.
$destCountry
= self::PUERTORICO_COUNTRY_ID;
139.
}
140.
141.
$r
->setDestCountry(Mage::getModel(
'directory/country'
)->load(
$destCountry
)->getIso2Code());
142.
143.
$r
->setDestRegionCode(
$request
->getDestRegionCode());
144.
145.
if
(
$request
->getDestPostcode()) {
146.
$r
->setDestPostal(
$request
->getDestPostcode());
147.
}
else
{
148.
149.
}
150.
151.
$weight
=
$this
->getTotalNumOfBoxes(
$request
->getPackageWeight());
152.
153.
if
(
$weight
== 0) {
154.
$weight
= .05;
155.
$this
->_isZeroWeight = true;
156.
}
157.
158.
$r
->setWeight(
$weight
);
159.
if
(
$request
->getFreeMethodWeight()!=
$request
->getPackageWeight()) {
160.
$r
->setFreeMethodWeight(
$request
->getFreeMethodWeight());
161.
}
162.
163.
$r
->setValue(
$request
->getPackageValue());
164.
$r
->setValueWithDiscount(
$request
->getPackageValueWithDiscount());
165.
166.
if
(
$request
->getUpsUnitMeasure()) {
167.
$unit
=
$request
->getUpsUnitMeasure();
168.
}
else
{
169.
$unit
=
$this
->getConfigData(
'unit_of_measure'
);
170.
}
171.
$r
->setUnitMeasure(
$unit
);
172.
173.
$this
->_rawRequest =
$r
;
174.
175.
return
$this
;
176.
}
177.
178.
public
function
getResult()
179.
{
180.
return
$this
->_result;
181.
}
182.
183.
protected
function
_getQuotes()
184.
{
185.
switch
(
$this
->getConfigData(
'type'
)) {
186.
case
'UPS'
:
187.
return
$this
->_getCgiQuotes();
188.
189.
case
'UPS_XML'
:
190.
return
$this
->_getXmlQuotes();
191.
}
192.
return
null;
193.
}
194.
195.
protected
function
_setFreeMethodRequest(
$freeMethod
)
196.
{
197.
$r
=
$this
->_rawRequest;
198.
199.
$weight
=
$this
->getTotalNumOfBoxes(
$r
->getFreeMethodWeight());
200.
$r
->setWeight(
$weight
);
201.
$r
->setAction(
$this
->getCode(
'action'
,
'single'
));
202.
$r
->setProduct(
$freeMethod
);
203.
}
204.
205.
protected
function
_getCgiQuotes()
206.
{
207.
$r
=
$this
->_rawRequest;
208.
209.
$params
=
array
(
210.
'accept_UPS_license_agreement'
=>
'yes'
,
211.
'10_action'
=>
$r
->getAction(),
212.
'13_product'
=>
$r
->getProduct(),
213.
'14_origCountry'
=>
$r
->getOrigCountry(),
214.
'15_origPostal'
=>
$r
->getOrigPostal(),
215.
'origCity'
=>
$r
->getOrigCity(),
216.
'19_destPostal'
=>
substr
(
$r
->getDestPostal(), 0, 5),
217.
'22_destCountry'
=>
$r
->getDestCountry(),
218.
'23_weight'
=>
$r
->getWeight(),
219.
'47_rate_chart'
=>
$r
->getPickup(),
220.
'48_container'
=>
$r
->getContainer(),
221.
'49_residential'
=>
$r
->getDestType(),
222.
'weight_std'
=>
strtolower
(
$r
->getUnitMeasure()),
223.
);
224.
$params
[
'47_rate_chart'
] =
$params
[
'47_rate_chart'
][
'label'
];
225.
226.
try {
227.
$url
=
$this
->getConfigData(
'gateway_url'
);
228.
if
(!
$url
) {
229.
$url
=
$this
->_defaultCgiGatewayUrl;
230.
}
231.
$client
=
new
Zend_Http_Client();
232.
$client
->setUri(
$url
);
233.
$client
->setConfig(
array
(
'maxredirects'
=>0,
'timeout'
=>30));
234.
$client
->setParameterGet(
$params
);
235.
$response
=
$client
->request();
236.
$responseBody
=
$response
->getBody();
237.
} catch (Exception
$e
) {
238.
$responseBody
=
''
;
239.
}
240.
241.
return
$this
->_parseCgiResponse(
$responseBody
);
242.
}
243.
244.
public
function
getShipmentByCode(
$code
,
$origin
= null){
245.
if
(
$origin
===null){
246.
$origin
=
$this
->getConfigData(
'origin_shipment'
);
247.
}
248.
$arr
=
$this
->getCode(
'originShipment'
,
$origin
);
249.
if
(isset(
$arr
[
$code
]))
250.
return
$arr
[
$code
];
251.
else
252.
return
false;
253.
}
254.
255.
protected
function
_parseCgiResponse(
$response
)
256.
{
257.
$costArr
=
array
();
258.
$priceArr
=
array
();
259.
$errorTitle
= Mage::helper(
'usa'
)->__(
'Unknown error'
);
260.
if
(
strlen
(trim(
$response
))>0) {
261.
$rRows
=
explode
(
"\n"
,
$response
);
262.
$allowedMethods
=
explode
(
","
,
$this
->getConfigData(
'allowed_methods'
));
263.
foreach
(
$rRows
as
$rRow
) {
264.
$r
=
explode
(
'%'
,
$rRow
);
265.
switch
(
substr
(
$r
[0],-1)) {
266.
case
3:
case
4:
267.
if
(in_array(
$r
[1],
$allowedMethods
)) {
268.
$responsePrice
= Mage::app()->getLocale()->getNumber(
$r
[8]);
269.
$costArr
[
$r
[1]] =
$responsePrice
;
270.
$priceArr
[
$r
[1]] =
$this
->getMethodPrice(
$responsePrice
,
$r
[1]);
271.
}
272.
break
;
273.
case
5:
274.
$errorTitle
=
$r
[1];
275.
break
;
276.
case
6:
277.
if
(in_array(
$r
[3],
$allowedMethods
)) {
278.
$responsePrice
= Mage::app()->getLocale()->getNumber(
$r
[10]);
279.
$costArr
[
$r
[3]] =
$responsePrice
;
280.
$priceArr
[
$r
[3]] =
$this
->getMethodPrice(
$responsePrice
,
$r
[3]);
281.
}
282.
break
;
283.
}
284.
}
285.
asort(
$priceArr
);
286.
}
287.
288.
$result
= Mage::getModel(
'shipping/rate_result'
);
289.
$defaults
=
$this
->getDefaults();
290.
if
(
empty
(
$priceArr
)) {
291.
$error
= Mage::getModel(
'shipping/rate_result_error'
);
292.
$error
->setCarrier(
'ups'
);
293.
$error
->setCarrierTitle(
$this
->getConfigData(
'title'
));
294.
//$error->setErrorMessage($errorTitle);
295.
$error
->setErrorMessage(
$this
->getConfigData(
'specificerrmsg'
));
296.
$result
->append(
$error
);
297.
}
else
if
(
$this
->_isZeroWeight == true) {
298.
foreach
(
$priceArr
as
$method
=>
$price
) {
299.
$rate
= Mage::getModel(
'shipping/rate_result_method'
);
300.
$rate
->setCarrier(
'ups'
);
301.
$rate
->setCarrierTitle(
$this
->getConfigData(
'title'
));
302.
$rate
->setMethod(
$method
);
303.
$method_arr
=
$this
->getCode(
'method'
,
$method
);
304.
$rate
->setMethodTitle(Mage::helper(
'usa'
)->__(
$method_arr
));
305.
$rate
->setCost(0);
306.
$rate
->setPrice(0);
307.
$result
->append(
$rate
);
308.
}
309.
}
else
{
310.
foreach
(
$priceArr
as
$method
=>
$price
) {
311.
$rate
= Mage::getModel(
'shipping/rate_result_method'
);
312.
$rate
->setCarrier(
'ups'
);
313.
$rate
->setCarrierTitle(
$this
->getConfigData(
'title'
));
314.
$rate
->setMethod(
$method
);
315.
$method_arr
=
$this
->getCode(
'method'
,
$method
);
316.
$rate
->setMethodTitle(Mage::helper(
'usa'
)->__(
$method_arr
));
317.
$rate
->setCost(
$costArr
[
$method
]);
318.
$rate
->setPrice(
$price
);
319.
$result
->append(
$rate
);
320.
}
321.
}
322.
//echo "<!--".print_r($result,1)."-->";
323.
return
$result
;
324.
}
325.
326.
//And so on..... I have truncated the rest of the file as no further changes are made. Don't delete the code here yourself.
What does this result in?
- Requesting a quote from the Cart page shows cost of zero for all shipping methods
- When checking out, users still must select a shipping method. They are all at zero cost, but users will still be able to check items such as 1-day shipping (And/or whatever methods you have enabled). Is this optimal? Probably not, however this issue is, unfortunately, outside of the scope of this article at this time.
- It appears that Magento will still calculate shopping carts with mixed products (productswith and without weights) correctly. You should test this to make sure customers aren't getting over or under charged.
Hope this helps someone!Magento, where art thou documentation? Where art thou support for community code and problem solutions?
Laments to the nature of Varien's views "Open Source" aside, the UPS shipping module has one glaring bug: The UPS API doesn't handle weights of zero (or, perhaps, as I havent verified this, Magento's UPS module code doesn't properly take into account that some products may have weight of zero).
(It would seem handy if we could set a shipping method per product. If only.)
Now, before I get into details on a work around to this issue, you should know that if you do not want products considered in shipping calculations, you should be using Virtual products. These act like simple products but are not calculated in the shipping. I have not tested how these interact with Bundled or Grouped products.
You should also consider using Promotions (Shopping Cart price rules) to give items meeting certain criteria free shipping (You can then give those products a weight to avoid the zero-weight issue).
Now, without further pontification (yay, big words),
here's the fix:
(p.s. – this is done using Magento version 1.3.2.4)
1) We are COPYING: app/code/core/Mage/Usa/Model/Shipping/Carrier/Ups.php and pasting it here:code/local/Mage/Usa/Model/Shipping/Carrier/Ups.php We do this so we overwrite the core code, without actually changing the core code (best practices). Make sure any edits are done to the Ups.php found in your "local" folder rather than the "core" folder.
2) What we want to do is test if a product has a weight of zero. If it does, we flag it, and tell UPS that we have a weight of .05. Pretending our product has some weight prevents UPS from returning a response we can't use. We then test for this flag later in the code to determine if we should reset the cost of the shipping to zero (since presumably, no weight = no cost – Apologies if this does not work with your business logic).
Code added to Ups.php:
01.
//Line 50
02.
protected
$_isZeroWeight
= false;
03.
04.
//Line 155ish
05.
if
(
$weight
== 0) {
06.
$weight
= .05;
07.
$this
->_isZeroWeight = true;
08.
}
09.
10.
//Line 295ish
11.
else
if
(
$this
->_isZeroWeight == true) {
12.
foreach
(
$priceArr
as
$method
=>
$price
) {
13.
$rate
= Mage::getModel(
'shipping/rate_result_method'
);
14.
$rate
->setCarrier(
'ups'
);
15.
$rate
->setCarrierTitle(
$this
->getConfigData(
'title'
));
16.
$rate
->setMethod(
$method
);
17.
$method_arr
=
$this
->getCode(
'method'
,
$method
);
18.
$rate
->setMethodTitle(Mage::helper(
'usa'
)->__(
$method_arr
));
19.
$rate
->setCost(0);
20.
$rate
->setPrice(0);
21.
$result
->append(
$rate
);
22.
}
23.
}
Now, here is the full code. I suggest you go by this to see how the changes relate to the rest of the code:
001.
<?php
002.
/**
003.
* Magento
004.
*
005.
* NOTICE OF LICENSE
006.
*
007.
* This source file is subject to the Open Software License (OSL 3.0)
008.
* that is bundled with this package in the file LICENSE.txt.
009.
* It is also available through the world-wide-web at this URL:
011.
* If you did not receive a copy of the license and are unable to
012.
* obtain it through the world-wide-web, please send an email
013.
* to license@magentocommerce.com so we can send you a copy immediately.
014.
*
015.
* DISCLAIMER
016.
*
017.
* Do not edit or add to this file if you wish to upgrade Magento to newer
018.
* versions in the future. If you wish to customize Magento for your
019.
* needs please refer to http://www.magentocommerce.com for more information.
020.
*
021.
* @category Mage
022.
* @package Mage_Usa
023.
* @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
024.
* @license http://opensource.org/licenses/osl-3.0.php ; Open Software License (OSL 3.0)
025.
*/
026.
027.
/**
028.
* UPS shipping rates estimation
029.
*
030.
* @category Mage
031.
* @package Mage_Usa
032.
* @author Magento Core Team <core@magentocommerce.com>
033.
*/
034.
class
Mage_Usa_Model_Shipping_Carrier_Ups
035.
extends
Mage_Usa_Model_Shipping_Carrier_Abstract
036.
implements
Mage_Shipping_Model_Carrier_Interface
037.
{
038.
039.
protected
$_code
=
'ups'
;
040.
041.
protected
$_request
= null;
042.
043.
protected
$_result
= null;
044.
045.
protected
$_xmlAccessRequest
= null;
046.
047.
protected
$_defaultCgiGatewayUrl
=
'http://www.ups.com:80/using/services/rave/qcostcgi.cgi'
;
048.
049.
protected
$_isZeroWeight
= false;
050.
051.
public
function
collectRates(Mage_Shipping_Model_Rate_Request
$request
)
052.
{
053.
if
(!
$this
->getConfigFlag(
'active'
)) {
054.
return
false;
055.
}
056.
057.
$this
->setRequest(
$request
);
058.
059.
$this
->_result =
$this
->_getQuotes();
060.
$this
->_updateFreeMethodQuote(
$request
);
061.
062.
return
$this
->getResult();
063.
}
064.
065.
public
function
setRequest(Mage_Shipping_Model_Rate_Request
$request
)
066.
{
067.
$this
->_request =
$request
;
068.
069.
$r
=
new
Varien_Object();
070.
071.
if
(
$request
->getLimitMethod()) {
072.
$r
->setAction(
$this
->getCode(
'action'
,
'single'
));
073.
$r
->setProduct(
$request
->getLimitMethod());
074.
}
else
{
075.
$r
->setAction(
$this
->getCode(
'action'
,
'all'
));
076.
$r
->setProduct(
'GND'
.
$this
->getConfigData(
'dest_type'
));
077.
}
078.
079.
if
(
$request
->getUpsPickup()) {
080.
$pickup
=
$request
->getUpsPickup();
081.
}
else
{
082.
$pickup
=
$this
->getConfigData(
'pickup'
);
083.
}
084.
$r
->setPickup(
$this
->getCode(
'pickup'
,
$pickup
));
085.
086.
if
(
$request
->getUpsContainer()) {
087.
$container
=
$request
->getUpsContainer();
088.
}
else
{
089.
$container
=
$this
->getConfigData(
'container'
);
090.
}
091.
$r
->setContainer(
$this
->getCode(
'container'
,
$container
));
092.
093.
if
(
$request
->getUpsDestType()) {
094.
$destType
=
$request
->getUpsDestType();
095.
}
else
{
096.
$destType
=
$this
->getConfigData(
'dest_type'
);
097.
}
098.
$r
->setDestType(
$this
->getCode(
'dest_type'
,
$destType
));
099.
100.
if
(
$request
->getOrigCountry()) {
101.
$origCountry
=
$request
->getOrigCountry();
102.
}
else
{
103.
$origCountry
= Mage::getStoreConfig(
'shipping/origin/country_id'
,
$this
->getStore());
104.
}
105.
106.
$r
->setOrigCountry(Mage::getModel(
'directory/country'
)->load(
$origCountry
)->getIso2Code());
107.
108.
if
(
$request
->getOrigRegionCode()) {
109.
$origRegionCode
=
$request
->getOrigRegionCode();
110.
}
else
{
111.
$origRegionCode
= Mage::getStoreConfig(
'shipping/origin/region_id'
,
$this
->getStore());
112.
if
(
is_numeric
(
$origRegionCode
)) {
113.
$origRegionCode
= Mage::getModel(
'directory/region'
)->load(
$origRegionCode
)->getCode();
114.
}
115.
}
116.
$r
->setOrigRegionCode(
$origRegionCode
);
117.
118.
if
(
$request
->getOrigPostcode()) {
119.
$r
->setOrigPostal(
$request
->getOrigPostcode());
120.
}
else
{
121.
$r
->setOrigPostal(Mage::getStoreConfig(
'shipping/origin/postcode'
,
$this
->getStore()));
122.
}
123.
124.
if
(
$request
->getOrigCity()) {
125.
$r
->setOrigCity(
$request
->getOrigCity());
126.
}
else
{
127.
$r
->setOrigCity(Mage::getStoreConfig(
'shipping/origin/city'
,
$this
->getStore()));
128.
}
129.
130.
if
(
$request
->getDestCountryId()) {
131.
$destCountry
=
$request
->getDestCountryId();
132.
}
else
{
133.
$destCountry
= self::USA_COUNTRY_ID;
134.
}
135.
136.
//for UPS, puero rico state for US will assume as puerto rico country
137.
if
(
$destCountry
==self::USA_COUNTRY_ID && (
$request
->getDestPostcode()==
'00912'
||
$request
->getDestRegionCode()==self::PUERTORICO_COUNTRY_ID)) {
138.
$destCountry
= self::PUERTORICO_COUNTRY_ID;
139.
}
140.
141.
$r
->setDestCountry(Mage::getModel(
'directory/country'
)->load(
$destCountry
)->getIso2Code());
142.
143.
$r
->setDestRegionCode(
$request
->getDestRegionCode());
144.
145.
if
(
$request
->getDestPostcode()) {
146.
$r
->setDestPostal(
$request
->getDestPostcode());
147.
}
else
{
148.
149.
}
150.
151.
$weight
=
$this
->getTotalNumOfBoxes(
$request
->getPackageWeight());
152.
153.
if
(
$weight
== 0) {
154.
$weight
= .05;
155.
$this
->_isZeroWeight = true;
156.
}
157.
158.
$r
->setWeight(
$weight
);
159.
if
(
$request
->getFreeMethodWeight()!=
$request
->getPackageWeight()) {
160.
$r
->setFreeMethodWeight(
$request
->getFreeMethodWeight());
161.
}
162.
163.
$r
->setValue(
$request
->getPackageValue());
164.
$r
->setValueWithDiscount(
$request
->getPackageValueWithDiscount());
165.
166.
if
(
$request
->getUpsUnitMeasure()) {
167.
$unit
=
$request
->getUpsUnitMeasure();
168.
}
else
{
169.
$unit
=
$this
->getConfigData(
'unit_of_measure'
);
170.
}
171.
$r
->setUnitMeasure(
$unit
);
172.
173.
$this
->_rawRequest =
$r
;
174.
175.
return
$this
;
176.
}
177.
178.
public
function
getResult()
179.
{
180.
return
$this
->_result;
181.
}
182.
183.
protected
function
_getQuotes()
184.
{
185.
switch
(
$this
->getConfigData(
'type'
)) {
186.
case
'UPS'
:
187.
return
$this
->_getCgiQuotes();
188.
189.
case
'UPS_XML'
:
190.
return
$this
->_getXmlQuotes();
191.
}
192.
return
null;
193.
}
194.
195.
protected
function
_setFreeMethodRequest(
$freeMethod
)
196.
{
197.
$r
=
$this
->_rawRequest;
198.
199.
$weight
=
$this
->getTotalNumOfBoxes(
$r
->getFreeMethodWeight());
200.
$r
->setWeight(
$weight
);
201.
$r
->setAction(
$this
->getCode(
'action'
,
'single'
));
202.
$r
->setProduct(
$freeMethod
);
203.
}
204.
205.
protected
function
_getCgiQuotes()
206.
{
207.
$r
=
$this
->_rawRequest;
208.
209.
$params
=
array
(
210.
'accept_UPS_license_agreement'
=>
'yes'
,
211.
'10_action'
=>
$r
->getAction(),
212.
'13_product'
=>
$r
->getProduct(),
213.
'14_origCountry'
=>
$r
->getOrigCountry(),
214.
'15_origPostal'
=>
$r
->getOrigPostal(),
215.
'origCity'
=>
$r
->getOrigCity(),
216.
'19_destPostal'
=>
substr
(
$r
->getDestPostal(), 0, 5),
217.
'22_destCountry'
=>
$r
->getDestCountry(),
218.
'23_weight'
=>
$r
->getWeight(),
219.
'47_rate_chart'
=>
$r
->getPickup(),
220.
'48_container'
=>
$r
->getContainer(),
221.
'49_residential'
=>
$r
->getDestType(),
222.
'weight_std'
=>
strtolower
(
$r
->getUnitMeasure()),
223.
);
224.
$params
[
'47_rate_chart'
] =
$params
[
'47_rate_chart'
][
'label'
];
225.
226.
try {
227.
$url
=
$this
->getConfigData(
'gateway_url'
);
228.
if
(!
$url
) {
229.
$url
=
$this
->_defaultCgiGatewayUrl;
230.
}
231.
$client
=
new
Zend_Http_Client();
232.
$client
->setUri(
$url
);
233.
$client
->setConfig(
array
(
'maxredirects'
=>0,
'timeout'
=>30));
234.
$client
->setParameterGet(
$params
);
235.
$response
=
$client
->request();
236.
$responseBody
=
$response
->getBody();
237.
} catch (Exception
$e
) {
238.
$responseBody
=
''
;
239.
}
240.
241.
return
$this
->_parseCgiResponse(
$responseBody
);
242.
}
243.
244.
public
function
getShipmentByCode(
$code
,
$origin
= null){
245.
if
(
$origin
===null){
246.
$origin
=
$this
->getConfigData(
'origin_shipment'
);
247.
}
248.
$arr
=
$this
->getCode(
'originShipment'
,
$origin
);
249.
if
(isset(
$arr
[
$code
]))
250.
return
$arr
[
$code
];
251.
else
252.
return
false;
253.
}
254.
255.
protected
function
_parseCgiResponse(
$response
)
256.
{
257.
$costArr
=
array
();
258.
$priceArr
=
array
();
259.
$errorTitle
= Mage::helper(
'usa'
)->__(
'Unknown error'
);
260.
if
(
strlen
(trim(
$response
))>0) {
261.
$rRows
=
explode
(
"\n"
,
$response
);
262.
$allowedMethods
=
explode
(
","
,
$this
->getConfigData(
'allowed_methods'
));
263.
foreach
(
$rRows
as
$rRow
) {
264.
$r
=
explode
(
'%'
,
$rRow
);
265.
switch
(
substr
(
$r
[0],-1)) {
266.
case
3:
case
4:
267.
if
(in_array(
$r
[1],
$allowedMethods
)) {
268.
$responsePrice
= Mage::app()->getLocale()->getNumber(
$r
[8]);
269.
$costArr
[
$r
[1]] =
$responsePrice
;
270.
$priceArr
[
$r
[1]] =
$this
->getMethodPrice(
$responsePrice
,
$r
[1]);
271.
}
272.
break
;
273.
case
5:
274.
$errorTitle
=
$r
[1];
275.
break
;
276.
case
6:
277.
if
(in_array(
$r
[3],
$allowedMethods
)) {
278.
$responsePrice
= Mage::app()->getLocale()->getNumber(
$r
[10]);
279.
$costArr
[
$r
[3]] =
$responsePrice
;
280.
$priceArr
[
$r
[3]] =
$this
->getMethodPrice(
$responsePrice
,
$r
[3]);
281.
}
282.
break
;
283.
}
284.
}
285.
asort(
$priceArr
);
286.
}
287.
288.
$result
= Mage::getModel(
'shipping/rate_result'
);
289.
$defaults
=
$this
->getDefaults();
290.
if
(
empty
(
$priceArr
)) {
291.
$error
= Mage::getModel(
'shipping/rate_result_error'
);
292.
$error
->setCarrier(
'ups'
);
293.
$error
->setCarrierTitle(
$this
->getConfigData(
'title'
));
294.
//$error->setErrorMessage($errorTitle);
295.
$error
->setErrorMessage(
$this
->getConfigData(
'specificerrmsg'
));
296.
$result
->append(
$error
);
297.
}
else
if
(
$this
->_isZeroWeight == true) {
298.
foreach
(
$priceArr
as
$method
=>
$price
) {
299.
$rate
= Mage::getModel(
'shipping/rate_result_method'
);
300.
$rate
->setCarrier(
'ups'
);
301.
$rate
->setCarrierTitle(
$this
->getConfigData(
'title'
));
302.
$rate
->setMethod(
$method
);
303.
$method_arr
=
$this
->getCode(
'method'
,
$method
);
304.
$rate
->setMethodTitle(Mage::helper(
'usa'
)->__(
$method_arr
));
305.
$rate
->setCost(0);
306.
$rate
->setPrice(0);
307.
$result
->append(
$rate
);
308.
}
309.
}
else
{
310.
foreach
(
$priceArr
as
$method
=>
$price
) {
311.
$rate
= Mage::getModel(
'shipping/rate_result_method'
);
312.
$rate
->setCarrier(
'ups'
);
313.
$rate
->setCarrierTitle(
$this
->getConfigData(
'title'
));
314.
$rate
->setMethod(
$method
);
315.
$method_arr
=
$this
->getCode(
'method'
,
$method
);
316.
$rate
->setMethodTitle(Mage::helper(
'usa'
)->__(
$method_arr
));
317.
$rate
->setCost(
$costArr
[
$method
]);
318.
$rate
->setPrice(
$price
);
319.
$result
->append(
$rate
);
320.
}
321.
}
322.
//echo "<!--".print_r($result,1)."-->";
323.
return
$result
;
324.
}
325.
326.
//And so on..... I have truncated the rest of the file as no further changes are made. Don't delete the code here yourself.
What does this result in?
- Requesting a quote from the Cart page shows cost of zero for all shipping methods
- When checking out, users still must select a shipping method. They are all at zero cost, but users will still be able to check items such as 1-day shipping (And/or whatever methods you have enabled). Is this optimal? Probably not, however this issue is, unfortunately, outside of the scope of this article at this time.
- It appears that Magento will still calculate shopping carts with mixed products (productswith and without weights) correctly. You should test this to make sure customers aren't getting over or under charged.
Hope this helps someone!
No comments:
Post a Comment