# Generated by Django 5.2.4 on 2026-07-17 10:53 import django.db.models.deletion from django.conf import settings from django.db import migrations, models def backfill_procurement_activity(apps, schema_editor): ProcurementRequest = apps.get_model("procurement", "ProcurementRequest") Activity = apps.get_model("procurement", "ProcurementRequestActivity") activities = [] activity_times = [] for procurement_request in ProcurementRequest.objects.iterator(chunk_size=500): entries = [ ( "created", procurement_request.created_at, procurement_request.requestor_id, ), ( "submitted", procurement_request.submitted_at, procurement_request.requestor_id, ), ( "started", procurement_request.started_at, procurement_request.executor_id, ), ( "completed", procurement_request.completed_at, procurement_request.executor_id, ), ] for action, created_at, actor_id in entries: if created_at is None: continue activities.append( Activity( request_id=procurement_request.pk, actor_id=actor_id, action=action, object_kind="request", object_id=procurement_request.pk, metadata={"backfilled": True}, ) ) activity_times.append(created_at) if not activities: return Activity.objects.bulk_create(activities, batch_size=500) for activity, created_at in zip(activities, activity_times): activity.created_at = created_at Activity.objects.bulk_update(activities, ["created_at"], batch_size=500) class Migration(migrations.Migration): dependencies = [ ('procurement', '0015_procurementitemattachment'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='ProcurementRequestActivity', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('action', models.CharField(choices=[('created', 'Создал заявку'), ('updated', 'Изменил заявку'), ('submitted', 'Отправил на согласование'), ('stage_approved', 'Согласовал этап'), ('stage_rejected', 'Отклонил этап согласования'), ('approved', 'Заявка согласована'), ('started', 'Взял заявку в работу'), ('executor_reassigned', 'Сменил исполнителя'), ('completed', 'Завершил заявку'), ('rejected', 'Отклонил заявку'), ('cancelled', 'Отменил заявку'), ('item_updated', 'Изменил исполнение позиции'), ('all_items_received', 'Отметил все позиции полученными'), ('attachment_added', 'Добавил файл'), ('attachment_removed', 'Удалил файл'), ('comment_added', 'Добавил комментарий'), ('comment_removed', 'Удалил комментарий'), ('arrival_notified', 'Уведомил о поступлении')], max_length=32, verbose_name='Действие')), ('object_kind', models.CharField(blank=True, choices=[('request', 'Заявка'), ('approval', 'Согласование'), ('item', 'Позиция'), ('attachment', 'Файл'), ('comment', 'Комментарий')], max_length=32, verbose_name='Тип объекта')), ('object_id', models.PositiveBigIntegerField(blank=True, null=True, verbose_name='ID объекта')), ('metadata', models.JSONField(blank=True, default=dict, verbose_name='Метаданные')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Создано')), ('actor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='procurement_activities', to=settings.AUTH_USER_MODEL, verbose_name='Инициатор')), ('request', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='activities', to='procurement.procurementrequest', verbose_name='Заявка')), ], options={ 'verbose_name': 'История заявки на закупку', 'verbose_name_plural': 'История заявок на закупку', 'ordering': ['-created_at', '-id'], 'indexes': [models.Index(fields=['request', '-created_at'], name='procurement_request_4b22f4_idx')], }, ), migrations.RunPython( backfill_procurement_activity, reverse_code=migrations.RunPython.noop, ), ]