# 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, ), ]