What would be the best way to implement a simple quote system to determine a job cost based on two attributes type and value.
The job cost would determined what range the value falls into for it’s type.
For example:
Job type A would cost
- $ 80 for value between $ 0-150
- $100 for value between $150-300
- $120 for value > $300
Job type B would cost
- $ 50 for value between $ 0-120
- $100 for value between $120-250
- $120 for value between $120-500
- $150 for value > $500
The band range should be configurable and each job type can have different range of bands.
The band ranges and costs may change and would ultimately be stored in a SQL server database accessed through a repository pattern so I could implement mock repository for TDD.
My initial development led me to having a lightweight class below representing the bands
public class JobCostBand
{
public int ID { get; set; }
public string Type { get; set; }
public float ValueLowerBand { get; set; }
public float ValueUpperBand { get; set; }
public float Cost { get; set; }
}
I had a mock repository using LINQ to select from a in memory list of these objects to return the costs. This class would map easily enough to a SQL table whereby I could use LINQ to SQL find the cost in my final DB repository.
My problem was what to do with last band for a given job type. I started off using float.MaxValue for the upper band but that didn’t sit well with me. I then thought about using either a upper or lower value to specify the band in the JobCostClass but again this didn’t sit well. Am I thinking too much about this or have I missed a real simple way of modelling this?
The job you’re trying to do is map an input value to a band. How you represent it is a secondary matter. So you should really be concentrating on an object that is able to return the correct band for a given input value.
I’d stick with representing only an upper or lower band for each
JobCostBand. Also have a nullable value for upper band in case the given band’s upper value is lower than the next band’s lower value. Have a ‘manager’ object which keeps the collection of bands, and which is able to query them in response to a value and decide which is the most appropriate. I would store these in a sorted list (ordered by lower band threshold), and iterate through the array in order until the band matches.