# Path: konfera/models/abstract.py
# class FromToModel(KonferaModel):
# 
#     class Meta:
#         abstract = True
# 
#     date_from = models.DateTimeField(verbose_name=_('Available from'), blank=True)
#     date_to = models.DateTimeField(verbose_name=_('Available to'), blank=True)
# 
#     def clean(self):
#         if self.date_from and self.date_to and self.date_from >= self.date_to:
#             msg = _('%(date_from)s have to be before %(date_to)s.') % {
#                 'date_from': self._meta.get_field('date_from').verbose_name,
#                 'date_to': self._meta.get_field('date_to').verbose_name
#             }
# 
#             raise ValidationError({'date_from': msg, 'date_to': msg})
# 
# Path: konfera/models/ticket.py
# class Ticket(KonferaModel):
#     REQUESTED = 'requested'
#     REGISTERED = 'registered'
#     CHECKEDIN = 'checked-in'
#     CANCELLED = 'cancelled'
# 
#     TICKET_STATUS = (
#         (REQUESTED, _('Requested')),
#         (REGISTERED, _('Registered')),
#         (CHECKEDIN, _('Checked-in')),
#         (CANCELLED, _('Cancelled')),
#     )
# 
#     type = models.ForeignKey('TicketType')
#     discount_code = models.ForeignKey('DiscountCode', blank=True, null=True)
#     status = models.CharField(choices=TICKET_STATUS, max_length=32)
#     title = models.CharField(choices=Speaker.TITLE_CHOICES, max_length=4, default=Speaker.TITLE_UNSET, blank=True)
#     first_name = models.CharField(max_length=128)
#     last_name = models.CharField(max_length=128)
#     email = models.EmailField()
#     phone = models.CharField(max_length=64, blank=True)
#     description = models.TextField(blank=True)
#     order = models.ForeignKey('Order', blank=True)
# 
#     def __str__(self):
#         return '{title} {first_name} {last_name}'.format(
#             title=dict(Speaker.TITLE_CHOICES).get(self.title, ''),
#             first_name=self.first_name,
#             last_name=self.last_name
#         ).strip()
# 
#     def discount_calculator(self):
#         if self.discount_code:
#             return self.type.price * self.discount_code.discount / 100
#         return 0
# 
#     def clean(self):
#         if self.discount_code and self.type and self.discount_code.ticket_type != self.type:
#             raise ValidationError(
#                 {'discount_code': _('Discount code is not applicable for the selected ticket type.')})
#         if hasattr(self, 'order'):
#             exist_ticket = self.order.ticket_set.first()
#             if exist_ticket and exist_ticket.type.event.id != self.type.event.id:
#                 raise ValidationError(_('All tickets must be for the same event.'))
#         if self.discount_code and not self.discount_code.is_available:
#             raise ValidationError(
#                 {'discount_code': _('Usage of the discount code has already exceeded allowed number.')})
#         super().clean()
# 
#     def save(self, *args, **kwargs):
#         self.clean()
#         recalculate_tickets = True
# 
#         if not hasattr(self, 'order'):
#             recalculate_tickets = False
#             discount = self.discount_calculator()
#             order = Order(price=self.type.price, discount=discount, status=Order.AWAITING,
#                           purchase_date=timezone.now())
#             order.save()
#             self.order = order
# 
#         if self.order.status == Order.PAID and self.status == self.REQUESTED:
#             self.status = self.REGISTERED
# 
#         if self.order.status == Order.CANCELLED:
#             self.status = self.CANCELLED
#             recalculate_tickets = False
# 
#         super().save(*args, **kwargs)
# 
#         if recalculate_tickets:
#             self.order.recalculate_ticket_price()


from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from konfera.models.abstract import FromToModel
from konfera.models.ticket import Ticket
    NOT_LISTED = 'not_listed'

    ACCESSIBILITY = (
        (PUBLIC, _('Public')),
        (PRIVATE, _('Private')),
        (DISABLED, _('Disabled')),
        (NOT_LISTED, _('Not listed')),
    )

    title = models.CharField(max_length=128)
    description = models.TextField(blank=True)
    price = models.DecimalField(decimal_places=2, max_digits=12, validators=[MinValueValidator(0)])
    attendee_type = models.CharField(choices=TICKET_TYPE_CHOICES, max_length=32, default=ATTENDEE)
    accessibility = models.CharField(choices=ACCESSIBILITY, max_length=32, default=PRIVATE)
    usage = models.IntegerField(default=-1, help_text=_('Number of tickets which can be issued. '
                                                        'For unlimited amount use -1.'))
    event = models.ForeignKey('Event')

    def __str__(self):
        return self.title

    def _get_current_status(self):
        now = timezone.now()
        status = TicketType.ACTIVE

        if not self.date_from or not self.date_to or now < self.date_from:
            status = TicketType.NOT_AVAILABLE
        elif self.date_to < now:
            status = TicketType.EXPIRED
        elif self.usage - self.issued_tickets == 0:

# Path: konfera/models/abstract.py
# class FromToModel(KonferaModel):
# 
#     class Meta:
#         abstract = True
# 
#     date_from = models.DateTimeField(verbose_name=_('Available from'), blank=True)
#     date_to = models.DateTimeField(verbose_name=_('Available to'), blank=True)
# 
#     def clean(self):
#         if self.date_from and self.date_to and self.date_from >= self.date_to:
#             msg = _('%(date_from)s have to be before %(date_to)s.') % {
#                 'date_from': self._meta.get_field('date_from').verbose_name,
#                 'date_to': self._meta.get_field('date_to').verbose_name
#             }
# 
#             raise ValidationError({'date_from': msg, 'date_to': msg})
# 
# Path: konfera/models/ticket.py
# class Ticket(KonferaModel):
#     REQUESTED = 'requested'
#     REGISTERED = 'registered'
#     CHECKEDIN = 'checked-in'
#     CANCELLED = 'cancelled'
# 
#     TICKET_STATUS = (
#         (REQUESTED, _('Requested')),
#         (REGISTERED, _('Registered')),
#         (CHECKEDIN, _('Checked-in')),
#         (CANCELLED, _('Cancelled')),
#     )
# 
#     type = models.ForeignKey('TicketType')
#     discount_code = models.ForeignKey('DiscountCode', blank=True, null=True)
#     status = models.CharField(choices=TICKET_STATUS, max_length=32)
#     title = models.CharField(choices=Speaker.TITLE_CHOICES, max_length=4, default=Speaker.TITLE_UNSET, blank=True)
#     first_name = models.CharField(max_length=128)
#     last_name = models.CharField(max_length=128)
#     email = models.EmailField()
#     phone = models.CharField(max_length=64, blank=True)
#     description = models.TextField(blank=True)
#     order = models.ForeignKey('Order', blank=True)
# 
#     def __str__(self):
#         return '{title} {first_name} {last_name}'.format(
#             title=dict(Speaker.TITLE_CHOICES).get(self.title, ''),
#             first_name=self.first_name,
#             last_name=self.last_name
#         ).strip()
# 
#     def discount_calculator(self):
#         if self.discount_code:
#             return self.type.price * self.discount_code.discount / 100
#         return 0
# 
#     def clean(self):
#         if self.discount_code and self.type and self.discount_code.ticket_type != self.type:
#             raise ValidationError(
#                 {'discount_code': _('Discount code is not applicable for the selected ticket type.')})
#         if hasattr(self, 'order'):
#             exist_ticket = self.order.ticket_set.first()
#             if exist_ticket and exist_ticket.type.event.id != self.type.event.id:
#                 raise ValidationError(_('All tickets must be for the same event.'))
#         if self.discount_code and not self.discount_code.is_available:
#             raise ValidationError(
#                 {'discount_code': _('Usage of the discount code has already exceeded allowed number.')})
#         super().clean()
# 
#     def save(self, *args, **kwargs):
#         self.clean()
#         recalculate_tickets = True
# 
#         if not hasattr(self, 'order'):
#             recalculate_tickets = False
#             discount = self.discount_calculator()
#             order = Order(price=self.type.price, discount=discount, status=Order.AWAITING,
#                           purchase_date=timezone.now())
#             order.save()
#             self.order = order
# 
#         if self.order.status == Order.PAID and self.status == self.REQUESTED:
#             self.status = self.REGISTERED
# 
#         if self.order.status == Order.CANCELLED:
#             self.status = self.CANCELLED
#             recalculate_tickets = False
# 
#         super().save(*args, **kwargs)
# 
#         if recalculate_tickets:
#             self.order.recalculate_ticket_price()


# Path: konfera/models/ticket_type.py
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from konfera.models.abstract import FromToModel
from konfera.models.ticket import Ticket

    NOT_LISTED = 'not_listed'

    ACCESSIBILITY = (
        (PUBLIC, _('Public')),
        (PRIVATE, _('Private')),
        (DISABLED, _('Disabled')),
        (NOT_LISTED, _('Not listed')),
    )

    title = models.CharField(max_length=128)
    description = models.TextField(blank=True)
    price = models.DecimalField(decimal_places=2, max_digits=12, validators=[MinValueValidator(0)])
    attendee_type = models.CharField(choices=TICKET_TYPE_CHOICES, max_length=32, default=ATTENDEE)
    accessibility = models.CharField(choices=ACCESSIBILITY, max_length=32, default=PRIVATE)
    usage = models.IntegerField(default=-1, help_text=_('Number of tickets which can be issued. '
                                                        'For unlimited amount use -1.'))
    event = models.ForeignKey('Event')

    def __str__(self):
        return self.title

    def _get_current_status(self):
        now = timezone.now()
        status = TicketType.ACTIVE

        if not self.date_from or not self.date_to or now < self.date_from:
            status = TicketType.NOT_AVAILABLE
        elif self.date_to < now:
            status = TicketType.EXPIRED
        elif self.usage - self.issued_tickets == 0:

            status = TicketType.SOLDOUT