Laravel - after date validation with date from rules set - validation

I'm trying to validate two dates to ensure one is greater than the other using the after validate rule. I have my rules set like this:
$rules = array(
'date_from' => 'required|date_format:"d/m/Y"',
'date_to' => 'required|date_format:"d/m/Y"|after:date_from',
// more rules ...
);
When using the following values:
date_from = "01/06/2014" and date_to = "01/06/2014" OR date_to = "12/06/2014" everything is hunky dory, however.. using anything above 12 for day fails i.e. date_to = "13/06/2014" to date_to = "31/06/2014"
I've also tried this and it gives the same results:
$dateFromForm = Input::get('date_from');
$rules = array(
'date_from' => 'required|date_format:"d/m/Y"',
'date_to' => 'required|date_format:"d/m/Y"|after:' . $dateFromForm,
);
Quite clearly to me it's reading the day as the month, any ideas what I'm doing wrong here?
Thanks

If you look at the Laravel docs - it says
The dates will be passed into the PHP strtotime function.
The problem with strtotime is that it assumes you are using m/d/Y. If you want d/m/Y - you need to change it to d-m-Y to be correctly parsed.
So change your date format to d-m-Y and it will work.

Related

how to use increment function in laravel

i am using DB to store values in database.
i have "course fees" column i what to "increment" the "course_fees" value in column.
for example
DB::table('student')->where('registration_id','=', $request->registration_id)->increment(['course_fees' =>$request->course_fees]);
this code increment the inserted value
how can i modified below code for increment "course_fees" value like above
DB::table('student')->where('registration_id','=', $request->registration_id)->update(['payment_date' => $request->payment_date,'balance_fees' => $request->balance_fees,'course_fees' =>$request->course_fees]);
You cannot use this method to increment multiple fields. You can use:
$studentQuery = DB::table('student')->where('registration_id','=', $request->registration_id);
(clone $studentQuery)->increment('payment_date',$request->payment_date);
(clone $studentQuery)->increment('balance_fees', $request->balance_fees);
(clone $studentQuery)->increment('course_fees', $request->course_fees);
but this way you will run 3 database queries to update.
But if you are sure there is exactly single record found for registration_id you can do it like this:
$student = DB::table('student')->where('registration_id','=', $request->registration_id)->first();
$student->update([
'payment_date' => $student->payment_date + $request->payment_date,
'balance_fees' => $student->balance_fees + $request->balance_fees,
'course_fees' => $student->course_fees + $request->course_fees
]);
EDIT
If you want to increment only course_fees column and want to update other 2 columns from input you can use:
DB::table('student')->where('registration_id','=', $request->registration_id)
->increment('course_fees' , $request->course_fees, [
'payment_date' => $request->payment_date,
'balance_fees' => $request->balance_fees
])
This is documentation about increment/decrement methods.
increment()/decrement() can take 3 parameters: $column, $amount, $extra.
$column is the field that you want to increment
$amount is by how much you want to increment the field by
$extra is an array of attributes that you also want to update in the query.
If you don't pass an amount the default for $amount is 1.
To achieve what you're after you could do:
DB::table('student')
->where('registration_id', $request->registration_id)
->increment('course_fees', $request->course_fees, [
'payment_date' => $request->payment_date,
'balance_fees' => $request->balance_fees,
]);

Adapt my code by adding start_time and stop_time in my booking

I have to add in my TrainingController two variables => start_time & stop_time.
In my old code I had this:
$conflictTraining = Training::where('fk_motorbike', $request->get('fk_motorbike'))
->whereDate('date_seance', "=" , Carbon::parse($date_seance))
->where('hour_start', "<=" , $request->get('hour_start'))
->where('hour_end', ">=" , $request->get('hour_end'))
->where('fk_former', $request->get('fk_former'))
->first();
My problem is that I would like to do a checking. How Can I avoid a duplicate for my request $conflictTraining with start_time & stop_time..
Here is my code for now:
public function store(Request $request)
{
$request->validate([
'date_seance' => 'required',
'hour_start' => 'required',
'hour_end' => 'required',
'fk_motorbike' => 'required',
'fk_former' => 'required',
'fk_student' => 'required',
'fk_typeseance' => 'required'
]);
$start_time = Carbon::createFromFormat('d-m-Y H:s', $date_seance . ' ' . $hour_start);
$stop_time = Carbon::createFromFormat('d-m-Y H:s', $date_seance . ' ' . $hour_end);
$conflictTraining = Training::where('fk_motorbike', $request->fk_motorbike)
->where('start_time', "<=", $start_time)
->where('stop_time', ">=", $stop_time)
->first();
if (isset($conflictTraining)) {
return redirect()->route('trainings.index')
->with('error', 'training duplicate');
}
$data = $request->all();
$data['start_time'] = $start_time;
$data['stop_time'] = $stop_time;
Training::create($data);
return redirect()->route('trainings.index')
->with('success', 'Add');
}
I thank you in advance for your help.
If you are asking how to add a new constraint for a couple of new database fields, start_time and stop_time, I think you are pretty close with your current query for $conflictTraining.
You didn't state what the specific problem was, but I'm guessing that these lines:
$start_time = Carbon::createFromFormat('d-m-Y H:s', $date_seance . ' ' . $hour_start);
$stop_time = Carbon::createFromFormat('d-m-Y H:s', $date_seance . ' ' . $hour_end);
are producing something that doesn't match the format in the database for start_time and stop_time. If you break down what you have created in those variables, you are basically telling Carbon to make a variable that looks something like this: "15-10-2019 10:00:00" (with the caveat that the 00 is seconds, not minutes since you used s instead of i).
So your first question should be, 'is my database storing the start time in the exact format that shows when I dump $start_time?' If not, the query will never produce a hit. You can certainly store your start times and stop times in the database as a a date and time... but keep in mind, you will be constrained by the date as well as the time if you do so. In other words, if you just want a start time to be 10:00 on any day, that won't work because the database is storing 10:00 on a specific date.
One way to resolve this is to keep this as simple as possible. If those times are NOT linked to a specific date, and are always going to be on the hour - save them as a simple number. E.g. 08 or 22. Then, you don't need to use Carbon, you are just comparing simple integers. If you want to use an actual time (you might want 18:20 or something), this is not much more complex - you just need to change the way you store and create the time.
You can play with this, but the general idea would be to just store / create the time in a consistent format between database and what you create from the form. So for start_time, you could perhaps save the hours and minutes in a different column. Or calculate the number of minutes after midnight and store as an integer. Or even store as text and use Carbon on both sides to make into a formatted object.
Personally I find it easiest to work with integers, so I would make a calc (maybe mins past midnight) and use that calc across the program to just stay with integers. There are a lot of ways to solve this - hopefully this explains the issue to you.

Can't add additional where queries in Ardent Model

I'm having a problem using LaravelBook/Ardent. My logic is exclude the soft deleted rows in unique validation using the code:
public static $rules = array(
'name' => 'required|unique:paper_colors,name,deleted_at,NULL',
'description' => 'required|between:2,255',
'code' => 'required'
);
But when I run the updateUniques I'm still getting The name has already been taken. and this sql:
select count(*) as aggregate from `paper_colors` where `name` = '4/0' and `id` <> '2'
I'm expecting the sql will be:
select count(*) as aggregate from `paper_colors` where `name` = '4/0' and `id` <> '2' and `deleted_at` is null
Can someone help me to solve this. I'm stuck almost last night on this. Still can't figure it out how to deal with this.
I found out that Ardent is dropping the Laravel Validation feature: Adding Additional Where Clauses
So my solution to overcome this bug is to add additional code under LaravelBook\Ardent\Ardent#buildUniqueExclusionRules at line: 799, but I didn't do that since I'm depending for their any updates in the future. So I just create a class that extend LaravelBook\Ardent\Ardent and copy buildUniqueExclusionRules and modify it.
if (count($params)>2)
{
$c = count($uniqueRules);
for ($i=1; $i < count($params); $i++, $c++) {
$uniqueRules = array_add($uniqueRules, $c, $params[$i]);
}
}

How to validate start date should be greater than current date in yii

I had a form in which a start date field is there. I need to check whether the start date entered is greater than Current date using yii validation rule.
Can any one help me in doing this?
This might work (needs to be added to the model rules)
array('startDate', 'compare', 'compareValue' => date("Y-m-d"), 'operator' => '>'),
$date_today = date('Y-m-d', strtotime(' -1 day'));
// -1, -2 depend on how back you want to go!!
$date_today = date("m/d/Y", strtotime($date_today));
return [
[
'alert_start_date', 'compare', 'compareValue' => $date_today,
'operator' => '>',
'message' => $attribute.'Alert Start Date Cannot be a date in the past'
],
];

how to get all products between two dates?

how to get all products between two dates like last month products, this month products , last week products and this week products etc.
i tried with this:
// current day to start with
$start = mktime(0,0,0,date('m'), date('d'), date('Y'));;
// calculate the first day of last month
$first = date('YYYY-MM-DD',mktime(0,0,0,date('m',$start) - 1,1,date('Y',$start)));
// calculate the last day of last month
$last = date('YYYY-MM-DD',mktime(0, 0, 0, date('m') -1 + 1, 0, date('Y',$start)));
if($filter == "lastmonth"){
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('updated_at', array('gteq' =>$first));
$collection->addAttributeToFilter('updated_at', array('lteq' => $last));
}
but i am not able to get the result :( any help ?
Modified after Daniel response !
1) First of all you need to change you date formate from 'YYYY-MM-DD' to 'Y-m-d'. This will return a date formate which magento records have.
2) There is a special condition for date as bellow mention with your example.
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('updated_at', array('gteq' =>$first));
$collection->addAttributeToFilter('updated_at', array('lteq' => $last));
To.
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('updated_at', array(
'from' => $first,
'to' => $last,
'date' => true,
));
I tried your code and had to swap 'lteq' and 'gteq' to make it work. The $fromdate is the lower number so you are searching for dates greater than that number.
Also you must remember to format the dates as MySQL likes it; date('Y-m-d').
PS. See the comparison operators for a full list
There is one issue with your code:
$collection->addFieldToFilter()
should be:
$collection->addAttributeToFilter()
I know that the question is little bit old but as it is quite well ranked in search engine results, I will correct the date() function that better take as arguments something like : Y-m-d H:i:s.
I hope it will help !

Resources