I have a Leave Application that checks when the users request a leave and after approval, it removes the days from the total amount they have left in the database the problem is the leave is taken only the latest so if 2 people were requesting at the same time it would take it for both the same amount because it's only taking it from the latest which is here in the User Model
public function leaveBalance($id)
{
$leave =new Leave;
$daysUsed= $leave->numberOfDays($id);
$days_granted = User::where('id', $id)
->latest()->first();
$leave_days_granted = $days_granted->leave_days_granted;
return $leave_days_granted - $daysUsed;
}
And here in the Leave Model
protected $dates = ['from', 'to'];
public function numberOfDays($id)
{
$datesx =Leave::where('user_id', $id)
->latest()->first();
$from =$datesx->from;
$to =$datesx->to;
$datetime1 = new DateTime($from);
$datetime2 = new DateTime($to);
$interval = $datetime1->diff($datetime2);
$days = $interval->format('%a');//now do whatever you like with $days
return $days;
}
As you can see it's taking it from the ->latest()->first(); but I don't know another way to select it and thus why I need help I would appreciate any suggestion
User::where('id', $id)->first();
Related
I'm working on a Symfony project that makes use of a
Repository file in which I have declared and created an instance of a query builder
(repository1)
$mk = $this->createQueryBuilder('up');
$later = date("Y-m-d", strtotime("-3 months"));
$today = date("Y-m-d");
$mk->andWhere('up.period BETWEEN :start AND :end');
$mk->setParameter('start', $later);
$mk->setParameter('end', $today);
return $mk->getQuery()->getResult();
automatically this generates data for my page between the above dates.
Now I want to create a form where I can make a search between two dates.
with the intention of passing the posted data from this form to my controller into my method below
My controller below (controller1)
protected function getData(EntityManagerInterface $entityManager,Request $request) {
// this code to get data from repository
$entityManager->getRepository(repository1::class)->getName()
// receive posted data
$date1 = $request->get('date');
$date2 = $request->get('date');
// now how to pass data to my repository1
}
Please how do I edit what I have to post data from within my controller to my (repository1)
so then it would be
$mk = $this->createQueryBuilder('up');
$later = $date1;
$today = $date2;
$mk->andWhere('up.period BETWEEN :start AND :end');
$mk->setParameter('start', $later);
$mk->setParameter('end', $today);
return $mk->getQuery()->getResult();
is this even possible, or im over thinking it?
RepositoryClass
public function getByStartEndDate(DateTimeInterface $start, DateTimeInterface $end)
{
return $this->createQueryBuilder('up')
->andWhere('up.period BETWEEN :start AND :end')
->setParameter('start', $start)
->setParameter('end', $end)
->getQuery()
->getResult()
;
}
Controller Class
private function getData(Request $request, RepositoryClass $repo)
{
// May need to convert these to DateTime objects
$start = $request->get('start');
$end = $request->get('end');
$records = $repo->getByStartEndDate($start, $end);
// do what you want with the records here
}
You can give the dates as parameters to your method.
Controller Class:
protected function getData(EntityManagerInterface $entityManager,Request $request) {
$start = $request->get('start') ? new \DateTime($request->get('start')) : null;
$end = $request->get('end') ? new \DateTime($request->get('end')) : null;
$result = $entityManager->getRepository(Entity::class)->getName($start, $end);
// do with result as desired
}
Repository Class:
public function getName(\DateTimeInterface $start, \DateTimeInterface $end)
{
return $this->createQueryBuilder('up')
->andWhere('up.period BETWEEN :start AND :end')
->setParameter('start', $start)
->setParameter('end', $end)
->getQuery()
->getResult()
;
}
How can I add delay to laravel observer before it execute function?
I have this code but it doesn't work:
public function created(School $school)
{
$addTime = Carbon::parse($school->created_at)
->addSeconds(6);
if(Carbon::now() = $addTime) {
$manager = School::where('id', $school->id)->with('manager')->first();
$user = User::where('id', $school->manager->id)->first();
Mail::to($user->email)->locale('id')->queue(new SchoolGenerated($school, $user));
}
}
Logic
I have such function in my controller
public function store(Request $request) {
$school = new School;
//.....
if($school->save()){
//save manager.....
}
}
As you see I assign manager to school after school data been saved therefore if I run my observe immediately It won't find my user (manager) so I need to put delay into my observer till manager data stored as well.
How can I add delay to my observer?
you can use sleep(int $seconds ) function in php, try this:
public function created(School $school)
{
// add delay
$seconds = 10;
sleep($seconds);
$manager = School::where('id', $school->id)->with('manager')->first();
$user = User::where('id', $school->manager->id)->first();
Mail::to($user->email)->locale('id')->queue(new SchoolGenerated($school, $user));
}
}
Solved
As there was no way for me to get school data after manager being created so I've changed my observe to rule on manager creation instead of school creation that way I can get manager data and based on manager data get school data. So I just basically rotate the logic 180˚ and got my desire result.
I have an events table and a tickets table. I am trying to decrement the available tickets in regular_atendies by the ordered tickets and same for vip
This is my store method:
// Create Ticket
$ticket = new Ticket();
$ticket->userName = $request->input('userName');
$ticket->userEmail = $request->input('userEmail');
$ticket->phoneNumber = $request->input('phoneNumber');
$ticket->regular_quantity = $request->input('regular_quantity');
$ticket->vip_quantity = $request->input('vip_quantity');
$ticket->event_id = $request->route('id');
$ticket->total = $request->input('regular_quantity') + $request->input('vip_quantity');
$event = Event::find(1);
$event = Event::where('id',$ticket->event_id);
if ($ticket->regular_quantity<$event->regular_attendies) {
DB::table('events')->decrement('regular_attendies', $ticket->regular_quantity);
} elseif ($ticket->vip_quantity<$event->$vip_attendies) {
DB::table('events')->decrement('vip_attendies', $ticket->vip_quantity);
} else {
echo "error";
}
$ticket->save();
return redirect('/');
You never execute your query. This line:
$event = Event::where('id',$ticket->event_id);
Needs a closure:
$event = Event::where('id',$ticket->event_id)->first();
// or ->firstOrFail();, etc
Otherwise, it's a Builder instance, and you can't access columns from a Builder. Using ->first() will convert it to an Event instance, or null.
Also, having this:
$event = Event::find(1);
// ^ I assume this is used for testing, probably should comment it out.
$event = Event::where('id',$ticket->event_id)->first();
Is redundant. Use one or the other.
i want to calculate the time difference and insert it into database...my model name is "booking" and the start time and end time will be taken input from users..and total_duration will be calculated from these two and will be inserted into database...i use these codes...but won't working.this is my controller.
<?php
/*namespace App\booking;*/
use Carbon\Carbon;
namespace App\Http\Controllers;
use App\booking;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Model;
class RoombookController extends Controller
{
public function showreport(Request $request)
{
/* dd($request->all());
*/ $time= Carbon.now();
$booking = new booking;
$booking->bookdate = $request->input('bookdate');
$booking->roomname = $request->input('roomname');
//echo $datefrom;
$booking->starttime =$startTime= $request->input('starttime');
$booking->endtime = $finishTime=$request->input('endtime');
$booking->purpose = $request->input('Purpose');
//echo $dateto;
$time->sTime = Carbon::parse($startTime);
$time->fTime = Carbon::parse($finishTime);
$time->total_time = $fTime->diffForHumans($sTime);
$booking->total_duration = $time->total_time;
$booking->save();
}
}
Using Carbon for calculation execution time is not very good idea. Just use plain old microtime():
$start = microtime(true);
.... // Do something here.
$end = microtime(true);
$time = $end - $start;
I think you should first convert it into seconds
$totalDuration = $finishTime->diffInSeconds($startTime);
and then desirable format
gmdate('H:i:s', $totalDuration);
or try this if this work for you
$finishTime->diff($startTime)->format('%H:%i:%s');
Is it possible to change the system date for php (only).
I want this for debugging/testing purpose.
//Test 1 (2010-01-01)
$datetime = new DateTime(); //(2010-01-01)
//Test 2 (2010-02-01)
$datetime = new DateTime(); //(2010-02-01)
I can't really change the real system clock, because other developers are working on the same system (well I could but still).
I'm just hoping this is possible, or that someone knows a nice trick.
When I print the phpinfo(); I see the following line:
Timezone Database internal
Maybe it's changeable to something like "manual" and ad a timezone with +120
Thanks!
This sounds like an encapsulation issue -- why not search for all mentions of date() or time() and replace them with $site->getDisplayedDate(), or something else appropriate to your code?
I feel your pain, but I don't think there's any way to do this. Think about it this way... how would you feel if, in some unrelated code, you called time() and it gave you some date 3 weeks in the future?
You can change only timezone (and ofcourse only couple hours forward / backward; and not whole day forward), but thats not correct solution...
You could create your own DateTime class that extends the default DateTime and hence change the behaviour:
<?php
class CustomDateTimeVariables {
public static $date = 'now';
}
class CustomDateTime extends DateTime {
public function __construct($time = null, DateTimeZone $timezone = null) {
if ($time === null) {
$time = CustomDateTimeVariables::$date;
}
if ($timezone !== null) {
parent::__construct($time, $timezone);
} else {
parent::__construct($time);
}
}
}
CustomDateTimeVariables::$date = '2010-01-01';
$datetime1 = new CustomDateTime();
CustomDateTimeVariables::$date = '2010-01-02';
$datetime2 = new CustomDateTime();
var_dump($datetime1->Format('Y-m-d H:i:s')); //"2010-01-01 00:00:00"
var_dump($datetime2->Format('Y-m-d H:i:s')); //"2010-01-02 00:00:00"
?>
DEMO
This way you can also set the default time very easily (check CustomDateTimeVariables):
<?php
class CustomDateTimeVariables {
public static $date = 'now +120 hours';
}
class CustomDateTime extends DateTime {
public function __construct($time = null, DateTimeZone $timezone = null) {
if ($time === null) {
$time = CustomDateTimeVariables::$date;
}
if ($timezone !== null) {
parent::__construct($time, $timezone);
} else {
parent::__construct($time);
}
}
}
$datetime = new CustomDateTime();
var_dump($datetime->Format('Y-m-d H:i:s')); //"2013-10-29 13:37:39"
?>
..and when it goes live, you can simply change the default back to now.