I was successfully getting the all the cart details(i.e total items, items in the cart, etc).
But i want only specific attributes from cart.
suppose i want to get store_id attribute, how can i achieve.
public function info($quoteId, $store = null)
{
$quote = $this->_getQuote($quoteId, $store);
$result_attr = $this->_getAttributes($quote, 'quote');
//this is giving error
$result_attr->getAttributeText('store_id');
}
if you are getting object in your $quote
you can get with below code
if($quote )
$store = $quote->getStoreId();
hope this will sure help you.
Related
I need to change the productname visible for the customer after adding it to the cart. Also it should show on invoice, order email and everything else visible for the customer.
I made an extension with observer checkout_cart_product_add_after
$item = $observer->getEvent()->getData('quote_item');
$item = ( $item->getParentItem() ? $item->getParentItem() : $item );
$item->getProduct()->setName('this is the productname');
$item->getProduct()->setIsSuperMode(true);
But the original productname is still visible on minicart, cartpage, etc.
The 'add to cart message' is the only place where the new changed productname is visible. What should I change?
use this event "sales_quote_item_set_product"
and in observer set name like this:
/* For minicart and cart */
$item->getProduct()->setName('Custom Name');
/* For checkout page cart items */
$item->setName('Custom Name');
$item->getProduct()->setIsSuperMode(true);
Found the solutions myself.
Hope this helps anyone searching for it, or if you have comments how it could be done a better way, please let me know.
Created a plugin with this code:
class Item
{
public function afterSetProduct(
\Magento\Quote\Model\Quote\Item $subject,
$result
){
$subject->setName('New Name');
}
}
So this sets a new name to the quote item, visible in everything, excepting cart and mini cart.
Now I have got my new productname visible in:
- Added to cart message
- Quote-item, even in admin and invoices
But not in:
- Mini cart
- Cartpage
For the cart page:
I changed output of function getProduct in Magento\Checkout\Block\Cart\Item\Renderer:
class Renderer
{
public function afterGetProductName(
\Magento\Checkout\Block\Cart\Item\Renderer $subject,
$result
){
return 'this is the name';
}
}
For minicart, also with plugin:
class DefaultItem
{
public function aroundGetItemData(
\Magento\Checkout\CustomerData\AbstractItem $subject,
\Closure $proceed,
\Magento\Quote\Model\Quote\Item $item
){
$data = $proceed($item);
$data['product_name'] = 'this is the productname';
return $data;
}
I am trying to display brand specific product. brand is one of my attribute which is mandatory and attached by each product.
I created different store under one website for each brand and also created different URL for each brand. so, i want to display product brand wise for each brand store.
So, which of the easiest way to filter product by attribute i.e brand.
I am using Magento 2.1.2, MySQL 6, PHP 7.0
Use the following code to Filter a Product Collection By Store ID:
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$productCollectionFactory = $objectManager->get('\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
$collection = $productCollectionFactory->create();
$collection->addAttributeToSelect('*')
$collection->addStoreFilter($storeid)
$collection->addAttributeToFilter('attribute_code');
use this code to filter the product collection by store id and attribute code
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
protected $collectionFactory
public function __construct(CollectionFactory $collectionFactory)
{
$this->collectionFactory =$collectionFactory;
}
public function productCollection($storeId ,$attributeCode)
{
$collection = $collectionFactory->create();
$collection->addAttributeToSelect('*')
$collection->addStoreFilter($storeId)
$collection->addAttributeToFilter($attributeCode);
return $collection;
}
use Magento\Framework\Data\OptionSourceInterface;
class Productlist implements OptionSourceInterface{
/**
* Get products
*
* #return array
*/
public function toOptionArray(){
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$store=$objectManager->create('\Magento\Store\Model\StoreRepository');
$productCollectionFactory =$objectManager->create('\Magento\Catalog\Model\Product')->getCollection();
$storeId='3';
$productCollectionFactory->addAttributeToSelect('name');
$rootCategoryId = $store->getById($storeId)->getRootCategoryId();
$productCollectionFactory->addAttributeToSelect('*');
$productCollectionFactory->addCategoriesFilter(array('eq' => $rootCategoryId));
$options = [];
foreach ($productCollectionFactory as $product) {
$options[] = ['label' => $product->getName(), 'value' => $product->getId()];
}
return $options;
}
I have created a new product type in Magento. However, I am having difficulty adding all of its associated products to the sales_flat_quote_item table. I only want the associated products added to the table and only the main parent product visible in the cart.
I am real close to achieving this. Right now only the parent item is visible in the cart when adding it to the cart. However, only one of it's associated products are being listed in the above mentioned table.
Here is a snippet of my code:
class Namespace_Module_Model_Product_Type_Custom extends Mage_Catalog_Model_Product_Type_Abstract {
........
protected function _prepareProduct(Varien_Object $buyRequest, $product, $processMode)
{
$qty = $buyRequest['qty'];
$associatedQty = $buyRequest['associated_qty'];
if($qty >= 1) {
$result = parent::_prepareProduct($buyRequest, $product, $processMode);
if (is_array($result)) {
$product = $this->getProduct($product);
foreach($buyRequest['associated'] as $associated){
if($associated){
$subProducts[] = Mage::getModel('catalog/product')->load($associated);
}
}
foreach($subProducts as $subProduct){
if($subProduct){
$product->setCartQty($qty);
$product->addCustomOption('product_qty_'.$subProduct->getId(), $associatedQty[$subProduct->getId()], $subProduct);
$product->addCustomOption('associated_product_' . $subProduct->getId(), $associatedQty[$subProduct->getId()]);
}
}
$_result = $subProduct->getTypeInstance(true)->_prepareProduct(
$buyRequest,
$subProduct,
$processMode
);
if (!isset($_result[0])) {
return Mage::helper('checkout')->__('Cannot add the item to shopping cart');
}
$_result[0]->setParentProductId($product->getId())
->addCustomOption('parent_product_id', $product->getId());
$result[] = $_result[0];
return $result;
} else {
return $this->getSpecifyOptionMessage();
}
} else {
return $this->getQtyMessage();
}
}
........
}
Right now only the associated product '53' is being added as a child product. I am still missing the other two. Basically, the foreach($subProducts as $subProduct) loop will loop 3 three times with the three associated products. I am assuming somewhere along the lines in Magento it is only using the last looped product.
Any advice or help with this would be great. Thanks in advance!
Got it figured out. I just had to shift the following into the foreach loop instead of outside of it.
$_result[0]->setParentProductId($product->getId())
->addCustomOption('parent_product_id', $product->getId());
$result[] = $_result[0];
I have developed a custom module to meet my project requirements using Alan Storms tutorial for creating modules in magento.
I had the requirement of changing the price attribute dynamically on frontend based on a livefeed. Everysecond the feed is updated so every time the page refreshes a new price must be displayed for each product on the site.
I have override the product module and the price modules for this purpose. The issue is with tier pricing. When tier pricing comes into place I need to calculate the tier-price based on the live price.
For this also I managed to change using the price_type class override.
Now whenever an item is added to cart the tier-pricing was not working for that I wrote event_trigger ie an Observer which updates the tier_pricing on the event "checkout_cart_save_before" and here's my code
class My_Custom_Model_Observer extends Varien_Event_Observer
{
public function __construct()
{
}
public function updateCartBasedOnLiveFeed($observer)
{
foreach ($observer->getCart()->getQuote()->getAllVisibleItems() as $item /* #var $item Mage_Sales_Model_Quote_Item */)
{
$tierPrices = array();
$tierPrices = $item->getProduct()->getTierPrice();
$itemPrice = $item->getProduct()->getPrice();
$i=0;
foreach($tierPrices as $key => $tierPrice)
{
if(!is_numeric($key))
{
$updatedTierPrice = $itemPrice - ($itemPrice * ($tierPrice['price']/100));
$tierPrices[$key]['price'] = $updatedTierPrice;
$tierPrices[$key]['website_price'] = $updatedTierPrice;
}
else
{
if($tierPrice['price'] > 0)
{
$updatedTierPrice = $itemPrice - ($itemPrice * ($tierPrice['price']/100));
$tierPrice['price'] = $updatedTierPrice;
$tierPrice['website_price'] = $updatedTierPrice;
$tierPrices[$i] = $tierPrice;
$i++;
}
}
}
$item->getProduct()->setData('tier_price',$tierPrices);
}
}
}
The above code works excellently in cart page. But when it comes to checkout page. It works for a single item and when tier-pricing comes into play it does apply cart prices.
Please help me with this.
I also tried using other events along with the above event.
Event: sales_quote_save_before
public function updateQuoteLive($observer)
{
$tierPrices = array();
$quote_item = $observer->getEvent()->getQuote;
$itemPrice = $quote_item->getProduct()->getPrice();
$tierPrices = $quote_item->getProduct()->getTierPrice();
$tierPricesSize = sizeof($tierPrices);
for($i=0;$i<$tierPricesSize;$i++)
{
$updatedTierPrice = $itemPrice - ($itemPrice * ($tierPrices[$i]['price']/100));
$tierPrices[$i]['price'] = $updatedTierPrice;
$tierPrices[$i]['website_price'] = $updatedTierPrice;
}
$quote_item->getProduct()->setData('tier_price',$tierPrices);
}
When I tried to print the getQuote() function available in Quote.php I find that the tier prices there are not the ones which I updated using the first event. So I think I need to update the price before saving the quote. Please any one help me and show the correct direction.
Please help me with this I am missing some important step. Any help is greatly appreciated.
Thanks in advance.
It might be better off "saving" the new price in to the database when you update.
Try something along the lines of:
$product = $observer->getProduct();
$procuct->setPrice($updatedPrice);
This way when it comes to checkout it will be pulling in the correct price from the database (and avoids the headache of correcting it "mid-flight"
i realized such a project like you. I have no sales_quote_save_before Observer. I only use the checkout_cart_save_before. Based on the session the price will be setted.
I realized that like this way:
public function updatePrice( $observer )
{
try {
$cart = $observer->getCart();
$items = $cart->getItems();
foreach($items as $item)
{
$item->setCustomPrice($price);
$item->setOriginalCustomPrice($price);
}
} catch ( Exception $e )
{
Mage::log( "checkout_cart_save_before: " . $e->getMessage() );
}
}
I calcute the tierprices on the fly and with this Observer. All prices will be set up correct in the qoute.
Maybe you should try this way.
Regards boti
At last figured out the issue and got the solution.
The problem was that in cart page or checkout page when the getTierPrice() function is called, which is present in /app/code/core/Mage/Catalog/Product.php. It takes one parameter named $qty which is by default null. This function in turn calls the function getTierPrice which is present in /app/code/core/Mage/Type/Price.php file which takes two parameters $qty and $productObject. By default $qty is null and when it is null the function returns an array of tier_prices. But when the $qty value is passed then the function returns a single for that particular quantity.
So, I wrote my own custom function which calculates the tier prices based no my requirements like
I overridden both the core files with my custom module following Alan Storm's tutorials.
I've extended Mage_Catalog_Model_Product with My_CustomModule_Model_Product class and
then
Mage_Catalog_Model_Product_Type_Price with My_CustomModule_Model_Price
And then in /app/code/local/My/Custommodule/Model/Product.php
I added my custom code like
public function getTierPrice($qty=null)
{
if($qty)
{
return $this->getPriceModel()->getCustomTierPrice($qty, $this);
}
return $this->getPriceModel()->getTierPrice($qty, $this);
}
Then in /app/code/local/My/Custommodule/Model/Price.php
<?php
public function getCustomTierPrice($qty = null, $product)
{
$allGroups = Mage_Customer_Model_Group::CUST_GROUP_ALL;
$prices = $product->getData('tier_price');
if (is_null($prices)) {
$attribute = $product->getResource()->getAttribute('tier_price');
if ($attribute) {
$attribute->getBackend()->afterLoad($product);
$prices = $product->getData('tier_price');
}
}
foreach($prices as $key => $customPrices)
{
if($prices[$key]['price'] < 1)
{
$prices[$key]['price'] = abs($product->getPrice() - ($productPrice * ($customPrices['price']/100)));
$prices[$key]['website_price'] = $prices[$key]['price'];
}
}
}
which retured a customized value when $qty is passed and voila it worked.
I just posed this answer so that any one else who has similar requirement may get benefited with this.
?>
I'm working on an observer that needs to add (a) serial key(s) to each item in the cart once an order is placed.
I'm listening to the event sales_model_service_quote_submit_success right now.
I've been able to access the order, get a list of the items, iterate through them, and get the product options. My code fails either when I try to setProductOptions or save--I'm not sure which, maybe it's both.
Here is the relevant code:
// Get access to order information
$lastOrderId = Mage::getSingleton('checkout/session')->getLastOrderId();
$order = Mage::getModel('sales/order')->load($lastOrderId);
// Get the items from the order
$items = $order->getAllItems();
foreach ($items as $item)
{
// Pretend here is the call that fetches the serial keys for this item and stores them in $keyString
// If we actually received the keys in a string, store them with the item
if (!empty($keyString))
{
$productOptions = array();
if (count($item->getProductOptions()))
{
$productOptions = $item->getProductOptions();
}
$productOptions['keys'] = $keyString;
$item->setProductOptions($productOptions);
$item->save();
}
}
Any ideas what I have forgotten or done wrong? Thanks a bunch.
no such observer , at least i didn't find it from codebase, here's what you can use
Mage::dispatchEvent('sales_model_service_quote_submit_before', array('order'=>$order, 'quote'=>$quote));
Mage::dispatchEvent('sales_model_service_quote_submit_after', array('order'=>$order, 'quote'=>$quote));
and in your observer method
/**
*
* #param Varien_Event_Observer $observer
*
*/
public function setShippingDefaults(Varien_Event_Observer $observer) {
$order = $observer->getEvent()->getOrder();
}
the idea is that if you do it in before-action then you won't need to call save and if you do it in after-action then you do and if you do it in before action you might just end in endless loop if you are not careful.