I'm using an observer to override the checkout_cart_product_add_after in order to update a unit price of a product. The price comes from a third party system and it tailored for each customer. I can set the price as follows:
$item = $observer->getQuoteItem();
if ($item->getParentItem()) {
$item = $item->getParentItem();
}
$specialPrice = $this->get_price($item->getsku(), $item->getQty());
$item->setCustomPrice($specialPrice);
$item->setOriginalCustomPrice($specialPrice);
$item->getProduct()->setIsSuperMode(true);
The product prices can technically be as many as 6 decimal places. I'm using the ET_Currency manager to set the display to 4 decimal places as that's the maximum it seems to allow. On small quantities it's not a problem but on large quantities it can be 30p - 40p out.
Can anyone advise how I can get this to 6 decimal places so the subtotals are more accurate?
Related
I have applied shopping cart rules in my magento store successfully, but in cart when total is calculated it shows directly total discount.
It doesn't show individual discount price applied to which product.
How to show individual discount to let customer know that on which product I got discount?
To get the individual discount amount for each product while checkout, you can do as below :
$quote = Mage::getSingleton('checkout/session')->getQuote();
foreach ($quote->getAllItems() as $item){
$discount = $item->getDiscountAmount();
// $discount is the discount amount for the individual item
}
I've tried every combination of conditions and actions available but can't seem to crack this. Should be simple. Any help would be much appreciated.
I have 5 SKU's. Lets call them A,B,C,D,E. All of them are the same price (8.99). For every 5 you buy - you get one free. This rule spans any combination of these SKU's. Examples that should match:
If 6 A's are in the cart, one is free (8.99 discount).
If 2 A's, 2 B's and 2 C's are in the cart, one is free (8.99 discount).
If 12 A's are in the cart, two are free (17.98 discount).
If 6 C's, 6 D's and 6 E's are in the cart, three are free (26.97 discount).
Here's what I believe should accomplish this but doesn't even come close:
Conditions:
Actions:
This extension did it for me:
http://blog.goods-pro.com/1733/magento-extension-buy-x-selection-of-products-get-another-y-selection-for-free/
I would prefer to use event - observer approach for this, that will give you maximum flexibility.
You can build an observer that catches the add-to-cart event sales_quote_add_item and put your logic there.
Following code within your observer function will point you in the right direction:
// Added product:
$item = $observer->getEvent()->getQuoteItem();
$itemQty = $item->getQty();
$itemSku = $item->getSku();
// Change price of added product
$item->setOriginalCustomPrice($newPrice);
// Get all products in cart:
$quote = Mage::getSingleton('checkout/session')->getQuote();
$cartItems = $quote->getAllVisibleItems();
foreach ($cartItems as $item) {
$itemSku = $item->getSku();
$itemQty = $item->getQty();
}
Good luck!
I have added new rule in Magneto for buying x product and getting y free . I have added a configurable product with multiple simple products . This rule works fine if I buy two of simple products with same sku values. What I want is that if user buys two simple products with different sku they should get second free .
How can i achieve this ?
This cannot be done with the default implementation of cart rules. You need to create new module and add your own type of rule to the list. I have made once such a module, in the following manner:
1) I add my own option to action dropdown. Luckily there is an event adminhtml_block_salesrule_actions_prepareform where you can hook. I used something like this
$form = $observer->getEvent()->getForm();
$options = $form->getElement('simple_action')->getValues();
$options[] = array(
'value' => self::BUY_ANY_X_GET_Y_ACTION,
'label' => Mage::helper('mymodule')->__('Extended Buy X get Y free (search all cart, discount amount is Y)'),
);
$form->getElement('simple_action')->setValues($options);
2) Then I hook into salesrule_validator_process where I checked whether cart items match the rule.
This was a little bit tricky as this validator is run for each cart item so you have to count how many times it was called and which items you have checked. I used conditions tab to prepare rules that says which X items have to be bought in order to get Y items according to conditions in actions tab.
With the first run of the validator you iterate over all cart collection and divides all products in two groups: one contains items that met criteria set by conditions tab, the second one met the criteria set by actions tab. In other words you form two arrays that contains items for X and items for Y.
foreach($quote->getItemsCollection() as $item) {
if (!$item->hasParentItemId()) {
if ($rule->getActions()->validate($item)) {
$ruleItems['y'][] = $item;
}
foreach($rule->getConditions()->getConditions() as $condition) {
foreach($condition->getConditions() as $check) {
if ($check->validate($item)) {
$ruleItems['x'][] = $item;
}
}
}
}
}
You calculate how many X's are there and how many Y's products will get discount. The when the event is called for each item you check if the item is in Y array and if there is enough discounts left for that item. If so you need to set discount amount and base discount amount calculated as item_qty * price and item_qty * base_price respectively. You need to set those values on result object that is in data passed to the observer method like:
$item = $observer->getEvent()->getItem();
$result = $observer->getEvent()->getResult();
$result->setDiscountAmount($item->getQty * $item->getPrice());
$result->setBaseDiscountAmount($item->getQty * $item->getBasePrice());
I’m making a call to $item->calcRowTotal() on a Mage_Sales_Model_Quote_Item object.
This works great to reset the row total and base row total, but it does not affect the row total including tax (row_total_incl_tax) attribute on the item.
I assume I have to manually do this after I have the new row total but I can’t figure out how to properly calculate the tax and populate the row_total_incl_tax attribute on the item.
Any suggestions would be much appreciated.
Get the tax rate and recalculate row_total_incl_tax. Here's how you can get tax rate.
Assuming your order no. is 101.
$sale = Mage::getModel('sales/sale)->load(101)
$taxModel = Mage::getModel('sales/order_tax')
->load($sale->getId(), 'order_id');
$taxRate = $taxModel->getPercent()
I think you know how to calculate the tax amount based on row total value.
Edit:
Get tax based on product:
$product = Mage::getModel('catalog/product')->load($item-getProductId());
$request = Mage::getSingleton('tax/calculation')
->getRateRequest()
->setProductClassId($product->getTaxClassId());
$taxRate = Mage::getSingleton('tax/calculation')
->getRate($request);
So you know the tax rate, row_total_incl_tax is sum of tax * qty + total amount (or you can calculate anyway you want). May be you need to check if item price is included tax or not, you can do this by Mage::getModel('Tax/Config')->priceIncludesTax()
How can I set the shipping cost for Magento for all baskets that are below a certain point. For example, all baskets under £5 have fixed shipping of £1.99.
I think this is what you are looking for, unless I have the wrong thing. It seems to be called Table Rate Shipping.
the only way i've managed to get it working is to add an extra case statement in my shipping module.
$result = Mage::getModel('shipping/rate_result');
...
} else if ($request->getPackageValue() < 6) {
$price = '1.99';
...