Ok, I solved this...
EDIT: Updated solution fixing some bugs...
These are the changes I did in Orders model file.
\administrator\components\com_virtuemart\models\orders.php
#1 Add a new method to get order items for an order (it's a clone of getOrder(), but getting only the order items, for better performance)
public function getOrderItems($virtuemart_order_id){
//sanitize id
$virtuemart_order_id = (int)$virtuemart_order_id;
$db = JFactory::getDBO();
$order = array();
// Get the order items
$q = 'SELECT virtuemart_order_item_id, product_quantity, order_item_name, order_item_sku, i.virtuemart_product_id, product_item_price, product_final_price, product_basePriceWithTax, product_discountedPriceWithoutTax, product_priceWithoutTax, product_subtotal_with_tax, product_subtotal_discount, product_tax, product_attribute, order_status, paid,
intnotes, virtuemart_category_id
FROM #__virtuemart_order_items i
LEFT JOIN #__virtuemart_products p
ON p.virtuemart_product_id = i.virtuemart_product_id
LEFT JOIN #__virtuemart_product_categories c
ON p.virtuemart_product_id = c.virtuemart_product_id
WHERE `virtuemart_order_id`="'.$virtuemart_order_id.'" group by `virtuemart_order_item_id`';
$orderBy = VmConfig::get('order_item_ordering','virtuemart_order_item_id');
if (!empty ( $orderBy)) {
$orderingDir = VmConfig::get('order_item_ordering_dir','ASC');
$q .= ' ORDER BY `'.$orderBy.'` ' . $orderingDir;
}
//group by `virtuemart_order_id`'; Why ever we added this, it makes trouble, only one order item is shown then.
// without group by we get the product 3 times, when it is in 3 categories and similar, so we need a group by
//lets try group by `virtuemart_order_item_id`
$db->setQuery($q);
$order['items'] = $db->loadObjectList();
$customfieldModel = VmModel::getModel('customfields');
$pModel = VmModel::getModel('product');
foreach($order['items'] as $p=>$item){
$ids = array();
$product = $pModel->getProduct($item->virtuemart_product_id, true, false, false);
if($product){
$pvar = get_object_vars($product);
foreach ( $pvar as $k => $v) {
if (!isset($item->{$k}) and strpos ($k, '_') !== 0 and property_exists($product, $k)) {
$item->{$k} = $v;
}
}
}
$item->paid = floatval($item->paid);
$order['items'][$p] = $item;
}
return $order;
}
#2 Update getOrdersListQuery() to always LEFT JOIN the virtuemart_order_items table
private function getOrdersListQuery($byOrderItem = false) {
$q = ' FROM #__virtuemart_orders as o
LEFT JOIN #__virtuemart_order_userinfos as u
ON u.virtuemart_order_id = o.virtuemart_order_id AND u.address_type="BT"
LEFT JOIN #__virtuemart_order_userinfos as st
ON st.virtuemart_order_id = o.virtuemart_order_id AND st.address_type="ST" ';
$q .= ' LEFT JOIN #__virtuemart_order_items as oi
ON o.virtuemart_order_id = oi.virtuemart_order_id '; // amivag: we need this to be able to search on product item SKUs
if($byOrderItem){
// $q .= ' LEFT JOIN #__virtuemart_order_items as oi
// ON o.virtuemart_order_id = oi.virtuemart_order_id ';
}
$q .= ' LEFT JOIN #__virtuemart_paymentmethods_'.VmConfig::$vmlang.' as pm
ON o.virtuemart_paymentmethod_id = pm.virtuemart_paymentmethod_id
LEFT JOIN #__virtuemart_shipmentmethods_'.VmConfig::$vmlang.' as sm
ON o.virtuemart_shipmentmethod_id = sm.virtuemart_shipmentmethod_id';
return $q;
}
#3 Update getOrdersList() to include product items in orders (and also search for product SKUs in Orders search)
if ($this->search){
$db = JFactory::getDBO();
$this->search = '"%' . $db->escape( $this->search, true ) . '%"' ;
$this->search = str_replace(' ','%',$this->search);
$searchFields = array();
$searchFields[] = 'u.first_name';
//$searchFields[] = 'u.middle_name';
$searchFields[] = 'u.last_name';
$searchFields[] = 'o.order_number';
$searchFields[] = 'u.company';
$searchFields[] = 'u.email';
$searchFields[] = 'u.phone_1';
$searchFields[] = 'u.address_1';
$searchFields[] = 'u.city';
$searchFields[] = 'u.zip';
//quorvia added ST data searches and virtuemart_order_id and order total
$searchFields[] = 'o.virtuemart_order_id';
$searchFields[] = 'round(o.order_total,2)';
$searchFields[] = 'u.customer_note';
$searchFields[] = 'o.order_note';
$searchFields[] = 'st.last_name';
$searchFields[] = 'st.company';
$searchFields[] = 'st.city';
$searchFields[] = 'st.zip';
$searchFields[] = 'oi.order_item_sku'; // amivag: also search in product SKUs
$where[] = implode (' LIKE '.$this->search.' OR ', $searchFields) . ' LIKE '.$this->search.' ';
//$where[] = ' ( u.first_name LIKE '.$search.' OR u.middle_name LIKE '.$search.' OR u.last_name LIKE '.$search.' OR `order_number` LIKE '.$search.')';
...
// AMIVAG: Make orders unique
$groupBy = " GROUP BY o.virtuemart_order_id "; // AMIVAG: Remove duplicate orders...
$ordersMayContainDuplicates = $this->exeSortSearchListQuery(0,$select,$from,$whereString,$groupBy,$ordering);
$this->_data = $ordersMayContainDuplicates; // GROUP BY takes care of duplicates
if($this->_data){
foreach($this->_data as $k=>$d){
$this->_data[$k]->order_name = htmlspecialchars(strip_tags(htmlspecialchars_decode($d->order_name)));
// AMIVAG: Get details for each order, including product items
$orderDetails = $this->getOrderItems($this->_data[$k]->virtuemart_order_id);
$orderItems = $orderDetails["items"];
//AMIVAG: Include products in each Order
$this->_data[$k]->product_skus = [];
$this->_data[$k]->product_names = [];
foreach($orderItems as $item) {
$this->_data[$k]->product_skus[] = $item->order_item_sku;
$this->_data[$k]->product_names[] = $item->order_item_name;
}
}
}