php: how to approach auto premium membership renewal? - php

scenario:
there are 4 items:
30day pass
60day pass
180day pass
365day pass
there is a monthly (30 day) credit cap. so if you use the credit up before the end of the month you need to purchase another 30day pass, or wait till the next renewal period.
A person purchases a 30day pass today, purchase date is recorded to DB. Expiry date is also recorded.
if ($todaysdate >= $expirydate) //DONE.
but whAt about for 60day and 180day passes ?
we have purchasedate & expiry date. every 30days, the credit needs to be reset for the next month.
I am really lost how to best approach this problem.

one way to do that is with cron and mysql
when you run this cron every day
define a variable
define (DAY_AMOUNT ,30);
check the day pass by query
SELECT mem_id DATEDIFF(CURDATE(),mem_date) AS daypass FROM table
WHERE ((DATEDIFF(CURDATE(),mem_date))=".DAY_AMOUNT."
the results that return is all the members that pass 30 days from the date.

You could run a task (or cron job) daily to check and see if the current date is later than the recorded expiration date, and if it is reset the users credit to 0, and send them an email letting them know their credit has expired.
As the users buys credit, you merely add 30, 60 or 90 days to their expiration date.
For more information, see php + cronjob tags.

in your situation, you could have a table like this:
pass: (id, user_id, start_time, end_time, credit)
every day you can flush the unused credit on any pass that has expired:
update user join
(select user_id, sum(credit) as credit from pass
group by user_id where end_time <= now() and not flushed) b
set user.credit = max(user.credit - b.credit, 0)
where user.user_id = b.user_id
update pass set flushed = 1 where end_time <= now() and not flushed
by using end_time <= now() you ensure the credit is only reset once the expiration date has passed. since you remember which passes were flushed, you can run this as often as you like and missing a day is not an issue (it will be detected on the next run).
this is effectively how a prepaid calling card would work - you have a certain number of minutes that are valid for X (30/60/90 whatever) days and the minutes are reset at the end.
btw, you can simplify all that stuff by using an easy to use subscription management system like recurly or chargify.

Or, in the database, you can save each person has their own expiry date.
To make an expiry date, you should use a unix timestamp. 30 days is 2592000 so to find the expiry date, you could use something like the following if you want to calculate the expiry date (Changing months with how many months).
$months = 2;
$expiry_date = time() + 2529000*$months;
Then, put those values into a database.
Then, you can do something that does an automated task (for example, cron).
When you run that automated task, you check if the current timestamp (another word for time) is bigger then the expiry date. If so, then change the value in the database in the field for if they have the right credits.

Related

How to calculate the total time logged in the system?

I am using CodeIgniter and I am calculating the total time from the dates.
Explanation:
What I am doing is, Every login I am inserting the last_Ativity date and time in the database using below code.
$data_login= array('emp_id' =>$result->id ,'last_activity' =>date("Y-m-d H:i:s", STRTOTIME(date('h:i:sa'))));
$this->db->insert('tbl_current_login',$data_login);
last_activity time continuously updating if the user still in the system . (I am using ajax to update the datetime. I haven't shared that code).
Now I have to calculate the total time of the specific user for a single day(current date).
For example- emp_id 26 logged in twice so I have to calculate the time
First-time login date and time:-2018-09-17 07:27:55
Second-time login date and time:- 2018-09-17 07:35:22
It will increase depending upon how many time the user logged in.
I am confused about the time. Am I on the right path to calculate the total hour login in the system?
Should I use an MYSQL query or PHP to calculate? I need some idea.
Would you help me out in this?
This is what I would do
last_activity time continuously updating if the user still in the system . (I am using ajax to update the datetime. I haven't shared that code).
Before you update the row.
check if a row for activity exists
if it does, get the timestamps for the date and subtract the current time (the one you are changing last_activity to, from the one stored in the DB) take that number and add it to an integer column named something like elapsed time (you would have to add this to the DB)
if not then enter a row with 0 elapsed time ( depending how you put the first row in, maybe on login) this may never be an issue.
For the timestamps, you would do a select to get the current row. Take the datetime field and use either
$time = strtotime($row['last_activity']);
OR
$time = (new DateTime($row['last_activity']))->getTimestamp();
Then you simply do the same thing to the date you are going to replace that with and then subtract to get the difference in seconds.
$elapsed = time() - $time;
And then add that to the current rows value, and save it. This way you can keep track of a running total in seconds of the time they spend during that session.
Then when you need to count the total time its a simple matter of doing
SELECT SUM(elapsed_time) FROM {table} WHERE DATE(last_Ativity) = :date
If you were dealing with just two date time fields in the DB it would be easier to just get the difference of those, but sense you already have code to constantly update the last active field this would require less work in the long run IMO.
Option2
The other option is to add another Datetime field to put a start time or login time in. Then when you query you can convert them to their timestamps and subtract to get the difference.
This makes the SQL harder (when doing the SUM ), I can't really think off the top of my head how I would calculate the elapsed time on multiple rows and then sum them up. But it does simplify the PHP quite a bit. So which ever way works best for what you need. Think about if you need the utility to know when they logged in, or if you just want an easier way to calculate the time they spend.
Something like that.
Assuming that the only log happens based on user actions, and so, after 15 minutes (for example) the user is assumed logged out
And assuming you'd want daily total, the solution should be something like this:
SELECT
first.emp_id,
SUM(TIMESTAMPDIFF(MINUTE,first.last_acivity, DATE_ADD(IFNULL(last.last_acivity, first.last_acivity), INTERVAL 15 MINUTE))) as logged_minutes
FROM
(
SELECT
la1.*
FROM
last_acivity la1
LEFT JOIN last_acivity la2 ON
la1.emp_id = la2.emp_id AND la1.last_acivity < la2.last_acivity
AND la2.activity =< #date0
WHERE
la1.last_acivity >= #date0
AND la2.login_id IS NULL
) first
LEFT JOIN
(
SELECT
la1.*
FROM
last_acivity la1
LEFT JOIN last_acivity la2 ON
la1.emp_id = la2.emp_id AND la1.last_acivity > la2.last_acivity
AND la2.activity =< #date0
WHERE
la1.last_acivity >= #date0
AND la2.login_id IS NULL
) last
ON
first.emp_id = last.emp_id
GROUP BY
emp_id
In this query need to set the date seperately:
SET #date0 = DATE(NOW()) ;
To get the first record of the day, or the last, we need to LEFT join the table to itself, on the same emp_id BUT witn with an inequality, which will get for each emp record its ancestors or predecessors
When we add the NULL condition we bring the we get the edge case: first or last
What's left then is just calculating the minutes between the 2 tables
Since I assumed no log out record occurs, I treated the case when the first and last logins are the same, or no last login

Decrement days daily in membership site

I have a database for membership site where users has a column day .This is number of days left until users membership expire.
Right now I run cron job daily at 12 AM to decrement day column by 1.
Is this the better solution or any other ideas available ? using date of registration and current today date.
Much better approach is to store membership expiration date and just compare with the current date.

How to auto update account balance in database every 30 days

I have a customer table in my database. This table contains customer information including his/her balance.
Now I want to add his/her balance after every 30 days depends on what promo or plan he/she applied
example: he applied for a plan 1599 so after every 30 days his balance must add the price of the plan he applied.
current balance = 0
after 30 days balance = 1599
How will i do this?
You can create a cron job for the same. Check the date difference for every user and if its greater than 30 days add the balance to the respective user's account.
You can do this like
Store the Date when user choose plan by using date('Y-m-d') in a variable
Add 30 Days in it by using date('Y-m-d',strtotime("+7 day", $date)) and save this in database
Write a query to check that date of today is equal to that stored date or not if so then add points to that account.
For point 3 you may also need cron job depends on your requirement.
If still need help feel free to comment

Filter records by date based on date ranges assigned in a table

I am setting up a scheduled cron job that launches a PHP script every other Monday.
My goal is to run a SQL query that returns work orders based on my company's pay period - each pay period ends on the Friday before I run this scheduled cron job.
I have a SQL table which lists all the pay periods of my company, so this table has two column: payperiod_from (start date range) and payperiod_to (end date range). The work orders that I am pulling have a date assigned to them. I would like to be able to pull the work orders where their date is between payperiod_from and payperiod_to.
Since pay periods end every other friday and this cron job is scheduled on the Monday after that, I can simply use CURDATE() - 3 (3 days before Monday - Friday); to get the payperiod_to date, but how can I run a query that filters work orders who's date fall under the correct pay period?
Hopefully this makes sense to some of you guys.
You may run into trouble trying to set up a cron job for "every other week". There's a StackOverflow answer about that here; note the comment under the answer.
As for selecting work orders whose date falls under the correct pay period, if you're already calculating the pay period end as three days before CURDATE() why not forget about the pay_periods table (or whatever it's named) and calculate the pay period beginning as 16 days before CURDATE():
SELECT * FROM wkorder
WHERE wkorder.orderdate BETWEEN CURDATE() - INTERVAL 16 DAY AND CURDATE - INTERVAL 3 DAY
If you can't get the cron job to reliably run every other week and have to set it to weekly, then you can use the pay_periods table to filter out the off weeks. This will prevent any results if the prior Friday wasn't a pay-period end date because there won't be a match in the pay_period table:
SELECT * FROM wkorder
INNER JOIN pay_period ON
payperiod_to = CURDATE() - INTERVAL 3 DAY AND
wkorder.orderdate BETWEEN pay_period.payperiod_from AND pay_period.payperiod_to
Finally, please note that the queries above are syntactically correct but they're not fully tested. It's too much of a leap to go from the information in the question to actual table structures.

How do I create a timed ban on an account? (PHP/mysql)

I want to create a function that allows me to ban an account for 10days.
In the dbc, I have a field called "ban" and Boolean of 1=notban, 0=ban. I also have a field called "date_banned" which is just the timestamp of when the user got banned.
My question is how do I create a time frame of 10days from the date the user was banned?
ex: James was banned on "2010-05-03 20:43:48". So how can I go about adding 10days to the timestamp? And after 10days, it would set the "ban" equal to 1(which is not banned).
EDIT: how can i show how many days the user has left of a ban? ex: 8 more days till unban
Can I...do NOW()-$date_banned? or how do I subtract the ban date from the current date?
To add 10 days to your date_banned field in MySQL, you can simply use the DATE_ADD() function. You could do the following check when the user tries to log-in, to see if the ban has expired:
... WHERE NOW() > DATE_ADD(date_banned, INTERVAL 10 DAY);
Then you may want to toggle the ban field when the user tries to log in. Otherwise you can run a scheduled job every day, or at any other rate, that checks for expired bans and updates this field accordingly.
However you do not actually need the ban field to check if a user is banned or not. In fact you may want to consider eliminating it. Actually, I would go further and suggest to use a banned_until instead of date_banned (or use them both). The banned_until field would make your queries simpler, and would allow you to predefine arbitrary ban durations at the time the ban is issued. In this case, when a user logs in, you can simply do the following check:
... WHERE NOW() > banned_until;
UPDATE:
To get the number of days remaining until the end of the ban, you can use the TIMESPANDIFF() function in MySQL:
SELECT TIMESTAMPDIFF(DAY, NOW(), DATE_ADD(date_banned, INTERVAL 10 DAY)) ...
Or if you were to use the banned_until field, it will be even shorter:
SELECT TIMESTAMPDIFF(DAY, NOW(), banned_until) ...
unban_date=DATE_ADD(NOW(), INTERVAL 10 DAY) should do the trick
Then just have a cron that checks to see if anybody's unban_date is in the past, and you can update your banned flag.

Categories