""" Views для управления единицами измерения (Unit of Measure) """ from django.contrib.auth.decorators import login_required from django.contrib import messages from django.shortcuts import render, redirect, get_object_or_404 from django.db.models import Q, Count from django.core.paginator import Paginator from django.urls import reverse from products.models import UnitOfMeasure, ProductSalesUnit from products.forms import ProductSalesUnitForm, UnitOfMeasureForm @login_required def unit_of_measure_list(request): """ Список всех единиц измерения с возможностью фильтрации и поиска """ # Получаем параметры фильтрации search_query = request.GET.get('q', '').strip() is_active_filter = request.GET.get('is_active', '') # Базовый queryset units = UnitOfMeasure.objects.all() # Аннотируем количество использований units = units.annotate( products_count=Count('products') ) # Применяем фильтры if search_query: units = units.filter( Q(code__icontains=search_query) | Q(name__icontains=search_query) | Q(short_name__icontains=search_query) ) if is_active_filter: units = units.filter(is_active=(is_active_filter == 'true')) # Сортировка units = units.order_by('position', 'code') # Пагинация paginator = Paginator(units, 50) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) context = { 'page_obj': page_obj, 'search_query': search_query, 'is_active_filter': is_active_filter, 'total_units': units.count(), } return render(request, 'products/uom/unit_list.html', context) @login_required def unit_of_measure_create(request): """ Создание новой единицы измерения """ # Проверка: PlatformAdmin не имеет доступа к бизнес-данным тенантов if request.user.__class__.__name__ == 'PlatformAdmin': messages.error(request, 'У вас недостаточно прав для выполнения этого действия') return redirect('products:unit-list') if request.method == 'POST': form = UnitOfMeasureForm(request.POST) if form.is_valid(): unit = form.save() messages.success(request, f'Единица измерения "{unit.name}" успешно создана!') return redirect('products:unit-list') else: form = UnitOfMeasureForm() context = { 'form': form, 'title': 'Создание единицы измерения', 'submit_text': 'Создать' } return render(request, 'products/uom/unit_form.html', context) @login_required def unit_of_measure_update(request, pk): """ Редактирование единицы измерения """ # Проверка: PlatformAdmin не имеет доступа к бизнес-данным тенантов if request.user.__class__.__name__ == 'PlatformAdmin': messages.error(request, 'У вас недостаточно прав для выполнения этого действия') return redirect('products:unit-list') unit = get_object_or_404(UnitOfMeasure, pk=pk) if request.method == 'POST': form = UnitOfMeasureForm(request.POST, instance=unit) if form.is_valid(): unit = form.save() messages.success(request, f'Единица измерения "{unit.name}" успешно обновлена!') return redirect('products:unit-list') else: form = UnitOfMeasureForm(instance=unit) context = { 'form': form, 'unit': unit, 'title': f'Редактирование: {unit.name}', 'submit_text': 'Сохранить' } return render(request, 'products/uom/unit_form.html', context) @login_required def unit_of_measure_delete(request, pk): """ Удаление единицы измерения """ # Проверка: PlatformAdmin не имеет доступа к бизнес-данным тенантов if request.user.__class__.__name__ == 'PlatformAdmin': messages.error(request, 'У вас недостаточно прав для выполнения этого действия') return redirect('products:unit-list') unit = get_object_or_404(UnitOfMeasure, pk=pk) # Проверяем использование products_using = unit.products.count() sales_units_using = ProductSalesUnit.objects.filter(product__base_unit=unit).count() can_delete = products_using == 0 and sales_units_using == 0 if request.method == 'POST': if can_delete: name = unit.name unit.delete() messages.success(request, f'Единица измерения "{name}" успешно удалена!') return redirect('products:unit-list') else: messages.error( request, f'Невозможно удалить единицу измерения "{unit.name}". ' f'Она используется в {products_using} товарах и {sales_units_using} единицах продажи.' ) return redirect('products:unit-list') context = { 'unit': unit, 'can_delete': can_delete, 'products_using': products_using, 'sales_units_using': sales_units_using, } return render(request, 'products/uom/unit_delete.html', context) @login_required def product_sales_unit_list(request): """ Список всех единиц продажи товаров с возможностью фильтрации """ # Получаем параметры фильтрации search_query = request.GET.get('q', '').strip() is_active_filter = request.GET.get('is_active', '') is_default_filter = request.GET.get('is_default', '') # Базовый queryset sales_units = ProductSalesUnit.objects.select_related('product').all() # Применяем фильтры if search_query: sales_units = sales_units.filter( Q(product__name__icontains=search_query) | Q(product__sku__icontains=search_query) | Q(name__icontains=search_query) ) if is_active_filter: sales_units = sales_units.filter(is_active=(is_active_filter == 'true')) if is_default_filter: sales_units = sales_units.filter(is_default=(is_default_filter == 'true')) # Сортировка sales_units = sales_units.order_by('product__name', 'position') # Пагинация paginator = Paginator(sales_units, 50) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) context = { 'page_obj': page_obj, 'search_query': search_query, 'is_active_filter': is_active_filter, 'is_default_filter': is_default_filter, 'total_sales_units': sales_units.count(), } return render(request, 'products/uom/sales_unit_list.html', context) @login_required def product_sales_unit_create(request): """ Создание новой единицы продажи """ if request.method == 'POST': form = ProductSalesUnitForm(request.POST) if form.is_valid(): sales_unit = form.save() messages.success( request, f'Единица продажи "{sales_unit.name}" для товара "{sales_unit.product.name}" успешно создана!' ) return redirect('products:sales-unit-list') else: # Предзаполнение товара если передан в параметрах initial = {} product_id = request.GET.get('product') if product_id: initial['product'] = product_id form = ProductSalesUnitForm(initial=initial) context = { 'form': form, 'title': 'Создание единицы продажи', 'submit_text': 'Создать' } return render(request, 'products/uom/sales_unit_form.html', context) @login_required def product_sales_unit_update(request, pk): """ Редактирование единицы продажи """ sales_unit = get_object_or_404(ProductSalesUnit, pk=pk) if request.method == 'POST': form = ProductSalesUnitForm(request.POST, instance=sales_unit) if form.is_valid(): sales_unit = form.save() messages.success( request, f'Единица продажи "{sales_unit.name}" успешно обновлена!' ) return redirect('products:sales-unit-list') else: form = ProductSalesUnitForm(instance=sales_unit) context = { 'form': form, 'sales_unit': sales_unit, 'title': f'Редактирование: {sales_unit.name}', 'submit_text': 'Сохранить' } return render(request, 'products/uom/sales_unit_form.html', context) @login_required def product_sales_unit_delete(request, pk): """ Удаление единицы продажи """ sales_unit = get_object_or_404(ProductSalesUnit, pk=pk) if request.method == 'POST': product_name = sales_unit.product.name unit_name = sales_unit.name sales_unit.delete() messages.success( request, f'Единица продажи "{unit_name}" для товара "{product_name}" успешно удалена!' ) return redirect('products:sales-unit-list') context = { 'sales_unit': sales_unit, } return render(request, 'products/uom/sales_unit_delete.html', context)