I'm trying to create hourly counting groups of tickets. I have to count three tickets for each hour and insert them as a bonus while inserting the remaining ones as a malus; every hour perform this count on a table where tickets are generated. I should calculate based on two time periods, one from 7 in the morning to 15 in the afternoon and one from 15 in the afternoon to 7 in the morning. I was taking a cue from this post, but I can't see the ticket number and time, while I can see the down, up, total and uptime columns. Can anyone help me perform this? I would also like to insert the count of time between the opening and closing of each intervention
Laravel group data by odd amount of hours throughout days
$uptimeData = Ticket::whereYear('created_at', '>=', Carbon::now()->year)
->whereYear('created_at', '<=', Carbon::now()->year)
->orderBy('created_at', 'asc')
->select('ticket_Id', 'created_at')
->get();
$intervals = \Carbon\CarbonInterval::hours(1)->toPeriod('2023/01/01 07:00:00', '2023/01/01 15:00:00');
$uptimeDataTimeline = $uptimeData->groupBy(function ($item, $key) use ($intervals) {
$date = Carbon::parse($item->created_at);
foreach ($intervals as $key => $interval) {
if ($date->hour == Carbon::parse($interval)->addHours(1)->hour) {
$actualHour1 = Carbon::parse($interval)->hour;
if (strlen($actualHour1) == 1) {
$actualHour1 = "0$actualHour1";
}
return $date->format("Y-m-d $actualHour1:00:00");
} else {
if ($date->hour == Carbon::parse($interval)->addHours(1)->hour) {
$actualHour2 = Carbon::parse($interval)->subHours(1)->hour;
if (strlen($actualHour2) == 1) {
$actualHour2 = "0$actualHour2";
}
return $date->format("Y-m-d $actualHour2:00:00");
}
}
}
return $date->format('Y-m-d H:00:00');
});
$uptimeDataTimeline = $uptimeDataTimeline->map(function ($checksInPeriod, $key) {
$down = 0;
$up = 0;
$total = 0;
$uptime = 0;
$fill = '#1fc777';
foreach ($checksInPeriod as $key => $value) {
$total++;
if ($total <= 3) {
$up++;
} else {
$down++;
}
}
$uptime = floatval(number_format(round($up / $total, 5) * 100, 2, '.', ','));
if ($uptime < 100) {
$fill = '#9deab8';
}
if ($uptime < 99) {
$fill = '#fbaa49';
}
if ($uptime < 98) {
$fill = '#e0465e';
}
return [
'total_ticket_Id' => $total,
'down_ticket_Id' => $down,
'up_ticket_Id' => $up,
'uptime' => $uptime,
'fill' => $fill,
];
});
Related
I am having table like below
So there are priority and sqft, i want to start manufacturing schedule (from current date) that every day 1700 SQFT will be processed, like below image
but as you can see its not working
I have tried below code
foreach($priorityArraySum as $key=>$val)
{
$totalDays=ceil($val/1700);
$cutSQFT=$val;
for($j=1;$j<=$totalDays;$j++)
{
if($cutSQFT>1700)
{
echo '1700';
$cutDate=date('Y-m-d', strtotime($cutDate. ' + 1 days'));
$cutSQFT=$cutSQFT-1700;
}
else
{
echo $cutSQFT;
$cutSQFT=$cutSQFT-$cutSQFT;
}
}
}
#Nigel, to Make this dynamic, I have changed code to below, but its not working.
$pln_qry=mysql_query("select * from tbl_mfg_schedule where ms_date='".$today."'") or die(mysql_error());
$pln_data=mysql_fetch_array($pln_qry);
$max = $pln_data['ms_po_sqft'];
$dailyLeft = $max;
$current = reset($priorityArraySum);
$output = [];
//$day = date('Y-m-d');
$day = date('Y-m-d');
while (true) {
$pln_qry=mysql_query("select * from tbl_mfg_schedule where ms_date='".$today."'") or die(mysql_error());
$pln_data=mysql_fetch_array($pln_qry);
$max = $pln_data['ms_po_sqft'];
if ( $current >= $dailyLeft ) {
//$day=date('Y-m-d', strtotime($day. ' + 1 days'));
$output[] = ["priority" => key($priorityArraySum),
"amount" => $dailyLeft,
"day" => $day
];
$day=date('Y-m-d', strtotime($day. ' + 1 days'));
$current -= $dailyLeft;
$dailyLeft = $max;
}
else {
$output[] = ["priority" => key($priorityArraySum),
"amount" => $current,
"day" => $day
];
$dailyLeft -= $current;
if ( ($current = next($priorityArraySum)) === false ) {
break;
}
}
}
This code uses a while() loop to create an output array of the days work. It uses $current to keep track of each item and how much is left to allocate. It also uses $dailyLeft to keep track of how much capacity is left on a particular day. It checks the two and if the current is less than the daily capacity left, it allocates a full day to that item and resets the daily capacity. If there is extra capacity for that day it allocates this item to the day and gets the next item.
The day is only incremented (using $day++) when the capacity for that day is filled...
$max = 1700;
$dailyLeft = $max;
$current = reset($priorityArraySum);
$output = [];
$day = 1;
while (true) {
// echo $current."/".$dailyLeft."=".$day.PHP_EOL;
if ( $current >= $dailyLeft ) {
$output[] = ["priority" => key($priorityArraySum),
"amount" => $dailyLeft,
"day" => $day++
];
$current -= $dailyLeft;
$dailyLeft = $max;
}
else {
$output[] = ["priority" => key($priorityArraySum),
"amount" => $current,
"day" => $day
];
$dailyLeft -= $current;
if ( ($current = next($priorityArraySum)) === false ) {
break;
}
}
}
print_r($output);
i have time slots like
$timeslot = ['09:00-10:00', .... '23:00-00:00', '00:00-01:00'];
I have records with updated time as 23:15:00, 23:30:00, 00:15:00, 09:15:00 etc.
What i'm trying to find is the sum of records between each of the $timeslot. I'm not considering what day got updated, only time i'm looking for.
i tried with:-
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
foreach($data as $val) {
$cnt = 0;
foreach($timeslot as $slots) {
$slot = explode("-", $slots);
if( (strtotime($val) > strtotime($slot[0])) && (strtotime($val) <= strtotime($slot[1])) ) {
$up_time[$slot[0] . '-' . $slot[1]] = $cnt++;
}
}
}
echo '<pre>';print_r($up_time);echo '</pre>';
The expected output is:-
09:00-10:00 = 1
23:00-00:00 = 2
00:00-01:00 = 1
Strtotime is not required since your time can be compared as strings.
This code works as you expected.
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
$timeslot = ['09:00-10:00', '23:00-00:00', '00:00-01:00'];
$up_time = array();
foreach ($data as $val) {
$myTime = substr($val, 0, 5);
foreach ($timeslot as $slot) {
$times = explode("-", $slot);
if (substr($times[1], 0, 3) == "00:") {
$times[1] = "24:" . substr($times[1], 3);
}
if ($myTime >= $times[0] && $myTime <= $times[1]) {
if (!isset($up_time[$slot])) {
$up_time[$slot] = 1;
} else {
$up_time[$slot]++;
}
}
}
}
echo '<pre>';
print_r($up_time);
echo '</pre>';
The if with 'substr' is needed because for midnight you have '00' and not '24' so the computer thinks is an empty set (such as hours bigger then 23 and smaller then 0).
Comparison is made between string because bigger time is also a bigger string since you use 2 digits for hours.
You need to count equal slots so you need an array with an element for each slot and increment if duplicate or create an element if not found (the condition '!isset').
Update for modification request
$data = ['23:15:00', '23:30:00', '00:15:00', '09:15:00'];
// added unused slot 8:00-9:00
$timeslot = ['08:00-09:00','09:00-10:00', '23:00-00:00', '00:00-01:00'];
$up_time = array();
// new initialization
foreach ($timeslot as $slot) {
$up_time[$slot] = 0;
}
foreach ($data as $val) {
$myTime = substr($val, 0, 5);
foreach ($timeslot as $slot) {
$times = explode("-", $slot);
if (substr($times[1], 0, 3) == "00:") {
$times[1] = "24:" . substr($times[1], 3);
}
if ($myTime >= $times[0] && $myTime <= $times[1]) {
$up_time[$slot]++; // simplified
}
}
}
I have two models, Payment and GroupStarts.
Payment has these fields:
student_id, amount_to_pay, student_paid, date_paid, due_date, group_name
On GroupStarts are:
group_name, group_start, group_end, group_status.
This is how it should work:
If payment is made for one month and it expires after month 1, it should add amount_to_pay to that for month 1 and if in month 2 student didn't paid nothing than we add + amount to pay, similar to: if student have to pay $10 and paid so owe is 0 but for next month he didn't paid so we add it to payment $10 if on month 3 he didn't paid we add $10 more to that amount.
How can I do that ?
This is code I tried:
private function getMonthlyUnpayments()
{
$payments = Payment::all();
$unpayment = 0;
$totalPayment = 0;
foreach ($payments as $key => $value) {
$unpayment += $value->amount_to_pay;
$totalPayment += $value->student_paid;
}
$studentsAllU = Student::where('is_canceled', '=', 0)->get();
$groupAllU = Gstart::where('group_status', '=', 0)->get();
$studentGroupAllU = [];
foreach ($studentsAllU as $key => $value) {
foreach ($groupAllU as $keys => $valu) {
foreach ($value->payment as $paymentID) {
if ($value->group_id == $valu->group_name) {
$studentGroupAllU[] = ['name' => $value->full_name, 'student_id' => $value->id, 'gr_id' => $value->group_id, 'paid' => $paymentID->student_paid, 'to_pay' => $paymentID->amount_to_pay, 'due_date' => $paymentID->due_date, 'group_ends' => $valu->group_end];
}
}
}
}
function nb_mois($from, $to)
{
$fromYear = date("Y", strtotime($from));
$fromMonth = date("m", strtotime($from));
$toYear = date("Y", strtotime($to));
$toMonth = date("m", strtotime($to));
if ($fromYear == $toYear) {
return ($toMonth-$fromMonth)+1;
} else {
return (12-$fromMonth)+1+$toMonth;
}
}
function createDateRangeArray($strDateFrom,$strDateTo)
{
$aryRange=array();
$iDateFrom=mktime(1,0,0,substr($strDateFrom,5,2), substr($strDateFrom,8,2),substr($strDateFrom,0,4));
$iDateTo=mktime(1,0,0,substr($strDateTo,5,2), substr($strDateTo,8,2),substr($strDateTo,0,4));
if ($iDateTo>=$iDateFrom)
{
array_push($aryRange,date('Y-m-d',$iDateFrom));
while ($iDateFrom<$iDateTo)
{
$iDateFrom+=86400;
array_push($aryRange,date('Y-m-d',$iDateFrom));
}
}
return $aryRange;
}
$dtArr = [];
$incrementer = 0;
$inc = 0;
foreach ($studentGroupAllU as $key => $value) {
if ($value['group_ends'] >= $value['due_date'] || $value['paid'] < $value['to_pay']) {
if ($value['paid'] < $value['to_pay']) {
$incrementer += ($value['to_pay'] - $value['paid']);
}
else {
$incrementer += ($value['to_pay']);
}
$dtArr[] = ['days_left' => count(createDateRangeArray($value['due_date'], $value['group_ends'])), 'group_id_d' => $value['gr_id'], 'paid' => $value['paid'], 'to_pay' => $value['to_pay'], 'student_id' => $value['student_id'], 'owe' => ($inc +=($value['to_pay'] - $value['paid'])), 'dates' => createDateRangeArray($value['due_date'], $value['group_ends']),'dates_fron_last_payment' => createDateRangeArray($value['due_date'], Carbon::now()->format('Y-m-d')), 'days_fron_last_payments' => count(createDateRangeArray($value['due_date'], Carbon::now()->format('Y-m-d')))];
}
$inc = 0;
}
function uniqueAssocArray($array, $uniqueKey) {
$arr = array();
foreach($array as $key => $item)
{
$arr[$item[$uniqueKey]][$key] = $item;
}
ksort($arr, SORT_NUMERIC);
return $arr;
}
$dd = uniqueAssocArray($dtArr, 'group_id_d');
$tpStudentGr = 0;
// dd($dtArr);
foreach ($dtArr as $key => $value) {
foreach ($value['dates'] as $k => $val) {
if ($val == Carbon::createFromFormat('Y-m-d', $val)->startOfMonth()->format('Y-m-d') && $val <= Carbon::now()->startOfMonth()->format('Y-m-d')) {
if ($value['paid'] < $value['to_pay']){
$tpStudentGr += ($value['to_pay'] - $value['paid'] + $value['to_pay']);
}
if ($value['paid'] == $value['to_pay']){
$tpStudentGr += $value['to_pay'];
}
}
}
if ($value['days_left'] > 0) {
}
}
$tpStudentGr = $unpayment - $totalPayment;
return $tpStudentGr;
}
got an update for you with my function. This also now works as it should, but I need it to work out total sick, based on years of service up to the 1st day they take of sick. Hope I have made that clear. I have marked the line of code that works out my sick but i only gives me one all the time, even when I know where are more years for that selected user.
Please help?
Glenn Curtis
function sickDay($id = null) {
if($this->CURRENT_USER['User']['role_id'] > 3) { //directors and admins
/*if(empty($this->data) || !isset($this->data['Holiday']['id'])) {
} else {*/
//Get the user sick days
$userSickDays = $this->Holiday->find(
'all',
array(
'conditions' => array(
'Holiday.holidaystype_id' => 3,
'Holiday.user_id' => $id
),
'order' => 'Holiday.startson ASC'
));
//Get years of service
$userContracts = $this->Holiday->User->Contract->find(
'all',
array(
'conditions' => array( 'Contract.user_id' => $id), //$data['user_id']),
'order' => array( 'Contract.startson' => 'ASC' )
));
//Loop through the user's sick days
foreach ($userSickDays as $k => $sickDay) {
//Get number of days in the current sick day
$totSickdays = $this->Holiday->getNumberDaysFromHoliday($sickDay['Holiday']['id']);
//Get number of sick days for the past 12 months
if($k > 0) {
for($i=0; $i<$k; $i++) {
if((strtotime(gmdate("Y-m-d", $sickDay['Holiday']['startson'])." -1 year GMT")) <= $userSickDays[$i]['Holiday']['startson']) {
$totSickdays += $this->Holiday->getNumberDaysFromHoliday($userSickDays[$i]['Holiday']['id']);
}
}
}
foreach ($userContracts as $y => $contract) {
THIS LINE HERE->$yearsService = $contract['Contract']['startson'] <= $sickDay['Holiday']['startson'];
if ($contract['Contract']['startson'] <= $sickDay['Holiday']['startson']) {
if ($yearsService <= 1) {
$entitlement = 10;
$remaingDays = $entitlement - $totSickdays;
//echo 'one year';
} elseif ($yearsService <= 2) {
$entitlement = 20;
$remaingDays = $entitlement - $totSickdays;
//echo 'two years';
} elseif ($yearsService <= 4) {
$entitlement = 40;
$remaingDays = $entitlement - $totSickdays;
//echo 'up to five years';
} elseif ($yearsService >= 5) {
$entitlement = 60;
$remaingDays = $entitlement - $totSickdays;
//echo 'five years or more';
} else {
$entitlement = 0;
$remaingDays = 0;
//echo 'no sick pay';
}
} //End of if statement.
} //End of $userContracts Foreach Loop
debug($yearsService);
} //End of Foreach Loop
//$this->render('/artists/holidayslist');
//} //End For if empty check
} // End for if CURRENT_USER
die();
} //End of Function
OLD POST BELOW
Now I have asked for help on this before, however that was over one selected area of my function, to get number of sick days. That now works, I found a function that was built for me within the site I am working on. So I have total number of sick days entered within the database. Now I don't seem to be able to work out why I cant set that to my years of service.
To make my myself more clearly, the outcome of this function is to check the current users sick taken within a selected year. But to a annual year, a contracted year, e.g. may to may.
That is why I have a number of if statements to set up the users entitlement, as that changed based on years of service. Then when that is set, to take off the sick days the user has taken within that contracted year.
I hope I have explain what I want to do, if that is not clear, please let me know and I try and explain in more detail.
Please help, this is written for a page used in a CakePHP project.
Many Many Thanks
Glenn Curtis
function sickDay($id = null) {
if($this->CURRENT_USER['User']['role_id'] > 3) { //directors and admins
//Caculate if it's a full pay, half pay or nothing
//$data = $this->data['Holiday'];
//Get Holidaytypes
$userSickDays = $this->Holiday->find(
'all',
array(
'conditions' => array(
'Holiday.holidaystype_id' => 3,
'Holiday.user_id' => $id
)
)
);
//Get starting date
$contracts = $this->Holiday->User->Contract->find(
'all',
array(
'conditions' => array(
'Contract.user_id' => $id //$data['user_id']
),
'order' => array(
'Contract.startson' => 'ASC'
)
)
);
$start = array_shift($contracts);
$end = array_pop($contracts);
$endDate = $end['Contract']['endson'];
$startDate = $start['Contract']['startson'];
if (empty($endDate)) { $endDate = time('now'); }
$SortEnd = strftime("%Y", $endDate);
$SortStart = strftime("%Y", $startDate);
$YearsService = $SortEnd - $SortStart;
//Get How Many sick days
foreach ($userSickDays as $sickDay) {
$typesDataEnds = strtotime($sickDay['Holiday']['endson']);
$typesDataStarts = $sickDay['Holiday']['startson'];
$DateNow = date('U', strtotime('Now'));
$GetSickDays = $this->Holiday->getNumberDaysFromHoliday($sickDay['Holiday']['id']);
$TotalSick += $GetSickDays;
if ($YearsService <= 1) {
$SetFullEntitlement = 5;
$SetHalfEntitlement = 5;
//echo 'one year';
} elseif ($YearsService <= 2) {
$SetFullEntitlement = 10;
$SetHalfEntitlement = 10;
//echo 'two years';
} elseif ($YearsService <= 5) {
$SetFullEntitlement = 20;
$SetHalfEntitlement = 20;
//echo 'up to five years';
} elseif ($YearsService >= 6) {
$SetFullEntitlement = 30;
$SetHalfEntitlement = 30;
//echo 'five years or more';
} else {
$SetFullEntitlement = 0;
$SetHalfEntitlement = 0;
//echo 'no sick pay';
}
}
//$this->render('/artists/holidayslist');
} // End for if CURRENT_USER
die();
} //End of Function
your code seems too complicated for what (it seems) is just
return (($TotalAnnualEntitlement - $SickDaysTakenThisYear) > 0) ? true : false;
You need to work out their entitlement, based on how long they have been contracted - easy enough, You then need to take their entitled holiday from the number of days they have already taken. Again, seems easy enough.
If they have any days remaining, you want to return true. If there have used their allowance, or gone over, return false.
or am i missing something?
This is my new code, its almost working, but I think my while loop is wrong some where?
Same as before, gets users taken sick puts it into a var. Then get users entitlement based on years of service, then work out what they have taken and see if the user has used all the full entitlement, then to see if they have used all there half pay entitlement.
Please Help?
if($this->CURRENT_USER['User']['role_id'] > 3) { //locks out user types
//Get Holidaytypes
$types = $this->Holiday->find(
'all',
array(
'conditions' => array(
'Holiday.holidaystype_id' => 3,
'Holiday.user_id' => $id
)));
//Get starting date
$contracts = $this->Holiday->User->Contract->find(
'all',
array(
'conditions' => array(
'Contract.user_id' => $id//$data['user_id']),
'order' => array('Contract.startson' => 'ASC')
)
);
//Get How Many sick days
foreach ($types as $key => $value) {
global $SickTotal;
$typesDataEnds = strftime ("%u-%d-%Y", $types[$key]['Holiday']['endson']);
$typesDataStarts = strftime ("%u-%d-%Y", $types[$key]['Holiday']['startson']);
$SickTotal = count($typesDataEnds - $typesDataStarts);
//echo $SickTotal;
//Get Contract Start & End Dates
$start = array_shift($contracts);
$end = array_pop($contracts);
$endDate = $end['Contract']['endson'];
$startDate = $start['Contract']['startson'];
if (empty($endDate)) {
$endDate = time('now');
}
if (!empty($startDate)) {
$SortEnd = strftime("%Y", $endDate);
$SortStart = strftime("%Y", $startDate);
$YearsService = $SortEnd - $SortStart;
if ($YearsService <= 1) {
$SetFullEntitlement = 5;
$SetHalfEntitlement = 5;
//echo 'one year';
} elseif ($YearsService >= 2) {
$SetFullEntitlement = 10;
$SetHalfEntitlement = 10;
//echo 'two years';
} elseif ($YearsService >= 5) {
$SetFullEntitlement = 20;
$SetHalfEntitlement = 20;
//echo 'up to five years';
} elseif ($YearsService > 5) {
$SetFullEntitlement = 30;
$SetHalfEntitlement = 30;
//echo 'five years or more';
} else {
$SetFullEntitlement = 0;
$SetHalfEntitlement = 0;
//echo 'no sick pay';
}
} else {
$YearsService = 0;
//echo 'Sorry No Start Date For You Found!';
}
while ($SickTotal > 0) {
if ($SetFullEntitlement != 0) {
$SetFullEntitlement--;
} elseif ($SetHalfEntitlement != 0) {
$SetHalfEntitlement--;
}
}
echo 'FullPay:';
echo $SetFullEntitlement;
echo '<br/><br/>Halpay:';
echo $SetHalfEntitlement;
echo $SickTotal;
}
debug($types);
die();
//$this->render('/artists/holidayslist');
}
}
If ($startdate <= 1 year) {
If that's literally what you've typed, it's not going to work. Maybe strtotime might make some sense of it?
In any case,
For ($i = $Totalsick, $i >= $Fulldays, $i--) {
For ($i = $Totalsick, $>= $Halfdays, $i--) {
you're missing an $i in there - you're evaluating nothing against $Halfdays. You're also using $i for two seperate loops, so they're both on the same counter. switch your second loop to use a different variable.
I'm not quite sure I follow exactly what you are trying to do here but you could tidy up your code a bit and save on lines of code. I assume that $startdate is how many years ago the user started.
$sickdays= array( 0=>5, 1=>10, 2=>20, 5=>30 );
$userdays= 0;
foreach ( array_keys( $sickdays ) as $years_service )
{
if ( $years_service <= $startdate )
$userdays=$sickdays[$years_service];
}
Now $userdays should be the correct number of paid sick days and half days ( the two are always the same in your example ) for this user. A simple comparison should be sufficient to check whether they have taken less or more than their allotted number of days and half days.
I haven't tried this as I'm not working with PHP today, so I'm sure someone will shoot me down directly, but by setting your variables once and writing fewer lines you should find your code gets easier to maintain.