Calculating Cost of Items for Finance

I am stuck in my project. The specific objective is trying to calculate profit. I am trying to calculate the total cost for every single order that every customer has ever made and calculate that as my total cost. I want to take that total cost and subtract it from my total revenue. By doing so I would have my total profit value. After that, I would show the total revenue - total cost = profit function in a respective HTML table. Each time a customer places an order

I was working with my tutor and helped me write a cost_of_items(self) function that on line 19 in the models.py file.

I have been tasked with trying to create a function to get the total revenue for every order. In order to do this my first step was to set a primary key for MenuItem. I was hoping that when an order is made an id would spit out for each recipe, and than if there are mutliple items ordered than it would spit out an id for each plate ordered. Than it would grab those values, and it would than calculate the cost of each ingredient by the price per unit and than add to total revenue += by the total cost of all the ingredients for all of the orders. I think my logic may be flawed in some way or the design is wrong.

My logic so far is:

def ingredient_cost_calculate(request): 
    cost_per_ingredient = Ingredient.price_per_unit * Ingredient.quantity
    for cost in cost_per_ingredient:
        total_cost_per_meal = cost_per_ingredient += total_cost_per_meal

am I on the right track?

models.py
from django.db import models

# Create your models here.

class Ingredient(models.Model):
    name = models.CharField(max_length = 20)
    quantity = models.FloatField()
    unit = models.CharField()
    price_per_unit = models.FloatField()
    
    def __str__(self): # without the def_str__ method it will not label ingredient by name
        return " " + self.name

class MenuItem(models.Model):
    name = models.CharField(max_length = 20)
    description = models.CharField(max_length = 200)
    price = models.FloatField()
    # I have set a primary key in hopes of having some way to identfy what has been ordered?
    # id = models.AutoField(primary_key=True) 
    
    def cost_of_items(self): # made for purchases sake
        ingredients = RecipeRequirement.objects.filter(recipe=self)

    def __str__(self):
        return self.name

        # go to the Receipe Requirements table.grab all of the recipe requiement data attributes. through .objects method. 
        # using.filter we tell python to only give me the objects when they equal this recipe. 
        # recipe is an attribute in the RecipeRequirement table line 44 see below.
        # when that recipe field is equal to self grab the items that were used in making the recipe. 
        # self is an instance of an object. and that was 
        # when this item is equal to the one listed in the recipe grab this value. 


        # we need to access the ingredient cost and add it up. price per unit by the amount used and add it up.
        

        #find me all of the recipe items you need to make this receipe. 
        #self is an instnace of the object. 
        #django djaffe cake as a menu item with descriptiona nd price. we pass that object in and say give me the recipe requirement
        # is this object. 



class RecipeRequirement(models.Model):
    # a recipe_id will populate with django here
    ingredient = models.ForeignKey(Ingredient,on_delete=models.CASCADE) # the ForeignKey will automatically reference the primary key that Django makes for us.
    recipe = models.ForeignKey(MenuItem,on_delete=models.CASCADE) # the table did not have a concept of which ingredients were tied to what recipe. this line of code associates ingredients with recipes.
    quantity = models.FloatField()

    def __str__(self):
        return self.recipe.name + " " + self.ingredient.name # you can access values outside of the class to name things. this line of code details the recipe name and ingredient

class Purchases(models.Model):
    # a purchase_id_field will populate with django here
    menu_order = models.ForeignKey(MenuItem,on_delete=models.CASCADE) # this will let us see what menu items were ordered. # without the str method its an object method that you can use for calculations for purchases
    timestamp = models.DateTimeField()

# menu order points to a row on the menu item table 
# menu item is a table with a primary key called id. 
# python will grab the menu item as an object and all of its data.
# menu order is a column in purchases that will have the menu item id in it. 
# django djaffa cake has one id number. and if coffee has an id of two. it will find things by id number. 
# each recipe has an id number of its own. on line 33 of models.py 
# its saying follow those id numbers.


    class Meta:
        verbose_name = "Purchase"


# ask myself what does this table need information for
# what questions am I trying to answer for my boss or for my project?
# when inside of virtual enviornment just run python 
# python manage.py 

views.py

from django.shortcuts import render
from django.urls import path 
from .models import Ingredient, MenuItem, Purchases
from django.views.generic import ListView

from django.http import HttpResponse

# Create your views here.

def finance(request):
    purchased_items = Purchases.objects.all() # this grabs every row in the purchases table

    total_revenue = 0 
    for item in purchased_items:
        total_revenue = total_revenue + item.menu_order.price #this uses the price of each item to calculate the revenue
    
    # i want the price of the item and the cost of each item.
    total_cost = 0
    
    
# str method made it django djaffa cake
        # this grabs the menu item with all of its data.
        # and then we want to get the price of that menu item.
        # price was accessed by dot notation to get the price for that single item that was purchased.
     


    return render(request,'inventory/finance.html')

def home(request):
    return render(request,'inventory/home.html')

class MenuView(ListView):
    model = MenuItem
    template_name = 'inventory/menu.html'

class PurchaseView(ListView):
    model = Purchases
    template_name = 'inventory/purchases.html'

class IngredientsView(ListView):
    model = Ingredient
    template_name = "inventory/ingredients.html"

I’m not addressing your logic or calculations yet, but the first thing I noticed is that you’re making a major mistake here.

As I wrote in my post at Design Problem - #4 by KenWhitesell

  • Never, under any condition or circumstance, for absolutely no reason whatever, should you ever, ever even think about using FloatField for financial data or financial-related fields. Not for costs, prices, totals, hours, rates, nothing - just don’t do it. Use the Decimal field for them.

While this issue goes well beyond just Python and Django, the Python docs at 15. Floating Point Arithmetic: Issues and Limitations — Python 3.11.3 documentation do a good job of introducing the topic.

Now, regarding your logic - what makes you think something is wrong? Do you have some data that you have tested with that is giving you unexpected values? Or are you getting some type of error message?

1 Like

agree with Ken, I cannot count the number of times I have seen numbers (financial or otherwise, though when financial, can cause worrisome side effects, especially with many numbers) such as:

. price_per_item: 11.2000000006
. profit: 99.000000000000001

etc, etc.

one rule:

from decimal import Decimal
1 Like

Thank you for your feedback. I was using float-field with a formatter for 2 decimal places. But it seems that is not best practice. Okay I will update that. I worked with my tutor and the problem was in depth but the back end logic works. On to my next step in the project.