Magento : How do I set the set the cart price? - php

I am a newbie to Magento Community Edition.
It might be a little thing but don’t know how to do that.
I want to set the cart price to cartprice * 5?
Example - if the cart items weight is greater then 10kg then set cartprice to (10 * 5).

You can do this by event observer.
<checkout_cart_product_update_after>
<observers>
<update_price_edit_save_product>
<class>ABC_MModule_Model_Observer</class>
<method>cartUpdatePrice</method>
</update_price_save_product>
</observers>
</checkout_cart_product_update_after>
in Observer class define this function, and do the implementation accordinly to set the price by item.
public function cartUpdatePrice(Varien_Event_Observer $obs){
// Get the quote item
$item = $obs->getQuoteItem();
// Ensure we have the parent item, if it has one
$item = ( $item->getParentItem() ? $item->getParentItem() : $item );
//hidden filed from detail page
$item->setCustomPrice($new_price);
$item->setOriginalCustomPrice($new_price);
$item->getProduct()->setIsSuperMode(true);
}

You can make your own module using event observers to accomplish this. First define a store config value for weight and how many times it should be increased i.e. 10kgs and 5 times in your requirement.
Using event checkout_cart_product_update_after you can call your observer function and include below code in that function
$items = Mage::getSingleton('checkout/session')->getQuote()->getAllItems();
$weight = 0;
foreach($items as $item) {
$weight += ($item->getWeight() * $item->getQty()) ;
}
if($weight > Mage::getStoreConfig('weight'))){
$weight = $weight * Mage::getStoreConfig('number of times you want to increase)
}
return $weight;

Related

Exclude several shipping classes from a fee based on cart items dimensions in Woocommerce

I've been getting great help here during the year, regarding a woocommerce issue where I needed an automatic fee added based on total cart height in this thread and then later updated with width in this thread.
Now my only issue is that I need to exclude some shipping classes from the function, as they are shipped differently and don't need a Bulky fee added.
I've been playing around with the answer to "Add a fee based on cart items dimensions in Woocommerce", trying to add a class variable to it:
// Initializing variables
$total_height = 0;
$class = 1390,1392,1389;
$apply_fee = false;
But it instantly breaks the website. I've been searching on stackoverflow.com and Google for a way to do this but no luck, and I'm still not qualified enough for that type of advanced editing of code.
Appreciate any help I can get.
You can't have a list of ids like that with just commas between them. To fix this put the ids in an array. Within the foreach loop, check the shipping class id of the product, and if it's in the array exclude it.
$exclClasses = array(1390,1392,1389);
// Checking item with
if ( $cart_item['data']->get_width() > $width_threshold ) {
$apply_fee = true;
}
// make sure product isn't in excluded shipping classes
if (in_array( $cart_item['data']->get_shipping_class_id(), $exclClasses))
{
$apply_fee = false;
}
or to use 1 statement instead of 2
if ( $cart_item['data']->get_width() > $width_threshold && !in_array( $cart_item['data']->get_shipping_class_id(), $exclClasses)) {
$apply_fee = true;
}

Magento custom price value not converting by changing currency

Following code is used to set custom price for simple product. Custom price set in cart as needed but when i switch currency then custom price value remains same with current currency symbol.
$item->setCustomPrice($customPrice);
$item->setOriginalCustomPrice($customPrice);
$item->getProduct()->setIsSuperMode(true);
Is there any way to set custom price that work with currency switching.
I found a solution to do this.
First Step:
Add item to quote with custom price using following code suggested by #Ashish Raj
$baseCurrencyCode = Mage::app()->getStore()->getBaseCurrencyCode();
$currentCurrencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
$price = $customPrice;
$customPrice = $Current_currency_price = Mage::helper('directory')->currencyConvert($price, $baseCurrencyCode, $currentCurrencyCode);
$item->setCustomPrice($customPrice);
$item->setOriginalCustomPrice($customPrice);
$item->getProduct()->setIsSuperMode(true);
Second Step:
Second step is to create an controller post dispatch observer by adding following code in config.xml file of module
<events>
<controller_action_postdispatch>
<observers>
<frontend_currency_change>
<class>modulename/observer</class>
<method>hookToControllerActionPostDispatch</method>
</frontend_currency_change>
</observers>
</controller_action_postdispatch>
</events>
And add following code to observer class
public function hookToControllerActionPostDispatch($observer) {
if ($observer->getEvent()->getControllerAction()->getFullActionName() == 'directory_currency_switch') {
$quote = Mage::getSingleton('checkout/session')->getQuote();
if ($quote && $quote->hasItems()) {
foreach ($quote->getAllVisibleItems() as $item):
//add condition for target item
$customPrice = 23;//use custom price logic
$baseCurrencyCode = Mage::app()->getStore()->getBaseCurrencyCode();
$currentCurrencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
$customPrice = Mage::helper('directory')->currencyConvert($customPrice, $baseCurrencyCode, $currentCurrencyCode);
$item->setCustomPrice($customPrice);
$item->setOriginalCustomPrice($customPrice);
$item->getProduct()->setIsSuperMode(true);
$quote->collectTotals()->save();
endforeach;
}
}
}
This is working for me. Hope this will help to someone having same issue.
I will prefer if somebody have better solution.
Thanks.
Use below code hope it will help you ...
First Step:
//you need to find base currency code and then find current currency code...
$baseCurrencyCode = Mage::app()->getStore()->getBaseCurrencyCode();
$currentCurrencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
$price = $customPrice;
Second Step:
//convert price from base currency to current currency
$customPrice = $Current_currency_price = Mage::helper('directory')->currencyConvert($price, $baseCurrencyCode, $currentCurrencyCode);
3rd Step:
then you can use your code:
$item->setCustomPrice($customPrice);
$item->setOriginalCustomPrice($customPrice);
$item->getProduct()->setIsSuperMode(true);

Magento - How to convert simple products to grouped ones programmat​ically?

My client and I are trying to achieve something that we are maybe not supposed to do. We have a demanding set of non-standard products that include different types of product conditions, e.g. grade B ware etc. In addition product data is coming in in form of feeds from several suppliers. In order not to clutter up the product listing we would like to convert existing, manually edited simple products into grouped ones (or whatever is appropriate) with associated new simple products programmatically on the fly and vice versa whenever necessary, i.e. when there are at least two different sub products.
So far we managed to do this somehow, a test scenario produces the seemingly right product structure – correctly associated products are displayed in the backend, the quantities have been correct before. The problem occurs with the frontend check on 'isSaleable()' for both the grouped product and the associated products, it returns 'false' no matter what we do. When we enforce the display of the qty input boxes and add-to-cart button they will (naturally?) just product the error message 'Please specify the quantity of product(s)'. We tried to set 'is_salable' by different means throughout the code. What else is missing? Any little hint, any advice here would be appreciated!
The code is quite lengthy already, and probably there's already some redundancy in there because of our attempts to somehow fix this. There's a main script that fetches a product collection and compares each entry with the existing supplier feeds. The essential part then is the function call to convert the product:
if (sizeof($newProducts[$productsSku]) > 1 && $_product->getTypeId() == 'simple') {
$newProductQtys = createGroupedProduct($_product, $newProducts[$productsSku]);
}
There are 2 functions for the actual conversion process, one which creates duplicates of the master products (type = simple) and sets their values accordingly:
function createDuplicate($product, $values) {
global $suppliers, $conditions_arr;
$sku = $product->getSku();
$newSku = $sku.'-v'.$suppliers[$values['feed']]['id'];
$qty = $values['qty'];
$feed = $values['feed'];
$cost = $values['cost'];
$item_condition = $values['item_condition'];
$box_condition = $values['box_condition'];
$notes = stripslashes($values['notes']);
$newProduct = $product->duplicate();
$newProduct->setTypeId('simple');
$newProduct->setStoreId(0);
$newProduct->setWebsiteIds(array(1));
$newProduct->setVisibility(2);
$newProduct->setSku($newSku);
$newProduct->setData('media_gallery', array());
$newProduct->setStatus(Mage_Catalog_Model_Product_​Status::smileyfrustrated:TATUS_ENABLED);
$newProduct->setPrice((real)($cost + $cost*$suppliers[$feed]['price_increase']));
$newProduct->setTaxClassId(2);
$newProduct->getResource()->save($newProduct);
$productId = $newProduct->getId();
// Check if there is a stock item object
$stockItem = Mage::getModel('cataloginventory/stock_item')->loa​dByProduct($productId);
$stockItemData = $stockItem->getData();
if (empty($stockItemData)) {
// Create the initial stock item object
$stockItem->setData('inventory_manage_stock_defaul​t', 1);
$stockItem->setData('manage_stock',1);
$stockItem->setData('is_in_stock', $qty ? 1 : 0);
$stockItem->setData('is_salable', 1);
$stockItem->setData('use_config_manage_stock', 1);
$stockItem->setData('stock_id',1);
$stockItem->setData('product_id',$productId);
$stockItem->setData('qty',$qty);
$stockItem->setTypeId( $newProduct->getTypeId() );
$stockItem->save();
// Init the object again after it has been saved so we get the full object
$stockItem = Mage::getModel('cataloginventory/stock_item')->loa​dByProduct($productId);
}
// Set the quantity
$stockItem->setData('qty',$qty);
$stockItem->setData('is_salable', 1);
$stockItem->save();
// $newProduct->assignProduct($newProduct, 1, 1);
$newProduct->setIsSalable(1);
$newProduct->setStatus(Mage_Catalog_Model_Product_​Status::smileyfrustrated:TATUS_ENABLED);
$newProduct->save();
$event = Mage::getSingleton('index/indexer')->logEvent($new​Product,$newProduct->getResource()->getType(),Mage​_Index_Model_Event::TYPE_SAVE,false);
Mage::getSingleton('index/indexer')->getProcessByC​ode('cataloginventory_stock')->setMode(Mage_Index_​Model_Process::MODE_REAL_TIME)->processEvent($even​t);
return $productId;
}
and
function createGroupedProduct($product, $newProductsArr) {
global $suppliers;
$origProductId = $product->getId();
$sku = $product->getSku();
$newProductId = array();
$newProductQtys = array();
$qty = 0;
$price = 999999;
$product->setTypeId('grouped');
$product->save();
foreach($newProductsArr as $key => $values) {
$id = createDuplicate($product, $values);
$newProductId[] = $id;
$newProductQtys[$id] = $values['qty'];
// add up all stock quantities of all slave products for master
$qty += $values['qty'];
// determine lowest price among all slave products
$subItemPrice = (real)($values['cost'] + $values['cost']*$suppliers[$values['feed']]['price​_increase']);
if ($subItemPrice < $price) $price = $subItemPrice;
}
if (sizeof($newProductId) > 1) {
$products_links = Mage::getModel('catalog/product_link_api');
foreach($newProductId as $key => $id) {
$products_links->assign('grouped', $origProductId, $id);
}
}
// set new values for grouped product according to slave products values
$product->setPrice($price);
$product->getResource()->save($product);
// Check if there is a stock item object
$stockItem = Mage::getModel('cataloginventory/stock_item')->loa​dByProduct($origProductId);
$stockItemData = $stockItem->getData();
if (empty($stockItemData)) {
// Create the initial stock item object
$stockItem->setData('manage_stock',1);
$stockItem->setData('is_in_stock', $qty ? 1 : 0);
$stockItem->setData('is_salable', 1);
$stockItem->setData('use_config_manage_stock', 1);
$stockItem->setData('stock_id',1);
$stockItem->setData('product_id',$origProductId);
$stockItem->setData('qty',$qty);
// $stockItem->setTypeId( $product->getTypeId() );
$stockItem->setTypeId('grouped');
$stockItem->save();
// Init the object again after it has been saved so we get the full object
$stockItem = Mage::getModel('cataloginventory/stock_item')->loa​dByProduct($origProductId);
}
// Set the quantity
$stockItem->setData('qty',$qty);
$stockItem->setData('is_in_stock', $qty ? 1 : 0);
$stockItem->setData('is_salable', 1);
$stockItem->save();
$product->setStatus(Mage_Catalog_Model_Product_Sta​tus::smileyfrustrated:TATUS_ENABLED);
$product->save();
$event = Mage::getSingleton('index/indexer')->logEvent($pro​duct,$product->getResource()->getType(),Mage_Index​_Model_Event::TYPE_SAVE,false);
Mage::getSingleton('index/indexer')->getProcessByC​ode('cataloginventory_stock')->setMode(Mage_Index_​Model_Process::MODE_REAL_TIME)->processEvent($even​t);
$cache = Mage::getSingleton('core/cache');
$cache->flush();
return $newProductQtys;
}
We tried using the store ID '1' as well and had some success with the shopping cart when the front end used the same kind of mass-product-add-to-cart form that we integrated into the product listing. But the associated products then showed no product name and no image, and not in the admin at all.
If more code from the main script is necessary I will happily provide this.

Magento getFinalPrice no working with customer group discounts

I have the following simple code with a loop of products:
$_product->setCustomerGroupId(6);
$price = $_product->getFinalPrice();
I have a customer group (id of 6) that has a 50% discount applied to it.
The $price variable is always the full price. How can I get the discounted price?
This is in an API script I am writing, so there is no customer/session object. I can create one if required but would prefer to try and steer clear of creating temp sessions.
Check This:
<?php
$now = Mage::getSingleton('core/date')->timestamp(time());
$websiteId = 1;
$customerGroup = 4;
$productId = 9369;
$rules = Mage::getResourceModel('catalogrule/rule');
$rules->getRulePrice($now, $websiteId, $customerGroup, $productId));
?>

Magento - get price rules from order

does anyone know how one can get the catalog- and cart price rules from an order?
I know that I can get the discount percentage from an order item via the method getDiscountPercent(), but how can I get all the rules that were applied to the whole order?
For example, I have a rule "Customer Group X gets 20% off all items in the store".
Now I want to determine which rules were actually applied when the order has been submitted by the user. I need this for an order export interface where I have to supply all discounts that the user got.
Thanks in advance!
Have a look in the sales_flat_order_item table. there is a field called applied_rule_ids which will give you the id of the rule applied to that item. Also you can find out in this table how much discount was applied and the percentage.
Example
//The order I want to check
$order_id = 859;
//Get the list of items for your order
$items = Mage::getModel('sales/order_item')
->getCollection()
->addFilter('order_id',array('eq'=>$order_id));
//loop through each item
foreach($items as $item){
//if the item has not had a rule applied to it skip it
if($item->getAppliedRuleIds() == '')continue;
/*
* I cant remember in the database they might be comma separated or space if multiple rules were applied
* the getAppliedRuleIds() function is the one you want
*/
foreach(explode(",",$item->getAppliedRuleIds()) as $ruleID){
//Load the rule object
$rule = Mage::getModel('catalogrule/rule')->load($ruleID);
// Throw out some information like the rule name what product it was applied to
echo "<p>".$item->getSku()." had rule ".$rule->getName()."(".$item->getAppliedRuleIds().") applied </p>";
}
}
/* Example of getting catalog rules applied for specific product */
$productId = 6;
$user = Mage::getSingleton('customer/session')->getCustomer();
$product = Mage::getModel('catalog/product')->load($productId);
$storeId = $product->getStoreId();
$websiteId = Mage::app()->getStore($storeId)->getWebsiteId();
$dateTs = Mage::app()->getLocale()->storeTimeStamp($storeId);
$customerGroupId = $user->getGroupId();
$resource = Mage::getResourceModel('catalogrule/rule');
$rules = $resource->getRulesFromProduct($dateTs, $websiteId, $customerGroupId, $productId);
Yeah, it's kind of a pain that Magento doesn't leave any history around in the order record when you use sale pricing with regard to how that base price was calculated.
Fortunately it's open source, so you can patch this in if you like.
I recently wrote an observer that fires when the order record is loaded, to address this very issue. It cross-references the line base_price with the product's current full-retail price. If there is a mismatch, it adds a couple fields to the order item to help expose this info to any external script that's listening (in our case, a custom order fulfillment script that relays orders to SAP using Magento's SOAP API).
Here's the basic idea - make a module in app/code/local/YourCo/SalePricing
and set up an observer class in app/code/local/YourCo/SalePricing/Model/Promo/Observer.php
<?php
class YourCo_SalePricing_Model_Promo_Observer
{
public function __construct()
{
}
// tag order items that have a sale-price
// with original retail price and total sale discount for this line
public function report_sale_pricing($observer)
{
$event = $observer->getEvent();
$order = $event->getOrder();
$items = $order->getAllItems();
foreach ($items as $item) {
// heads up, you may want to do this for other types as well...
if ($item->getProductType() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE) {
$regular_price = $this->_lookupFullRetail($item,$order->getStoreId());
$sale_price = $item->getBasePrice();
if ($regular_price - $sale_price > 0.005) {
$qty = $item->getQtyOrdered();
$total_sale_discount = ($regular_price * $qty) - ($sale_price * $qty);
$item->setFullRetailPrice((string)$regular_price);
$item->setSaleDiscount((string)$total_sale_discount);
}
}
}
}
private function _lookupFullRetail(&$item,$store_id)
{
$mpid = $item->getProductId();
$p = Mage::getModel('catalog/product')->setStoreId($store_id)->load($mpid);
return $p->getPrice();
}
}
Your module's etc/config.xml needs to tell magento when to run your observer:
<?xml version="1.0"?>
<config>
<global>
<models>
<yourco_salepricing>
<class>YourCo_SalePricing_Model</class>
</yourco_salepricing>
</models>
<events>
<sales_order_load_after>
<observers>
<yourco_salepricing>
<type>singleton</type>
<class>YourCo_SalePricing_Model_Promo_Observer</class>
<method>report_sale_pricing</method>
</yourco_salepricing>
</observers>
</sales_order_load_after>
</events>
</global>
</config>
Make sure to activate your new module in app/etc/modules/... and clear the config cache.
Now, when you load the order, you can loop over each item and check for $item->getFullRetailPrice() -- if it's there, you know the item was on sale (well, either that or the price has gone up since the order was placed). You still don't know why, ie which sale price rule was in force, but for our application we didn't really care, and getting that info to be saved with the order would have been a much tougher mod.
What might help you though:
$order = Mage::getModel('sales/order')->load(20569);
echo Mage::helper('sales')->__('Discount (%s)', $order->getDiscountDescription());
This prints out all the discount rules name which have been applied to the order.

Categories