383 lines
14 KiB
Python
383 lines
14 KiB
Python
"""Представления документов: списки и формы создания/редактирования."""
|
|
import logging
|
|
from django.views.generic import ListView, CreateView, UpdateView, DeleteView, DetailView
|
|
from config.mixins import LoginRequiredMixin
|
|
from django.urls import reverse_lazy
|
|
from django.shortcuts import redirect, get_object_or_404
|
|
from django.contrib import messages
|
|
from django.http import HttpResponseRedirect
|
|
|
|
from users.utils import get_author_employee
|
|
from references.models import Employee
|
|
from .models import (
|
|
CustomerOrder,
|
|
SupplierOrder,
|
|
CashInflow,
|
|
CashTransfer,
|
|
CashExpense,
|
|
)
|
|
from .forms import (
|
|
CustomerOrderForm,
|
|
CustomerOrderItemFormSet,
|
|
CustomerOrderItemFormSetUpdate,
|
|
SupplierOrderForm,
|
|
SupplierOrderItemFormSet,
|
|
SupplierOrderItemFormSetUpdate,
|
|
CashInflowForm,
|
|
CashTransferForm,
|
|
CashExpenseForm,
|
|
)
|
|
from .services import next_number
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def set_author(form, request):
|
|
"""Подставить автора при создании документа: из профиля пользователя (UserProfile.employee) или сотрудник по имени пользователя."""
|
|
if form.instance.pk:
|
|
return # при редактировании автора не меняем
|
|
author = _get_author_for_request(request)
|
|
if author:
|
|
form.instance.author = author
|
|
|
|
|
|
def _get_author_for_request(request):
|
|
"""Сотрудник-автор: из профиля пользователя или по ФИО/логину."""
|
|
if not request.user.is_authenticated:
|
|
return None
|
|
author = get_author_employee(request.user)
|
|
if author:
|
|
return author
|
|
name = (request.user.get_full_name() or "").strip() or request.user.username
|
|
author = Employee.objects.filter(name=name).first()
|
|
if not author:
|
|
author = Employee.objects.create(name=name)
|
|
return author
|
|
|
|
|
|
# --- Заказы клиентов ---
|
|
class CustomerOrderList(LoginRequiredMixin, ListView):
|
|
model = CustomerOrder
|
|
template_name = "documents/customer_order_list.html"
|
|
context_object_name = "object_list"
|
|
|
|
class CustomerOrderCreate(LoginRequiredMixin, CreateView):
|
|
model = CustomerOrder
|
|
form_class = CustomerOrderForm
|
|
template_name = "documents/order_form.html"
|
|
success_url = reverse_lazy("documents:customer_order_list")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["formset"] = CustomerOrderItemFormSet(instance=self.object) if self.object and self.object.pk else CustomerOrderItemFormSet()
|
|
ctx["title"] = "Заказ клиента"
|
|
ctx["author_display"] = _get_author_for_request(self.request) if not self.object or not self.object.pk else self.object.author
|
|
return ctx
|
|
|
|
def form_valid(self, form):
|
|
set_author(form, self.request)
|
|
self.object = form.save()
|
|
formset = CustomerOrderItemFormSet(self.request.POST, instance=self.object)
|
|
if formset.is_valid():
|
|
formset.save()
|
|
self.object.recalc_total()
|
|
self.object.save()
|
|
logger.info("Создан заказ клиента %s", self.object)
|
|
messages.success(self.request, "Заказ создан.")
|
|
return redirect(self.success_url)
|
|
return self.render_to_response(self.get_context_data(form=form, formset=formset))
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
self.object = None
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
|
|
class CustomerOrderUpdate(LoginRequiredMixin, UpdateView):
|
|
model = CustomerOrder
|
|
form_class = CustomerOrderForm
|
|
template_name = "documents/order_form.html"
|
|
context_object_name = "object"
|
|
success_url = reverse_lazy("documents:customer_order_list")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["formset"] = CustomerOrderItemFormSetUpdate(instance=self.object)
|
|
ctx["title"] = "Заказ клиента"
|
|
ctx["author_display"] = self.object.author
|
|
return ctx
|
|
|
|
def form_valid(self, form):
|
|
formset = CustomerOrderItemFormSetUpdate(self.request.POST, instance=self.object)
|
|
if formset.is_valid():
|
|
form.save()
|
|
formset.save()
|
|
self.object.recalc_total()
|
|
self.object.save()
|
|
logger.info("Обновлён заказ клиента %s", self.object)
|
|
messages.success(self.request, "Заказ сохранён.")
|
|
return redirect(self.success_url)
|
|
return self.render_to_response(self.get_context_data(form=form, formset=formset))
|
|
|
|
|
|
class CustomerOrderDelete(LoginRequiredMixin, DeleteView):
|
|
model = CustomerOrder
|
|
template_name = "documents/confirm_delete.html"
|
|
success_url = reverse_lazy("documents:customer_order_list")
|
|
context_object_name = "object"
|
|
|
|
|
|
class CustomerOrderDetail(LoginRequiredMixin, DetailView):
|
|
model = CustomerOrder
|
|
template_name = "documents/customer_order_detail.html"
|
|
context_object_name = "object"
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["economics"] = self.object.get_economics()
|
|
return ctx
|
|
|
|
|
|
# --- Заказы поставщику ---
|
|
class SupplierOrderList(LoginRequiredMixin, ListView):
|
|
model = SupplierOrder
|
|
template_name = "documents/supplier_order_list.html"
|
|
context_object_name = "object_list"
|
|
|
|
class SupplierOrderCreate(LoginRequiredMixin, CreateView):
|
|
model = SupplierOrder
|
|
form_class = SupplierOrderForm
|
|
template_name = "documents/supplier_order_form.html"
|
|
success_url = reverse_lazy("documents:supplier_order_list")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["formset"] = SupplierOrderItemFormSet(instance=self.object) if self.object and self.object.pk else SupplierOrderItemFormSet()
|
|
ctx["title"] = "Заказ поставщику"
|
|
ctx["author_display"] = _get_author_for_request(self.request) if not self.object or not self.object.pk else self.object.author
|
|
return ctx
|
|
|
|
def form_valid(self, form):
|
|
set_author(form, self.request)
|
|
self.object = form.save()
|
|
formset = SupplierOrderItemFormSet(self.request.POST, instance=self.object)
|
|
if formset.is_valid():
|
|
formset.save()
|
|
self.object.recalc_totals()
|
|
self.object.save()
|
|
logger.info("Создан заказ поставщику %s", self.object)
|
|
messages.success(self.request, "Заказ создан.")
|
|
return redirect(self.success_url)
|
|
return self.render_to_response(self.get_context_data(form=form, formset=formset))
|
|
|
|
def get(self, request, *args, **kwargs):
|
|
self.object = None
|
|
return super().get(request, *args, **kwargs)
|
|
|
|
|
|
class SupplierOrderUpdate(LoginRequiredMixin, UpdateView):
|
|
model = SupplierOrder
|
|
form_class = SupplierOrderForm
|
|
template_name = "documents/supplier_order_form.html"
|
|
context_object_name = "object"
|
|
success_url = reverse_lazy("documents:supplier_order_list")
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["formset"] = SupplierOrderItemFormSetUpdate(instance=self.object)
|
|
ctx["title"] = "Заказ поставщику"
|
|
ctx["author_display"] = self.object.author
|
|
return ctx
|
|
|
|
def form_valid(self, form):
|
|
formset = SupplierOrderItemFormSetUpdate(self.request.POST, instance=self.object)
|
|
if formset.is_valid():
|
|
form.save()
|
|
formset.save()
|
|
self.object.recalc_totals()
|
|
self.object.save()
|
|
logger.info("Обновлён заказ поставщику %s", self.object)
|
|
messages.success(self.request, "Заказ сохранён.")
|
|
return redirect(self.success_url)
|
|
return self.render_to_response(self.get_context_data(form=form, formset=formset))
|
|
|
|
|
|
class SupplierOrderDelete(LoginRequiredMixin, DeleteView):
|
|
model = SupplierOrder
|
|
template_name = "documents/confirm_delete.html"
|
|
success_url = reverse_lazy("documents:supplier_order_list")
|
|
context_object_name = "object"
|
|
|
|
|
|
# --- Поступление денежных средств ---
|
|
class CashInflowList(LoginRequiredMixin, ListView):
|
|
model = CashInflow
|
|
template_name = "documents/cash_inflow_list.html"
|
|
context_object_name = "object_list"
|
|
|
|
class CashInflowCreate(LoginRequiredMixin, CreateView):
|
|
model = CashInflow
|
|
form_class = CashInflowForm
|
|
template_name = "documents/cash_doc_form.html"
|
|
success_url = reverse_lazy("documents:cash_inflow_list")
|
|
|
|
def get_initial(self):
|
|
initial = super().get_initial()
|
|
initial["number"] = next_number(CashInflow)
|
|
return initial
|
|
|
|
def form_valid(self, form):
|
|
set_author(form, self.request)
|
|
form.save()
|
|
logger.info("Создано поступление %s", form.instance)
|
|
messages.success(self.request, "Поступление создано.")
|
|
return redirect(self.success_url)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["title"] = "Поступление денежных средств"
|
|
ctx["cancel_url"] = reverse_lazy("documents:cash_inflow_list")
|
|
return ctx
|
|
|
|
|
|
class CashInflowUpdate(LoginRequiredMixin, UpdateView):
|
|
model = CashInflow
|
|
form_class = CashInflowForm
|
|
template_name = "documents/cash_doc_form.html"
|
|
context_object_name = "object"
|
|
success_url = reverse_lazy("documents:cash_inflow_list")
|
|
|
|
def form_valid(self, form):
|
|
form.save()
|
|
logger.info("Обновлено поступление %s", self.object)
|
|
messages.success(self.request, "Поступление сохранено.")
|
|
return redirect(self.success_url)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["title"] = "Поступление денежных средств"
|
|
ctx["cancel_url"] = reverse_lazy("documents:cash_inflow_list")
|
|
return ctx
|
|
|
|
|
|
class CashInflowDelete(LoginRequiredMixin, DeleteView):
|
|
model = CashInflow
|
|
template_name = "documents/confirm_delete.html"
|
|
success_url = reverse_lazy("documents:cash_inflow_list")
|
|
context_object_name = "object"
|
|
|
|
|
|
# --- Перемещение денежных средств ---
|
|
class CashTransferList(LoginRequiredMixin, ListView):
|
|
model = CashTransfer
|
|
template_name = "documents/cash_transfer_list.html"
|
|
context_object_name = "object_list"
|
|
|
|
class CashTransferCreate(LoginRequiredMixin, CreateView):
|
|
model = CashTransfer
|
|
form_class = CashTransferForm
|
|
template_name = "documents/cash_doc_form.html"
|
|
success_url = reverse_lazy("documents:cash_transfer_list")
|
|
|
|
def get_initial(self):
|
|
initial = super().get_initial()
|
|
initial["number"] = next_number(CashTransfer)
|
|
return initial
|
|
|
|
def form_valid(self, form):
|
|
set_author(form, self.request)
|
|
form.save()
|
|
logger.info("Создано перемещение %s", form.instance)
|
|
messages.success(self.request, "Перемещение создано.")
|
|
return redirect(self.success_url)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["title"] = "Перемещение денежных средств"
|
|
ctx["cancel_url"] = reverse_lazy("documents:cash_transfer_list")
|
|
return ctx
|
|
|
|
|
|
class CashTransferUpdate(LoginRequiredMixin, UpdateView):
|
|
model = CashTransfer
|
|
form_class = CashTransferForm
|
|
template_name = "documents/cash_doc_form.html"
|
|
context_object_name = "object"
|
|
success_url = reverse_lazy("documents:cash_transfer_list")
|
|
|
|
def form_valid(self, form):
|
|
form.save()
|
|
logger.info("Обновлено перемещение %s", self.object)
|
|
messages.success(self.request, "Перемещение сохранено.")
|
|
return redirect(self.success_url)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["title"] = "Перемещение денежных средств"
|
|
ctx["cancel_url"] = reverse_lazy("documents:cash_transfer_list")
|
|
return ctx
|
|
|
|
|
|
class CashTransferDelete(LoginRequiredMixin, DeleteView):
|
|
model = CashTransfer
|
|
template_name = "documents/confirm_delete.html"
|
|
success_url = reverse_lazy("documents:cash_transfer_list")
|
|
context_object_name = "object"
|
|
|
|
|
|
# --- Расход денежных средств ---
|
|
class CashExpenseList(LoginRequiredMixin, ListView):
|
|
model = CashExpense
|
|
template_name = "documents/cash_expense_list.html"
|
|
context_object_name = "object_list"
|
|
|
|
class CashExpenseCreate(LoginRequiredMixin, CreateView):
|
|
model = CashExpense
|
|
form_class = CashExpenseForm
|
|
template_name = "documents/cash_doc_form.html"
|
|
success_url = reverse_lazy("documents:cash_expense_list")
|
|
|
|
def get_initial(self):
|
|
initial = super().get_initial()
|
|
initial["number"] = next_number(CashExpense)
|
|
return initial
|
|
|
|
def form_valid(self, form):
|
|
set_author(form, self.request)
|
|
form.save()
|
|
logger.info("Создан расход %s", form.instance)
|
|
messages.success(self.request, "Расход создан.")
|
|
return redirect(self.success_url)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["title"] = "Расход денежных средств"
|
|
ctx["cancel_url"] = reverse_lazy("documents:cash_expense_list")
|
|
return ctx
|
|
|
|
|
|
class CashExpenseUpdate(LoginRequiredMixin, UpdateView):
|
|
model = CashExpense
|
|
form_class = CashExpenseForm
|
|
template_name = "documents/cash_doc_form.html"
|
|
context_object_name = "object"
|
|
success_url = reverse_lazy("documents:cash_expense_list")
|
|
|
|
def form_valid(self, form):
|
|
form.save()
|
|
logger.info("Обновлён расход %s", self.object)
|
|
messages.success(self.request, "Расход сохранён.")
|
|
return redirect(self.success_url)
|
|
|
|
def get_context_data(self, **kwargs):
|
|
ctx = super().get_context_data(**kwargs)
|
|
ctx["title"] = "Расход денежных средств"
|
|
ctx["cancel_url"] = reverse_lazy("documents:cash_expense_list")
|
|
return ctx
|
|
|
|
|
|
class CashExpenseDelete(LoginRequiredMixin, DeleteView):
|
|
model = CashExpense
|
|
template_name = "documents/confirm_delete.html"
|
|
success_url = reverse_lazy("documents:cash_expense_list")
|
|
context_object_name = "object"
|