basically i’m creating a tariff calculator for a utility company in my country, based on a progressive rates table, an example given below
2.(a) In any one month for less than 1,001 gallons a fee of ………………………..… $9.23
(b) Proportionate fee for every gallon thereafter up to 2,000 gallons inclusive at the rate per 1,000 gallons of ………………..$15.89
(c) Proportionate fee for every gallon above 2,000 gallons and up to 3,000 gallons inclusive at the rate per 1,000 gallons of .………..$17.43
(d) Proportionate fee for every gallon above 3,000 gallons and up to 4,000 gallons inclusive at the rate per 1,000 gallons of .………..$18.45
(e) Proportionate fee for every gallon above 4,000 gallons and up to 5,000 gallons inclusive at the rate per 1,000 gallons of .………..$19.48
(f) Proportionate fee for every gallon above 5,000 gallons and up to 6,000 gallons inclusive at the rate per 1,000 gallons of .………..$20.50
(g) Proportionate fee for every gallon above 6,000 gallons and up to 7,000 gallons inclusive at the rate per 1,000 gallons of .………..$21.01
(h) Proportionate fee for every gallon above 7,000 gallons and up to 8,000 gallons inclusive at the rate per 1,000 gallons of .………..$21.53
(i) Proportionate fee for every gallon above 8,000 at the rate per 1,000 gallons of …$22.04
I’m thinking of doing a Rate model with the following fields:
- area of supply
- description
- from_gallons (starting range of gallons)
- to_gallons (end range of gallons)
- rate_per_1000g
my view would accept post from a form with the amount of gallons, area of supply and should post back the usage calculated from the rate table.
i would do something like this in the view
from models import Rate
def tarrif_calc(request,gallons,area):
rate = Rate.objects.get(area_of_supply=area, from_gallons >= gallons, to_gallons <= gallons)
rate_per_gal = rate.rate_per_1000g/1000
usage = gallons * rate_per_gal
return usage
this is the most simple e.g i can think of, however i’m not sure how i would handle the progressive rates… any ideas? am i on the right track?
Business rules should be expressed in code. More info
After reading your question a little closer, It looks possible that you might have many such tables you’ve got to query. Putting many similar such structures legitimately goes into a database. For now I’ll assume you have that. If you really only have one table, a case analysis is probably most concise.
In my own django apps I’ve found that a very natural place to put business logic is in forms. Models seem obvious, but seldom have access to the context necessary to make informed decisions about what can go where.
Usually I’ll divide this into several, dependent apps. One app provides very high level, abstract models and forms. Another app extends the forms from the first with business rules.
The first problem is querying the Rate model. The bit of code for that doesn’t actually work. You can’t pass lazy comparisons in python. Django has a mechanism for that, by mangling the argument names.
I’m not sure what your db looks like, but make sure there’s an index on from_gallons and to_gallons, or this query will be very slow.
Your example doesn’t sound like it actually alters state. If this is true, then you should probably be using a GET view rather than POST.
In either case the first part of the logic is the same. Recieve a request and validate the form input.
Now all thats needed is to actually use it.
Very little business knowledge is embedded in the view. Only the fact that the form
stores a cleaned calculation result in its “usage” key. But since the view is precisely for obtaining that value, this is doing the right thing.
A template to use the form is also required. (My django template skill is only so-so. As i said, I prefer jinja2 and so should you)
Personally, I don’t much like to muck about with moving individual form results into a template context, I just use the whole, processed form. I write my own templates in jinja2, though, so if your template designers are not trustworthy, you might want to craft your contexts a bit more carefully than this.
Again, no more business logic appears in the template than does in the view.