# Generated by Django 5.1.1 on 2026-10-05 10:44 import apps.payments.models 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 = [ ('notifications', '0017_alter_smstemplate_event_type'), ('staff', '0012_organizationalunit_supervisor_mobile_5'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='BankInstitution', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.SlugField(unique=True)), ('name', models.CharField(max_length=100)), ('is_active', models.BooleanField(default=True)), ('historical', models.BooleanField(default=False)), ], options={ 'ordering': ['historical', 'name'], }, ), migrations.CreateModel( name='PaymentAccessConfiguration', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('singleton', models.PositiveSmallIntegerField(default=1, editable=False, unique=True)), ('open_view', models.BooleanField(default=True, verbose_name='مشاهده برای همه کارشناسان فعال')), ('open_create', models.BooleanField(default=True, verbose_name='ایجاد برای همه کارشناسان فعال')), ], options={ 'permissions': [('manage_payment_access', 'Manage payment access')], }, ), migrations.CreateModel( name='CompanyBankAccount', 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)), ('name', models.CharField(max_length=120, verbose_name='نام نمایشی حساب')), ('holder', models.CharField(max_length=150, verbose_name='صاحب حساب')), ('account_number', models.CharField(blank=True, max_length=40, verbose_name='شماره حساب')), ('iban', models.CharField(blank=True, max_length=26, verbose_name='شبا')), ('card_number', models.CharField(blank=True, max_length=16, verbose_name='شماره کارت')), ('requires_deposit_id', models.BooleanField(default=False, verbose_name='شناسه واریز الزامی')), ('is_active', models.BooleanField(default=True, verbose_name='فعال کلی')), ('available_to_staff', models.BooleanField(default=True, verbose_name='قابل انتخاب کارشناسان')), ('available_to_customers', models.BooleanField(default=True, verbose_name='قابل انتخاب مشتریان')), ('sort_order', models.PositiveIntegerField(default=0)), ('bank', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='payments.bankinstitution', verbose_name='بانک')), ], options={ 'ordering': ['sort_order', 'name', 'pk'], 'permissions': [('manage_company_bankaccounts', 'Manage company bank accounts')], }, ), migrations.CreateModel( name='PaymentAuditEvent', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('actor_name', models.CharField(max_length=150)), ('action', models.CharField(max_length=50)), ('object_type', models.CharField(max_length=50)), ('object_id', models.CharField(max_length=64)), ('details', models.JSONField(default=dict)), ('created_at', models.DateTimeField(auto_now_add=True, db_index=True)), ('actor', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ['-created_at', '-pk'], 'permissions': [('view_payment_audit', 'View financial audit')], }, ), migrations.CreateModel( name='PaymentNotice', 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)), ('account_snapshot', models.JSONField()), ('subject', models.CharField(max_length=200)), ('amount', models.BigIntegerField()), ('deposit_id', models.CharField(blank=True, max_length=100)), ('invoice_number', models.CharField(blank=True, max_length=100)), ('description', models.TextField(blank=True)), ('cancelled_at', models.DateTimeField(blank=True, null=True)), ('account', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='payments.companybankaccount')), ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='issued_payment_notices', to=settings.AUTH_USER_MODEL)), ('customer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='payment_notices', to=settings.AUTH_USER_MODEL)), ('owning_unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='staff.organizationalunit')), ], options={ 'ordering': ['-created_at', '-pk'], }, ), migrations.CreateModel( name='PaymentNotification', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('context', models.JSONField()), ('rendered_body', models.TextField(blank=True)), ('template_snapshot', models.JSONField(default=dict)), ('job', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='payment_notification', to='notifications.notificationjob')), ('notice', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='payments.paymentnotice')), ('unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='staff.organizationalunit')), ], ), migrations.CreateModel( name='PaymentNotificationAttempt', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('started_at', models.DateTimeField(auto_now_add=True)), ('finished_at', models.DateTimeField(null=True)), ('success', models.BooleanField(null=True)), ('provider_code', models.CharField(blank=True, max_length=50)), ('provider_id', models.CharField(blank=True, max_length=500)), ('error', models.TextField(blank=True)), ('notification', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='attempt_log', to='payments.paymentnotification')), ], ), migrations.CreateModel( name='PaymentReceipt', 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)), ('status', models.CharField(choices=[('PENDING', 'در انتظار بررسی'), ('PARTIAL', 'تأیید ناقص'), ('APPROVED', 'تأیید شده'), ('REJECTED', 'رد شده')], db_index=True, default='PENDING', max_length=12)), ('submission_key', models.UUIDField(unique=True)), ('current_version', models.PositiveIntegerField(default=1)), ('customer', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='payment_receipts', to=settings.AUTH_USER_MODEL)), ('notice', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='receipts', to='payments.paymentnotice')), ('owning_unit', models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='staff.organizationalunit')), ('submitted_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='submitted_payment_receipts', to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ['-created_at', '-pk'], 'permissions': [('approve_paymentreceipt', 'Approve payment receipt'), ('senior_approve_paymentreceipt', 'Senior final approval'), ('submit_customer_receipt', 'Submit receipt for customer'), ('view_all_payments', 'View payments across units')], }, ), migrations.CreateModel( name='PaymentReceiptRevision', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('version', models.PositiveIntegerField()), ('amount', models.BigIntegerField()), ('paid_date', models.DateField()), ('account_snapshot', models.JSONField()), ('origin_other', models.CharField(blank=True, max_length=100)), ('deposit_id', models.CharField(blank=True, max_length=100)), ('tracking_number', models.CharField(blank=True, max_length=100)), ('description', models.TextField(blank=True)), ('destination_mismatch', models.BooleanField(default=False)), ('created_at', models.DateTimeField(auto_now_add=True)), ('image', models.FileField(max_length=500, upload_to=apps.payments.models.receipt_path)), ('mime_type', models.CharField(max_length=100)), ('sha256', models.CharField(max_length=64)), ('original_name', models.CharField(max_length=255)), ('file_size', models.PositiveBigIntegerField()), ('destination', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='payments.companybankaccount')), ('origin_bank', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='payments.bankinstitution')), ('receipt', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='revisions', to='payments.paymentreceipt')), ], ), migrations.CreateModel( name='ReceiptApprovalCycle', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('policy_snapshot', models.JSONField(default=dict)), ('status', models.CharField(choices=[('PENDING', 'در انتظار بررسی'), ('PARTIAL', 'تأیید ناقص'), ('APPROVED', 'تأیید شده'), ('REJECTED', 'رد شده')], default='PENDING', max_length=12)), ('finalized_at', models.DateTimeField(blank=True, null=True)), ('finalized_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), ('revision', models.OneToOneField(on_delete=django.db.models.deletion.PROTECT, related_name='cycle', to='payments.paymentreceiptrevision')), ], ), migrations.CreateModel( name='ReceiptApprovalAssignment', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('is_senior', models.BooleanField(default=False)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), ('cycle', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='assignments', to='payments.receiptapprovalcycle')), ], ), migrations.AddField( model_name='paymentnotification', name='cycle', field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='payments.receiptapprovalcycle'), ), migrations.CreateModel( name='ReceiptDecision', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('action', models.CharField(choices=[('APPROVE', 'تأیید'), ('REJECT', 'رد'), ('SENIOR_APPROVE', 'تأیید ارشد')], max_length=20)), ('reason', models.TextField(blank=True)), ('actor_name', models.CharField(max_length=150)), ('created_at', models.DateTimeField(auto_now_add=True)), ('cycle', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='decisions', to='payments.receiptapprovalcycle')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='PaymentApprovalPolicy', 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=100, verbose_name='عنوان سیاست')), ('is_active', models.BooleanField(default=True)), ('reviewers', models.ManyToManyField(related_name='payment_review_policies', to=settings.AUTH_USER_MODEL, verbose_name='افراد الزامی تأیید')), ('seniors', models.ManyToManyField(blank=True, related_name='payment_senior_policies', to=settings.AUTH_USER_MODEL, verbose_name='تأییدکنندگان ارشد')), ('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='staff.organizationalunit', verbose_name='واحد (خالی: عمومی)')), ], options={ 'permissions': [('manage_payment_approval_policy', 'Manage payment approval policy')], 'constraints': [models.UniqueConstraint(condition=models.Q(('is_active', True), ('unit__isnull', False)), fields=('unit',), name='pay_active_unit_policy'), models.UniqueConstraint(condition=models.Q(('is_active', True), ('unit__isnull', True)), fields=('is_active',), name='pay_active_global_policy')], }, ), migrations.AddIndex( model_name='paymentnotice', index=models.Index(fields=['customer', '-created_at'], name='payments_pa_custome_bc6e3f_idx'), ), migrations.AddIndex( model_name='paymentnotice', index=models.Index(fields=['owning_unit', '-created_at'], name='payments_pa_owning__f2b6af_idx'), ), migrations.AddConstraint( model_name='paymentnotice', constraint=models.CheckConstraint(condition=models.Q(('amount__gt', 0), ('amount__lte', 9007199254740991)), name='pay_notice_amount'), ), migrations.AddIndex( model_name='paymentreceipt', index=models.Index(fields=['customer', '-created_at'], name='payments_pa_custome_e266cc_idx'), ), migrations.AddIndex( model_name='paymentreceipt', index=models.Index(fields=['status', '-created_at'], name='payments_pa_status_5cd50b_idx'), ), migrations.AddConstraint( model_name='paymentreceiptrevision', constraint=models.UniqueConstraint(fields=('receipt', 'version'), name='pay_receipt_revision'), ), migrations.AddConstraint( model_name='paymentreceiptrevision', constraint=models.CheckConstraint(condition=models.Q(('amount__gt', 0), ('amount__lte', 9007199254740991)), name='pay_receipt_amount'), ), migrations.AddConstraint( model_name='receiptapprovalassignment', constraint=models.UniqueConstraint(fields=('cycle', 'user', 'is_senior'), name='pay_cycle_assignment'), ), migrations.AddConstraint( model_name='receiptdecision', constraint=models.UniqueConstraint(fields=('cycle', 'user'), name='pay_one_vote_per_user'), ), ]