Files
xvatayka/core/apps/management/views/common/create.py
Abdulaziz Axmadaliyev 3691e2d068 Initial commit
2026-02-17 19:05:54 +05:00

382 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from django.db.models import F, Sum
from core.apps.management.forms import DeviceForm, IncomeForm, WarehouseForm, UserCreateForm, ExpenseFormEmployee, \
ExpenseFormManager, ExpenseFormBusinessman, ReportForm
from django.db import transaction
from django.shortcuts import render, redirect
from core.apps.management.forms import ToyMovementForm, ToyMovementFormEmployee
from django.contrib.auth.decorators import login_required
from core.apps.management.decorators import role_required
from core.apps.management.forms import UserCreateFormManagerToEmployee, UserCreateFormBusinessman
from core.apps.management.forms.RentForm import RentForm
from core.apps.management.models import ToyMovement, Warehouse, Report
@login_required
@role_required(["manager", "businessman"])
def create_device(request):
user = request.user
if request.method == "POST":
form = DeviceForm(request.POST, user=user)
if form.is_valid():
form.save()
return redirect("dashboard")
else:
form = DeviceForm(user=user)
return render(
request,
"common/create/device_create.html",
{
"form": form,
"title": "Aparat Yaratish"
}
)
@login_required
@role_required(["employee"])
def create_income(request):
if request.method == "POST":
form = IncomeForm(request.POST, user=request.user)
if form.is_valid():
income = form.save(commit=False)
if request.user.role == "employee":
income.amount = None
income.save()
return redirect("income_list")
else:
form = IncomeForm(user=request.user)
return render(request, "common/create/income_create.html", {"form": form})
@login_required
@role_required(['manager', 'businessman'])
def create_income_manager_and_businessman(request):
if request.method == "POST":
form = IncomeForm(request.POST, user=request.user)
if form.is_valid():
with transaction.atomic():
income = form.save(commit=False)
income.created_by = request.user
income.save()
warehouse = income.warehouse
warehouse.toys_count += income.amount
warehouse.save()
return redirect("common/create/income_create.html")
else:
form = IncomeForm(user=request.user)
return render(request=request, template_name="common/create/income_create.html", context={"form": form})
@login_required
def create_expense(request):
user = request.user
# select form based on role
if user.role == "employee":
form_class = ExpenseFormEmployee
elif user.role == "manager":
form_class = ExpenseFormManager
else: # businessman or superuser
form_class = ExpenseFormBusinessman
if request.method == "POST":
form = form_class(request.POST)
if form.is_valid():
with transaction.atomic():
expense = form.save(commit=False)
expense.created_by = user
# AUTO CONFIRM for manager & businessman
if user.role in ["manager", "businessman"]:
expense.is_confirmed = True
expense.confirmed_by = user
expense.save()
return redirect("dashboard")
else:
form = form_class()
return render(request, "common/create/expense_create.html", {
"form": form,
"title": "Xarajat qoʻshish",
"user_role": user.role
})
@login_required
@role_required(["businessman"])
def create_warehouse(request):
form = WarehouseForm(request.POST or None)
if form.is_valid():
form.save()
return redirect("businessman_dashboard")
return render(request, "common/create/warehouse_create.html", {
"form": form,
"title": "Sklad Yaratish"
})
@login_required
@role_required(["manager", "businessman"])
def create_user(request):
if request.user.role == "businessman":
form_class = UserCreateFormBusinessman
form_kwargs = {}
redirect_to = "businessman_dashboard"
else: # manager
form_class = UserCreateFormManagerToEmployee
form_kwargs = {"manager": request.user}
redirect_to = "manager_dashboard"
form = form_class(request.POST or None, **form_kwargs)
if form.is_valid():
form.save()
return redirect(redirect_to)
return render(request, "common/create/user_create.html", {
"form": form,
"title": "Foydalanuvchi yaratish",
})
@login_required
def create_toy_movement(request):
user = request.user
if user.role == "employee":
form_class = ToyMovementFormEmployee
else:
form_class = ToyMovementForm
if request.method == "POST":
form = form_class(request.POST, user=user)
if form.is_valid():
with transaction.atomic():
quantity = form.cleaned_data["quantity"]
if user.role == "employee":
# Auto determine warehouse by region
from_wh = Warehouse.objects.select_for_update().filter(
region=user.region
).first()
if not from_wh:
form.add_error(None, "No warehouse assigned to your region.")
return render(request,
"common/create/toy_movement_create.html",
{"form": form})
if from_wh.toys_count < quantity:
form.add_error("quantity", "Not enough toys in warehouse.")
return render(request,
"common/create/toy_movement_create.html",
{"form": form})
# Deduct stock
Warehouse.objects.filter(pk=from_wh.pk).update(
toys_count=F("toys_count") - quantity
)
movement = form.save(commit=False)
movement.movement_type = "from_warehouse"
movement.from_warehouse = from_wh
movement.to_warehouse = None
movement.created_by = user
movement.save()
else:
# Manager / Businessman normal logic
from_wh = form.cleaned_data["from_warehouse"]
movement_type = form.cleaned_data["movement_type"]
to_wh = form.cleaned_data.get("to_warehouse")
from_wh = Warehouse.objects.select_for_update().get(pk=from_wh.pk)
if from_wh.toys_count < quantity:
form.add_error("quantity", "Not enough toys in warehouse.")
return render(request,
"common/create/toy_movement_create.html",
{"form": form})
Warehouse.objects.filter(pk=from_wh.pk).update(
toys_count=F("toys_count") - quantity
)
if movement_type == "between_warehouses" and to_wh:
to_wh = Warehouse.objects.select_for_update().get(pk=to_wh.pk)
Warehouse.objects.filter(pk=to_wh.pk).update(
toys_count=F("toys_count") + quantity
)
movement = form.save(commit=False)
movement.created_by = user
movement.save()
return redirect("dashboard")
else:
form = form_class(user=user)
return render(
request,
"common/create/toy_movement_create.html",
{"form": form}
)
@login_required
@role_required(["manager", "businessman"])
def create_toy_movement_auto(request):
user = request.user
if request.method == "POST":
form = ToyMovementForm(request.POST, user=user)
if form.is_valid():
with transaction.atomic():
# Get cleaned data
from_wh = form.cleaned_data.get("from_warehouse")
to_wh = form.cleaned_data.get("to_warehouse")
movement_type = form.cleaned_data.get("movement_type")
quantity = form.cleaned_data.get("quantity")
# Validate warehouse exists
if not from_wh:
form.add_error("from_warehouse", "Source warehouse is required.")
return render(request, "common/create/toy_movement_create.html", {"form": form})
# Lock and get fresh warehouse data
from_wh = Warehouse.objects.select_for_update().get(pk=from_wh.pk)
# Check stock
if from_wh.toys_count < quantity:
form.add_error("quantity", "Not enough toys in warehouse.")
return render(request, "common/create/toy_movement_create.html", {"form": form})
# Deduct from source warehouse
Warehouse.objects.filter(pk=from_wh.pk).update(
toys_count=F("toys_count") - quantity
)
# Add to destination warehouse if between_warehouses
if movement_type == "between_warehouses" and to_wh:
to_wh = Warehouse.objects.select_for_update().get(pk=to_wh.pk)
Warehouse.objects.filter(pk=to_wh.pk).update(
toys_count=F("toys_count") + quantity
)
# Save movement
movement = form.save(commit=False)
movement.created_by = user
movement.save()
return redirect("toy_movement_list")
else:
# Form has errors, display them
return render(request, "common/create/toy_movement_create.html", {"form": form})
else:
# GET request → render the create form
form = ToyMovementForm(user=user)
return render(
request,
"common/create/toy_movement_create.html",
{"form": form}
)
@login_required
@role_required(["manager", "businessman"])
def create_rent(request):
if request.method == "POST":
form = RentForm(request.POST)
if form.is_valid():
rent = form.save(commit=False)
rent.created_by = request.user
rent.save()
return redirect("dashboard")
else:
form = RentForm()
return render(request, "common/create/rent_create.html", {"form":form, "title":"Create Rent"})
@login_required
@role_required(["employee"])
def create_report(request):
if request.method == "POST":
form = ReportForm(request.POST, user=request.user)
if form.is_valid():
# 🔥 Employee MUST have warehouse
if not request.user.warehouse:
form.add_error(None, "Sizga ombor biriktirilmagan.")
return render(
request,
"common/create/report_create.html",
{"form": form, "title": "Yakuniy Hisobot"}
)
device = form.cleaned_data["device"]
entered_quantity = form.cleaned_data["quantity"]
with transaction.atomic():
# ✅ 1. Save last entered quantity as ToyMovement
ToyMovement.objects.create(
movement_type="from_warehouse",
from_warehouse=request.user.warehouse,
device=device,
quantity=entered_quantity,
created_by=request.user,
)
# ✅ 2. Find last report for this device
last_report = Report.objects.filter(
device=device
).order_by("-created_at").first()
if last_report:
last_time = last_report.created_at
total_since_last = ToyMovement.objects.filter(
device=device,
created_at__gt=last_time
).aggregate(
total=Sum("quantity")
)["total"] or 0
else:
total_since_last = ToyMovement.objects.filter(
device=device
).aggregate(
total=Sum("quantity")
)["total"] or 0
# ✅ 3. Create Report
Report.objects.create(
device=device,
quantity=total_since_last,
created_by=request.user
)
return redirect("employee_dashboard")
else:
form = ReportForm(user=request.user)
return render(
request,
"common/create/report_create.html",
{
"form": form,
"title": "Yakuniy Hisobot"
}
)