# Path: app/timetables/models.py
# class Timetable(SlugifyMixin, TimestampMixin):
#     """
#     Central model of the platform.
# 
#     It represents/encapsulates the entire structure and
#     scheduling of meals, menu-items, dishes, courses etc,
#     served at a location, to a team or the entire organisation.
#     """
# 
#     name = models.CharField(max_length=255, verbose_name='Timetable Name')
#     slug = models.SlugField(max_length=255, unique=True, null=True, editable=False)
#     cycle_length = models.PositiveSmallIntegerField(
#         validators=[MinValueValidator(1)],
#         help_text=(
#             'Number of days in which the menu timetable is repeated '
#             'after a period of time. E.g, A cycle length of '
#             '14 days (2 weeks) including the inactive weekdays '
#             'like weekends after which the food schedule is repeated.'
#         )
#     )
#     ref_cycle_day = models.PositiveSmallIntegerField(
#         validators=[MinValueValidator(1)],
#         help_text=(
#             'The reference day (numerical value) in time '
#             'with which cycle day for any other following date '
#             'can be computed. E.g, 1 if today is Sunday as '
#             'first day of the cycle length. No need to always '
#             'update this except the cycle changes.'
#         )
#     )
#     ref_cycle_date = models.DateField(
#         help_text=(
#             'The reference date in time with which cycle day '
#             'for any other following date can be computed. '
#             'E.g, 1 if today is Sunday as first day of the '
#             'cycle length. No need to always '
#             'update this except the cycle changes.'
#         )
#     )
#     inactive_weekdays = models.CharField(
#         max_length=13,  # At max., we would have '0,1,2,3,4,5,6'
#         blank=True,
#         validators=[validate_comma_separated_integer_list]
#     )
#     vendors = models.ManyToManyField(Vendor, through='VendorService')
#     is_active = models.BooleanField(default=True)
#     description = models.TextField(blank=True)
#     admins = models.ManyToManyField(User, through='TimetableManagement')
# 
#     slugify_field = 'name'
# 
#     def clean(self):
#         # Ensure ref_cycle_day and cycle_length are not None before compare
#         if self.ref_cycle_day and self.cycle_length:
#             if self.ref_cycle_day > self.cycle_length:
#                 raise ValidationError(_(
#                     'Ensure Ref cycle day is not greater than Cycle length.')
#                 )
# 
#         super().clean()
# 
#     def save(self, *args, **kwargs):
#         # Calling full_clean instead of clean to ensure validators are called
#         self.full_clean()
#         return super().save(*args, **kwargs)
# 
#     def __str__(self):
#         return self.name
# 
#     def calculate_cycle_day(self, date):
#         days_interval = (date - self.ref_cycle_date).days
# 
#         if days_interval < 0:
#             raise ValidationError(
#                 _('Supply a date later than or equal to {}'.format(self.ref_cycle_date))
#             )
# 
#         cycle_day = (((days_interval % self.cycle_length) + self.ref_cycle_day)
#                      % self.cycle_length)
# 
#         if cycle_day == 0:
#             cycle_day = self.cycle_length
# 
#         return cycle_day
# 
#     def get_vendors(self, date):
#         return [vendor for vendor in Vendor.objects.filter(
#             timetable__slug=self.slug,
#             vendorservice__start_date__lte=date,
#             vendorservice__end_date__gte=date
#         )]
# 
#     def is_timetable_inactive_this_day(self, date):
#         return str(date.weekday()) in self.inactive_weekdays
# 
# Path: app/api/cruds/vendor_crud.py
# class VendorNode(DjangoObjectType):
#     """API functionality for vendor model. """
# 
#     original_id = graphene.Int()
# 
#     class Meta:
#         model = Vendor
#         interfaces = (graphene.relay.Node,)
# 
#     def resolve_original_id(self, args, context, info):
#         return self.id
# 
# Path: app/api/cruds/user_crud.py
# class UserNode(DjangoObjectType):
#     original_id = graphene.Int()
# 
#     class Meta:
#         model = User
#         interfaces = (graphene.relay.Node, )
# 
#     def resolve_original_id(self, args, context, info):
#         return self.id


import graphene
from graphene_django import DjangoObjectType, DjangoConnectionField
from django_filters import OrderingFilter, FilterSet
from app.timetables.models import Timetable
from .vendor_crud import VendorNode
from .user_crud import UserNode



class TimetableFilter(FilterSet):

    order_by = OrderingFilter(fields=[('id', 'id'),
                                      ('name', 'name'),
                                      ('cycle_length', 'cycle_length'),
                                      ('ref_cycle_length', 'ref_cycle_length'),
                                      ('ref_cycle_date', 'ref_cycle_date'),
                                      ('inactive_weekdays', 'inactive_weekdays'),
                                      ('is_active', 'is_active'),
                                      ('date_created', 'date_created'),
                                      ('date_modified', 'date_modified')]
                              )

    class Meta:
        fields = {
            'name': ['icontains']
        }
        model = Timetable


class TimetableNode(DjangoObjectType):
    original_id = graphene.Int()
    vendors = DjangoConnectionField(lambda: VendorNode)
    admins = DjangoConnectionField(lambda: UserNode)

    class Meta:

# Path: app/timetables/models.py
# class Timetable(SlugifyMixin, TimestampMixin):
#     """
#     Central model of the platform.
# 
#     It represents/encapsulates the entire structure and
#     scheduling of meals, menu-items, dishes, courses etc,
#     served at a location, to a team or the entire organisation.
#     """
# 
#     name = models.CharField(max_length=255, verbose_name='Timetable Name')
#     slug = models.SlugField(max_length=255, unique=True, null=True, editable=False)
#     cycle_length = models.PositiveSmallIntegerField(
#         validators=[MinValueValidator(1)],
#         help_text=(
#             'Number of days in which the menu timetable is repeated '
#             'after a period of time. E.g, A cycle length of '
#             '14 days (2 weeks) including the inactive weekdays '
#             'like weekends after which the food schedule is repeated.'
#         )
#     )
#     ref_cycle_day = models.PositiveSmallIntegerField(
#         validators=[MinValueValidator(1)],
#         help_text=(
#             'The reference day (numerical value) in time '
#             'with which cycle day for any other following date '
#             'can be computed. E.g, 1 if today is Sunday as '
#             'first day of the cycle length. No need to always '
#             'update this except the cycle changes.'
#         )
#     )
#     ref_cycle_date = models.DateField(
#         help_text=(
#             'The reference date in time with which cycle day '
#             'for any other following date can be computed. '
#             'E.g, 1 if today is Sunday as first day of the '
#             'cycle length. No need to always '
#             'update this except the cycle changes.'
#         )
#     )
#     inactive_weekdays = models.CharField(
#         max_length=13,  # At max., we would have '0,1,2,3,4,5,6'
#         blank=True,
#         validators=[validate_comma_separated_integer_list]
#     )
#     vendors = models.ManyToManyField(Vendor, through='VendorService')
#     is_active = models.BooleanField(default=True)
#     description = models.TextField(blank=True)
#     admins = models.ManyToManyField(User, through='TimetableManagement')
# 
#     slugify_field = 'name'
# 
#     def clean(self):
#         # Ensure ref_cycle_day and cycle_length are not None before compare
#         if self.ref_cycle_day and self.cycle_length:
#             if self.ref_cycle_day > self.cycle_length:
#                 raise ValidationError(_(
#                     'Ensure Ref cycle day is not greater than Cycle length.')
#                 )
# 
#         super().clean()
# 
#     def save(self, *args, **kwargs):
#         # Calling full_clean instead of clean to ensure validators are called
#         self.full_clean()
#         return super().save(*args, **kwargs)
# 
#     def __str__(self):
#         return self.name
# 
#     def calculate_cycle_day(self, date):
#         days_interval = (date - self.ref_cycle_date).days
# 
#         if days_interval < 0:
#             raise ValidationError(
#                 _('Supply a date later than or equal to {}'.format(self.ref_cycle_date))
#             )
# 
#         cycle_day = (((days_interval % self.cycle_length) + self.ref_cycle_day)
#                      % self.cycle_length)
# 
#         if cycle_day == 0:
#             cycle_day = self.cycle_length
# 
#         return cycle_day
# 
#     def get_vendors(self, date):
#         return [vendor for vendor in Vendor.objects.filter(
#             timetable__slug=self.slug,
#             vendorservice__start_date__lte=date,
#             vendorservice__end_date__gte=date
#         )]
# 
#     def is_timetable_inactive_this_day(self, date):
#         return str(date.weekday()) in self.inactive_weekdays
# 
# Path: app/api/cruds/vendor_crud.py
# class VendorNode(DjangoObjectType):
#     """API functionality for vendor model. """
# 
#     original_id = graphene.Int()
# 
#     class Meta:
#         model = Vendor
#         interfaces = (graphene.relay.Node,)
# 
#     def resolve_original_id(self, args, context, info):
#         return self.id
# 
# Path: app/api/cruds/user_crud.py
# class UserNode(DjangoObjectType):
#     original_id = graphene.Int()
# 
#     class Meta:
#         model = User
#         interfaces = (graphene.relay.Node, )
# 
#     def resolve_original_id(self, args, context, info):
#         return self.id


# Path: app/api/cruds/timetable_crud.py
import graphene
from graphene_django import DjangoObjectType, DjangoConnectionField
from django_filters import OrderingFilter, FilterSet
from app.timetables.models import Timetable
from .vendor_crud import VendorNode
from .user_crud import UserNode




class TimetableFilter(FilterSet):

    order_by = OrderingFilter(fields=[('id', 'id'),
                                      ('name', 'name'),
                                      ('cycle_length', 'cycle_length'),
                                      ('ref_cycle_length', 'ref_cycle_length'),
                                      ('ref_cycle_date', 'ref_cycle_date'),
                                      ('inactive_weekdays', 'inactive_weekdays'),
                                      ('is_active', 'is_active'),
                                      ('date_created', 'date_created'),
                                      ('date_modified', 'date_modified')]
                              )

    class Meta:
        fields = {
            'name': ['icontains']
        }
        model = Timetable


class TimetableNode(DjangoObjectType):
    original_id = graphene.Int()
    vendors = DjangoConnectionField(lambda: VendorNode)
    admins = DjangoConnectionField(lambda: UserNode)

    class Meta:

        model = Timetable