tags:

views:

159

answers:

3

Anyone have any ideas on a good way to model the following scenario in my domain/database for a .NET application? Let's say I have certain discounts that can be applied to sales transactions, but the discounts should only be applied on certain days of the week at certain times. So for example, if a sale occurs on Monday between the hours of 9AM and noon, the discount should be applied, but if a sale occurs on Tuesday between those hours, no discount is applied. I would like to be able to handle multiple time periods within the same day as well (ie - Wednesday from 9AM - noon and 6PM - midnight.

+1  A: 

I would simply write a "GetDiscount" method that would implement the logic you are describing. You can use the DateTime object to determine current day and time.

From your description it is not clear why such simple solution wont work for you. What exactly are you expecting?

Sesh
The days and time periods would need to be set up differently for each discount. So there will be a UI that allows and end user to specify the the days and time periods for each individual discount. So I need to persist those to the database along with the discount that they are tied to.
A: 

I've done something similar to this.

Your SalePrice table would look like (damn markdown tables):

SalePriceId Guid, PK
ItemId Guid, FK
StartTime Timespan
EndTime Timespan
DaysOfWeek DaysOfWeek (flag enum)
Discount double

(This is from the code view; Timespan is a .NET class that maps in Sql 2008)

DaysOfWeek is a flag enum containing Sun-Sat.

So to find any sales for an item that are in effect on tuesday, you would do something like

select * 
from SalePrice
where ItemId = @itemGuid
and StartTime <= @time 
and EndTime >= @time
and DaysOfWeek & @DOW = @DOW

This is the basic pattern. Don't expect this to copy-paste work (I'm not sure about my bitwise query stuff), but I'm using this pattern successfully to track current prices.

Will
you should use the decimal type for Discount or (money in SQL)
MaLio
A: 

I would just create the following two classes assuming you apply the discount to a comlete order, not single items.

class Order
{
    Guid Id;
    DateTime TimeStamp;
    Discount Discount;
}

class Discount
{
    Guid Id;
    DayOfWeek Day;
    TimeSpan StartTime;
    TimeSpan EndTime;
    Decimal Amount;
}

Then you can use Order.TimeStamp.DayOfWeek and Order.TimeStamp.TimeOfDay and search through a list of discounts until you find a Discount valid for the processed order and store a reference on the Order object. Mapping this to a database should be quite simple - DayofWeek can be stored as an integer, DateTime and TimeSpan are availiable, too.

The tricky part is constraining the one-to-many relationship between Order and Discount. One could try using triggers or check constraints, but I would suggest to enforce this logic only in the application because you don't gain that much by enforcing it at the database level.

Daniel Brückner