I'm using Magento Community 1.7. When I go to Sales-->Orders I see all the orders. Currently I can tick certain orders and, using the action dropdown, I can print invoices, cancel, hold etc. I'm wondering if there is anyway that I can add actions like "Requires Refund", "Fraud". The actions wouldn't neccessarily have to do anything just change the status so I can see clearly for later the status of these orders. Any ideas?
In order to add more actions you need to override this method Mage_Adminhtml_Block_Sales_Order_Grid::_prepareMassaction().
For each action you add, you will need a method in the controller you send it to.
Take for example the action Cancel. It is added to the mass action block like this:
$this->getMassactionBlock()->addItem('cancel_order', array(
'label'=> Mage::helper('sales')->__('Cancel'),
'url' => $this->getUrl('*/sales_order/massCancel'),
));
and the corresponding method is Mage_Adminhtml_Sales_OrderController::massCancelAction()
Related
I want to check whether a customer is allowed to use one of the activated payment methods.
For example:
If the customer had enabled "Cash on Delivery", he should see the method but I can't find anything similar in the code.
In Magento 1 there was:
public function isAvailable()
Is there any similar way to do it with Magento 2 ?
There are 2 approaches you could take:
Observer
If you take a look at \Magento\Payment\Model\Method\AbstractMethod (the parent class of \Magento\OfflinePayments\Model\Cashondelivery) in the isAvailable method, you will find that it dispatches the payment_method_is_active event which could be used to performs some additional logic (such as determine if a customer had enabled the specific method or not):
$this->eventManager->dispatch(
'payment_method_is_active',
[
'result' => $checkResult,
'method_instance' => $this,
'quote' => $quote
]
);
Plugin
Since isAvailable is a public method, you could add a plugin to the method. Whether you use before, after, or around depends on your specific needs. However, a good place for learning how to do this is the Magento DevDocs site: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html
How might it be possible to get Commerce-Product-Display information in a Commerce-Order object?
The issue is I need to publish a Commerce-Product-Display node when a user has made a payment to publish the node. I am using Rules to detect the payment and attempt to publish the node.
My problem is, because the Completing the checkout process Rules event only has data for a Commerce-Order, and the Commerce-Order does not have information for the Product nor the Product display, I am unable to publish the node.
OK, so here's my new answer based on the new info you provided in your question
=================================
So this is probably a little more complicated than you expected, but not impossible! Two things are important:
the line-items that are attached to your order will contain your products and
you will need to use a rule component, in order to be able to have an additional 'condition-action' combo inside your rule action
Here is how to do it:
In your rule that is triggered upon 'Completing the checkout process', add a loop in your 'Actions' section. You should see 'Add loop' right next to 'Add action'. We'll use this loop to iterate through all the commerce-line-items in your order: that's where the products are hiding
When configuring the loop, tell it to iterate through 'commerce-order:commerce-line-items' and either rename, or remember what it's going to call each line item as it goes through it.
Now - as it's going through each of your order's line items, we'll want to call an entire new rule with its own set of 'condition' and 'action'. The condition we need is to check that the line item contains the product you expect, and the action can be whatever you want - publish a node based on a certain field or whatever. In my case, the action will just be sending an email to prove I found a product. When we need condition-action sets within a rule, we need to create a rule component!!
Go to /admin/config/workflow/rules/components to create a new rule component to run for each of the above items. Click the 'Add new component' link at the top of the page
Select 'Rule' from the drop-down options, since this will be a component that contains both a condition and an action
Name the rule, and in the 'Variables' section, we have to let it know we're going to pass it a parameter to work with. In our case, it will be the commerce line item that is currently being iterated through.
Add two conditions to your component (or whatever checks you think are necessary). I added 'Entity is of type' => Commerce Line item and 'Entity has field' => commerce_product. So this runs for all my products at the moment.
The condition I set on my component is to send an email, and I filled in the following for the body of the email: [line-item:commerce_product], and it prints out the product's name beautifully in the email each time I've tested checking out!
But first - how do I call this component for each of my line item types after I save it?? Read on:
After the component is saved, Add an action to your loop:
From now on, at the very bottom of your actions, you'll see a brand new 'Components' section, and in your case, you should only have one now. Select it to call it for each item:
Last step will be to fill in the parameter to pass to this component, which is obviously the list_item you're currently on, or whatever the computer name of the current item was if you changed it.
Save and test!
Whew! It's a little complicated, but I hope it puts you in the right direction!
The way rules work in Drupal is that not all fields are shown for your entity by default in the actions. What you need to do is prompt Rules to recognize your object as a certain type of node in order for the Rule to add all of its appropriate fields.
You can do this either by
using the 'Content is of type' under the Node section check (and select your Commerce Display node type or
directly using the 'Entity has field' check under the Entities section to check for a specific field you want to use.
Either of those should prompt Rules to recognize the type of entity you're working with and populate the Actions with the necessary fields.
Let us know if this works!
I am trying to listen to the "catalog_product_save_before" and "catalog_product_save_after" events which are correctly triggered when I save individual product from admin interface.
But, these events are not triggered when I use the "update attributes" action for multiple product selections, from the product list grid. Is there any event which is triggered whenever a product attribute is updated ?? I know I need to write different observer function for csv upload but I need the event for grid action "Update attributes"..
Thanks in advance.
Cheers..
Got this to work out!!
I used this event : catalog_product_attribute_update_before
This give an array with changed attributes and product ids :
[attributes_data] => Array
(
[price_markup] => 10
)
[product_ids] => Array
(
[0] => 6
)
[store_id] => 0
Hope this helps ..
Cheers!!!
this might be a vague answer, I am not sure what you try to do with the attribute but maybe have a look into the Mage_Indexer module. Its bit more complex but it listens to all events or at least Magento takes care of notifying it if something is outdated or has changed.
And also if something goes funky with your data, rerunning your indexer should clean up all the data in an ideal world.
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');
I had a custom utility task that allowed users to choose an image to accompany the gift card notice that is sent to the recipient when a gift card is purchased at the magento run shop. In the template, there is an assortment of variables available so you can customize the email that is sent. However, in order to add the correct image, I need to have access to the gift card sku number since my method for handling this was to simply create many gift cards and apply separate images for each one, then use javascript to swap the sku numbers when the user clicks the images. Simple enough.
In the app/code/core/Enterprise/GiftCard/Model/Observer.php file, the variables are set:
$templateData = array(
'name' => $item->getProductOptionByCode('giftcard_recipient_name'),
'email' => $item->getProductOptionByCode('giftcard_recipient_email'),
'sender_name_with_email' => $sender,
'sender_name' => $senderName,
'gift_message' => $item->getProductOptionByCode('giftcard_message'),
'giftcards' => $codeList->toHtml(),
'balance' => $balance,
'is_multiple_codes' => 1 < $goodCodes,
'store' => $order->getStore(),
'store_name' => $order->getStore()->getName(), // #deprecated after 1.4.0.0-beta1
'is_redeemable' => $isRedeemable,
);
So I could add the product sku to this array and it would be available in the template system. Problem is, I don't know where to trace this back to even know how to get the Sku. I assume it is somehow available in the $item var, but magento has no documentation on this particular case and I can't guess since there is no method for testing. The email script is activated when the card is purchased so I can't just click a "Send test" button to see what comes out in the email that is sent to the user. The preview button dismisses variables.
Anyone happen to know about this? Possibly something like $item->getSku()
Any input helps.
Thanks
That snippet is from the method Enterprise_GiftCard_Model_Observer::generateGiftCardAccounts() which is registered as a handler for sales_order_save_after event. That event is passed the same 'order' object as the "new order placed" emails have. You can experiment by altering that email template and triggering a new email by resending from the order page in admin.
$item->getSku() is almost certainly right.