views:

26

answers:

3

In an invoicing application, consider following:

I have a products table that also contains the price of the product. And then I have an invoice and invoice_lines table and in each invoice line, I refer to the product id along with quantity. In this case, I am not storing the price of the product with the invoice line.

Now few months later, if the price of the product changes, any report would show the volume of the sales based on current price instead of the price on which the product was actually sold.

One solution that comes to my mind is that we keep a separate table named prices that links to each product and whenever the price of the product is changed a record is inserted into this prices table. The latest record in this table always is considered as the current price for new invoices. Each invoice line indicates its price by indicating the id of the price so that it shows correctly later in reports.

What are the best practices for handling such situations?

A: 

Add a price field to the invoice line.

Vebjorn Ljosa
Yeah, agreed. I'd store the current price of the product in the product table, and the price at the time of the sale on the invoice line.
Wade Williams
+2  A: 

I would always store the actual name, quantity and price at the time of purchase against each order item, effectively de-normalising the data. An order is a snap-shot in time and shouldn't be related back to something that can change. Not only can prices fluctuate, but what happens if you delete or rename the original product and your invoice relates back to it?

Dan Diplo
A: 

I would echo your suggestion: Breaking out Prices into a separate table with these columns:

PriceId, ProductId, Price, StartDate, EndDate.

This way you can also plan ahead for future price changes. Current data could be gotten using (Sql Server syntax):

SELECT *
FROM Products
   Inner Join Prices ON Products.ProductId = Prices.ProductId 
      And GetDate() Between StartDate and EndDate
Shlomo
Another advantage to this approach is that you capture price changes that may never appear on an invoice.
bobs