from django.db import models from django.contrib.auth import get_user_model from django.urls import reverse_lazy from .helpers import generate_voucher_code from ..const import PAYMENT_STATUS_SUCCESS, PAYMENT_STATUS_FAILED, PAYMENT_STATUS_REFUNDED from ..models import InvoicePayment from clients.models import ClientProfile from dbsettings.functions import getValue from datetime import timedelta import uuid class Voucher(models.Model): code = models.BigIntegerField(default=generate_voucher_code, unique=True) value = models.DecimalField(max_digits=10, decimal_places=2) created_at = models.DateTimeField(auto_now_add=True) @property def is_active(self): try: self.voucheractivation return True except VoucherActivation.DoesNotExist: return False def get_absolute_url(self): return VoucherDownloadURL.objects.create(voucher=self).get_absolute_url() class VoucherDownloadURL(models.Model): uuid = models.UUIDField(default=uuid.uuid4, primary_key=True) voucher = models.ForeignKey(Voucher, models.CASCADE) created = models.DateTimeField(auto_now_add=True) @property def expiry(self): return self.created + timedelta(seconds=getValue("payment.voucher.urlvalidity", 300)) def get_absolute_url(self): return reverse_lazy("payment:voucher:download") class VoucherActivation(models.Model): voucher = models.OneToOneField(Voucher, models.PROTECT) user = models.ForeignKey(get_user_model(), models.PROTECT) activated_at = models.DateTimeField(auto_now_add=True) data = models.CharField(max_length=256) class VoucherApplication(models.Model): voucher = models.OneToOneField(Voucher, models.PROTECT) client = models.ForeignKey(get_user_model(), models.PROTECT) applied_at = models.DateTimeField(auto_now_add=True) class VoucherInvoicePayment(InvoicePayment): success = models.BooleanField(default=True) @property def gateway(self): return "Voucher" @classmethod def initiate(cls, invoice, amount=None): amount = amount or (invoice.balance * -1) payment = cls.objects.create(invoice=invoice, amount=amount, gateway_id=uuid.uuid4()) if invoice.user.balance <= 0: payment.success = False payment.save() invoice.finalize() return reverse_lazy("payment:status", args=[payment.uuid]) @property def status(self): return PAYMENT_STATUS_SUCCESS if self.success else PAYMENT_STATUS_FAILED