How can I query data with two date ranges in CakePHP? - cakephp

I'm trying to execute this query to fetch 'Banners' between a date_start and a date_end.
$current_date = date('Y-m-d');
$banners = $this->Banner->find('all',
array('conditions' =>
array("date_start >= " => $current_date,
"date_end <= " => $current_date)
));
I've attempted to use NOW() which seems to cause problems, I've tried using an "AND" condition and I've also concatenated the query with $current_date (eg. "date_start =>".$current_date)
Any ideas where I'm going wrong?
Edit
Managed to get it working by switching the conditions around:
$banners = $this->Banner->find('all', array('conditions' => array("'$current_date' >=" >= "date_start", "'$current_date' <=" => 'date_end')));

you should change your equation
date_start <= $current_date and
date_end >= $current date
lets say date_start is 1/5/2011
and date_end is 3/5/2011
and curr_date is 2/5/2011
notice that curr_date is bigger than start_date and smaller than end_date, in your condition you check the opposite

Related

How to get last month row sum in cakephp 3

I need to get last month transactions amount sum , I wrote query but getting error Error: Call to undefined function App\Controller\YEAR()
// sum of total received amount
$conditions['transaction_type']=1;
$conditions['AND']['YEAR(Transactions.created) >='] = YEAR('CURRENT_DATE - INTERVAL 1 MONTH');
$conditions['AND']['MONTH(Transactions.created) <='] = MONTH('CURRENT_DATE - INTERVAL 1 MONTH');
$query = $this->Transactions->find('all',['conditions'=>$conditions]);
$collection = new Collection($query);
$sumOfReceivedAmount = $collection->sumOf('amount');
$this->set('sumOfReceivedAmount',$sumOfReceivedAmount);
I have also tried using query builder
$query = $this->Transactions->find()
->where(function ($exp, $q) {
$year = $q->func()->year([
'created' => 'identifier'
]);
$month = $q->func()->month([
'created' => 'identifier'
]);
return $exp
->eq($year, $q->func()->year(['CURRENT_DATE - INTERVAL 1 MONTH']))
->eq($month, $q->func()->month(['CURRENT_DATE - INTERVAL 1 MONTH']));
});
For this code I am getting query like
SELECT
*
FROM
transactions Transactions
WHERE
(
year(created) = (
year(
'CURRENT_DATE - INTERVAL 1 MONTH'
)
)
AND month(created) = (
month(
'CURRENT_DATE - INTERVAL 1 MONTH'
)
)
)
Problem is this single quote 'CURRENT_DATE - INTERVAL 1 MONTH'
How can I remove this single quote ?
Similar to your other year() usage where you decalare the passed value to be an identifier, you'd have to declare your other values as literal values (or pass expression objects) so that they are inserted into the query as is, instead of being bound.
['CURRENT_DATE - INTERVAL 1 MONTH' => 'literal']
CakePHP also ships with methods to express similar functionality, specifically the FunctionsBuilder::dateAdd() method. Also when expressing CURRENT_DATE as a function the query builder will be able to convert the SQL for other DBMS like SqlServer, which has no CURRENT_DATE:
$q->func()->year(
[$q->func()->dateAdd($q->func()->CURRENT_DATE(), -1, 'MONTH')]
)
NOW() should work too:
$q->func()->dateAdd($q->func()->now(), -1, 'MONTH')
See also
Cookbook > Database Access & ORM > Query Builder > Using SQL Functions

Magento using operators in where clauses

My products have date_created and expires_in attributes. date_created is Magento date backend format while expires_in is a select that contains options as 1 week, 1 month etc.
Using those two attributes I'm trying to determine the total number of expired products. My idea was to write a query that selects:
products where date created + 1 week < now() AND expires_in = 1 week
AND
products where date created + 1 month < now() AND expires_in = 1 month
...
But I don't seem to be able to make even the first part of the first step to work:
$currentTimestamp = Mage::getModel('core/date')->timestamp(time());
$oneWeekTimestamp = Mage::getModel('core/date')->timestamp(strtotime("+1 week"));
$products = Mage::getResourceModel('catalog/product_collection')
->setStoreId(Mage::app()->getStore()->getId())
->addAttributeToSelect('')
...
//these are what i have tried so far:
$products->addAttributeToFilter('date_updated + ' . $oneWeekTimestamp , array('gt' => $currentTimestamp));
$products->addAttributeToFilter(new Zend_Db_Expr('date_updated + ' . $oneWeekTimestamp), array('gt' => $currentTimestamp));
$products->addAttributeToFilter("DATEDIFF($currentTimestamp, 'date_updated')" , array('gt' => 7));
$countExpired = $products -> count();
None of them seem to work. If possible I'd like the cross RDBMS solution.
You can do this in following way:
$currentTimestamp = Mage::getModel('core/date')->timestamp(time());
$oneWeekTimestamp = Mage::getModel('core/date')->timestamp(strtotime("+1 week"));
$oneweekDate=date("Y-m-d H:i:s",$oneWeekTimestamp);
$products->addAttributeToFilter('date_updated',array('date'=>true,'gt',$oneweekDate);

How to find items by date when the field is datetime?

I have a model with a DateTime field.
How can I get all entries by Date even if the column is DateTime?
Example table Cars:
id; expiration
1;2014-12-22 00:00:00
2;2014-12-22 03:12:00
3;2014-10-09 01:10:29
If I do this:
$this->Car->find("all", array('conditions' => array('expiration' => '2014-12-22' ) ))
I get only the item with ID 1 (2014-12-22 00:00:00)
But I need all the items (1 and 2)
Any ideas how to accomplish this? in MySql I could do something like this:
SELECT * ... FROM..WHERE DATE_FORMAT(conditions, '%Y-%m-%d') = '2014-12-22'
Try this
$this->Car->find("all", array('conditions' => array('DATE(ondate)' => '2014-12-22') ));
This will generate
SELECT * ... FROM..WHERE WHERE DATE(ondate) = '2014-12-22'
You need to update your query as shown below:
$this->Car->find("all", array(
'conditions' => array(
'DATE(expiration)' => '2014-12-22'
)
)
);
In the above query, Mysql now compare only date not the date and time as it was using in the query mentioned by you.
You will need to search trough a range: 00:00:00 - 23:59:59
http://cookbook.mongodb.org/patterns/date_range/

CakePHP : Search date from form helper

I use form helpers to show drop down select date. My problem is, i can't compare date from ms sql with form data.
My View :
<?php echo $this->Form->input('collect_date', array('label' => 'Collect Date','type'=>'date','dateFormat'=> 'DMY','minYear' => date('Y'),'maxYear' => date('Y')+1));?>
My Controller
$status =array(0,2,4);
$find_date = $this->data['Transaction']['collect_date'];
$field = array('Transaction.status','Catalogue.title', 'Catalogue.author', 'Catalogue.isbn', 'Location.rack');
$condition = array('OR' => array('AND' =>array('Transaction.return_date <'=> $find_date,'Transaction.status '=> '3'),array('Transaction.status'=> $status)));
$data = $this->Catalogue->Transaction->find('count',array('fields' => $field,'conditions'=>$condition,'order'=>array('Transaction.id desc') ));
$this->set('Found', $data);
And the sql dump
SELECT COUNT(*) AS [count] FROM [transactions] AS [Transaction]
LEFT JOIN [catalogues] AS [Catalogue] ON ([Transaction].[catalogue_id] = [Catalogue].[id])
LEFT JOIN [users] AS [User] ON ([Transaction].[user_id] = [User].[id])
WHERE (((([Transaction].[return_date] < ('01', '09', 2013))
AND ([Transaction].[status] = 3))) OR ([Transaction].[status] IN (0, 2, 4)))
As you can see the date format ('01', '09', 2013). But when try to convert use this
'Transaction.return_date <'=> date('Y-m-d', strtotime($find_date))
it show error:
Warning (2): strtotime() expects parameter 1 to be string, array given [APP\Controller\CataloguesController.php, line 66]
and the sql show:
[Transaction].[return_date] < '1970-01-01'
You could use:
$date = DateTime::createFromFormat('d/m/y', implode('/', $find_date));
'Transaction.return_date <'=> $date->format('Y-m-d');
Edit:
I think the way its meant to be 'flattened' is with
$this->Model->deconstruct('find_date', $find_date);
However, last time i tried to use this, i couldn't get it to work properly, so i went with the above.
http://api21.cakephp.org/class/model#method-Modeldeconstruct
Try converting return date using UNIX_TIMESTAMP in sql query and then comparing it with
strtotime($find_date).

cakephp check multiple tables

I am getting a list of Rate information from the database with conditions. However I wish to add another condition of minimum Stay if the date range has a date in it and rateID form another table called minimum stay. The Rate table already has a min stay but on certain dates I want to over ride this if the date falls within the date range I pass.
I am new to cakephp so I am unsure how to check the minStay table for dates in the date range. Then get the largest minStay and the add it to the condition.
Default minStay in Rate table is 1
Here is the data in the minStay table:
date:31-10-2011 rateID:21 minStay:2
date:1-11-2011 rateID:21 minStay:3
Results: If date range is 31-10-2011 to 2-11-2011 / 2 nights then no results. If 3 nights or more then result.
I hope I have explaind that correctly.
Variable containing the date range is $todays
$conditions = array(
'Rate.enabled'=>1,'Rate.is_corporate'=>$is_corporate, 'Rate.minimum_stay <='=>$days,
'Rate.valid_from < '=>$date_start,'Rate.valid_to >'=>$date_end,
'OR'=>array('Rate.maximum_stay'=>0,'Rate.maximum_stay >='=>$days)
);
$order = 'Rate.list_no';
$this->Rate->contain('Room.id','Room.title','Room.max_adults','Room.max_children');
$rates = $this->Rate->find('all',array('conditions'=>$conditions,'order'=>$order));
I think i understood what you want to do, if not please comment.
To do that you need to do somthing like this (assuming you have something like has many MinStay)
$conditions = array(
'Rate.enabled'=>1,'Rate.is_corporate'=>$is_corporate, 'Rate.minimum_stay <='=>$days,
'Rate.valid_from < '=>$date_start,'Rate.valid_to >'=>$date_end,
'OR'=>array('Rate.maximum_stay'=>0,'Rate.maximum_stay >='=>$days),
'AND' => array('OR'=> array('minStay.date BETWEEN ? AND ?' => array($date_start,$date_end)),
'minStay.minimum_stay <' =>$days )
);
$order = 'Rate.list_no';
$fields = array ('Room.id','Room.title','Room.max_adults','Room.max_children');
$rates = $this->Rate->find('all',array('conditions'=>$conditions,'order'=>$order, 'fields'=> $fields));
I think that will do it, hope it works for you

Resources