Error trying to group in Magento join - magento

I'm facing the error in title with Magento. I'm trying to group the records in the grid by county, which is one of the fields obtained in the join, not the main table. When I run the SQL query generated against DB it runs as expected but when trying to access the grid in Magento, I get that error. This is my join:
$collection = Mage::getModel('sales/order_address')->getCollection();
$collection
->addAttributeToSelect('region')
->addAttributeToSelect('city')
->addAttributeToFilter('address_type', 'shipping')
->addAttributeToFilter('region', 'California')
->addAttributeToFilter('created_at', array('from' => $from, 'to' => $to))
->addFieldToFilter(array('status', 'status'),
array(
array('eq' => 'complete'),
array('eq' => 'processing')
));
$collection->getSelect()->joinLeft(
array('order' => 'sales_flat_order'),
'order.entity_id = main_table.parent_id',
array('status' => 'order.status',
'created_at' => 'order.created_at',
'grand_total' => 'SUM(order.grand_total)'))
->joinLeft(
array('order_tax' => 'sales_order_tax'),
'order_tax.order_id = main_table.parent_id',
array('county' => 'order_tax.title',
'tax_amount' => 'SUM(order_tax.amount)',
'tax_rate' => 'order_tax.percent'))
->group('county')
->group('city')
->distinct(true);
And this is the generated SQL:
SELECT DISTINCT `main_table`.`region`, `main_table`.`city`, `order`.`status`, `order`.`created_at`, SUM(order.grand_total) AS `grand_total`, `order_tax`.`title` AS `county`, SUM(order_tax.amount) AS `tax_amount`, `order_tax`.`percent` AS `tax_rate` FROM `sales_flat_order_address` AS `main_table` LEFT JOIN `mvmt_sales_flat_order` AS `order` ON order.entity_id = main_table.parent_id LEFT JOIN `mvmt_sales_order_tax` AS `order_tax` ON order_tax.order_id = main_table.parent_id WHERE (address_type = 'shipping') AND (region = 'California') AND (created_at >= '2013-08-01 00:00:00' AND created_at <= '2013-12-31 00:00:00') AND ((status = 'complete') OR (status = 'processing')) GROUP BY `county`, `city`
Does someone knows what is happening here and why SQL is accepting the query but not Magento?
Thanks for the help in advance.

$collection = Mage::getModel('sales/order_address')->getCollection();
$collection
->addAttributeToSelect('region')
->addAttributeToSelect('country_id')
->addAttributeToSelect('city')
->addAttributeToFilter('address_type', 'shipping')
->addAttributeToFilter('region', 'California')
->addAttributeToFilter('created_at', array('from' => $from, 'to' => $to))
->addFieldToFilter(array('status', 'status'),
array(
array('eq' => 'Pending'),
array('eq' => 'processing')
));
$collection->getSelect()->joinLeft(
array('order' => 'sales_flat_order'),
'order.entity_id = main_table.parent_id',
array('order.status','order.created_at','SUM(order.grand_total)'));
$collection->getSelect()
->joinLeft(
array('order_tax' => 'sales_order_tax'),
'order_tax.order_id = main_table.parent_id',
array('order_tax.title','SUM(order_tax.amount)','order_tax.percent'))
->group('country_id')
->group('city')
->distinct(true);
Hope this will work for you. :)
Best of luck.

Related

How to filter Magento collection for a date or null

I have some Magento code that I'm trying to use to filter a collection of products. I want to find all products where the date is BEFORE a certain date OR the date hasn't been set (ie is null).
I have:
function getProduct($product_id) {
global $proxy, $sessionId, $conn, $start_date, $time_to_run;
if ($product_id == 'all') {
$result=Mage::getModel("catalog/product")
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('price_adjust_active', array('null' => true))
->addAttributeToFilter('price_adjust_active', '1')
->addAttributeToFilter(array(
array('attribute'=> 'price_adjust_last_run','lt' => date('Y-m-d H:i:s', $time_to_run)),
array('attribute'=> 'price_adjust_last_run', 'null' => true)
))
->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
->setOrder('entity_id', 'DESC')
->setPageSize(1);
} else {
$result=Mage::getModel("catalog/product")
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter('entity_id', array('eq' => $product_id))
->addAttributeToFilter('price_adjust_active', array('null' => true))
->addAttributeToFilter('price_adjust_active', '1')
->addAttributeToFilter(array(
array('attribute'=> 'price_adjust_last_run','lt' => date('Y-m-d H:i:s', $time_to_run)),
array('attribute'=> 'price_adjust_last_run', 'null' => true)
))
->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
->setOrder('entity_id', 'DESC')
->setPageSize(1);
}
and I can successfully filter out the products with the dates set before my specified date. I just can't get the "null" attribute to work. As you can see from my code, I have 2 different filters in there, and neither of them seem to give me the desired results.
The two faulty attempts are:
->addAttributeToFilter('price_adjust_active', array('null' => true))
or
array('attribute'=> 'price_adjust_last_run', 'null' => true)
Magento has a special way to filter dates instead of just using a straight greater or less than.
Try this...
->addAttributeToFilter('price_adjust_last_run', array('or'=> array(
0 => array(
'date' => true,
'from' => date('Y-m-d H:i:s', $time_to_run - 1)
),
1 => array('is' => new Zend_Db_Expr('null')))
), 'left')
You are setting date to true and then you'll probably want to make sure to subtract 1 second from your $time_to_run variable.
This works similarly with addFieldToFilter() as well.

Magento OR query

I would like to use OR in magento mysql query, I am looking for an equivalent in magento
where (is_in_stock=0 and show_in_front=1) and (is_in_stock=1 and show_in_front=1)
I know following can be used for 'OR', but am not sure how to produce an equiavlent query as above;
->addAttributeToFilter(
array(
'attribute' => 'is_in_stock',
'eq' => '0',
),
Following is example code for OR condition
$collection->addAttributeToFilter(
array(
array('attribute'=> 'attribute1','like' => 'value1'),
array('attribute'=> 'attribute2','like' => 'value2'),
array('attribute'=> 'attribute3','like' => 'value3'),
)
);
Please check this query
//OR Condition
->addAttributeToFilter(array(array('attribute' => 'is_in_stock','eq' => '0'),array('attribute' => 'show_in_front','eq' => '1')));
//And Condition
->addAttributeToFilter('is_in_stock', array('eq' => '1'));
->addAttributeToFilter('show_in_front', array('eq' => '1'));

Magento - Collection OR AND filter

I want to select products collection with condition "A or (B and C)" by using AddAttributeToFilter, but I have no idea..
Can someone help me?
$collection = Mage::getModel('xyz/abc')->getCollection();
$collection->addAttributeToFilter(
array(
array('attribute'=> 'someattribute','like' => 'value'),
array('attribute'=> 'otherattribute','like' => 'value'),
array('attribute'=> 'anotherattribute','like' => 'value'),
)
);
$collection->addAttributeToFilter('status', array('eq' => 1));
Transnational will be look like
WHERE ((someattribute LIKE 'value') OR (otherattribute LIKE 'value') OR (anotherattribute LIKE 'value')) and status=1
You can also visit this link for more info
Magento addFieldToFilter: Two fields, match as OR, not AND

magento filter order_invoice_item by date

hi i want to filter an magento order_invoice_item collection by date
as parameter i have a timstamp-string "20130701T00:00:00"
i trid to filter it like that
$invoiceitems = Mage::getModel('sales/order_invoice_item')->getCollection()
->addAttributeToFilter('sku', array('in' => $skuList))
->addAttributeToFilter('created_at', array('lt' => strtotime("20130701T00:00:00")));
but this won't work because the "created_at" is on the invoice.
how can i join the invoice to filter it by date?
my solution is
$invoiceitems = Mage::getModel('sales/order_invoice_item')->getCollection()
->addAttributeToFilter('sku', array('in' => $skuList));
$invoiceitems->getSelect()->where("created_at >= CONVERT_TZ(FROM_UNIXTIME(".strtotime($from)."), ##session.time_zone,'UTC')");
$invoiceitems->getSelect()->where("created_at <= CONVERT_TZ(FROM_UNIXTIME(".strtotime($to)."), ##session.time_zone,'UTC')");
$invoiceitems->getSelect()->joinInner("sales_flat_invoice", "parent_id=sales_flat_invoice.entity_id", 'created_at');

How to compare two fields in a Magento query?

I'm getting all my active special products using this code that I've found somewhere:
$collection = $this->_addProductAttributesAndPrices($collection)
->addStoreFilter()
->addAttributeToFilter('special_from_date', array('date' => true, 'to' => $todayDate))
->addAttributeToFilter('special_to_date', array('or'=> array(
0 => array('date' => true, 'from' => $todayDate),
1 => array('is' => new Zend_Db_Expr('null')))
), 'left')
->setPageSize($this->get_prod_count())
->setCurPage($this->get_cur_page());
Now I want to get only the products that have a special price <= price, however I still can't realize how to do it.
I've been reading this page: http://www.magentocommerce.com/wiki/5_-_modules_and_development/catalog/using_collections_in_magento
and I tried this without success:
->addAttributeToFilter('special_price', array('lt' => 'price'))
Thanks for your help!
You can try this, thanks for Zyava!
On my case:
->addAttributeToFilter('price', ['gt' => new Zend_Db_Expr('final_price')])
A lesser efficient solution would be to iterate through the collection,
$products = array();
$collection = Mage::getResourceModel('catalog/product_collection');
foreach($collection as $col) {
$product = Mage::getModel('catalog/product')->load($col->getId());
if( $product->getPrice() > $product->getSpecialPrice() ) {
$products[] = $product;
}
}
you will have an array of products in the end...

Resources