Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
nyashaChiza committed Aug 11, 2024
1 parent d35f60a commit d9364ae
Show file tree
Hide file tree
Showing 12 changed files with 206 additions and 49 deletions.
2 changes: 1 addition & 1 deletion accounts/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class CompanyAdmin(admin.ModelAdmin):

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
list_display = ('username', 'email', 'gender', 'role', 'status', 'is_logged_in')
list_display = ('username', 'company','email', 'gender', 'role', 'status', 'is_logged_in')
list_filter = ('role', 'status', 'is_logged_in')
search_fields = ('username', 'email', 'phone_number')

Expand Down
5 changes: 3 additions & 2 deletions accounts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ def create_staff(request, pk:int):
if request.method == 'POST':
form = UserForm(request.POST, request.FILES)
if form.is_valid():
staff_user = form.save(commit=False)
site = Site.objects.get(pk=pk) # Assuming the site is selected in the form
staff_user = form.save(commit=False)
staff_user.company = request.user.company

# Assign the user as the site's manager or operator based on their role
if staff_user.role == 'Manager':
Expand Down Expand Up @@ -142,5 +143,5 @@ class SiteDetailView(TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['site'] = Site.objects.filter(uuid=kwargs.get('uuid')).first()
context["remaining_stock"] = DashboardData(self.request.user, datetime.now()).get_stock_data().get('current_available_Stock_quantity')
context["remaining_stock"] = DashboardData(self.request.user).get_stock_data().get('current_available_Stock_quantity')
return context
157 changes: 142 additions & 15 deletions dashboard/helpers/dashboard_data.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,155 @@
from transactions.models import Transaction
from stock.models import Stock
from accounts.models import Site, User
from datetime import datetime
from requisition.models import Requisition
from datetime import datetime, timedelta
from django.db.models import Sum, F

class DashboardData:
def __init__(self, user:User, date: datetime):
self.date = date
def __init__(self, user: User):
self.user = user

self.site = self.get_site_data()

def get_site_data(self):
return self.user.site
"""Returns the site associated with the user based on their role."""
if self.user.role == "Operator":
return self.user.operation_site
elif self.user.role == "Manager":
return self.user.managed_site
return None

def get_sales_data(self):
"""Returns a dictionary with sales data."""
return {
"current_month_total_sales": self.calculate_current_month_sales(),
"total_sales": self.calculate_total_sales(),
"last_month_total_sales": self.calculate_last_month_sales(),
"week_total_sales": self.calculate_week_sales(),
"total_sales_today": self.calculate_today_sales()
}

def calculate_current_month_sales(self):
"""Calculate total sales for the current month."""
start_of_month = datetime.now().replace(day=1)
# Calculate the total sales for the last month by summing quantity * unit_cost
return Transaction.objects.filter(
site=self.site,
created__gte=start_of_month,
).aggregate(
total_sales=Sum(F('quantity') * F('unit_cost'))
)['total_sales'] * self.site.stock.first().price or 0.00

def calculate_total_sales(self):
"""Calculate total sales for today."""
return Transaction.objects.filter(site=self.site).aggregate(
total_sales=Sum(F('quantity') * F('unit_cost'))
)['total_sales'] * self.site.stock.first().price or 0.00

def calculate_last_month_sales(self):
"""Calculate total sales for the last month."""
start_of_last_month = (datetime.now().replace(day=1) - timedelta(days=1)).replace(day=1)
end_of_last_month = datetime.now().replace(day=1) - timedelta(days=1)

# Calculate the total sales for the last month by summing quantity * unit_cost
return Transaction.objects.filter(
site=self.site,
created__gte=start_of_last_month,
created__lte=end_of_last_month
).aggregate(
total_sales=Sum(F('quantity') * F('unit_cost'))
)['total_sales'] or 0.00

def calculate_week_sales(self):
"""Calculate total sales for the current week."""
start_of_week = datetime.now() - timedelta(days=datetime.now().weekday())

# Calculate the total sales for the current week by summing quantity * unit_cost
return Transaction.objects.filter(
site=self.site,
created__gte=start_of_week
).aggregate(
total_sales=Sum(F('quantity') * F('unit_cost'))
)['total_sales'] * self.site.stock.first().price or 0.00

return {"current_month_total_sales": 678, "total_sales": 1000, "last_month_total_sales": 679, "week_total_sales": 67.45 , "total_sales_today":14.7}

def get_stock_data(self):

return {"current_month_total_sales_quantity": 340.3,"week_total_sales_quantity":29.4, "total_sales_quantity": 340.3,"last_month_total_sales_quantity": 340.3, "current_available_Stock_quantity":65, "total_Stock_quantity_sold":1220, "total_requisitions":68 }

def calculate_today_sales(self):
"""Calculate total sales for today."""
today = datetime.now().date()
return Transaction.objects.filter(site=self.site, created__date=today).aggregate(
total_sales=Sum(F('quantity') * F('unit_cost'))
)['total_sales'] * self.site.stock.first().price or 0.00
def get_stock_data(self):
"""Returns a dictionary with stock data."""
return {
"current_month_total_sales_quantity": self.calculate_current_month_sales_quantity(),
"week_total_sales_quantity": self.calculate_week_sales_quantity(),
"total_sales_quantity": self.calculate_total_sales_quantity(),
"last_month_total_sales_quantity": self.calculate_last_month_sales_quantity(),
"current_available_stock_quantity": self.calculate_current_available_stock_quantity(),
"total_stock_quantity_sold": self.calculate_total_stock_quantity_sold(),
"total_requisitions": self.calculate_total_requisitions()
}

def calculate_current_month_sales_quantity(self):
"""Calculate total quantity of items sold in the current month."""
start_of_month = datetime.now().replace(day=1)
return Transaction.objects.filter(site=self.site, created__gte=start_of_month).aggregate(Sum('quantity'))['quantity__sum'] or 0

def calculate_week_sales_quantity(self):
"""Calculate total quantity of items sold in the current week."""
start_of_week = datetime.now() - timedelta(days=datetime.now().weekday())
return Transaction.objects.filter(site=self.site, created__gte=start_of_week).aggregate(Sum('quantity'))['quantity__sum'] or 0
def calculate_total_sales_quantity(self):
"""Calculate total quantity of items sold for the site."""
return Transaction.objects.filter(site=self.site).aggregate(Sum('quantity'))['quantity__sum'] or 0

def calculate_last_month_sales_quantity(self):
"""Calculate total quantity of items sold in the last month."""
start_of_last_month = (datetime.now().replace(day=1) - timedelta(days=1)).replace(day=1)
end_of_last_month = datetime.now().replace(day=1) - timedelta(days=1)
return Transaction.objects.filter(site=self.site, created__gte=start_of_last_month, created__lte=end_of_last_month).aggregate(Sum('quantity'))['quantity__sum'] or 0

def calculate_current_available_stock_quantity(self):
"""Calculate current available stock quantity."""
return Stock.objects.filter(site=self.site).aggregate(Sum('quantity'))['quantity__sum'] or 0

def calculate_total_stock_quantity_sold(self):
"""Calculate total quantity of stock sold."""
return self.calculate_total_sales_quantity()

def calculate_total_requisitions(self):
"""Calculate total number of requisitions."""
# Assuming `requisitions` is a related field in `Transaction` or a similar model
return Requisition.objects.filter(site=self.site).count()

def get_sales_plot_data(self):

return {"monthly_average":345, "weekly_average":89.3, "daily_average":23.4, "plot_data":[]}

"""Returns a dictionary with data for plotting sales."""
return {
"monthly_average": self.calculate_monthly_average(),
"weekly_average": self.calculate_weekly_average(),
"daily_average": self.calculate_daily_average(),
"plot_data": self.calculate_plot_data()
}

def calculate_monthly_average(self):
"""Calculate the average monthly sales."""
return self.calculate_total_sales() / 12 # Simplified; adjust as needed

def calculate_weekly_average(self):
"""Calculate the average weekly sales."""
return self.calculate_total_sales() / 52 # Simplified; adjust as needed

def calculate_daily_average(self):
"""Calculate the average daily sales."""
return self.calculate_total_sales() / 365 # Simplified; adjust as needed

def calculate_plot_data(self):
"""Generate plot data."""
# Implement the actual logic to generate plot data based on your requirements
return []

def get_stock_sales_table_data(self):

return Transaction.objects.filter().all()
"""Returns a queryset of all transactions for the user's site."""
if self.site:
return Transaction.objects.filter(site=self.site)
return Transaction.objects.none() # Return an empty queryset if no site is assigned
23 changes: 11 additions & 12 deletions dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,22 @@ class DashboardView(TemplateView):
template_name = 'dashboard/index.html'

def dispatch(self, request, *args, **kwargs):
# Check if the user is an Admin
if request.user.role == 'Admin':
# Check if the admin has a company set up
if not request.user.company:
user = request.user

if user.role == 'Admin':
# Admin must have a company set up
if not user.company:
return redirect('create_company')

# Check if the user is a Manager or Operator
if request.user.role in ['Manager', 'Operator']:
# Check if the manager/operator has a company and site assigned
if not request.user.company or not request.user.site:
# Show a banner/message

elif user.role in ['Manager', 'Operator']:
# Manager or Operator must have a company and a site assigned
if not user.company or (user.role == 'Manager' and not user.managed_site) or (user.role == 'Operator' and not user.operation_site):
messages.info(request, "Please contact your admin to set up your company and site.")
return redirect('account_login')

return super().dispatch(request, *args, **kwargs)

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['dashboard_data'] = DashboardData(self.request.user, datetime.now())
context['dashboard_data'] = DashboardData(self.request.user)
return context
4 changes: 2 additions & 2 deletions requisition/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class RequisitionDetailView(DetailView):

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["remaining_stock"] = DashboardData(self.request.user, datetime.now()).get_stock_data().get('current_available_Stock_quantity')
context["remaining_stock"] = DashboardData(self.request.user).get_stock_data().get('current_available_Stock_quantity')
return context

class RequisitionCreateView(View):
Expand Down Expand Up @@ -89,7 +89,7 @@ class RequisitionUpdateView(UpdateView):

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["remaining_stock"] = DashboardData(datetime.now()).get_stock_data().get('current_available_Stock_quantity')
context["remaining_stock"] = DashboardData(self.request.user).get_stock_data().get('current_available_Stock_quantity')
return context

class RequisitionDeleteView(View):
Expand Down
2 changes: 1 addition & 1 deletion stock/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class RecieptDetailView(DetailView):

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["remaining_stock"] = DashboardData(datetime.now()).get_stock_data().get('current_available_Stock_quantity')
context["remaining_stock"] = DashboardData(self.request.user).get_stock_data().get('current_available_Stock_quantity')
return context

class RecieptDeleteView(View):
Expand Down
8 changes: 4 additions & 4 deletions templates/dashboard/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ <h6 class="title">Available Stock Stock</h6>
</div>
<div class="data">
<div class="data-group">
<div class="amount">{{ dashboard_data.get_stock_data.current_available_Stock_quantity }}kg</div>
<div class="amount">{{ dashboard_data.site.stock.first.quantity}}kg</div>
</div>
</div>
</div><!-- .card-inner -->
Expand Down Expand Up @@ -187,7 +187,7 @@ <h6 class="title">Site Statistics</h6>
<li class="item">
<div class="info">
<div class="title">Quantity Moved</div>
<div class="count">{{ dashboard_data.get_stock_data.total_Stock_quantity_sold }}kg</div>
<div class="count">{{ dashboard_data.get_stock_data.total_stock_quantity_sold }}kg</div>
</div>
<em class="icon bg-purple-dim ni ni-unarchive"></em>
</li>
Expand All @@ -208,8 +208,8 @@ <h6 class="title">Site Statistics</h6>
</li>
<li class="item">
<div class="info">
<div class="title">Address</div>
<div class="count">{{ dashboard_data.get_site_data.address }}</div>
<div class="title">Site</div>
<div class="count">{{ dashboard_data.get_site_data.name }}</div>
</div>
<em class="icon bg-purple-dim ni ni-truck"></em>
</li>
Expand Down
4 changes: 3 additions & 1 deletion templates/reciept/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ <h3 class="nk-block-title page-title">Stock Reception</h3>
<ul class="nk-block-tools g-3">

<li class="nk-block-tools-opt">
{% if request.user.role == "Manager" or request.user.role == "Operator" %}
<a class="btn btn-icon btn-primary d-md-none"><em data-bs-toggle="modal" data-bs-target="#addRecieptModal" class="icon ni ni-plus"></em></a>
<a href="#" data-bs-toggle="modal" data-bs-target="#addRecieptModal" class="btn btn-primary d-none d-md-inline-flex"><em class="icon ni ni-plus"></em><span>Add Requisition</span></a>
<a href="#" data-bs-toggle="modal" data-bs-target="#addRecieptModal" class="btn btn-primary d-none d-md-inline-flex"><em class="icon ni ni-plus"></em><span>Add Receipt</span></a>
{% endif %}
</li>
</ul>
</div>
Expand Down
2 changes: 2 additions & 0 deletions templates/requisition/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ <h3 class="nk-block-title page-title">Requisitions</h3>
</div>
</li>
<li class="nk-block-tools-opt">
{% if request.user.role == "Manager" or request.user.role == "Operator" %}
<a class="btn btn-icon btn-primary d-md-none"><em data-bs-toggle="modal" data-bs-target="#addRequisitionModal" class="icon ni ni-plus"></em></a>
<a href="#" data-bs-toggle="modal" data-bs-target="#addRequisitionModal" class="btn btn-primary d-none d-md-inline-flex"><em class="icon ni ni-plus"></em><span>Add Requisition</span></a>
{% endif %}
</li>
</ul>
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/transactions/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ <h5 class="card-title">Sale: {{ sale.order_number.upper }}</h5>
<li class="item">
<div class="info">
<div class="title">Product</div>
<div class="count">${{ sale.product }}</div>
<div class="count">{{ sale.product }}</div>
</div>
<em class="icon bg-primary-dim ni ni-bag"></em>
</li>
Expand Down
2 changes: 2 additions & 0 deletions templates/transactions/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ <h3 class="nk-block-title page-title">Stock Sales (Remaining Quantity: {{ remain
<a class="btn btn-icon btn-warning d-md-none"><em class="icon ni ni-alert-fill-c"></em></a>
<a disabled class="btn btn-warning d-none d-md-inline-flex"><em class="icon ni ni-alert-fill-c"></em><span>Out Of Stock</span></a>
{% else %}
{% if request.user.role == "Manager" or request.user.role == "Operator" %}
<a href="#" data-bs-toggle="modal" data-bs-target="#addSaleModal" class="btn btn-icon btn-primary d-md-none"><em class="icon ni ni-plus"></em></a>
<a href="#" data-bs-toggle="modal" data-bs-target="#addSaleModal" class="btn btn-primary d-none d-md-inline-flex"><em class="icon ni ni-plus"></em><span>Add Sale</span></a>
{% endif %}
{% endif %}
</li>
</ul>
</div>
Expand Down
Loading

0 comments on commit d9364ae

Please sign in to comment.