For php does not increase - php

I have a table of users in a database, where I have the following fields:
id_usuario
login
passwd
dias_disponibles (Fixed users have 24 days available)
fecha_ingreso (Date entry in company)
tipo_usuario (Fixed or Temporary)
Each user can make a vacation request. The user admin is responsible for adding the new users. My problem is with temporary users. A temporary user will have the available days according to the months worked up to one year. For every month worked, dias_disponibles is increased by 2. For example, if user1 since joining the company, it has been working for 2 months now it will have 4 dias_disponibles and so on until it takes 12 months, then from there, it will always be 24 dias_disponibles . I have this function that calculates the difference of months since I joined the company until today:
function difmeses($fechaingreso){
$fechainicial = new DateTime($fechaingreso);
$fechaactual = (new DateTime)->format('Y-m-d H:i');
$fechafinal = new DateTime($fechaactual);
$diferencia = $fechainicial->diff($fechafinal);
$meses = ( $diferencia->y * 12 ) + $diferencia->m;
return $meses;
}
My question is what to use so that it increases until 12 months in the company, if it takes 12 months, stop. I have created this for, but I do not know how to continue so that it increases in 2 days available:
$mes = difmeses("2018-03-15 00:00");
for($i = 1; $mes <= 12; $i++){
mysql_query("update sec_users set dias_disponibles = dias_disponibles + 2 where login = 'user1'");
}
It does not do what I want very well.

First of all your logical problem
The problem you have is in your last part of the code
$mes = difmeses("2018-03-15 00:00");
for($i = 1; $mes <= 12; $i++){
mysql_query("update sec_users set dias_disponibles = dias_disponibles + 2 where login = 'user1'");
}
First of all, there is no need at all to use a for loop here. You overwrite the update commands of the previous runs of the loop, so at the end only the last one will be in the table. Because of this you can work with the last one without a loop.
Sencond you got a really simple formula here: Free days = (month worked * 2) max 24. Just write that down as code:
$mes = difmeses("2018-03-15 00:00");
$dias = max($mes * 2, 24);
mysql_query("UPDATE sec_users SET dias_disponibles = $dias where login = 'user1'");
Now another huge problem
Do not use the mysql_ functions. They are deprecated! Instead use the mysqli_ functions or PDO and read about prepared statements.

Related

rowCount for items over 45 days old

I have a table and use this to show me how many days the widgets have been in stock, this is the code I am using for this
$getWidgets = $db->prepare("SELECT * FROM widgettracker WHERE id=id");
$getWidgets->execute();
$widgets = $getWidgets->fetchAll();
foreach ($widgets as $widget) {
$startDate = new DateTime();
$endDate = new DateTime($widget['dadded']);
$diff = date_diff($endDate,$startDate);
$days = (int) $diff->format('%a');
I have info boxes at the top of the screen giving me different widget info, what I wanted is one of these info boxes to give me a total of how many widgets have been in stock for 45 days +
I am using this code for other sections of the site but I hate working with days/dates and simply cannot get my head round where and how I put the count in for the ones over 45 days
$widget45days = $db->query("SELECT id FROM widgettracker WHERE widgetstatus='Widgets for Sale'");
$widget45dayscounted = $widget45days->rowCount();
The query should look like this:
SELECT *
FROM widgettracker
WHERE dadded < NOW() - INTERVAL 45 DAY;

php - how to increment a user's known earning every day for 4 months

I want to display to a user an amount per day and increment it until the next 124 days assumed to be four months.
I have a system where a user invest and a total ernable profit is calculated with the percentage ROI for such stock. Assuming someone invested in a stockA that has 20% ROI and matures in 4 months; assuming a user purchased that stockA that is sold $100 and he bought 4 units meaning he spent $400 and will earn
as follows:
$units = 4;
$cost = 100;
$roi = 20/100;
$total_invested = $units * $cost;
$profit = $total_invest * $roi;
// $profit will be $80
My problem is I want to display value of $profit/124 that is the displaying a fraction of total earning to the user daily until maturity of 4 months. I can't figure out how to do that daily not just with loop of 124 iterations.
that is if the user total earning is $80/124 giving 0.65 on the first day and increment it with same value the next day until it reached the end date which is 4 months from now
/**
*
* display and increment earning every day for 4 months or 124 days
*
*/
function display_earning() {
$profit = $profit_roi;
$dateBegin = now();
$dateEnd = "date of 4 month from now";
$earning = 0;
for ($i = 0; $i < 124; $i++) {
$earning += $profit / 124;
return $earning;
}
}
I think your problem is to update and save the updated earning of user for 4 months. To do that you need to write a server level cron-job that run on every day and a script in which you update and save the earning of user and check it has reached 4 months for that user since you started or not.
I hope you want this and that will help you. Happy Learning.
It's not clear what you want your code to do. Do you want it to give the total earned cumulatively by day x or give the total earned on any one day? If it is any one day and you don't want to take compound interest into account the earning will be the same every single day. In which case all your function has to do is return
function return_earnings($profit, $totalDays) {
return $profit / $totalDays;
}
as the amount earned each day will be the same as any other day. If you do want compound interest then you'll need to code that it. I assume you don't as there is no sign of it in the code you supplied.
I get the feeling what you are looking for instead is a list of how much was earned each day cumulatively. If that's the case, the code you've written is more appropriate but needs some modification. At the moment your code is returning $earning after the first iteration of the loop. Moving return to the end of the function should fix that.
function display_earning() {
$profit = $profit_roi;
$dateBegin = now();
$dateEnd = "date of 4 month from now";
$earning = 0;
$totalDays = 124; // You might want to change '124' in future
// and having $totalDays in the for loop makes it more
// obvious what your code is trying to do.
for ($i = 0; $i < $totalDays; $i++) {
$earning += $profit / $totalDays;
}
return $earning;
}
However now because of the line $earning += you will return the sum of earning at the end of $totalDays, ie the $profit, which you already know! You may want the cumulative earnings by a given day to be an item in an array, in which case:
function display_earning() {
$profit = $profit_roi;
$dateBegin = now();
$dateEnd = "date of 4 month from now";
$totalEarning = 0; //renamed to $totalEarning
$earningsByDay = array();
$totalDays = 124;
for ($i = 0; $i < $totalDays; $i++) {
$totalEarning += $profit / $totalDays;
$earningsByDay[$i] = $totalEarning;
}
return $earningsByDay;
}
This will now return an array with each element of the array amounting to the sum earned by that day. For example, $earningsByDay[0] will be the first day, $earningsByDay[11] will be the 10th day etc. If this is what you are looking for, you can use php's native range() function to make your life easier:
function display_earning() {
$profit = $profit_roi;
$dateBegin = now();
$dateEnd = "date of 4 month from now";
$totalEarning = 0; //renamed to $totalEarning
$earningsByDay = array();
$totalDays = 124;
return range(0, $profit, $profit/$totalDays)
}
A few final thoughts:
You say you want to display the amount earned each day. You function does not display anything it just calculates a value and returns it. That's good practise. Have your functions do one thing. Some other function can display the data from this one, or perhaps multiple functions can, each formatting it in a way that is appropriate for your current need. I can't help you with the display as I have no way of knowing what format you want. $dateEnd probably doesn't need to be in the function.
On a related note, another function name might lead to less confusion about what the function does.
I'm not sure what $dateBegin = now(); adds, unless as Moeez Saiyam suggests, you are trying to automate this somehow.
You've defined $profit = $profit_roi; without declaring what $profit_roi is in the scope of your function. I know it was in your introductory notes, but the function won't know that.
Is the function the right place to define $profit and $totalDays? They are probably passed to the function form elsewhere.
Combining these thoughts, this gives us:
function getIncrementalEarnings($profit, $totalDays) { //function renamed to clarify its purpose
return range(0, $profit, $profit/$totalDays)
}

Calculating frequency interval for tasks

I have a cron job that gets results from the DB to check it the interval set by user falls on today's date. I am currently thinking of doing it as below :
Get the time column for the row. Ex:2017-05-25 00:00:00
Get the frequency set. Ex:Every 2 weeks.
Get the current date in above format. Ex:2017-05-31 00:00:00
Get the difference in days. Ex:6 days.
Convert the frequency set to days. Ex:2 weeks = 14 days;
Divide (difference in time(days)) by (frequency in days). Ex:6/14
This way I will only get the result to be true when 2 weeks have passed since the time set. I.e., 14/14, 28/14, 42/14,...
If the frequency is in months, I can start dividing by 30. But somehow this feels like a hacky way of doing it. So my question is if there is better way of doing this calculation to check the difference.
This is what I have done as explained by above example.
` $frequency = ; // Get the relevant fields from db
$today = date(Y-m-d H:i:s);
foreach ($frequency as $key => $value) {
$frequency_in_days;
$frequency_type = $value->type;
$frequency_repeat = $value->repeat;
if($frequency_type == 1){
$frequency_in_days = $frequency_repeat;
} elseif($frequency_type == 2) {
$frequency_in_days = $frequency_repeat * 7;
} elseif($frequency_type == 3) {
$frequency_in_days = $frequency_repeat * 30;
} elseif($frequency_type == 4) {
$frequency_in_days = $frequency_repeat * 365;
}
// Get number of days spent between start_date and today in days.
$interval = date_diff($value->start_date, $today)->format('%a');
$result = $interval % $frequency_in_days;
if ($result == 0) {
// Frequency falls today! Do the job.
}
}`
Note: The cron job runs this script. The script again needs to check if the today falls under the frequency set.
Also for argument's sake, is this the best logic to calculate the difference?
Thank you.
This will work
Table "schedule"
`last_run` timestamp,
`frequency_seconds` int
example query for tasks that should go every two weeks:
SELECT *
FROM schedule
WHERE TIMESTAMPDIFF(last_run, NOW()) >= frequency_seconds
after fetching rows update last_run to NOW()

Calculating different bands of overtime in php

This is my first time posting here so I'm sorry if I get something wrong. I'm trying to calculate how many hours overtime a worker has worked based on when they signed in. The problem is that we have different bands of overtime:
If the worker works between 5 and 7 then it's 25% extra per hour
If they worked between 7pm and 10pm then its 50% extran for each hour
If the worker works between 10 and 12 then it's 75% extra
If the worker works between 12am and 7am is 100% more
I need to count how many hours they worked at each of the overtime bands
$number_of_25_percent_hours=0;
$number_of_50_percent_hours=0;
$number_of_75_percent_hours=0;
$number_of_100_percent_hours=0;
$clockInTime=$arr['4'];
$clockOutTime=$arr['5'];
$startingPieces=explode(':',$clockInTime);
$startingHour=$startingPieces[0];
$finishingPieces=explode(':',$clockInTime);
$finishingHour=$finishingPieces[0];
//Regular hours are between 7am and and 5pm
//If the worker works between 5 and 7 then it's 25% extra per hour
if(($startingHour<=5)&&($finishingHour>=6)){$number_of_25_percent_hours++;}
if(($startingHour<=6)&&($finishingHour>=7)){$number_of_25_percent_hours++;}
The problem with using the lines above is that it does not work if for example they worked an hour from 6:30 to 7:30.
I'm interested in finding other ways to do this.
you need to store the data more exactly. From your script it looks as if you were only saving the starting hour - which propably is a full number (1,2,3,4 whatsoever)
You script however needs a exact time representation. There are surely many ways to do this but for the sake of a better Script (and as you will propably be able to use some of these more exact values later on) I'd recommend you to store it as a UNIX Timestamp, then get the hour of the Timestamp :
$startingHour = date('H' $timeStampStored)
and check if it's in any of your "bonus" segments. If the user started working at 6:30, the value will hold 6.
This code is completely off the top of my head, untested etc. It's intended as a suggestion of one method you might use to solve the problem, not as a robust example of working code. It uses integers instead of dates, relies on array data being entered in order etc, and probably wouldn't even run.
The basic idea is to set up the scales for each level of overtime multiplier, as well as the hours for non-overtime pay in an array, then loop through that array checking how many hours of each level of overtime have been worked between the inputted times, meanwhile keeping track of a total billable hours value.
$PayMultipliers = array();
$PayMultipliers[0] = array(17,19,1.25);
$PayMultipliers[1] = array(19,22,1.5);
$PayMultipliers[2] = array(22,24,1.75);
$PayMultipliers[3] = array(0,7,1.5);
$PayMultipliers[4] = array(7, 17, 1);
$Start = 3;
$End = 11;
$TotalHours = 0;
for($i = 0; $i <= count($PayMultipliers); $i++)
{
if($Start > $PayMultipliers[$i][0] && $Start < $PayMultipliers[$i][1])
{
$TotalHours += ($PayMultipliers[$i][1] - $Start) * $PayMultipliers[$i][2];
$Start = $PayMultipliers[$i][1];
}
}
echo $TotalHours;
If you want to calculate from 6:30 to 7:30 you'll have to caclulate in minutes, not hours. You can convert the hours and minutes to timestamps, check each time period, and then convert the seconds back to hours.
<?php
$number_of_overtime_hours = array();
$clockInTime = "18:30:00";
$clockOutTime = "19:30:00";
$startingPieces = explode(':',$clockInTime);
$finishingPieces = explode(':',$clockOutTime);
//Timestamps
$startTimestamp = mktime($startingPieces[0],$startingPieces[1],$startingPieces[2]);
$finishTimestamp = mktime($finishingPieces[0],$finishingPieces[1],$finishingPieces[2]);
//finish after 0h
if ($finishTimestamp < $startTimestamp){
$finishTimestamp += 3600 * 24;
}
//set starting and ending points
$overtimePeriods = array(
25 => array (17,19),
50 => array (19,22),
75 => array (22,24),
100 => array (24,31)
);
$overtimeWork = array();
foreach ($overtimePeriods as $key => $val){
//create Timestamps for overtime periods
$beginTimestamp = mktime($val[0],0,0);
$endTimestamp = mktime($val[1],0,0);
//calculate hours inside the given period
$overtimeWork[$key] = (min($finishTimestamp,$endTimestamp) - max($startTimestamp,$beginTimestamp)) / 3600;
//negative values mean zero work in this period
if ($overtimeWork[$key] < 0) $overtimeWork[$key] = 0;
}
var_dump($overtimeWork);

How can I get unix times for the start and end of last twelve months in a loop?

I wish to print the totals of a column in my database for each month in the last year. The code I have so far to do this is:
$month = date("n");
$year = date("Y");
$loop = 12;
while($loop>1) {
$first = mktime(0,0,0,$month,1,$year);
$last = mktime(23,59,00,$month+1,0,$year);
$spendingData = mysql_query("SELECT * FROM spending WHERE date BETWEEN $first AND $last") or die(mysql_error());
$totalMonth = 0;
while($spending = mysql_fetch_array($spendingData))
{
$totalMonth = $totalMonth + $spending['amount'];
}
print "£".$totalMonth;
$loop = $loop-1;
print "<br>";
}
My quesiton is how, in the loop, do I adjust the times for each month? I thought about just taking a months worth of seconds away from the timestamps, but as I don't know how many days are in each month I don't think this will work. I also don't think I can just keep taking 1 away from the month figure as this will not account for years. I also don't want to hard code the figures in, as they will change with each new month.
How can I achieve this?
Thank you
You could do this rather trivially in MySQL:
SELECT MONTH(date) AS month, SUM(amount) AS amount
FROM yourtable
WHERE YEAR(date) = $year
GROUP BY MONTH(date)
without ever having to involve PHP for the date manipulation stuff.

Categories