add retry sms manually
This commit is contained in:
1 parent
33930e972c
commit
cb92abbb41
42 files changed
+1628
-1484
No files matched your search
@@ -1,130 +1,130 @@
|
||||
# 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'),
|
||||
),
|
||||
]
|
||||
# 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'),
|
||||
),
|
||||
]
|
||||
+102
-102
@@ -1,102 +1,102 @@
|
||||
# Generated by Django 5.1.1 on 2026-09-08 09:57
|
||||
|
||||
import apps.core.models
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('customers', '0003_contactgroup_customerprofile_organization_name_and_more'),
|
||||
('staff', '0004_organizationalunit_staffprofile_primary_unit_and_more'),
|
||||
('tickets', '0003_ticket_city_ticket_province'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='TicketTag',
|
||||
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)),
|
||||
('name', models.CharField(max_length=80, unique=True)),
|
||||
('slug', models.SlugField(max_length=80, unique=True)),
|
||||
('color', models.CharField(default='#52677d', max_length=7)),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'برچسب تیکت',
|
||||
'verbose_name_plural': 'برچسب\u200cهای تیکت',
|
||||
'ordering': ['name'],
|
||||
},
|
||||
bases=(apps.core.models.PersianTextNormalizationMixin, models.Model),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='assigned_unit',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='assigned_tickets', to='staff.organizationalunit'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='created_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='created_tickets', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='delivery_type',
|
||||
field=models.CharField(choices=[('INDIVIDUAL', 'فردی'), ('GROUP', 'ارسال گروهی')], db_index=True, default='INDIVIDUAL', max_length=12),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='owning_unit',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='owned_tickets', to='staff.organizationalunit'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GroupDispatch',
|
||||
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)),
|
||||
('subject', models.CharField(max_length=200, validators=[django.core.validators.MinLengthValidator(5)])),
|
||||
('body', models.TextField()),
|
||||
('status', models.CharField(choices=[('DRAFT', 'پیش\u200cنویس'), ('QUEUED', 'در صف ارسال'), ('SENT', 'ارسال\u200cشده'), ('PARTIAL', 'ارسال ناقص'), ('CANCELLED', 'لغوشده')], db_index=True, default='DRAFT', max_length=12)),
|
||||
('recipient_count', models.PositiveIntegerField(default=0)),
|
||||
('dispatched_at', models.DateTimeField(blank=True, null=True)),
|
||||
('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tickets.ticketcategory')),
|
||||
('contact_group', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='dispatches', to='customers.contactgroup')),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='created_group_dispatches', to=settings.AUTH_USER_MODEL)),
|
||||
('unit', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='group_dispatches', to='staff.organizationalunit')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'ارسال گروهی',
|
||||
'verbose_name_plural': 'ارسال\u200cهای گروهی',
|
||||
'ordering': ['-created_at'],
|
||||
'permissions': [('dispatch_group_tickets', 'Can dispatch isolated tickets to a contact group')],
|
||||
},
|
||||
bases=(apps.core.models.PersianTextNormalizationMixin, models.Model),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='group_dispatch',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tickets', to='tickets.groupdispatch'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='tags',
|
||||
field=models.ManyToManyField(blank=True, related_name='tickets', to='tickets.tickettag'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='ticket',
|
||||
index=models.Index(fields=['owning_unit', 'status'], name='tickets_tic_owning__e629e3_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='ticket',
|
||||
index=models.Index(fields=['delivery_type', 'last_activity_at'], name='tickets_tic_deliver_c53084_idx'),
|
||||
),
|
||||
]
|
||||
# Generated by Django 5.1.1 on 2026-09-08 09:57
|
||||
|
||||
import apps.core.models
|
||||
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):
|
||||
|
||||
dependencies = [
|
||||
('customers', '0003_contactgroup_customerprofile_organization_name_and_more'),
|
||||
('staff', '0004_organizationalunit_staffprofile_primary_unit_and_more'),
|
||||
('tickets', '0003_ticket_city_ticket_province'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='TicketTag',
|
||||
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)),
|
||||
('name', models.CharField(max_length=80, unique=True)),
|
||||
('slug', models.SlugField(max_length=80, unique=True)),
|
||||
('color', models.CharField(default='#52677d', max_length=7)),
|
||||
('is_active', models.BooleanField(default=True)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'برچسب تیکت',
|
||||
'verbose_name_plural': 'برچسب\u200cهای تیکت',
|
||||
'ordering': ['name'],
|
||||
},
|
||||
bases=(apps.core.models.PersianTextNormalizationMixin, models.Model),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='assigned_unit',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='assigned_tickets', to='staff.organizationalunit'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='created_by',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='created_tickets', to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='delivery_type',
|
||||
field=models.CharField(choices=[('INDIVIDUAL', 'فردی'), ('GROUP', 'ارسال گروهی')], db_index=True, default='INDIVIDUAL', max_length=12),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='owning_unit',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='owned_tickets', to='staff.organizationalunit'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GroupDispatch',
|
||||
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)),
|
||||
('subject', models.CharField(max_length=200, validators=[django.core.validators.MinLengthValidator(5)])),
|
||||
('body', models.TextField()),
|
||||
('status', models.CharField(choices=[('DRAFT', 'پیش\u200cنویس'), ('QUEUED', 'در صف ارسال'), ('SENT', 'ارسال\u200cشده'), ('PARTIAL', 'ارسال ناقص'), ('CANCELLED', 'لغوشده')], db_index=True, default='DRAFT', max_length=12)),
|
||||
('recipient_count', models.PositiveIntegerField(default=0)),
|
||||
('dispatched_at', models.DateTimeField(blank=True, null=True)),
|
||||
('category', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tickets.ticketcategory')),
|
||||
('contact_group', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='dispatches', to='customers.contactgroup')),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='created_group_dispatches', to=settings.AUTH_USER_MODEL)),
|
||||
('unit', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='group_dispatches', to='staff.organizationalunit')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'ارسال گروهی',
|
||||
'verbose_name_plural': 'ارسال\u200cهای گروهی',
|
||||
'ordering': ['-created_at'],
|
||||
'permissions': [('dispatch_group_tickets', 'Can dispatch isolated tickets to a contact group')],
|
||||
},
|
||||
bases=(apps.core.models.PersianTextNormalizationMixin, models.Model),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='group_dispatch',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='tickets', to='tickets.groupdispatch'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticket',
|
||||
name='tags',
|
||||
field=models.ManyToManyField(blank=True, related_name='tickets', to='tickets.tickettag'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='ticket',
|
||||
index=models.Index(fields=['owning_unit', 'status'], name='tickets_tic_owning__e629e3_idx'),
|
||||
),
|
||||
migrations.AddIndex(
|
||||
model_name='ticket',
|
||||
index=models.Index(fields=['delivery_type', 'last_activity_at'], name='tickets_tic_deliver_c53084_idx'),
|
||||
),
|
||||
]
|
||||
@@ -1,24 +1,24 @@
|
||||
# Generated by Django 5.1.1 on 2026-09-09 05:43
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('staff', '0005_organizationalunit_accepts_external_tickets'),
|
||||
('tickets', '0006_assign_legacy_contacts_to_sales'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='ticketcategory',
|
||||
options={'ordering': ['unit__name', 'sort_order', 'title']},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticketcategory',
|
||||
name='unit',
|
||||
field=models.ForeignKey(blank=True, help_text='برای دسته\u200cهای قدیمی عمومی می\u200cتواند خالی باشد؛ دسته\u200cهای جدید باید واحد داشته باشند.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ticket_categories', to='staff.organizationalunit', verbose_name='واحد سازمانی'),
|
||||
),
|
||||
]
|
||||
# Generated by Django 5.1.1 on 2026-09-09 05:43
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('staff', '0005_organizationalunit_accepts_external_tickets'),
|
||||
('tickets', '0006_assign_legacy_contacts_to_sales'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='ticketcategory',
|
||||
options={'ordering': ['unit__name', 'sort_order', 'title']},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticketcategory',
|
||||
name='unit',
|
||||
field=models.ForeignKey(blank=True, help_text='برای دسته\u200cهای قدیمی عمومی می\u200cتواند خالی باشد؛ دسته\u200cهای جدید باید واحد داشته باشند.', null=True, on_delete=django.db.models.deletion.PROTECT, related_name='ticket_categories', to='staff.organizationalunit', verbose_name='واحد سازمانی'),
|
||||
),
|
||||
]
|
||||
@@ -1,28 +1,28 @@
|
||||
# Generated by Django 5.1.1 on 2026-09-09 09:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
# Generated by Django 5.1.1 on 2026-09-09 09:31
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0009_seed_customer_facing_units_and_categories'),
|
||||
('staff', '0006_alter_organizationalunit_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='ticketcategory',
|
||||
options={'ordering': ['unit__sort_order', 'unit__name', 'sort_order', 'title', 'pk']},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticketcategory',
|
||||
name='search_keywords',
|
||||
field=models.TextField(blank=True, help_text='مترادف\u200cها و عبارت\u200cهای رایج مشتری را وارد کنید.', verbose_name='کلیدواژه\u200cهای جستجو'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ticketcategory',
|
||||
name='sort_order',
|
||||
field=models.PositiveIntegerField(db_index=True, default=0, verbose_name='ترتیب نمایش'),
|
||||
),
|
||||
]
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='ticketcategory',
|
||||
options={'ordering': ['unit__sort_order', 'unit__name', 'sort_order', 'title', 'pk']},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='ticketcategory',
|
||||
name='search_keywords',
|
||||
field=models.TextField(blank=True, help_text='مترادف\u200cها و عبارت\u200cهای رایج مشتری را وارد کنید.', verbose_name='کلیدواژه\u200cهای جستجو'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ticketcategory',
|
||||
name='sort_order',
|
||||
field=models.PositiveIntegerField(db_index=True, default=0, verbose_name='ترتیب نمایش'),
|
||||
),
|
||||
]
|
||||
@@ -1,18 +1,18 @@
|
||||
# Generated by Django 5.1.1 on 2026-09-09 09:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0010_alter_ticketcategory_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='ticketcategory',
|
||||
name='show_in_customer_form',
|
||||
field=models.BooleanField(default=True, help_text='در صورت خاموش بودن، این دسته در انتخاب و جستجوی مشتری دیده نمی\u200cشود.', verbose_name='نمایش در فرم مشتری'),
|
||||
),
|
||||
]
|
||||
# Generated by Django 5.1.1 on 2026-09-09 09:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tickets', '0010_alter_ticketcategory_options_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='ticketcategory',
|
||||
name='show_in_customer_form',
|
||||
field=models.BooleanField(default=True, help_text='در صورت خاموش بودن، این دسته در انتخاب و جستجوی مشتری دیده نمی\u200cشود.', verbose_name='نمایش در فرم مشتری'),
|
||||
),
|
||||
]
|
||||
Reference in new issue
Block a user