Magento Event Observer Change Cart Base Subtotal - magento

I've been trying to get this right for the past couple of days. I've read so many posts I am sure I am close (or at least close at some point) but I just can't seem to get this. I am using the even observer checkout_cart_save_after Here is what I am doing inside of the checkout_cart_save_after
$session = Mage::getSingleton('checkout/session');
$quote = Mage::getSingleton('checkout/session')->getQuote();
$quote->setBaseSubtotal(0);
$quote->save();
All I am trying to do is get the Subtotal to equal 0 ... From what I read I want to set the "BaseSubtotal" because of currency differences. Eventually what I will do with this once I can get it working is dynamically change the price so it's not always going to be 0. But baby steps here lol I just want to try and change the price to specific value first.

You forgot to do
$quote->setSubtotal(0); // needs to be there ;)
$quote->setBaseSubtotal(0);
An object and a Base objects are two different things and both need to be set.

Related

Magento - Get attribute options value and quantity

Hello and good day to all the members of this great community. I'm still new in PHP and especially in Magento.
I'm not posting, waiting for answers, and leaving without replying back. This is a learning process. I hope to get a great support from all of you.
I have a product. I did create custom option for the product, that is an attribute named "a_size". The attribute has value of S, M and L. Each of the value has quantity.
In the single product view, I would like to call all the available size. That is the size (S, M, or L) that has quantity more than 0. I just want to show the available size, not how much the size left.
Can anybody guide me? I'm using Magento 1.7.x and as far for this 2 weeks, I did try pretty many of suggested answers from the community thru the search function.
The replies will be much appreciated. Thank you.
There are a few things to try.
Firstly check that when you set up your new attribute in the Magento Admin (Catalog->Attributes->Manage Attribute) that in the Frontend Properties box you have set Visible on Product View Page on Front-end to yes.
To get size values I use this code:
$cabac_sizeAttribute = $_product->getAttributeText("a_size");
but I have other code for getting attribute values that goes like this:
$_product_helper = Mage::helper('catalog/output');
$temp = $_product_helper->productAttribute($_product, $_product->getASize(), 'a_size');
I think it is related to the type of attribute: text, dropdown, multiselect etc so try both and see how you get on. But really the function productAttribute() is just applying formatting. You can read the function in the file app/core/Mage/Catalog/Helper/Output.php
Also, I wonder, if you have set up a configurable product and you are on the product view page then you will be viewing the configurable product. That product won't have an a_size value: you are trying to access the a_size attribute of the simple products that make up the configurable product, yes? Everything I wrote above is (I think) correct but to get the attribute of the simple products that are part of a configured product you should study the code in the function getJsonConfig() of the file app/core/Mage/Catalog/Block/Product/View/Type/Configurable.php
And in particular to these lines:
//file: file app/core/Mage/Catalog/Block/Product/View/Type/Configurable.php
//class: Mage_Catalog_Block_Product_View_Type_Configurable
//function: getJsonConfig()
foreach ($this->getAllowProducts() as $product) {
$productId = $product->getId();
foreach ($this->getAllowAttributes() as $attribute) {
$productAttribute = $attribute->getProductAttribute();
$productAttributeId = $productAttribute->getId();
$attributeValue = $product->getData($productAttribute->getAttributeCode());
Being careful about variable naming: $product is local here, I suggest changing it, and about $this - but if you are in a .phtml of the product view for configurables then I think your $this is already Mage_Catalog_Block_Product_View_Type_Configurable
Welcome to Magento coding. You are doing well; it is a long but rewarding path. (hints: local.xml is your vital friend and so is Alan Storm if you haven't come across his content yet.)
[Additionally, (welcome to Magento) I think you are trying to say eg S and L are out of stock and M is in stock but actually the function getAllowProducts() will disallow a product with zero stock and exclude it from the returned object. You will need to use
$allProducts = $this->getProduct()->getTypeInstance(true)
->getUsedProducts(null, $this->getProduct());
(taken from function getAllowProducts() in file app/core/Mage/Catalog/Block/Product/View/Type/Configurable.php)
and then, if needed, check that each product is allowed to be shown eg status=ENABLED, and then check its stock level...
]
Malachy.
If you want to get the values of your drop down attribute use the following code
$_product->getASize();
and initially load the product object

Magento - Credit Memo "Return to Stock" not updating Stock Availability

So when you do a credit memo in Magento, it sets the stock back to the correct level but does not change the "out of stock" back to "in stock" (if applicable). I came across this post by Wright Creatives (http://wrightcreativelabs.com/blog/55-credit-memo-in-stock.html) and it solves this problem. However, the method is too slow! It takes about 30 seconds per product.
I've ultimately had to remove this as a solution (because of the "speed") and now my boss would like the functionality reimplemented.
I know that the is_in_stock data controls this & I'm wondering if there is already a module out there, an article/tutorial, or someone who can help me get started on a "better/faster" solution.
I know it's old but because this isn't yet fixed not even in 1.7.0.1 I came up with a better solution.
Tested on 1.5.1 and above:
\app\code\core\Mage\CatalogInventory\Model\Observer.php
in
public function refundOrderInventory($observer)
after
Mage::getSingleton('cataloginventory/stock')->revertProductsSale($items);
//add this
foreach ($creditmemo->getAllItems() as $item) {
$productId = $item->getProductId();
$product = Mage::getModel('catalog/product')->load($productId);
if(!$product->isConfigurable()){
$stockItem = $product->getStockItem();
//$stockItem->setQty($item->getQty());
$stockItem->setIsInStock(1);
$stockItem->save();
$product->setStockItem($stockItem);
$product->save();
}
}
Write a module that observes the event for credit memos and sets the in_stock flag on the products stock item object before product save. I cant tell you the event you want to observe but I am positive you can find it :)
If there is none, the uglier way would be to observe the products before save. More logic to pull it off but if you always want products to be in stock if they have qty regardless of anything else, then its not a bad idea.
Stores >> Config >> Inventory >> scroll to bottom
Go to System -> Configuration -> Inventory (under Catalog) -> Product Stock Options -> Automatically Return Credit Memo Item to Stock and make sure it's set to Yes.
Or simply go to your database and in core_config_data where the path is 'cataloginventory/item_options/auto_return' make sure that the value column is set to '1';

Magento: increment_id empty after first order

I need the increment id from an order to create a folder on my server for moving some order specific files there, after a customer has successfully ordered something. This is what I've got so far:
$chkoutSess = Mage::getSingleton('checkout/session');
$lastOrderId = $chkoutSess->getLastOrderId();
$order = Mage::getModel('sales/order');
$order->load($lastOrderId);
$incid = $order->getData("increment_id");
I guess this can be done much easier but it works for me. The problem I have with this is that the $order is totally empty when I order something "the first time". After this it always works. So I think I can only get this data out of a session object when there's an actual session...this of course is senseless because there should always be a "lastOrderId" when a customer orders something. Is there any other way to simply get the last order and it's incremented out of the database? I tried several things but the objects where always empty..
The function I use is executed right after the user successfully hits the order submit button (event observer "sales_order_place_after"). Anyone can help me with this?
Try $chkoutSess->getRealOrderId(); and not $chkoutSess->getLastOrderId();

Magento - tracking who to give back to

We have a Magento multi-site that give a percentage back to a non-profit, and what we would like to do is to allow customers to select which non-profit or a group within that non-profit to receive the percentage.
Trying to keep it simple we thought allowing customers to enter a discount code named something like "GIVE BACK to {non-profit name}" (but no actual dollar amount subtracted from the purchase or maybe just a penny, I don't think you can have a 0 to a discount code), then internally we know to give the percentage back to that non-profit.
It just seems a little bit of an odd way of doing this, it would be better to have a drop down of the none-profits at the end, but we are not sure how to create that.
Does anyone have any suggestions, on an easy way of doing this?
Thanks in advance!
You could add an attribute to the quote/order model and then populate that with an appropriate value, populated at the cart level? It's the kind of think we've done for affiliate modules we've built in the past.
You'll need a custom controller to grab the value when the customer moves from the cart to the checkout, which means you'll also need to make the Cart -> Checkout step a form submission instead of a straight link.
Then, at the end of the month, you'll need to run a report on the collection with something along the lines of:
// I've added a * in the SELECT because I'm not sure of the attribute names off the top of my head :)
$collection = Mage::getModel('sales/order')->getCollection()
->addAttributeToSelect('*')
// Make sure the orders are in the correct date range
->addAttributeToFilter(...)
// Make sure the orders are in a valid state, e.g. processing, pending, complete, etc..
->addAttributeToFilter(...)
$donation_total = array();
foreach ($collection as $order) {
// You'll have to investigate the attribute values for these
$charity = $order->getData('charity_attribute_code');
$order_total = $order->getData('order_total_attribute_code');
if (!isset($donation_total[$charity])) {
$donation_total[$charity] = 0;
}
$donation_total[$charity] += $order_total;
}
print_r($donation_total);
You could make this more efficient with proper SUM()ing in the query.

How do I get the shipping method the user has chosen during checkout?

I want to get the name of the shipping method the user has chosen during checkout. Does anyone know how to retrieve that info?
This will get it to some extent but it is cached:
Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getShippingDescription();
When I am on the onestep checkout and I go back to the shipping tab and change the shipping, it is still holding the old shipping method. I need to figure out how to get the current one.
Foreword
Constructed from Magento app/code/core/Mage/Checkout/Block/Onepage/Shipping/Method/Available.php and others:
app/design/frontend/base/default/template/checkout/onepage/shipping_method/available.phtml uses this code to determine which shipping method was selected:
$this->getAddressShippingMethod()
app/code/core/Mage/Checkout/Block/Onepage/Shipping/Method/Available.php expands that code to this:
return $this->getAddress()->getShippingMethod();
Let's research a bit and expand it even deeper:
$this->getQuote()->getShippingAddress()->getShippingMethod();
Parent block expands method getQuote():
return $this->getCheckout()->getQuote();
And deeper:
public function getChechout() {
return Mage::getSingleton('checkout/session');
}
Merging all that code gives us this:
Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getShippingMethod()
That gives you the shipping method code. Giving that, you could manipulate it just as you wish. This data is stored within the database, so when you change shipping method, the code changes too.
Getting deeper and deeper!
If you've ever created your own shipping method, you'd know, that it has the method called collectRates().
It fills a set of shipping/rate_result_method models, stores it within the instance of shipping/rate_result model and returns it (you can get each model' instance using Mage::getModel(<model i've named>); ).
Yet, note: one could contain multiple rate_result_method instances, while the shipping method code is the same for all those instances!
Thus, in order to get the description, you need to get one of the rate_result_method instances and retrieve its methodTitle or carrierTitle.
After a small researching i've found how to retrieve all these rates:
Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getShippingRatesCollection()
This will provide you with a collection of all rates for the selected shipping method. You can operate it with getItems() and get a hash. Or you could use getFirstItem() and use it as the template.
Anyway, let's assume u've retrieved some item of that collection and stored it within the $rate variable:
$rate->getCarrier(); // This will provide you with the carrier code
$rate->getCarrierTitle(); // This will give you the carrier title
$rate->getCode(); // This will give you **current shipping method** code
$rate->getMethod(); // This will provide you with the **shipping method** code
$rate->getMethodTitle(); // This will tell you current shipping method title
$rate->getMethodDescription(); // And this is the description of the current shipping method and **it could be NULL**
That's all, folks!
I am really sorry for my poor English and for my strange mind flow. Hope this will help you or someone else. Thanks!
Just in case you need it still. You can get shipping method from order by:
$order->getShippingMethod();
Of course how you get your $order depends on context.
Also you can get description by:
$order->getShippingDescription();
shipping method in magento
$methods = Mage::getSingleton('shipping/config')->getActiveCarriers();
$options = array();
foreach($methods as $_code => $_method)
{
if(!$_title = Mage::getStoreConfig("carriers/$_code/title"))
$_title = $_code;
$options[] = array('value' => $_code, 'label' => $_title . " ($_code)");
}
echo "<xmp>";
print_r($options);
echo "</xmp>";
In your checkout controller you need to add extra steps to save your quote if you want this information to be accessible to you.
I added a few '$quote->save();' entries to get this to work, however, I cannot definitively say which entry is the one that did the fix. I also cannot find the link on Magento forums, however, I hope I have given you a head start on what is going on.
You could override the saveShippingMethodAction() function in the Mage_Checkout_OnepageController, or extend upon it, and save the method into the registry by inserting:
Mage::register('blahShippingMethod', $this->getRequest()->getPost('shipping_method'));
and call upon it as you need it: Mage::registry('blahShippingMethod');
Don't forget to unset it when you no longer need it as you will run into an error if you try to reset when it's already been set.
Mage::unregister('blahShippingMethod');

Resources