from django.db import models import os from django.utils.translation import gettext_lazy as _ from apps.account.models import StudentUser, User from apps.course.models import Course from phonenumber_field.modelfields import PhoneNumberField from utils.validators import validate_possible_number def receipt_file_upload_to(instance, filename): return os.path.join(f"receipts/{instance.transaction.id}/{filename}") class TransactionParticipant(models.Model): class TransactionStatus(models.TextChoices): PENDING = 'pending', _('Pending') WAITING_APPROVAL = 'waiting_approval', _('Waiting for Approval') SUCCESS = 'success', _('Success') FAILED = 'failed', _('Failed') class PaymentMethods(models.TextChoices): RECEIPT = 'receipt', _('Receipt') FREE = 'free', _('Free') PAYMENT_GATEWAY = 'Payment_Gateway', _('Payment Gateway') user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='transactions', verbose_name=_('User')) course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='course_transactions', verbose_name=_('Course')) payment_method=models.CharField(max_length=20, choices=PaymentMethods.choices, default=PaymentMethods.PAYMENT_GATEWAY, verbose_name=_('Transaction Payment Method')) # is_paid = models.BooleanField(default=False, verbose_name='Payment Status', help_text='Indicates whether the payment has been completed or not') price = models.DecimalField(max_digits=10, decimal_places=2, default=0.00, verbose_name=_('Transaction Price')) status = models.CharField(max_length=20, choices=TransactionStatus.choices, default=TransactionStatus.PENDING, verbose_name=_('Transaction Status')) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created at")) updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated at")) is_deleted = models.BooleanField(default=False, verbose_name=_('Is Deleted')) def __str__(self): return f"{self.user.email} - {self.course.title} ({self.status})" def is_participant_enrolled(self): """بررسی اینکه آیا کاربر در دوره ثبت‌نام شده یا نه""" from apps.course.models import Participant return Participant.objects.filter( student=self.user, course=self.course ).exists() def get_participant(self): """دریافت شرکت‌کننده دوره اگر وجود داشته باشد""" from apps.course.models import Participant return Participant.objects.filter( student=self.user, course=self.course ).first() class Meta: verbose_name = _('Transaction Participant') verbose_name_plural = _('Transaction Participants') class ParticipantInfo(models.Model): class GenderChoices(models.TextChoices): MALE = 'male', _('Male') FEMALE = 'female', _('Female') transaction_participant = models.ForeignKey( TransactionParticipant, on_delete=models.CASCADE, related_name='participant_infos', verbose_name=_("Transaction Participant") ) fullname = models.CharField(max_length=255, verbose_name=_("Full Name"), help_text=_("Enter the full name of the user.")) email = models.EmailField(verbose_name=_("Email Address"), help_text=_("Enter the user's email address.")) phone_number = PhoneNumberField(validators=[validate_possible_number], null=True, blank=True, verbose_name=_('phone')) gender = models.CharField( max_length=20, choices=GenderChoices.choices, null=True, blank=True, verbose_name=_('Gender'), help_text=_("Select the user's gender.") ) birthdate = models.DateField(verbose_name=_('birthdate'), null=True, blank=True) def __str__(self): return f"{self.fullname} (Transaction: {self.transaction_participant.id}) - {self.email}" class Meta: verbose_name = _('Participant Info') verbose_name_plural = _('Participant Infos') class TransactionReceipt(models.Model): """ Model for storing payment receipts uploaded by users for transactions """ transaction = models.ForeignKey( TransactionParticipant, on_delete=models.CASCADE, related_name='receipts', verbose_name=_('Transaction') ) file = models.FileField( upload_to=receipt_file_upload_to, verbose_name=_('Receipt File'), help_text=_('Upload payment receipt image or document') ) uploaded_at = models.DateTimeField(auto_now_add=True, verbose_name=_('Uploaded At')) description = models.TextField( blank=True, null=True, verbose_name=_('Description'), help_text=_('Optional description or notes about the receipt') ) class Meta: verbose_name = _('Transaction Receipt') verbose_name_plural = _('Transaction Receipts') ordering = ['-uploaded_at'] def __str__(self): return f"Receipt for Transaction #{self.transaction.id} - {self.uploaded_at.strftime('%Y-%m-%d %H:%M')}"