We have a custom observer that executes after "sales_order_place_after" that compiles a list of purchased items from the order and sends them to a 3rd party.
This script worked fine in Magento 1, but since upgrading to Magento 2, we're seeing both the configurable product and its parent product being listed - the code is as follows:
public function execute(\Magento\Framework\Event\Observer $observer) {
$order = $observer->getOrder(); foreach($order->getAllVisibleItems() as $item) { // Build XML } }
The resulting XML looks like this:
<item> <price>7.90</price> <sku>THE_SKU_NUMBER</sku> <qty>1</qty> </item> <item> <price>0.00</price> <sku>THE_SKU_NUMBER</sku> <qty>1</qty> </item>
Again, the "getAllVisibleItems" function worked fine in Magento 1, and as outlined by this stack exchange post:
https://magento.stackexchange.com/questions/111112/magento2-correct-way-to-get-order-items
...I understand that it should work similarly in Magento 2, however the user in that post also had a similar issue with duplicate items being listed - is there a different function we should be using to NOT show the parent product, and only show the configurable product that was actually purchased?
Note that I'd like to not have to check for a "0.00" price here - that seems like a workaround and not an actual solution to the issue.
Any information is helpful, thank you.
We have experienced the same issue. Would be good to get an answer from Magento.
Does anyone have any suggestions on how to restore this functionality or change our code to make it work as expected?
We currently have the fix in place that I didn't want to do originally (only including products with a price greater than "0.00"), but this is becoming an issue since we will be offering free products via coupon codes, and they will be skipped with this in place.
Please advise.
Hi,
Here is the solution to your issue:
getAllVisibleItems: How To Show Only Configurable Products & Hide Parent Products?
Hope that you find it useful.
You may want to rewrite your own getAllVisibleItems, in order to have it working as you had in Magento 1.
See what I did:
/**
* Retrieves visible products of the order, omitting its children (yes, this is different than Magento's method)
* @param Magento\Sales\Model\Order $order
*
* @return array
*/
public function getAllVisibleItems($order)
{
$items = [];
foreach ($order->getItems() as $item) {
if (!$item->isDeleted() && !$item->getParentItem()) {
$items[] = $item;
}
}
return $items;
}
Baiscally it's the same thing, but using getParentItem() instead of getParentId() witch always return null.
@Ricardo_Martins, why should one have to rewrite the core method getAllVisibleItems() itself instead of working on what it returns where you use this function?
@pramod kumar_th wrote:@Ricardo_Martins, why should one have to rewrite the core method getAllVisibleItems() itself instead of working on what it returns where you use this function?
Because the current method in M2 doesn't work as expected (and in the same way as it worked in M1).It uses getParentId() method within witch always return null (perhaps it's a bug).
Well it is not really a bug but it is using getParentId() method because it thinks it is to be used after the Order has been saved and records in the database ... that is why in the case when order has been placed but not saved as Observer for place event still going etc ... getParentId() always returns NULL and getParentItem() works
I agree they could just use getParentItem() and then it should not matter when it is being used