479 lines
17 KiB
Python
479 lines
17 KiB
Python
# Generated by Django 5.2.4 on 2026-09-07 09:28
|
||
|
||
import django.db.models.deletion
|
||
from django.conf import settings
|
||
from django.db import migrations, models
|
||
|
||
|
||
class Migration(migrations.Migration):
|
||
initial = True
|
||
|
||
dependencies = [
|
||
("attendance", "0006_attendanceautosyncsettings"),
|
||
("commerce", "0014_externalproject_projectpayment_and_more"),
|
||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||
]
|
||
|
||
operations = [
|
||
migrations.CreateModel(
|
||
name="AllocationReminder",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("last_claim_date", models.DateField(null=True)),
|
||
("snoozed_until", models.DateTimeField(null=True)),
|
||
("enabled", models.BooleanField(default=True)),
|
||
(
|
||
"employee",
|
||
models.OneToOneField(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
to=settings.AUTH_USER_MODEL,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
migrations.CreateModel(
|
||
name="DailyAllocation",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("date", models.DateField()),
|
||
(
|
||
"status",
|
||
models.CharField(
|
||
choices=[("draft", "Черновик"), ("confirmed", "Подтверждено")],
|
||
default="draft",
|
||
max_length=12,
|
||
),
|
||
),
|
||
(
|
||
"hours",
|
||
models.DecimalField(
|
||
blank=True, decimal_places=3, max_digits=6, null=True
|
||
),
|
||
),
|
||
("hours_source", models.CharField(default="unknown", max_length=30)),
|
||
("note", models.TextField(blank=True)),
|
||
("version", models.PositiveIntegerField(default=0)),
|
||
("updated_at", models.DateTimeField(auto_now=True)),
|
||
(
|
||
"attendance_record",
|
||
models.ForeignKey(
|
||
null=True,
|
||
on_delete=django.db.models.deletion.SET_NULL,
|
||
to="attendance.attendancerecord",
|
||
),
|
||
),
|
||
(
|
||
"employee",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
related_name="project_days",
|
||
to=settings.AUTH_USER_MODEL,
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"ordering": ["-date"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="AllocationRevision",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("snapshot", models.JSONField()),
|
||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||
(
|
||
"actor",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
to=settings.AUTH_USER_MODEL,
|
||
),
|
||
),
|
||
(
|
||
"day",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
related_name="revisions",
|
||
to="projects.dailyallocation",
|
||
),
|
||
),
|
||
],
|
||
),
|
||
migrations.CreateModel(
|
||
name="Project",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("name", models.CharField(max_length=255, verbose_name="Название")),
|
||
(
|
||
"description",
|
||
models.TextField(blank=True, verbose_name="Цель и описание"),
|
||
),
|
||
(
|
||
"customer",
|
||
models.CharField(
|
||
blank=True, max_length=255, verbose_name="Заказчик"
|
||
),
|
||
),
|
||
(
|
||
"status",
|
||
models.CharField(
|
||
choices=[
|
||
("planned", "Планируется"),
|
||
("active", "В работе"),
|
||
("paused", "Приостановлен"),
|
||
("completed", "Завершён"),
|
||
("archived", "Архив"),
|
||
],
|
||
default="planned",
|
||
max_length=16,
|
||
),
|
||
),
|
||
("starts_on", models.DateField(blank=True, null=True)),
|
||
("ends_on", models.DateField(blank=True, null=True)),
|
||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||
("updated_at", models.DateTimeField(auto_now=True)),
|
||
(
|
||
"created_by",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
related_name="created_projects",
|
||
to=settings.AUTH_USER_MODEL,
|
||
),
|
||
),
|
||
(
|
||
"manager",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
related_name="managed_projects",
|
||
to=settings.AUTH_USER_MODEL,
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"verbose_name": "Локальный проект",
|
||
"verbose_name_plural": "Локальные проекты",
|
||
"ordering": ["name", "pk"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="ProjectEvent",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("action", models.CharField(max_length=100)),
|
||
("details", models.JSONField(default=dict)),
|
||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||
(
|
||
"actor",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
to=settings.AUTH_USER_MODEL,
|
||
),
|
||
),
|
||
(
|
||
"project",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
related_name="events",
|
||
to="projects.project",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"ordering": ["-created_at", "-id"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="ProjectExternalBinding",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("external_id", models.CharField(max_length=255)),
|
||
("object_type", models.CharField(default="project", max_length=50)),
|
||
("external_name", models.CharField(blank=True, max_length=255)),
|
||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||
(
|
||
"project",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
related_name="bindings",
|
||
to="projects.project",
|
||
),
|
||
),
|
||
(
|
||
"source",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
to="commerce.sourcesystem",
|
||
),
|
||
),
|
||
],
|
||
),
|
||
migrations.CreateModel(
|
||
name="ProjectMembership",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("role", models.CharField(default="Участник", max_length=100)),
|
||
(
|
||
"planned_percent",
|
||
models.DecimalField(decimal_places=2, default=0, max_digits=5),
|
||
),
|
||
("starts_on", models.DateField(blank=True, null=True)),
|
||
("ends_on", models.DateField(blank=True, null=True)),
|
||
(
|
||
"employee",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
related_name="project_memberships",
|
||
to=settings.AUTH_USER_MODEL,
|
||
),
|
||
),
|
||
(
|
||
"project",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="memberships",
|
||
to="projects.project",
|
||
),
|
||
),
|
||
],
|
||
),
|
||
migrations.CreateModel(
|
||
name="ProjectResource",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("title", models.CharField(max_length=255)),
|
||
(
|
||
"kind",
|
||
models.CharField(
|
||
choices=[
|
||
("task", "Задача"),
|
||
("procurement", "Закупка"),
|
||
("document", "Документ"),
|
||
],
|
||
max_length=16,
|
||
),
|
||
),
|
||
("url", models.CharField(max_length=1000)),
|
||
("created_at", models.DateTimeField(auto_now_add=True)),
|
||
(
|
||
"project",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="resources",
|
||
to="projects.project",
|
||
),
|
||
),
|
||
],
|
||
),
|
||
migrations.CreateModel(
|
||
name="ProjectStage",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
("name", models.CharField(max_length=255)),
|
||
("due_on", models.DateField(blank=True, null=True)),
|
||
("done", models.BooleanField(default=False)),
|
||
("position", models.PositiveIntegerField(default=0)),
|
||
(
|
||
"project",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="stages",
|
||
to="projects.project",
|
||
),
|
||
),
|
||
],
|
||
options={
|
||
"ordering": ["position", "id"],
|
||
},
|
||
),
|
||
migrations.CreateModel(
|
||
name="TimeAllocation",
|
||
fields=[
|
||
(
|
||
"id",
|
||
models.BigAutoField(
|
||
auto_created=True,
|
||
primary_key=True,
|
||
serialize=False,
|
||
verbose_name="ID",
|
||
),
|
||
),
|
||
(
|
||
"activity",
|
||
models.CharField(
|
||
blank=True,
|
||
choices=[
|
||
("", "Проект"),
|
||
("department", "Работа отдела"),
|
||
("training", "Обучение"),
|
||
("support", "Поддержка"),
|
||
],
|
||
max_length=20,
|
||
),
|
||
),
|
||
("percent", models.DecimalField(decimal_places=2, max_digits=5)),
|
||
(
|
||
"day",
|
||
models.ForeignKey(
|
||
on_delete=django.db.models.deletion.CASCADE,
|
||
related_name="allocations",
|
||
to="projects.dailyallocation",
|
||
),
|
||
),
|
||
(
|
||
"project",
|
||
models.ForeignKey(
|
||
blank=True,
|
||
null=True,
|
||
on_delete=django.db.models.deletion.PROTECT,
|
||
related_name="time_allocations",
|
||
to="projects.project",
|
||
),
|
||
),
|
||
],
|
||
),
|
||
migrations.AddConstraint(
|
||
model_name="dailyallocation",
|
||
constraint=models.UniqueConstraint(
|
||
fields=("employee", "date"), name="project_day_unique"
|
||
),
|
||
),
|
||
migrations.AddConstraint(
|
||
model_name="project",
|
||
constraint=models.CheckConstraint(
|
||
condition=models.Q(
|
||
("ends_on__isnull", True),
|
||
("starts_on__isnull", True),
|
||
("ends_on__gte", models.F("starts_on")),
|
||
_connector="OR",
|
||
),
|
||
name="project_dates_order",
|
||
),
|
||
),
|
||
migrations.AddConstraint(
|
||
model_name="projectexternalbinding",
|
||
constraint=models.UniqueConstraint(
|
||
fields=("source", "object_type", "external_id"),
|
||
name="project_external_identity",
|
||
),
|
||
),
|
||
migrations.AddConstraint(
|
||
model_name="projectmembership",
|
||
constraint=models.UniqueConstraint(
|
||
fields=("project", "employee"), name="project_member_unique"
|
||
),
|
||
),
|
||
migrations.AddConstraint(
|
||
model_name="projectmembership",
|
||
constraint=models.CheckConstraint(
|
||
condition=models.Q(
|
||
("planned_percent__gte", 0), ("planned_percent__lte", 100)
|
||
),
|
||
name="project_member_percent",
|
||
),
|
||
),
|
||
migrations.AddConstraint(
|
||
model_name="projectmembership",
|
||
constraint=models.CheckConstraint(
|
||
condition=models.Q(
|
||
("ends_on__isnull", True),
|
||
("starts_on__isnull", True),
|
||
("ends_on__gte", models.F("starts_on")),
|
||
_connector="OR",
|
||
),
|
||
name="project_member_dates",
|
||
),
|
||
),
|
||
migrations.AddConstraint(
|
||
model_name="timeallocation",
|
||
constraint=models.CheckConstraint(
|
||
condition=models.Q(("percent__gt", 0), ("percent__lte", 100)),
|
||
name="project_allocation_percent",
|
||
),
|
||
),
|
||
migrations.AddConstraint(
|
||
model_name="timeallocation",
|
||
constraint=models.CheckConstraint(
|
||
condition=models.Q(
|
||
models.Q(("activity", ""), ("project__isnull", False)),
|
||
models.Q(
|
||
("activity__in", ["department", "training", "support"]),
|
||
("project__isnull", True),
|
||
),
|
||
_connector="OR",
|
||
),
|
||
name="project_allocation_target",
|
||
),
|
||
),
|
||
]
|