diff --git a/myproject/inventory/forms.py b/myproject/inventory/forms.py index 0e8fc39..d5a14c3 100644 --- a/myproject/inventory/forms.py +++ b/myproject/inventory/forms.py @@ -108,17 +108,18 @@ class WriteOffForm(forms.ModelForm): class InventoryForm(forms.ModelForm): class Meta: model = Inventory - fields = ['warehouse', 'conducted_by', 'notes'] + fields = ['warehouse', 'notes'] widgets = { 'warehouse': forms.Select(attrs={'class': 'form-control'}), - 'conducted_by': forms.TextInput(attrs={'class': 'form-control'}), 'notes': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}), } def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) + # Фильтруем только активные склады (исключаем скрытые) self.fields['warehouse'].queryset = Warehouse.objects.filter(is_active=True) + # Если есть склад по умолчанию и значение не установлено явно - предвыбираем его if not self.initial.get('warehouse'): default_warehouse = Warehouse.objects.filter( diff --git a/myproject/inventory/migrations/0017_change_conducted_by_to_fk.py b/myproject/inventory/migrations/0017_change_conducted_by_to_fk.py new file mode 100644 index 0000000..0055fe5 --- /dev/null +++ b/myproject/inventory/migrations/0017_change_conducted_by_to_fk.py @@ -0,0 +1,101 @@ +# Generated manually - Change conducted_by from CharField to ForeignKey + +from django.db import migrations, models +import django.db.models.deletion + + +def migrate_conducted_by_data(apps, schema_editor): + """ + Миграция данных: для существующих записей инвентаризации + найти первого пользователя с ролью "owner" (владелец) в текущем тенанте + и проставить его UserRole. Если владельца нет - оставить NULL. + """ + Inventory = apps.get_model('inventory', 'Inventory') + UserRole = apps.get_model('user_roles', 'UserRole') + Role = apps.get_model('user_roles', 'Role') + + # Находим первого владельца в текущем тенанте + try: + owner_role = Role.objects.get(code='owner', is_system=True) + owner_user_role = UserRole.objects.filter( + role=owner_role, + is_active=True + ).first() + + if owner_user_role: + # Обновляем все существующие инвентаризации, у которых есть старое текстовое значение + # Используем conducted_by_old (переименованное поле) для проверки + Inventory.objects.exclude(conducted_by_old__isnull=True).exclude(conducted_by_old='').update( + conducted_by_new=owner_user_role + ) + except Role.DoesNotExist: + # Если нет роли - оставляем NULL + pass + + +def reverse_migration(apps, schema_editor): + """ + Откат: очищаем новое поле + """ + Inventory = apps.get_model('inventory', 'Inventory') + Inventory.objects.filter(conducted_by_new__isnull=False).update(conducted_by_new=None) + + +class Migration(migrations.Migration): + + dependencies = [ + ('inventory', '0016_add_document_number_to_inventory'), + ('user_roles', '0001_initial'), + ] + + operations = [ + # Шаг 1: Переименовываем старое поле в conducted_by_old + migrations.RenameField( + model_name='inventory', + old_name='conducted_by', + new_name='conducted_by_old', + ), + # Шаг 2: Добавляем новое поле как ForeignKey + migrations.AddField( + model_name='inventory', + name='conducted_by_new', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='inventories_new', + to='user_roles.userrole', + verbose_name='Провел инвентаризацию' + ), + ), + # Шаг 3: Миграция данных + migrations.RunPython( + migrate_conducted_by_data, + reverse_code=reverse_migration + ), + # Шаг 4: Удаляем старое поле + migrations.RemoveField( + model_name='inventory', + name='conducted_by_old', + ), + # Шаг 5: Переименовываем новое поле в conducted_by + migrations.RenameField( + model_name='inventory', + old_name='conducted_by_new', + new_name='conducted_by', + ), + # Шаг 6: Исправляем related_name + migrations.AlterField( + model_name='inventory', + name='conducted_by', + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name='inventories', + to='user_roles.userrole', + verbose_name='Провел инвентаризацию' + ), + ), + ] + diff --git a/myproject/inventory/templates/inventory/base_inventory_minimal.html b/myproject/inventory/templates/inventory/base_inventory_minimal.html index 9b79564..5db0ec8 100644 --- a/myproject/inventory/templates/inventory/base_inventory_minimal.html +++ b/myproject/inventory/templates/inventory/base_inventory_minimal.html @@ -11,7 +11,7 @@ diff --git a/myproject/inventory/templates/inventory/inventory/inventory_detail.html b/myproject/inventory/templates/inventory/inventory/inventory_detail.html index fcfc54e..771c3a2 100644 --- a/myproject/inventory/templates/inventory/inventory/inventory_detail.html +++ b/myproject/inventory/templates/inventory/inventory/inventory_detail.html @@ -3,7 +3,9 @@ {% load static %} {% block inventory_title %}Детали инвентаризации{% endblock %} -{% block breadcrumb_current %}Инвентаризация{% endblock %} +{% block breadcrumb_current %} + Инвентаризация +{% endblock %} {% block inventory_content %} @@ -198,6 +200,9 @@ + {% endif %} @@ -241,6 +246,43 @@ + +{% if inventory.status != 'completed' %} +
+{% endif %} + diff --git a/myproject/inventory/templates/inventory/inventory/inventory_form.html b/myproject/inventory/templates/inventory/inventory/inventory_form.html index 229ea60..12d27c0 100644 --- a/myproject/inventory/templates/inventory/inventory/inventory_form.html +++ b/myproject/inventory/templates/inventory/inventory/inventory_form.html @@ -1,7 +1,9 @@ {% extends 'inventory/base_inventory_minimal.html' %} {% block inventory_title %}Новая инвентаризация{% endblock %} -{% block breadcrumb_current %}Инвентаризация{% endblock %} +{% block breadcrumb_current %} + Инвентаризация +{% endblock %} {% block inventory_content %}