Magento Free Shipping for Match Items Only - Using Table Rates Based on Order Total - magento

Can I achieve the following with Magento:
I'm using a table rate system of price vs destination. And I've got a shopping cart price rule of Free Shipping for products with the attribute free_shipping -> to set yes.
This works fine if you have normal products in the basket OR free shipping products in the basket. However if you have both a normal product AND a free shipping product in the basket. It calculates the shipping based on the order total including the product with free shipping.
How can I correct this, so the shipping is applied only to the order total of products not including free shipping, when both type of products exist in the basket?
Is there a Magento Plugin for this?

I had the same problem and implemented a small code change to make it work.
Basically forget the promotion rule. Disable it. It doesn't seem to work properly with the shipping rates table when applying free shipping to individual items. The shipping rules seem to take precedence and calculate based on cart total.
The trick is to subtract the free shipping items from the cart total at the point the Shipping Rates module is making the calculation.
In my case everything inside a particular category (id:15) was to get free shippping. But you can amend the logic to suit your needs.
You will need to amend the following file (or copy it to your local codebase to do things properly).
app\code\core\Mage\Shipping\Model\Carrier\Tablerate.php
CHANGE THIS:
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
if (!$this->getConfigFlag('active')) {
return false;
}
// exclude Virtual products price from Package value if pre-configured
if (!$this->getConfigFlag('include_virtual_price') && $request->getAllItems()) {
foreach ($request->getAllItems() as $item) {
if ($item->getParentItem()) {
continue;
}
if ($item->getHasChildren() && $item->isShipSeparately()) {
foreach ($item->getChildren() as $child) {
if ($child->getProduct()->isVirtual()) {
$request->setPackageValue($request->getPackageValue() - $child->getBaseRowTotal());
}
}
} elseif ($item->getProduct()->isVirtual()) {
$request->setPackageValue($request->getPackageValue() - $item->getBaseRowTotal());
}
}
}
TO THIS:
public function collectRates(Mage_Shipping_Model_Rate_Request $request)
{
if (!$this->getConfigFlag('active')) {
return false;
}
// exclude Virtual products price from Package value if pre-configured
//And Exclude items which should have Free Shipping
if (!$this->getConfigFlag('include_virtual_price') && $request->getAllItems()) {
$freeshipping_category_id = 15;
foreach ($request->getAllItems() as $item) {
if ($item->getParentItem()) {
continue;
}
if ($item->getHasChildren() && $item->isShipSeparately()) {
foreach ($item->getChildren() as $child) {
if ($child->getProduct()->isVirtual()) {
$request->setPackageValue($request->getPackageValue() - $child->getBaseRowTotal());
}
//If it's in the free shipping, remove it's value from the basket
$arr_category_ids = $child->getProduct()->getCategoryIds();
if ( in_array($freeshipping_category_id, $arr_category_ids) ) {
$request->setPackageValue($request->getPackageValue() - $child->getBaseRowTotal());
}
}
} elseif ($item->getProduct()->isVirtual()) {
$request->setPackageValue($request->getPackageValue() - $item->getBaseRowTotal());
}
//If it's in the free shipping category, remove it's value from the basket
$arr_category_ids = $item->getProduct()->getCategoryIds();
if ( in_array($freeshipping_category_id, $arr_category_ids) ) {
$request->setPackageValue($request->getPackageValue() - $item->getBaseRowTotal());
}
}
}

In your sales rule set the Free Shipping to 'FOR MATCHING ITEMS ONLY'.

If I understood your question correctly, the solution is really easy and quick, here is how I've solved it:
In the file: Validator.php (/app/code/core/Mage/SalesRule/Model/)
search for the string "case Mage_SalesRule_Model_Rule::FREE_SHIPPING_ITEM:" and just before the "break;" add this simple thing "$item->setWeight(0);"
This will force the weight of the item to be 0 so no shipping price will be calculated on it, and if you disable the free shipping option for hat item, the weight is considered and everything works fine.

I know that this question has been answered and accepted, but I would like to offer a way to do this without programming, or changing core files if at all possible
If you want to create your item as a "Virtual" item, you can exclude virtual items from shipping fees
If item is created already
Go to your database with a program like phpMyAdmin and navigate to catalog_product_entity, find your product SKU and change type_id to virtual
If item is not created
Create item as Virtual Product during the first step of product creation (instead of Simple Product or Bundled Product, etc.)
To exclude Virtual Products from shipping fees
Navigate to System > Configuration > Shipping Methods and under the Table Rates header set Include Virtual Products in Price Calculation to No
Please note, this will only work for, and is only necessary for, the Table Rates shipping method
UPS, USPS, FedEx and DHL determine by weight, so since Virtual Product types have a product weight of 0 it will not affect shipping costs for these methods

Related

How to filter zero-prices products in listing page

I have used the sorting by ->setOrder('price','desc');
but in this case its not working well when we sort the products by name
Is there any way to sort by price (from lower to bigger) in such way, that products with zero price will bein the end of the list???
public function setCollection($collection)
{
$this->_collection = $collection;
$this->_collection->setCurPage($this->getCurrentPage());
// we need to set pagination only if passed value integer and more that 0
$limit = (int)$this->getLimit();
if ($limit) {
$this->_collection->setPageSize($limit);
}
if ($this->getCurrentOrder()) {
$this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection())
->setOrder('price','desc');
}
return $this;
}
The question not very clear, yet from what I understand:
(Price Sorting) This feature is provided by default in Magento in Product Listing Pages.
Maybe you have changed the price attribute # backend.
Check for price attribute.
Used in Product Listing = Yes
Used for Sorting in Product Listing = Yes
Clear Cache, and you should be ready to go.

Magento - Get Product SKU's and quantities on order

I have created an event observer on the "sales_order_place_after" event, which fires when the user places an order in Magento's checkout. That event triggers my observer, which needs to get the following information, which is then sent to an external inventory management system.
Information needed: The SKU and quantity of every product on the order
I have included part of my observer model below. I am accessing the order object. I can get all the items in the order, but how do I get the SKU for every product that makes up the order. For example, with a simple product, this is very easy. However, with a bundled or configurable product I do not know how to access the children that make up that bundled product with their SKU's and quantities. That is the info I need for both bundled and configurable products. I need the SKU and quantities of the children that were selected. For the life of me, I can't figure out what method to call to access that information. I wish there was something like: $item->getBundleChildrenSkuQuantity();
$order = $observer->getEvent()->getOrder();
$joomecomPacket = array();
if ($order->getTotalItemCount() > 0) {
$items = $order->getAllItems();
foreach ($items as $item) {
$productType = $item->getProductType();
switch ($productType) {
case 'bundle':
break;
case 'configurable':
default: // simple products
if (isset($joomecomPacket[$item['sku']])) {
$joomecomPacket[$item['sku']] += $item['qty_ordered'];
} else {
$joomecomPacket[$item['sku']] = $item['qty_ordered'];
}
break;
}
}
}
You're missing a break after your configurable case. The default case is executing for configurable products.
Try this:
$items = $order->getAllVisibleItems(); // gives only parent items
foreach ($items as $item){
$childItem = $item->getChildren(); //do something with $cildItem like $childItem->getSku() etc...
}

Magento : Get all Shipping Rates

How can I get an array/object with the shipping rates in magento such as Flat Rate, Free Delivery etc ?
Irrelevant of the address or products selected.
Here's another way. You need to set a zip and country - even if that doesn't matter for your shipping methods.
// Change to your postcode / country.
$zipcode = '2000';
$country = 'AU';
// Update the cart's quote.
$cart = Mage::getSingleton('checkout/cart');
$address = $cart->getQuote()->getShippingAddress();
$address->setCountryId($country)
->setPostcode($zipcode)
->setCollectShippingrates(true);
$cart->save();
// Find if our shipping has been included.
$rates = $address->collectShippingRates()
->getGroupedAllShippingRates();
foreach ($rates as $carrier) {
foreach ($carrier as $rate) {
print_r($rate->getData());
}
}
you can't do it "irrelevant" as you need address data (billing or shipping if only billing then shipping set same as billing: country, zip, region dependant of your shipping methods) to be set and quote to have at least one simple item (quote existing, virtual and downloadable products don't need shipping). After that you can call on your quote object
$quote->getShippingAddress()->getGroupedAllShippingRates();
I figured it out...
$carriers = Mage::getStoreConfig('carriers', Mage::app()->getStore()->getId());
foreach ($carriers as $carrierCode => $carrierConfig) {
print_R($carrierConfig);
}
Thanks for the help

Magento Shipping Module: Get all items currently in cart

I'm in the middle of developing a shipping module for Magento but get stuck on How to get the items that's currently in the cart for that session.
I follow some tutorial on the internet, they use:
if ($request->getAllItems()) {
foreach ($request->getAllItems() as $item) {
//do something here.....
}
}
My problem is that I don't know exactly what info/data that's on the $item variable??.
I want to get the weight and the price of the product that's currently on the cart to calculate the shipping fee. I tried to print the $item value by using Mage::log or printing it to the screen using print_r or var_dump but it's not successful. The log is empty and the variable won't be printed on screen.
Can somebody inform me of how to get the $item attributes/method or is there any other way to get the product information that's currently in cart?
you can achive this by using one of three methods which are available in Mage::getSingleton('checkout/session')->getQuote();
getItemsCollection() - retrive sales/quote_items collection
getAllItems() - retrive all items
getAllVisibleItems() - retrive items which aren't deleted and have parent_item_id != null
I was searching for this solution and found below. but not tested.
$CartSession = Mage::getSingleton('checkout/session');
foreach($CartSession->getQuote()->getAllItems() as $item)
{
$productWeight = $item->getWeight();
$productExPrice = $item->getPrice(); // price excluding tax
$productIncPrice = $item->getPriceInclTax(); // price excluding tax
}
If you want to know information about $item, you can do this:
print_r($item->getData());
If you want to get item weight, here is it:
$item->getWeight();

Magento: showing prices ex/inc TAX/VAT depending on customer group

Previously I have implemented a 'trade only' store front that shows both in and ex-VAT prices for trade customers. They still get billed the VAT, it is just the catalog shows ex-VAT prices as well as the regular inc VAT prices.
I would like to be able to implement the same functionality without creating a new store front, i.e. if someone is in the 'trade' customer group, they get prices shown inc and ex vat. They are still on the same tax rate as everyone else, so I am not looking to have a 0% tax group, what I want is just to be able to switch the prices based on their group. This also includes the labels, so there isn't just a price but a clear indication of inc/ex VAT/TAX.
It took me a while to Google this with 'tax' instead of 'VAT', however, to date I haven't found many clues as to where to start. If there is a reason why this cannot be done easily then I would like to know. Failing that, if there is a frontend hack to try, e.g. some conditional prototype to un-css-hide the prices/labels then that will have to be the route to go.
EDIT
Inspired by Clockworkgeek I did this, not yet the perfect module solution, but something that works for me for now:
Cloned core file to app/code/local/Mage/Tax/Model/Config.php and updated the getPriceDisplayType function:
public function getPriceDisplayType($store = null)
{ $customer = Mage::helper('customer')->getCustomer();
if ($customer->getGroupId() > 1) {
return self::DISPLAY_TYPE_BOTH;
} else {
return (int)Mage::getStoreConfig(self::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE, $store);
}
}
This relies on 0 being not logged in, 1 being normal customers and any 'special' group higher than that. I did not think it was working at first, but then I logged in...
There is a config setting for whether to include or exclude tax but it is not customer-specific. I believe the most direct way would be to override the point where this is read. The following is pseudocode...
class Your_Module_Model_Config extends Mage_Tax_Model_Config
{
public function getPriceDisplayType($store = null)
{
$customer = Mage::helper('customer')->getCustomer();
if ($customer->getGroupId() == 'TRADE') {
return self::DISPLAY_TYPE_BOTH;
}
return parent::getPriceDisplayType($store);
}
}
You can try this to show prices without tax only for specified customer groups:
http://www.magentocommerce.com/magento-connect/catalog/product/view/id/18364/

Resources