Files
bbs/bbs/views/reports.py
T

146 lines
5.7 KiB
Python

from datetime import timedelta
from itertools import groupby
from django.contrib import messages
from django.shortcuts import redirect, render
from django.utils import timezone
from bbs.forms import DateRangeForm, InventoryTransactionForm
from bbs.models import InventoryTransaction, Order, Product, Transaction, UserProfile
def report(request):
# FIXME: split this up in smaller pieces
datetime_now = timezone.localtime()
start_time = timezone.localtime() - timedelta(days=30)
# start of day, 1 month
start_time = start_time.replace(hour=0, minute=0, second=0, microsecond=0)
# end of day
end_time = timezone.localtime().replace(hour=23, minute=59, second=59, microsecond=999)
if request.GET.get("start_time", False) or request.GET.get("end_time", False):
form = DateRangeForm(request.GET)
if form.is_valid():
start_time = form.cleaned_data["start_time"]
# end of day
end_time = form.cleaned_data["end_time"].replace(hour=23, minute=59, second=59, microsecond=999)
else:
form = DateRangeForm(
initial={
"start_time": start_time.strftime("%Y-%m-%d"),
"end_time": end_time.strftime("%Y-%m-%d"),
}
)
# Inventory
products = (
Product.objects.filter(transactions__created__range=[start_time, end_time])
.values("name", "transactions__unit_price", "transactions__amount")
.order_by("name")
)
# group by name and sum
inventory_products = {}
for k, g in groupby(products, lambda x: x["name"]):
group = []
for el in g:
el["transactions__price"] = el["transactions__amount"] * el["transactions__unit_price"]
group.append(el)
inventory_products.update(
{
k: {
"name": k,
"transactions": group,
"transactions_sum": sum(x["transactions__price"] for x in group),
"transactions_units": sum(x["transactions__amount"] for x in group),
}
}
)
itrans = InventoryTransaction.objects.filter(created__range=[start_time, end_time])
inv_in = sum(x[1].get("transactions_sum", 0) for x in inventory_products.items())
# out
out_products = (
Product.objects.filter(orderlines__order__created__range=[start_time, end_time])
.values("name", "orderlines__unit_price", "orderlines__amount")
.order_by("name")
)
# group by name and sum
for k, g in groupby(out_products, lambda x: x["name"]):
group = []
for el in g:
el["orderlines__price"] = el["orderlines__amount"] * el["orderlines__unit_price"]
group.append(el)
product = {
"name": k,
"orderlines": group,
"orderlines_sum": sum(x["orderlines__price"] for x in group),
"orderlines_units": sum(x["orderlines__amount"] for x in group),
}
if k in inventory_products:
# add diff
inventory_products[k].update(product)
else:
inventory_products.update({k: product})
for p in inventory_products.items():
p[1]["value_diff"] = p[1].get("transactions_sum", 0) - p[1].get("orderlines_sum", 0)
p[1]["units_diff"] = p[1].get("transactions_units", 0) - p[1].get("orderlines_units", 0)
inv_out = sum(x[1].get("orderlines_sum", 0) for x in inventory_products.items())
inv_diff = inv_in - inv_out
# Deposits and sales
saldo_profiles = sum(UserProfile.objects.all().values_list("balance", flat=True))
deposits = sum(Transaction.objects.all().values_list("amount", flat=True))
purchases = sum(Order.objects.all().values_list("order_sum", flat=True))
saldo = deposits - purchases
deposits_start = sum(Transaction.objects.filter(created__lt=start_time).values_list("amount", flat=True))
purchases_start = sum(Order.objects.filter(created__lt=start_time).values_list("order_sum", flat=True))
saldo_start = deposits_start - purchases_start
deposits_end = sum(Transaction.objects.filter(created__lt=end_time).values_list("amount", flat=True))
purchases_end = sum(Order.objects.filter(created__lt=end_time).values_list("order_sum", flat=True))
saldo_end = deposits_end - purchases_end
deposits_diff = deposits_end - deposits_start
purchases_diff = purchases_end - purchases_start
saldo_diff = saldo_end - saldo_start
return render(request, "report.html", locals()) # noqa: DJ003
def inventory(request):
products = Product.objects.all().order_by("-active", "inventory_amount", "name")
transactions = InventoryTransaction.objects.all().order_by("-created")
products_active = products.filter(active=True)
wholesale_value = sum([p.wholesale_value for p in products_active])
num_products = sum(products_active.values_list("inventory_amount", flat=True))
return render(request, "inventory.html", locals()) # noqa: DJ003
def inventory_add(request):
if request.method == "POST":
form = InventoryTransactionForm(data=request.POST)
if form.is_valid():
itrans = form.save(commit=False)
# Add amount and user, then save
itrans.product.inventory_amount += itrans.amount
itrans.user = request.user
itrans.product.save()
itrans.save()
messages.success(request, f"Satt inn {itrans.amount} stk {itrans.product}.")
return redirect("inventory-add")
messages.error(request, "Feil med skjemaet, se under.")
form = InventoryTransactionForm(data=request.POST)
else:
form = InventoryTransactionForm()
return render(request, "inventory_add.html", locals()) # noqa: DJ003