예제 #1
0
class PromoCode(TimestampedModel):
    objects = PromoCodeQuerySet.as_manager()

    name = models.CharField(_('Promo Code'),
                            max_length=32,
                            unique=True,
                            db_index=True)
    discount_percent = models.IntegerField(_('Discount percent'))
    active = models.BooleanField(_('Active'), default=True)
    comment = models.TextField(_('Comment'), blank=True, null=True)

    courses = models.ManyToManyField(
        'products.Course',
        help_text=_('Can not be used for courses not checked here'),
        blank=True)

    class Meta:
        verbose_name = _('Promo Code')
        verbose_name_plural = _('Promo Codes')

    def compatible_with(self, course: Course) -> bool:
        return self.courses.count() == 0 or course in self.courses.all()

    def apply(self, course: Course) -> Decimal:
        if not self.compatible_with(course):
            return course.price

        return Decimal(course.price * (100 - self.discount_percent) / 100)
예제 #2
0
class PromoCode(TimestampedModel):
    objects = PromoCodeQuerySet.as_manager()

    name = models.CharField(_('Promo Code'), max_length=32, unique=True, db_index=True)
    discount_percent = models.IntegerField(_('Discount percent'))
    active = models.BooleanField(_('Active'), default=True)
    comment = models.TextField(_('Comment'), blank=True, null=True)

    class Meta:
        verbose_name = _('Promo Code')
        verbose_name_plural = _('Promo Codes')

    def apply(self, price: Decimal) -> Decimal:
        return Decimal(price * (100 - self.discount_percent) / 100)
예제 #3
0
class PaymentNotification(TimestampedModel):
    STATUS_CHOICES = (
        ('AUTHORIZED', _('Authorized')),
        ('CONFIRMED', _('Confirmed')),
        ('REVERSED', _('Reversed')),
        ('REFUNDED', _('Refunded')),
        ('PARTIAL_REFUNDED', _('Partial refunded')),
        ('REJECTED', _('Rejected')),
    )

    terminal_key = models.CharField(max_length=512)
    order_id = models.IntegerField()
    success = models.BooleanField()
    status = models.CharField(max_length=128, choices=STATUS_CHOICES)
    payment_id = models.BigIntegerField()
    error_code = models.CharField(max_length=512, null=True)
    amount = models.DecimalField(decimal_places=2, max_digits=9)
    rebill_id = models.BigIntegerField(null=True)
    card_id = models.CharField(null=True, max_length=64)
    pan = models.CharField(max_length=128, null=True)
    data = models.TextField(null=True)
    token = models.CharField(max_length=512)
    exp_date = models.CharField(max_length=32, null=True)
예제 #4
0
class Order(TimestampedModel):
    objects = OrderQuerySet.as_manager()  # type: OrderQuerySet

    user = models.ForeignKey('users.User',
                             verbose_name=_('User'),
                             on_delete=models.PROTECT)
    price = models.DecimalField(_('Price'), max_digits=9, decimal_places=2)
    promocode = models.ForeignKey('orders.PromoCode',
                                  verbose_name=_('Promo Code'),
                                  blank=True,
                                  null=True,
                                  on_delete=models.PROTECT)

    paid = models.DateTimeField(
        _('Date when order got paid'),
        null=True,
        blank=True,
        help_text=_('If set during creation, order automaticaly gets shipped'),
    )
    shipped = models.DateTimeField(_('Date when order was shipped'),
                                   null=True,
                                   blank=True)

    desired_bank = models.CharField(_('User-requested bank string'),
                                    blank=True,
                                    max_length=32)

    course = ItemField(to='products.Course',
                       verbose_name=_('Course'),
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)
    record = ItemField(to='products.Record',
                       verbose_name=_('Record'),
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)
    bundle = ItemField(to='products.Bundle',
                       verbose_name=_('Bundle'),
                       null=True,
                       blank=True,
                       on_delete=models.PROTECT)

    giver = models.ForeignKey('users.User',
                              verbose_name=_('Giver'),
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL,
                              related_name='created_gifts')
    desired_shipment_date = models.DateTimeField(
        _('Date when the gift should be shipped'), null=True, blank=True)
    gift_message = models.TextField(_('Gift message'), default='', blank=True)
    notification_to_giver_is_sent = models.BooleanField(default=False)

    class Meta:
        ordering = ['-id']
        verbose_name = _('Order')
        verbose_name_plural = _('Orders')

    def __str__(self):
        return f'Order #{self.pk}'

    @property
    def item(self):
        """Find the attached item. Simple replacement for ContentType framework
        """
        for field in self.__class__._meta.get_fields():
            if getattr(field, '_is_item', False):
                if getattr(self, f'{field.name}_id', None) is not None:
                    return getattr(self, field.name)

    @classmethod
    def _iterate_items(cls) -> Iterable[models.fields.Field]:
        for field in cls._meta.get_fields():
            if getattr(field, '_is_item', False):
                yield field

    @classmethod
    def get_item_foreignkey(cls, item) -> Optional[models.fields.Field]:
        """
        Given an item model, returns the ForeignKey to it"""
        for field in cls._iterate_items():
            if field.related_model == item.__class__:
                return field.name

    def reset_items(self):
        for field in self._iterate_items():
            setattr(self, field.name, None)

    def set_item(self, item):
        foreign_key = self.__class__.get_item_foreignkey(item)
        if foreign_key is not None:
            self.reset_items()
            setattr(self, foreign_key, item)
            return

        raise UnknownItemException('There is not foreignKey for {}'.format(
            item.__class__))

    def set_paid(self, silent=False):
        from orders.services.order_is_paid_setter import Griphook
        Griphook(self, silent=silent)()

    def ship(self, silent: bool = False):
        """Ship the order. Better call it asynchronously"""
        from orders.services.order_shipper import Pigwidgeon
        Pigwidgeon(self, silent=silent)()