unable to set discount amount programatically - magento

I am trying to create order programatically. Which is happening perfectly fine. I just don't know how to set discount amount programmatically. which is going to be different for different orders.

You can add a custom price to a product when you add it into the quote using this:
$custom_price = 100; //Products new price for the specific order/customer.
$qty = 1;
$product_id = 210;
$product = Mage::getModel('catalog/product')->load($product_id);
$quoteItem = $quote->addProduct($product, $qty);
$quoteItem->setCustomPrice($custom_price);
$quoteItem->setOriginalCustomPrice($custom_price);
$quoteItem->getProduct()->setIsSuperMode(true);
$quote->save();

Related

Magento Multiple Wishlist creation programmatically

I know how to add products to a customer's wishlist programmatically however it only adds to one wishlist. I have the multiple wishlist option set to enabled however I do not know how to create a new wishlist instead of merging products into the existing wishlist.
public function submitQuote(Mage_Adminhtml_Model_Session_Quote $quote)
{
$currentQuote = $quote->getQuote();
$customer = $currentQuote->getCustomer();
$items = $currentQuote->getAllVisibleItems();
//$wishlist = Mage::helper('wishlist')->getWishlist();
//Mage::register('wishlist', $wishlist);
$wishlist = Mage::getModel('wishlist/wishlist');
$curretDate = date('m/d/Y', time());
$wishlist->setCustomerId($customer->getId());
$wishlist->setName('Quote ' . $curretDate)
->setVisibility(false)
->generateSharingCode()
->save();
foreach ($items as $item)
{
$productId = $item->getProductId();
$product = Mage::getModel('catalog/product')->load($productId);
$buyRequest = $item->getBuyRequest();
$result = $wishlist->addNewItem($product, $buyRequest);
if(is_string($result))
{
Mage::throwException($result);
}
$wishlist->save();
}
//Mage::unregister('wishlist');
}
I've had this problem before. To add a product to a customer's wishlist you need to start a wishlist model and call the addNewItem method passing the product object. Here is how I do it.
$customer = Mage::getModel('customer/customer');
$wishlist = Mage::getModel('wishlist/wishlist');
$product = Mage::getModel('catalog/product');
$customer_id = 1;
$product_id = 1;
$customer->load($customer_id);
$wishlist->loadByCustomer($customer_id);
$wishlist->addNewItem($product->load($product_id));
Hope this helps!
EDITED:
$customerid= "YOUR CUSTOMER ID "; // Modify This
$customer=Mage::getModel("customer/customer")->load($customerid);
$wishlist=Mage::getModel("wishlist/wishlist")->loadByCustomer($customer,true);
Check for reference this: app/code/core/Mage/Wishlist/Model/Wishlist.php
LATEST EDIT:
I see that your problem is here:
$result = $wishlist->addNewItem($product, $buyRequest);
FINAL EDIT:
Then create another function and add the items and wishlist you want to add it to (as parameters). This should add items to the wishlist that you have passed as an argument when calling the function. Its the only solution I can come up with. Hope this helps!
I just stumbled across this question because I'm trying to do something similar - your code part helped me to create a new wishlist, and I've managed to do the rest so thought I'd share.
This code will;
Create a new wishlist with the name 'Quote dd/mm/YY h:m:s'
Load the wishlist collection for the current user, ordered by highest ID first
Load the newest wishlist
Add all basket items to it
Redirect the user to the new wishlist view.
public function addToQuoteAction() {
if(Mage::getSingleton('customer/session')->isLoggedIn()) {
$customerData = Mage::getSingleton('customer/session')->getCustomer();
$customerId = $customerData->getId();
} else {
Mage::getSingleton('core/session')->addError($this->__('Please login to use this feature'));
return $this->_redirectUrl($this->_getRefererUrl());
}
// Create the wishlist
$newWishlist = Mage::getModel('wishlist/wishlist');
$curretDate = date('d/m/Y h:m:s', time());
$newWishlist->setCustomerId($customerId);
$newWishlist->setName('Quote ' . $curretDate)
->setVisibility(false)
->generateSharingCode()
->save();
// Find the newly create list and load it
$wishlistCollection = Mage::getModel('wishlist/wishlist')->getCollection()
->addFieldToFilter('customer_id',$customerId)->setOrder('wishlist_id');;
$firstWish = $wishlistCollection->getFirstItem();
$wishlist = Mage::getModel('wishlist/wishlist')->load($firstWish->getWishlistId());
$cart = Mage::getModel('checkout/cart')->getQuote();
//getAllItems
foreach ($cart->getAllVisibleItems() as $item) {
$productId = $item->getProductId();
$buyRequest = $item->getBuyRequest();
$result = $wishlist->addNewItem($productId, $buyRequest);
$wishlist->save();
}
Mage::getSingleton('core/session')->addSuccess($this->__('All items have been moved to your quote'));
return $this->_redirectUrl(Mage::getBaseUrl().'wishlist/index/index/wishlist_id/'.$firstWish->getWishlistId().'/');
}

Loop: getPriceHtml() gives the same price for all products

there's a loop I'm using in a .phtml file, that looks like this:
$model = Mage::getModel('catalog/product');
$result = array();
$cnt = 0;
foreach ($result_skus as $index => $num) {
$result[$cnt] = $index;
$cnt ++;
}
for($cnt = 0; $cnt<count($result); $cnt++){
//load product data
$_product = $model->load($result[$cnt]);
//display product name
echo 'product name = '.$this->htmlEscape($_product->getName());
echo '<br>';
//display product price
echo 'product price = '.$this->getPriceHtml($_product, true, '-bestseller')
}
$_product->getName() gives the correct product name
but
getPriceHtml() gives the price of the first product that was accessed in the loop.
As a result, all products are displayed with the same price...
Is there something that I could do to refresh the product data? Why is price not changing for each product?
What is $this? Mage_Catalog_Block_Product_List? Why are you passing in the idSuffix = '-bestseller'? I think you should just call $this->getPriceHtml($_product, true);
**EDIT
So now I am thinking two things:
a) following your comment above, I think you want to get a new model instance each time. So inside the loop either replace $model with Mage::getModel('catalog/product'); or redeclare
$model = Mage::getModel('catalog/product');
at the start of the loop.
OR
b) following your comment below and taking a fresh look at this, I think you might need to get the price before generating the price HTML, so try adding the line:
$dummyPrice = $model->getPrice();
before echo 'product price = '.$this->getPriceHtml($_product, true). And actually this might be the thing: because you are using the same instance $model and loading the new product on top of the old product I think $model is holding the first '$_product->getPrice()' price calculation and then not recalculating it because the function is:
public function getPrice()
{
if ($this->_calculatePrice || !$this->getData('price')) {
return $this->getPriceModel()->getPrice($this);
} else {
return $this->getData('price');
}
}
If you don't do a) above, I think you need to force a price recalculation after each $model->load(); so in that scenario your loop would be
//load product data over the top of the previous loaded product
$_product = $model->load($result[$cnt]);
//force price recalculation
$_product->getPriceModel()->getPrice($_product);
//now ask for the price as HTML
echo 'product price = '.$this->getPriceHtml($_product, true);
But I think it is better to use Mage::getModel('catalog/product'); on each loop because we don't know what else Magento is or isn't clearing or overwriting.
This raises some interesting questions: Where are all the model instances going? Into memory? Maybe. I dug around a bit and found an interesting article by Drew Gillson about the function
Mage_Core_Model_Abstract::clearInstance();
So now I am learning things too and I think you want a loop like this:
for($cnt = 0; $cnt<count($result); $cnt++){
//load product data
$_product = $model->load($result[$cnt]);
//display product name
echo 'product name = '.$this->htmlEscape($_product->getName());
echo '<br>';
//display product price
echo 'product price = '.$this->getPriceHtml($_product, true);
//clear the $model for next time round (I reckon this will clear the calculated price too)
$model->clearInstance();
}
After all that, if it still isn't working out I recommend some more debugging. If you are getting the correct product name then that is encouraging.
Inside your product loop also echo out:
$_product->getId();
$_product->getSku();
$_product->getData('price');
$_product->getPrice('');
$_product->getPriceModel()->getPrice($_product);
$_product->getPriceModel()->getBasePrice($_product);
$_product->getPriceModel()->getFinalPrice($_product);
$_product->getData('price');
$_product->getFormatedPrice('');
This should help confirm that you are loading the correct product info and expose what is available and hopefully shed some light on why you are not getting the price you expect. Many other price functions exist for tier prices and special prices and minimum prices.
If it still isn't doing what you want take a long look at your Magento settings and complete a re-index and cache-flush.
You could also pick an SKU that you know the price of and pass that through your code to see if it returns the expected price.
The issue is that getPriceHtml() function is defined in the Mage_Catalog_Block_Product block, rather than the standard Mage_Core_Block_Template.
So you have to first instantiate the Product block class which contains the method in your custom script.
$product_block = new Mage_Catalog_Block_Product;
$product_block->getPriceHtml($product,true);
so in your case just use this script
$model = Mage::getModel('catalog/product');
$result = array();
$cnt = 0;
foreach ($result_skus as $index => $num) {
$result[$cnt] = $index;
$cnt ++;
}
for($cnt = 0; $cnt<count($result); $cnt++){
//load product data
$_product = $model->load($result[$cnt]);
//display product name
echo 'product name = '.$this->htmlEscape($_product->getName());
echo '<br>';
$product_block = new Mage_Catalog_Block_Product;
//instantiate the Product block class which contains the method
//display product price
echo 'product price = '. $product_block->getPriceHtml($_product,true);
}
Let me know if you have any problem

Magento: Can I load a cart by quoteId?

I need to load a cart by a quoteId, cause I want to add a product to a different cart than the current cart. Is this possible?
TIA!
$cartId = 99;
$cart = Mage::getModel('sales/quote')->load($cartId);
$productId = 55;
$product = Mage::getModel('catalog/product')->load($productId());
$cart->addProduct($product);

Get Random SKU Product Number

I have the following code:
$sku = $id;
$_product=Mage::getModel('catalog/product')->loadByAttribute('sku',$sku); //Get Product by ID (ASIN)
$qtyStock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty(); //if in stock
$_prodcats = $_product->getCategoryIds();
It works by specfing the SKU id, I want to be able to get random SKU product number and use it so
$sku = random product number from database
I used the following script to generate a random sku from the collection. You can use it to suit your requirement also.
//Geting a random sku from collection
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->getSelect()->order(new Zend_Db_Expr('RAND()'));
$randomSku = $collection->setPage(1, 1)->getFirstItem()->getSKU();
In your case your code should look like.......
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->getSelect()->order(new Zend_Db_Expr('RAND()'));
$_product = $collection->setPage(1, 1)->getFirstItem()->load();
$qtyStock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_product)->getQty(); //if in stock
$_prodcats = $_product->getCategoryIds();
Something like that should work fine ;)
$collection = Mage::getResourceModel(‘catalog/product_collection’);
Mage::getModel(‘catalog/layer’)->prepareProductCollection($collection);
$collection->getSelect()->order(‘rand()’);
$collection->addStoreFilter();
$collection->setPage(1, 1);
$_product = $collection->getFirstItem();
Below code I used in project and its working fine for me :
<?php
// get Random prdocut list
$collection = Mage::getResourceModel(‘catalog/product_collection’);
Mage::getModel(‘catalog/layer’)->prepareProductCollection($collection);
$collection->getSelect()->order(‘rand()’);
$collection->addStoreFilter();
$numProducts = $this->getNumProducts() ? $this->getNumProducts() : 2;
$collection->setPage(1, $numProducts);
foreach($collection as $product){
echo $product->getName();
}
?>

Magento: Increase "Qty" upon cancel a shipped order

I'm on Magento 1.7.0.2. I'm using "Cash On Delivery" as my payment method.I'll tell you exactly the steps That i follow on any order. When an order is placed(Qty decreased 1 item), I create a shipment for it and if customer paid the order grand total price. I create an invoice for that order.
My problem, If an order is placed(Qty decreased 1 item), I create a shipment for this order. If the customer refused to pay, I open this order and "Cancel" it and on this case the "Qty" doesn't increase so How can I make it increase?
If order status is Processing
Create a custom module with observer for 'order_cancel_before' (see example # Change Magento default status for duplicated products change <catalog_model_product_duplicate> to <order_cancel_before>
since <order_cancel_before> is not defined in app/code/core/Mage/Sales/Model/Order.php
You could override/rewrite order model class see e.g http://phprelated.myworks.ro/how-to-override-rewrite-model-class-in-magento/
In your local module do
public function cancel()
{
if ($this->canCancel()) {
Mage::dispatchEvent('order_cancel_before', array('order' => $this));
$this->getPayment()->cancel();
$this->registerCancellation();
Mage::dispatchEvent('order_cancel_after', array('order' => $this));
}
return $this;
}
Or you could create a new method increaseProductQty() in your model and copy the code below into it (this way you would not need an observer). Then replace the line Mage::dispatchEvent('order_cancel_before'... with $this->increaseProductQty()
In your observer method (pseudo code)
$curr_date = date('Y-m-d H:i:s');
$order = $observer->getEvent()->getOrder();
foreach ($order->getItemsCollection() as $item)
{
$productId = $item->getProductId();
$qty = $item->getQty();
// you need to check order status to make sure it processing
//$order->getStatus() (assuming you are canceling entire order)
//$order->getPayment();
$product = Mage::getModel('catalog/product')->load($product_id);
$stock_obj = Mage::getModel('cataloginventory/stock_item')->load($product_id);
$stockData = $stock_obj->getData();
$product_qty_before = (int)$stock_obj->getQty();
$product_qty_after = (int)($product_qty_before + $qty);
$stockData['qty'] = $product_qty_after;
$productInfoData = $product->getData();
$productInfoData['updated_at'] = $curr_date;
$product->setData($productInfoData);
$product->setStockData($stockData);
$product->save();
}
If you have issue with updating stock see Set default product values when adding new product in Magento 1.7
Reference http://pragneshkaria.com/programatically-change-products-quantity-after-order-cancelled-magento/
If order status is Pending
Take a look at System > Configuration > Inventory
Set Items’ Status to be In Stock When Order is Cancelled — Controls whether products in pending orders automatically return to the stock if orders are cancelled. Scope: STORE VIEW.
Read more #
How to Manage Magento Store Inventory?
ADMIN: System → Configuration → Inventory Tab
Thanks to R.S as he helped me more & more.
I followed all instructions on R.S's reply https://stackoverflow.com/a/13330543/1794834 and I've only changed the observer code. Here is the observer code that worked with me on Magento 1.7.0.2.
$curr_date = date('Y-m-d H:i:s');
$order = $observer->getEvent()->getOrder();
foreach ($order->getItemsCollection() as $item)
{
$productId = $item->getProductId();
$qty = (int)$item->getQtyOrdered();
$product = Mage::getModel('catalog/product')->load($productId);
$stock_obj = Mage::getModel('cataloginventory/stock_item')->loadByProduct($productId);
$stockData = $stock_obj->getData();
$product_qty_before = (int)$stock_obj->getQty();
$product_qty_after = (int)($product_qty_before + $qty);
$stockData['qty'] = $product_qty_after;
/*
* it may be case that admin has enabled product add in stock, after product sold,
* he set is_in_stock = 0 and if order cancelled then we need to update only qty not is_in_stock status.
* make a note of it
*/
if($product_qty_after != 0) {
$stockData['is_in_stock'] = 1;
}else{
$stockData['is_in_stock'] = 0;
}
$productInfoData = $product->getData();
$productInfoData['updated_at'] = $curr_date;
$product->setData($productInfoData);
$product->setStockData($stockData);
$product->save();
}

Resources