Question: For example, let say a user purchase product called `soap` with price of `1.50` on `20th sept 2012`. This have been recorded on database under `purchase` table with `productID` and `date`.

Let say on 22nd sept 2012, the admin changed the price of `soap` to `1.20`, now the report price is changed because of this.

What is the best approach to make sure that old data of `1.50` is stored for old reports and `1.20` for new reports. Should i insert all data including, product name, product price onto `purchase` table?

Answer: 
The simple answer to your questions is yes. 

When it comes to financial systems, well any systems that may be required to be audited "transactions" should be stored in their entirety in a "document" or "record". 

There are other methods such as recording each deletion or modification with "flags" (E.G. current, deleted, modified, etc), "from\_date" and "to\_date" instead of actually deleting or modifying the data from the database, however this will use more server resources and the programming is significantly more complicated not only in mySQL but PHP also. But it allows you to provide only a relationship between records at the same time. 

My suggestion is to keep it simple and store all required data in a single record. You will save time and legally, should the system ever need to be audited you're much safer. 

Good luck and I hope it helps!
I've recently been working on a product close to what you described. And I believe your answer relies on the level of complication you are willing to implement your project. The simplest way is to store product information in your invoice record. But this leads to redundancy over the time.

On the other hand you can implement a revision mechanism so you can keep track of your records' changes over the time. This can be easily done by using two ids for your records instead of one. Here's a sample table:

```
CREATE TABLE IF NOT EXISTS `product` (
  `product_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `entity_id` bigint(20) unsigned NOT NULL,
  `name` varchar(255) NOT NULL,
  `price` double NOT NULL DEFAULT '0',
  PRIMARY KEY (`product_id`),
  KEY `inx_entity_id` (`entity_id`)
) DEFAULT CHARSET=utf8 ;

```

While `product_id` is your ordinary auto increment id, the `entity_id` is a special id which is the same for all the records of the same product. In this design you'll never delete a record, nor update it. You will always just insert into the table and when you need to get the list of products, you'll just have to keep in mind that a group by over the `entity_id` is in order. The product information can be found in the record with the biggest `product_id`. Perhaps you may want to create an entity table to keep track of `entity_id`s.

This design is more complicated than copying products' information to invoice. But it has so many great benefits. Like you can keep track of price changes of a product. Or you can use a foreign key to `product_id` to point to one specific revision of the product or use the `entity_id` to indicate a product type instead of some specific revision of it. Of course its complication will cost you but it's you who can tell if it is worth it.