How to compare two fields in a Magento query? - magento

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...

Related

Undefinde offset:1 when importing laravel excel

this my code cause the trouble,
$cust = Customer::where('name', '=', $data[$i][0]['customer_name'])
->pluck('customer_id')[0];
this one for get customer id when i do store to sales order
$sales = array(
'customer_id' => Customer::where('name', '=', $data[$i][0]['customer_name'])->pluck('customer_id')[0],
'logistics_id' => Logistic::where('logistics_name', '=', $data[$i][0]['logistics'])->pluck('logistics_id')[0],
'subtotal' => $data[$i][0]['subtotal_rp'],
'shipping_cost' => $data[$i][0]['shipping_cost_rp'],
'discount_code' => 0,
'date_of_sales' => $data[$i][0]['date'],
'grand_total' => $data[$i][0]['grand_total_rp'],
'tax' => $data[$i][0]['tax_rp'],
'status' => $data[$i][0]['status'],
'discount_amount' => $data[$i][0]['discount_amount_rp']
);
$store_so = SalesOrder::create($sales);
but, when i do dd(), i get the right data
First of all, you need to check if the $data variable returns the data as you expect.
dd($data);
Next, you need to check that the $data array has the number of elements according to $total_data.
dd(count($data) == $total_data));
So basically, you just need to give condition or try-catch (recommended) :
if (isset($data[$i][0])) {
$customer = Customer::where('name', $data[$i][0]['customer_name'])->first();
$logistic = Logistic::where('logistics_name', $data[$i][0]['logistics'])->first();
if(!$customer){
dd('No customer found!');
}
if(!$logistic){
dd('No logistic found!');
}
$sales = [
'customer_id' => $customer->customer_id,
'logistics_id' => $logistic->logistics_id,
'subtotal' => $data[$i][0]['subtotal_rp'],
'shipping_cost' => $data[$i][0]['shipping_cost_rp'],
'discount_code' => 0,
'date_of_sales' => $data[$i][0]['date'],
'grand_total' => $data[$i][0]['grand_total_rp'],
'tax' => $data[$i][0]['tax_rp'],
'status' => $data[$i][0]['status'],
'discount_amount' => $data[$i][0]['discount_amount_rp'],
];
$store_so = SalesOrder::create($sales);
}
else{
dd('No $data[$i][0] found!');
}
PS : I recommend using the first() method instead of pluck('customer_id')[0].
It seems you need to get a customer_id from a customer_name.
Try to make everything simple:
$sales = array(
'customer_id' => Customer::where('name', $data[$i][0]['customer_name'])->first()->id,
...
);

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.

Show Sale product on category view page Magento

How can I get sale products(special price) on category view page. Products must be from same category or sub-categories. Thanks.
First of all you have to edit list.phtml from
app/design/frontend/YOURPACKAGE/YOURTHEME/template/catalog/product/list.phtml
and write below code at starting of file
$_productCollection=$this->getLoadedProductCollection() // Remember you have to comment this line
Mage::getSingleton('core/session', array('name' => 'frontend'));
$_productCollection = Mage::getResourceModel('catalogsearch/advanced_collection')
->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
->addMinimalPrice()
->addStoreFilter();
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($_productCollection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($_productCollection);
$todayDate = date('m/d/y');
$tomorrow = mktime(0, 0, 0, date('m'), date('d'), date('y'));
$tomorrowDate = date('m/d/y', $tomorrow);
$currentCategory = Mage::registry('current_category');
$_productCollection->addAttributeToFilter('special_from_date', array('date' => true, 'to' => $todayDate))
->addAttributeToFilter('special_to_date', array('or'=> array(
0 => array('date' => true, 'from' => $tomorrowDate),
1 => array('is' => new Zend_Db_Expr('null')))
), 'left')
->addAttributeToFilter('category_id', array(
array('finset' => $currentCategory->getId()))
;
and comment this line
$_productCollection=$this->getLoadedProductCollection();
Let me know if you have any query
The easiest way is to make a duplicate of the List block and add the filter you need.
You May need to modify your attribute in the Magento admin area to "show in product listing" too.
for example:
{{block type="catalog/product_list" template="catalog/product/list.phtml"}}
this will use the List block to filter the collection for you, lets make a copy:
app/code/core/Mage/Catalog/Block/Product/List.php
to
app/code/local/Mage/Catalog/Block/Product/Mylist.php
Now lets modify the Block to use our custom attribute, something like this should work (not tested)
Mylist.php
class Mage_Catalog_Block_Product_Mylist extends Mage_Catalog_Block_Product_List
{
/**
* Retrieve loaded category collection
*
* #return Mage_Eav_Model_Entity_Collection_Abstract
*/
protected function _getProductCollection()
{
$collection = parent::_getProductCollection();
$todayDate = Mage::app()->getLocale()->date()->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
$collection->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')
->addAttributeToSort('special_from_date', 'desc');
return $collection;
}
}
Now you simple use your new block:
{{block type="catalog/product_mylist" template="catalog/product/list.phtml"}}
Thanks to(ref by): How to filter product list by custom attribute on category page of Magento?

Error trying to group in Magento join

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.

Filtering invoice collection by created_at in magento

I'm trying to find a way to filter the results of getInvoiceCollection in the function below:
// "eachInvoice" is each of the Invoice object of the order "$orders"
if ($order->hasInvoices()) {
foreach ($order->getInvoiceCollection() as $eachInvoice) {
$invoiceIncrementId = $eachInvoice->getIncrementId();
}
}
Can adding the filter below to $order->getInvoiceCollection()
$order->getInvoiceCollection()
->addAttributeToFilter('created_at', array(
'from' => $from_date,
'to' => $today,
'date' => true,));
So the entire function would be, is the correct way to do this, it doesn't seem like its right.
// "eachInvoice" is each of the Invoice object of the order "$orders"
if ($order->hasInvoices()) {
foreach ($order->getInvoiceCollection()$order->getInvoiceCollection()
->addAttributeToFilter('created_at', array( 'from' => $from_date,
'to' => $today, 'date' => true,)) as $eachInvoice) {
$invoiceIncrementId = $eachInvoice->getIncrementId();
}
}
Whats the "correct way" to go about doing this?
To get the increment ids as is shown in your sample code there is no need to loop:
$invoiceCollection = $order->getInvoiceCollection();
$invoiceCollection
->addAttributeToFilter('created_at', array(
'from' => $from,
'to' => $to,
));
$incrementIds = $invoiceCollection->getColumnValues('increment_id');

Resources