How can I prevent someone using a promo code twice? - php

I have a database that looks like this:
When user wants to use a promo code, it first checks if used_promo is null, that means the user has not used any promo code before. (User can only use 1 promo code)
I can do something like this
SELECT used_promo FROM users WHERE id=5
then I can check with PHP if used_promo is null and if it is, I can do
UPDATE users SET used_promo=2, balance=balance+100 WHERE id=5
Is it possible that the user can try to use the promo code multiple times at the same time, the SELECT will return that used_promo is null before it is set to 2 and the balance will be added multiple times?

In the scenario you've described it's theoretically possible to use the promo code multiple times. Use a single query, which will return an id if the update is successful or no rows otherwise.
UPDATE users
SET used_promo=2, balance=balance+100
WHERE id=5 AND used_promo is null
RETURNING id;

Create one more relational table "promo_used", where columns would be:
id
user_id
promo_code_id
timestamp
Once user apply promo code, this table will have new entry. This way, if user tries to apply same promo code again, we can check by searching through this table.
Hope this helps.

As understood you are worried that a user may use promo code multiple times before you update used_promo column. I don't know what your business model is. However, it is possible in a scenario like this:
User enters the promo code. You reduce the price of item accordingly, but you can't update the used_promo field since purchase is not complete. Without completing the purchase user enters the promo code for another product and gets a reduction again. And after doing this multiple time times user goes completing purchases. Since you don't check the validity of the code at the final step user can get all the price reductions.
So
Maintain the validity status of promo code
Always check the validity
Use atomic way to update validity status, used_promo and finalize the purchase. (Transactions)
of promo code and used_promo before finalizing purchase

Related

Wanting to update with two conditions both with multiple values

I am building a status system that shows satus of units, if you press a button the status of the task will update if your name is like one of the roles for that task. however i don't want the status to downgrade, it needs to display the latest status. So what i wanted to do is like this
update status Set status=cleared where jobtask1=name or jobtask2=name AND status=in_progress OR status=in_wait
UPDATE data
SET status='cleared' WHERE person1='$name' OR person2='$name' OR person3='$name' OR person4='$name'
AND status='in_progress' OR status='preparation' OR status='in_wait' OR
status=''
So it results in checking if one of the persons is the person updating the status or if the status is like one of the specified statusses. I want it to check if the person is like the person updating the status, if so then check if the status is like one of the specified statusses and if both are correct update the status.
you could try to use SWITCH CASE logic
UPDATE data
SET status =
CASE
WHEN (person1='$name' OR person2='$name' OR person3='$name' OR person4='$name') THEN 'cleared'
WHEN (<second_condition>) THEN 'in_progress'
...
ELSE ''
END
You should also consider redesigning the DB according to normalization principles.
Thanks Salman and nacho for the solution, I just needed to add parenthesis.

Prevent multiple form submission from same user at the same time with different devices

I have website login system and after logging in, users can withdraw amount that is stored in database, the problem is when someone login using multiple devices and submit withdraw form at the same time he/she will recieve the amount multiple times. How to prevent users submitting at the same time ?
Make a field in the users table LOCKED with default value of zero and when its value is 1 disallow the transaction and every time a transaction takes place toggle it to 1 and back to zero when finished.
In order to answer your questions, I'll assume that:
1. You are using mysql database.
2. A user is allowed ONLY one withdrawal.
In your database, create a table named withdrawal.
Then, add fields like:
id INT PRIMARY KEY
user_id INT UNIQUE
withdraw_amount DECIMAL(10,2)
In this case, the user can only submit ONE record to withdrawal table since the user_id field is UNIQUE.
But, if my assumptions don't match with exactly what you require, then provide more information about what you need.

Having a <select> whose value is not in the <options>

Lets say I have a database table containing a list of statuses.
In my apps form, I have a <select> containing options for all of those statuses which a user can select.
Now, lets say there is another table called people which contains a column for status which represents a status that was previously selected from the list of statuses.
And lets say that I have removed a status from my statuses table, but there are still database rows for people with that removed status.
Now in my form, I can no longer pre-select the <select> option for that status because it no longer exists in my statuses table.
So how would I handle this so that it still pre-selects the removed status in the select? Is my only option to have an <input type="text"> and then some type of autocompletion like twitter typeahead? And if so, how would I validate this? Would I check if the status they enter is what is already there and also in the database table statuses?
Any insight would be awesome.
SOLUTION
Since you are using PHP, you could dynamically append the appropriate status value to the end of your list based on the person.
SUGGESTIONS
First, you should be using a foreign key to link the status table to your person table, and not just storing the status string in the person table. Creating this relationship would have kept the referential integrity of your tables and prevented you from deleting current statuses in the first place.
Never delete statuses from your table. If you need to remove a status from the list of active statuses, you should add a bit field to your status table called "IsActive" (or something similar). Then you could query SELECT * FROM status where IsActive=1 for new records while still having all the old values when needed.

Number of posts since last visit

I have a website where people can make posts and follow other users. I have a sidebar that has a value that keeps track of the number of posts that have been posted since your last visit.
I'm stuck thinking of how I should handle this. Should I create an entirely new table in the database called notifications that would hold the user's id and the number of posts since last visit, should I just add a column in the existing user table for this value, or should I use an entirely different method?
Thanks.
First of all: Think, which object this is a property of. In your case, the count will differ from user to user, so we might assume, it is a user property.
We could hang it on the last login, but this would give us a wrong count, if the user is logged in for a long period (The user doesn't want to know the count since his last login, but since his last activity!).
So the easiest way could be to add a field to the users table, that holds the last post ID - We just SELECT MAX(id) FROM posts and update users.lastSeenPost with the result on every user action. We can then display MAX(post.id)-users.lastSeenPost as the new post count.
Every post has a date recording when it was made.
Every user will have a date keeping track of when he/she logged in the last time.
By the following SQL statement you could ask the database to return the number of posts since the user logged in last:
SELECT COUNT(*) FROM `posts` WHERE `posts.post_date` > `user.lastlogin_date`
I suggest that you will create a cookie ($_COOKIE['lastPostId']) in each customer webbrowser with the LAST ID of your posts, and, when the user return, you will read $_COOKIE['lastPostId'] and query your database as SELECT * FROM posts WHERE id>lastPostId

How do I store order history in a database using php?

I have a site where users can place an order. The order goes through various stages before it is ready for delivery. I want to be able to log anytime anything happens relating to an order.
Here's an example of what I would like for it to look:
(2/13/12 4:41pm): Order initiated by Customer (2/13/12 4:41pm): Order
sent to Manager for approval (2/13/12 4:43pm): Order approved by
Manager (2/14/12 6:03pm): The order was edited by the user: City: 'Los
Angeles' to 'San Diego' (2/14/12 6:09pm): The order was edited by the
admin: Email: 'gearge#gmail.com' to 'george#gmail.com' (2/15/12
8:41pm): Order ready for Delivery
What is the best approach for me to store this type of order history? I have created a table in the DB called history where I would like to store the history as it pertains to each order. My columns are history_id(primary), order_id(foreign), date added(timestamp), and history_message(varchar).
Ideally I would like to create numbered codes for each step in the ordering process, such as an order approval, order edit, or order delivery and then just assign the number for that row instead of the actual history message, which is more characters. I feel that this way I won't overstuff my DB. The problem with this approach is that I would like to keep a log of the actual data that was changed(as you can see in the edits by the user and admin in the example) and I'm not sure how I can accomplish that without saving the complete history message for each row.
What is the best way to store order history in a database for my situation?
You can use trigger to update a child table keeping track of each order status.
Basically using insert trigger or do manual insert after update in order status by insert query you can copy required data from orders table to a new table we can call trackorders. tracking table will keep track of all changes and record with current status will be in main table.

Categories