Files
customerTicket/apps/tickets/migrations/0001_initial.py
T
2026-09-23 18:23:18 +03:30

131 lines
8.6 KiB
Python

# Generated by Django 5.1.1 on 2026-09-05 07:03
import django.core.validators
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('messaging', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='SLAConfig',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('priority', models.CharField(max_length=15, unique=True)),
('first_response_minutes', models.PositiveIntegerField()),
('resolution_minutes', models.PositiveIntegerField()),
('is_active', models.BooleanField(default=True)),
],
),
migrations.CreateModel(
name='TicketCategory',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('title', models.CharField(max_length=100)),
('slug', models.SlugField(unique=True)),
('description', models.TextField(blank=True)),
('icon', models.CharField(blank=True, max_length=50)),
('sort_order', models.PositiveIntegerField(default=0)),
('is_active', models.BooleanField(default=True)),
],
options={
'ordering': ['sort_order', 'title'],
},
),
migrations.CreateModel(
name='Ticket',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('public_id', models.UUIDField(default=uuid.uuid4, editable=False, unique=True)),
('ticket_number', models.CharField(editable=False, max_length=30, unique=True)),
('subject', models.CharField(max_length=200, validators=[django.core.validators.MinLengthValidator(5)])),
('status', models.CharField(choices=[('NEW', 'جدید'), ('OPEN', 'باز'), ('WAITING_CUSTOMER', 'در انتظار مشتری'), ('WAITING_STAFF', 'در انتظار کارشناس'), ('RESOLVED', 'حل\u200cشده'), ('CLOSED', 'بسته'), ('REOPENED', 'بازگشایی\u200cشده')], db_index=True, default='NEW', max_length=25)),
('priority', models.CharField(choices=[('NORMAL', 'عادی'), ('IMPORTANT', 'مهم'), ('URGENT', 'فوری')], db_index=True, default='NORMAL', max_length=15)),
('origin_visibility', models.CharField(choices=[('PUBLIC', 'عمومی'), ('SELECTED', 'کارشناس انتخابی')], default='PUBLIC', max_length=15)),
('last_activity_at', models.DateTimeField(db_index=True)),
('first_response_at', models.DateTimeField(blank=True, null=True)),
('last_customer_message_at', models.DateTimeField(blank=True, null=True)),
('last_staff_message_at', models.DateTimeField(blank=True, null=True)),
('first_response_due_at', models.DateTimeField(blank=True, null=True)),
('resolution_due_at', models.DateTimeField(blank=True, null=True)),
('resolved_at', models.DateTimeField(blank=True, null=True)),
('closed_at', models.DateTimeField(blank=True, null=True)),
('reopened_at', models.DateTimeField(blank=True, null=True)),
('customer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='customer_tickets', to=settings.AUTH_USER_MODEL)),
('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='owned_tickets', to=settings.AUTH_USER_MODEL)),
('selected_expert', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='selected_tickets', to=settings.AUTH_USER_MODEL)),
('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='tickets', to='tickets.ticketcategory')),
],
options={
'ordering': ['-last_activity_at'],
'permissions': [('view_all_tickets', 'Can view all tickets'), ('claim_ticket', 'Can claim ticket'), ('transfer_ticket', 'Can transfer ticket'), ('share_ticket', 'Can share ticket'), ('change_ticket_priority', 'Can change ticket priority'), ('view_customer_history', 'Can view customer history')],
},
),
migrations.CreateModel(
name='TicketEvent',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('event_type', models.CharField(choices=[('CREATED', 'ایجاد'), ('CLAIMED', 'برداشت'), ('TRANSFERRED', 'انتقال'), ('SHARED', 'اشتراک'), ('ACCESS_REVOKED', 'لغو دسترسی'), ('STATUS_CHANGED', 'تغییر وضعیت'), ('PRIORITY_CHANGED', 'تغییر اولویت'), ('REOPENED', 'بازگشایی'), ('RESOLVED', 'حل'), ('CLOSED', 'بستن')], max_length=30)),
('metadata', models.JSONField(blank=True, default=dict)),
('created_at', models.DateTimeField(auto_now_add=True)),
('actor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='events', to='tickets.ticket')),
],
),
migrations.CreateModel(
name='TicketReadState',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('last_read_at', models.DateTimeField()),
('last_read_message', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='messaging.message')),
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tickets.ticket')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='TicketAccessGrant',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('permission_level', models.CharField(choices=[('VIEW_ONLY', 'فقط مشاهده'), ('REPLY', 'پاسخ'), ('FULL', 'کامل')], default='FULL', max_length=15)),
('created_at', models.DateTimeField(auto_now_add=True)),
('revoked_at', models.DateTimeField(blank=True, null=True)),
('granted_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='granted_ticket_access', to=settings.AUTH_USER_MODEL)),
('ticket', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='access_grants', to='tickets.ticket')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='ticket_grants', to=settings.AUTH_USER_MODEL)),
],
options={
'constraints': [models.UniqueConstraint(condition=models.Q(('revoked_at__isnull', True)), fields=('ticket', 'user'), name='unique_active_ticket_grant')],
},
),
migrations.AddIndex(
model_name='ticket',
index=models.Index(fields=['status', 'last_activity_at'], name='tickets_tic_status_dbef56_idx'),
),
migrations.AddIndex(
model_name='ticket',
index=models.Index(fields=['owner', 'status'], name='tickets_tic_owner_i_70fd59_idx'),
),
migrations.AddIndex(
model_name='ticket',
index=models.Index(fields=['selected_expert', 'status'], name='tickets_tic_selecte_71a761_idx'),
),
migrations.AddConstraint(
model_name='ticketreadstate',
constraint=models.UniqueConstraint(fields=('ticket', 'user'), name='unique_ticket_read_state'),
),
]