How to check current stock remaining - python

I am struggling to get current remaining stock in my inventory application.
I have written code to calculate remaining quantity but it calculates based on purchased quantity only. I want to add total sold quantity and find the difference between purchased and total sold quantity.
How do I calculate total sold quantity and calculate the remaining stock.
models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100, blank=True, null=True)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=100)
slug = models.CharField(max_length=100)
price = models.DecimalField(max_digits=6, decimal_places=2)
quantity = models.IntegerField(null=True, blank=True)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.name
class Stock(models.Model):
sold_quantity = models.IntegerField(null=True, blank=True, default=0)
product = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.product.name
#property
def get_difference(self):
total = self.product.quantity-self.sold_quantity
return total
Views.py
def add_sales(request):
form = AddSalesForm()
if request.method == 'POST':
form = AddSalesForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.product.quantity -= instance.sold_quantity
instance.save()
return redirect('stock_details')
contex = {'form': form}
return render(request, 'stockmgmt/add_sales.html', contex)
templates
{% extends 'stockmgmt/base.html' %}
{% block content %}
<form method="GET">
Add Sales
<p>
<table class="table table-bordered">
<tr>
<th>Item</th>
<th>Category</th>
<th>Purchased Qty</th>
<th>Sold Qty</th>
<th>Remaining Qty</th>
<th>Price</th>
<th>Action</th>
</tr>
{% for item in stocks %}
<tr>
<td>{{item.product.name}}</td>
<td>{{item.product.category}}</td>
<td>{{item.product.quantity}}</td>
<td>{{item.sold_quantity}}</td>
<td>{{item.get_difference}}</td>
<td>{{item.product.price}}</td>
<td>Delete
Edit
</td>
</tr>
{% endfor %}
</table>
</form>
{% endblock %}

you need to update the existing stock after each order
for ex.
opening stock = 100
current stock = 100
after first order of 10 qty
opening stock = 100
current stock = current stock - order qty = 100 - 10 = 90
after second order of 5 qty
opening stock = 100
current stock = current stock - order qty = 90 - 5 = 85
if i purchase or add new stock the current stock will be updated
after adding 50 qty
current stock = current stock + purchase qty = 85 + 50 = 135
you can have a log table (Model) for income and outgoing of stock for tracking
hope you understand the concept i'm trying to explain

Related

How can I get Total Deposit of Customers

I am working on a Django project with 2 Models; Customer and Deposit and I want to display a list of Customers with their names, deposited dated, account number, and Total Deposited within the year so how do I do it the right way.
See what I have tried but Couldn't get the Customers' name in my Django Templates.
Models:
class Customer(models.Model):
surname = models.CharField(max_length=10, null=True)
othernames = models.CharField(max_length=20, null=True)
account_number = models.CharField(max_length=10, null=True)
address = models.CharField(max_length=50, null=True)
phone = models.CharField(max_length=11, null=True)
date = models.DateTimeField(auto_now_add=True, null=True)
#Get the url path of the view
def get_absolute_url(self):
return reverse('customer_create', args=[self.id])
#Making Sure Django Display the name of our Models as it is without Pluralizing
class Meta:
verbose_name_plural = 'Customer'
#
def __str__(self):
return f'{self.surname} {self.othernames} - {self.account_number}'
class Deposit(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True)
acct = models.CharField(max_length=6, null=True)
staff = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
deposit_amount = models.PositiveIntegerField(null=True)
date = models.DateTimeField(auto_now_add=True)
def get_absolute_url(self):
return reverse('create_account', args=[self.id])
def __str__(self):
return f'{self.customer} Deposited {self.deposit_amount} by {self.staff.username}'
here is my view code:
def customer_list(request):
#Get Current Date
current_date = datetime.now().date()
#Get Current Month Name from Calendar
current_month_name = calendar.month_name[date.today().month]
group_deposits = Deposit.objects.filter(date__year=current_date.year).order_by('acct')
grouped_customer_deposit = group_deposits.values('acct').annotate(total `=Sum('deposit_amount')).order_by()`
context = { 'customers':grouped_customer_deposit,}
Here is how I tried to display the result in Django Template:
{% for deposit in customers %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ deposit.acct }}</td>
<td>{{ deposit.customer.surname }}</td>
<td>{{ deposit.total }}</td>
<td>{{ customer.deposit.date }}</td>
<th scope="row"><a class="btn btn-info btn-sm" href=" ">Deposit</a></th>
</tr>
{% endfor %}
Someone should graciously help with the most efficient way of getting the Total Deposit for each customer with their names, account number, and date deposited. Thank in anticipation for your kind answers.
As you are using the values method:
grouped_customer_deposit = group_deposits.values('acct').annotate(total `=Sum('deposit_amount')).order_by()`
Django will return a queryset that returns dictionaries rather than model instances. See Django Queryset API reference for more details.
This means that you cannot reference your model relationships as you are trying to do here:
<td>{{ deposit.customer.surname }}</td>
as that information will not be in the dictionary passed to the template (you can do a print of grouped_customer_deposit in your view, or display it in your template -- {{ customers }} -- to see what I mean).
Ergo, if you remove your call to values() then your template will receive model instances which should solve your problem, and make your template work as-is.
grouped_customer_deposit = group_deposits.annotate(total `=Sum('deposit_amount')).order_by()`
(Although your syntax for your annotate is not correct, so I'm assuming that was a mistake when you pasted your code here.)

How can i group by student id

Please i would like anyone to help me out, tryna grouping this student result from the lecturer session so that lecturer can view each student based on the course student submitted i have successfully get a list but the list are not grouped by the student ids
here is the view for lecturer request
class LecturerListOfStudentResult(View):
def get(self, request, *args, **kwargs):
lecturer = Lecturers.objects.get(admin=request.user.id)
result = LecturerCourse.objects.filter(lecturer=lecturer)
context = {
'question':result,
}
return render(request, 'superadmin/lecturer/list-result-
student.html', context)
Here is the list of all submitted student result view
class ListAllSubmittedAnswerByCourseRegister(View):
def get(self, request, *args, **kwargs):
lecturer = Lecturers.objects.get(admin=request.user.id)
result = StudentSubmittedAnswer.objects.filter(lecturer=lecturer,
student=int(kwargs['id']))
context = {'question':result}
return render(request, 'superadmin/lecturer/list-all-result-
student.html', context)
here is the detailview for the list which i only get the count record
class LecturerListOfStudentResultDetail(View):
def get(self, request, *args, **kwargs):
student = Students.objects.get(admin=int(kwargs['id']))
result = StudentSubmittedAnswer.objects.filter(student=student)
skipped = StudentSubmittedAnswer.objects.filter(student=student,
right_answer='Not Submitted').count()
attempted = StudentSubmittedAnswer.objects.filter
(student=student).exclude(right_answer='Not Submitted').count()
rightAns=0
percentage=0
for row in result:
if row.question.right_opt == row.right_answer:
rightAns+=1
if len(result) > 0:
percentage=(rightAns*100)/result.count()
return render(request, 'superadmin/lecturer/view-result-
detail.html', {'result': result,'total_skipped':
skipped,'attempted': attempted, 'rightAns': rightAns,
'percentage':percentage})
Here is my url.py
path('lecturer/course/registration',
LecturerCourseRegistration.as_view(), name="lecturer-course-
registration"),
path('list/lecturer/course/registration',
ListLecturerCourseRegistration.as_view(), name="list-lecturer-
course-registration"),
path('list/submitted/course/answer/student/<int:id>/',
ListAllSubmittedAnswerByCourseRegister.as_view(), name="list-all-
submitted-course-question-by-student"),
here is the list of student html
{% for r in question %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ r.course.name }}</td>
<td>{{ r.created_at }}</td>
<td><a href="{% url 'emisapp:list-all-submitted-course-
question-by-student' r.lecturer.admin.id %}">View</a></td>
{% endfor %}
Here is the html view for looping all the exam submitted for each student
{% for row in result %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ row.course.name }}</td>
<td>{{ row.question.question }}</td>
<td>{{ row.question.right_opt }}</td>
{% if row.question.right_opt == row.right_answer %}
<td class="bg-success text-white">{{ row.right_answer }}</td>
{% else %}
<td class="bg-danger text-white">{{ row.right_answer }}</td>
{% endif %}
</tr>
{% endfor %}
Models.py
class StudentSubmittedAnswer(models.Model):
id = models.AutoField(primary_key=True)
course = models.ForeignKey(Courses)
lecturer = models.ForeignKey(Lecturers)
question = models.ForeignKey(QuizQuestion)
student = models.ForeignKey(Students)
right_answer = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True, null=True)
Here is my added Models.py
class StudentSubmittedAnswer(models.Model):
id = models.AutoField(primary_key=True)
lecturercourse = models.ForeignKey(LecturerCourse, null=True,
related_name='studentsubmittedanswer', on_delete=models.CASCADE)
lecturer = models.ForeignKey(Lecturers, null=True,
related_name='studentsubmittedanswer', on_delete=models.CASCADE)
question = models.ForeignKey(QuizQuestion,
related_name='studentsubmittedanswer', on_delete=models.CASCADE)
student = models.ForeignKey(Students,
related_name='studentsubmittedanswer', null=True,
on_delete=models.CASCADE)
right_answer = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True, null=True)
class Faculty(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
slug = models.SlugField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
class Department(models.Model):
id = models.AutoField(primary_key=True)
faculty = models.ForeignKey(Faculty, default=None)
name = models.CharField(max_length=255)
slug = models.SlugField(null=True)
short_desc = models.TextField(null=True, blank=True)
class Courses(models.Model):
id = models.AutoField(primary_key=True)
faculty = models.ManyToManyField(Faculty, related_name='courses')
department = models.ManyToManyField(Department)
name = models.CharField(max_length=255)
slug = models.SlugField()
short_desc = models.TextField(blank=True, null=True)
long_desc = models.TextField(blank=True, null=True)
class StudentFaculty(models.Model):
id = models.AutoField(primary_key=True)
student = models.ForeignKey(Students, null=True)
studentfaculty = models.ForeignKey('Faculty')
slug = models.SlugField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now_add=True)
class StudentDepartment(models.Model):
id = models.AutoField(primary_key=True)
student = models.ForeignKey(Students)
studentfaculty = models.ForeignKey(StudentFaculty)
studentdepartment = models.ForeignKey(Department)
slug = models.SlugField(null=True)
class StudentCourses(models.Model):
id = models.AutoField(primary_key=True)
student = models.ForeignKey(Students)
studentfaculty = models.ForeignKey(StudentFaculty)
studentdepartment = models.ForeignKey('StudentDepartment')
studentcourse = models.ForeignKey(Courses)
class QuizQuestion(models.Model):
id = models.AutoField(primary_key=True)
lecturer = models.ForeignKey(Lecturers)
faculty = models.ForeignKey(LecturerFaculty, null=True)
lecturerdepartment = models.ForeignKey(LecturerDepartment, null=True)
lecturercourse = models.ForeignKey(LecturerCourse)
session = models.ForeignKey(SessionYearModel)
semester = models.ForeignKey(Semester, null=True)
mark = models.IntegerField(null=True)
examtype = models.ForeignKey('ExamType', related_name='quizzes')
question = models.TextField()
opt_1 = models.CharField(max_length=255)
opt_2 = models.CharField(max_length=255)
opt_3 = models.CharField(max_length=255)
opt_4 = models.CharField(max_length=255)
class LecturerFaculty(models.Model):
id = models.AutoField(primary_key=True)
lecturer = models.ForeignKey('Lecturers',
related_name='lecturerfaculty', null=True, on_delete=models.CASCADE)
faculty = models.ForeignKey('Faculty')
slug = models.SlugField(null=True)
class LecturerDepartment(models.Model):
id = models.AutoField(primary_key=True)
lecturer = models.ForeignKey('Lecturers')
lecturerfaculty = models.ForeignKey('LecturerFaculty')
lecturerdepartment = models.ForeignKey('Department')
class LecturerCourse(models.Model):
id = models.AutoField(primary_key=True)
lecturer = models.ForeignKey('Lecturers')
faculty = models.ForeignKey('Faculty')
lecturerdepartment = models.ForeignKey('LecturerDepartment')
lecturercourse = models.ForeignKey('Courses')
slug = models.SlugField(null=True)
class Lecturers(models.Model):
id = models.AutoField(primary_key=True)
admin = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
profile_pic = models.ImageField(default='default.jpg')
middle_name = models.CharField(max_length=255)
You can use values and annotate to group by student Ids.
class ListAllSubmittedAnswerByCourseRegister(View):
def get(self, request, *args, **kwargs):
lecturer = Lecturers.objects.get(admin=request.user.id)
=> result = StudentSubmittedAnswer.objects.values('student','lecturer').annotate(answers_count=Count('answers')).filter(lecturer=lecturer,
student=int(kwargs['id'])).order_by()
context = {'question':result}
return render(request, 'superadmin/lecturer/list-all-result-
student.html', context)
I assumed the name of the fields in the model student answers lecturer
Refrence
Django documentation: values(), annotate(), and Count
Django documentation: Aggregation, and in particular the section entitled Interaction with default ordering or order_by()
https://docs.djangoproject.com/en/4.0/topics/db/aggregation/#order-of-annotate-and-values-clauses

Dictionary items not showing up in template in django

I have gathered data from two tables that is Orders and Purchases (joined) and saved that in dictionary, when I'm printing the qty on the console its giving me the value but when I'm trying to print the values on template it not showing up however columns from the orders table like first name last name status address is shown on the template but qty and product from the purchases table is not showing up on the template but can be easily printed on console
can somebody help???
Models.py
Dispatcher = models.ForeignKey(Dispatchers , null=True, on_delete=models.SET_NULL )
Firstname = models.CharField(max_length=200 , null=True)
Lastname = models.CharField(max_length=200 , null=True)
Email = models.CharField(max_length=200 , null=True)
Address = models.CharField(max_length=200 , null=True)
Country = models.CharField(max_length=200 , null=True)
State = models.CharField(max_length=200 , null=True)
status = models.CharField(max_length=200 , null=True)
def __str__(self):
return self.Lastname
class purchases(models.Model):
orders_id = models.ForeignKey(Orders , null=True, on_delete=models.SET_NULL )
product = models.CharField(max_length=200 , null=True)
qty = models.CharField(max_length=200 , null=True)
price = models.CharField(max_length=200 , null=True)
def __str__(self):
return self.product
views.py file
dispatcherOrders = {}
orders = request.user.dispatchers.orders_set.all()
for order in orders:
dispatcherOrders[order] = purchases.objects.get(orders_id = order.id)
print(dispatcherOrders[order].qty)
return render(request , 'dispatcherOrders.html',{'dispatcherOrders' : dispatcherOrders})
dispatcherOrders.html
{%for Orders in dispatcherOrders%}
<tr>
<th scope="row">1</th>
<td>{{Orders.Firstname}}</td>
<td>{{Orders.Lastname}}</td>
<td>{{Orders.Address}}</td>
<td>{{Orders.product}}</td>
<td>{{Orders.qty}}</td>
<td>{{Orders.status}}</td>
</tr>
{% endfor %}
In your code, dispatcherOrders dictionary keys are orders and dictionary values are purchases:
dispatcherOrders[order] = purchases.objects.get(orders_id = order.id)
yet you are iterating only on dictionary keys, the orders:
{%for Orders in dispatcherOrders%}
To get the info from purchases, iterate the dictionary items too.
So your template code should be similar to
{%for Orders, Purchase in dispatcherOrders.items %}
<tr>
<th scope="row">1</th>
<td>{{Orders.Firstname}}</td>
<td>{{Orders.Lastname}}</td>
<td>{{Orders.Address}}</td>
<td>{{Purchase.product}}</td>
<td>{{Purchase.qty}}</td>
<td>{{Purchase.status}}</td>
</tr>
{% endfor %}
Here's how .items work: https://stackoverflow.com/a/6285769/3694363

How can I show in cart items in my index view?

I'm working on an ecommerce app, and I have a template that displays all my products.
I want to show how many of the item are in the cart. But I can't seem to figure out how to get that information from my for loop.
I want to check if the current product in my for loop matches with an OrderItem for that user.
I'm able to do this in the detail view but not my catalogue/index
Code:
template
{% for product in products %}
{{product.title}} - {{product.quantity_in_cart}}
{% endfor %}
(As of right now, product.quantity_in_cart does nothing. I would like it to show how many of this product are in the cart)
view
def product_index(request):
title = "My Products"
products = Product.objects.all()
order = get_cart(request)
cart = Order.objects.get(id=order.id, complete=False)
items = cart.orderitem_set.all()
context = {
'title' : title,
'products' : products,
'cart' : cart,
'items': items
}
return render(request, "store/product_index.html", context)
models
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
complete = models.BooleanField(default=False, null=True, blank=False)
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
class Product(models.Model):
name = models.CharField(max_length=64)
slug = models.SlugField(unique=True, null=True)
description = RichTextField(blank=True)
price = models.DecimalField(max_digits=8, decimal_places=2)
quantity = models.IntegerField()
def product_index(request):
title = "My Products"
products = Product.objects.all()
order = get_cart(request)
cart = Order.objects.get(id=order.id, complete=False)
items = cart.orderitem_set.all()
# Changes
for product in products:
qty = 0
if items.filter(product=product).exists():
qty = items.get(product=product).quantity
setattr(product, 'quantity_in_cart', qty)
context = {
'title' : title,
'products' : products,
'cart' : cart,
'items': items
}
return render(request, "store/product_index.html", context)
Add a session key called 'cart' which can be a list and each item in the list can be a dictionary containing 'name', 'quatity' and price, as the the user is adding to the cart you add you the session variable and in the template you can render the cart using a for like this
{% for product in request.session.carr%}
{%endfor%}

How can i fetch a specific to a variable

Hello i want to fetch a specific field to a variable
For that I have Order model:
class Order(models.Model):
product = models.ForeignKey(
Product, on_delete=models.CASCADE, related_name="product")
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
fname = models.CharField(max_length=100, null=True)
address = models.CharField(max_length=1000, null=True)
phone = models.CharField(max_length=12, null=True)
price = models.IntegerField()
date = models.DateField(datetime.datetime.today, null=True)
status = models.ForeignKey(
Status, on_delete=models.CASCADE, blank=True, null=True)
payment_method = models.ForeignKey(
PaymentMethod, on_delete=models.CASCADE, blank=True, null=True)
total = models.IntegerField(null=True)
Here I want to fetch total field in a variable.But I am new for that reason I am really confused about this topic
There is another method you can use. You would have to define a method or property for the field and then call it in your templates.
models.py
class Order(models.Model):
total = models.IntegerField(null=True)
#property
def get_total(self):
return self.total
views.py
from django.shortcuts import render
from .models import *
def Index(request):
Orders = Order.objects.all()
context = {"Orders":Orders}
return render(request, "template/page.html", context)
page.html
{% for order in Orders %}
{{order.get_total}}
# You can do the same to other field to get them
{% endfor %}
Its quite easy. Since you have defined your models already. All you have to do is to use it in your view.py and then in your templates. Exaple is the below:
view.py
from django.shortcuts import render
from .models import *
def Index(request):
Orders = Order.objects.all()
context = {"Orders":Orders}
return render(request, "template/page.html", context)
page.html
{% for order in Orders %}
{{order.total}}
{{order.price}}
# You can do the same to other field to get them
{% endfor %}

Categories

Resources