# Path: app/reviews/models.py
# class Review(TimestampMixin):
#     """Model representing ratings and comments on served menu items."""
# 
#     EXCELLENT = 5
#     GOOD = 4
#     FAIR = 3
#     POOR = 2
#     TERRIBLE = 1
# 
#     RATINGS = (
#         (EXCELLENT, 'EXCELLENT'),
#         (GOOD, 'GOOD'),
#         (FAIR, 'FAIR'),
#         (POOR, 'POOR'),
#         (TERRIBLE, 'TERRIBLE')
#     )
# 
#     # Make nullable for anonymity of reviewers.
#     user = models.ForeignKey(
#         User, on_delete=models.SET_NULL, blank=True, null=True
#     )
#     # anonymity_id is just a hashed unique identifier for the reviewer used
#     # as a check prevent multiple reviews from one person
#     anonymity_id = models.CharField(blank=True, null=True, max_length=250)
#     serving = models.ForeignKey(Serving, on_delete=models.CASCADE)
#     value = models.PositiveSmallIntegerField(choices=RATINGS)
#     comment = models.TextField(blank=True)
# 
#     def __str__(self):
#         return '{}\'s review of {}'.format(
#             self.user or self.anonymity_id, self.serving
#         )
# 
#     def clean(self):
#         if self.user:
#             if self.__class__.objects.filter(
#                 user=self.user, serving=self.serving
#             ).exists():
#                 raise ValidationError(_('user and serving must be unique'))
#         if self.anonymity_id:
#             if self.__class__.objects.filter(
#                 anonymity_id=self.anonymity_id, serving=self.serving
#             ).exists():
#                 raise ValidationError(
#                     _('anonymity_id and serving must be unique')
#                 )
#         super().clean()
# 
#     def save(self, *args, **kwargs):
#         self.clean()
#         return super().save(*args, **kwargs)
# 
# Path: app/timetables/models.py
# class Serving(TimestampMixin):
#     """Model representing already served menu."""
# 
#     public_id = HashidField(
#         alphabet='0123456789abcdefghijklmnopqrstuvwxyz',
#         default=timestamp_seconds,
#         unique=True
#     )
#     menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
#     vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
#     date_served = models.DateField()
# 
#     def __str__(self):
#         return '{} served on {}'.format(self.menu_item, self.date_served)
# 
#     class Meta:
#         unique_together = ('menu_item', 'vendor', 'date_served')
# 
# Path: app/api/cruds/utils.py
# def get_errors(e):
#     # transform django errors to redux errors
#     # django: {"key1": [value1], {"key2": [value2]}}
#     # redux: ["key1", "value1", "key2", "value2"]
#     fields = e.message_dict.keys()
#     messages = ['; '.join(m) for m in e.message_dict.values()]
#     errors = [i for pair in zip(fields, messages) for i in pair]
#     return errors
# 
# def get_object(object_name, relayId, otherwise=None):
#     try:
#         return object_name.objects.get(pk=from_global_id(relayId)[1])
#     except:
#         return otherwise
# 
# def load_object(instance, args, exception=['id']):
#     if instance:
#         [setattr(instance, key, value) for key, value in args.items() if key not in exception]
# 
#     return instance


from django.core.exceptions import ValidationError
from graphene_django import DjangoObjectType
from django_filters import OrderingFilter, FilterSet
from app.reviews.models import Review
from app.timetables.models import Serving
from .utils import get_errors, get_object, load_object
import graphene
    class Input:
        id = graphene.String(required=True)
        value = graphene.String(required=True)
        comment = graphene.String(required=False)

    @classmethod
    def mutate_and_get_payload(cls, args, context, info):
        review = get_object(Review, args.get('id'))
        review = load_object(review, args)
        try:
            if review:
                review.full_clean()
                review.save()
            return cls(review=review)
        except ValidationError as e:
            return cls(review=review, errors=get_errors(e))


class DeleteReview(graphene.relay.ClientIDMutation):
    """API functionality to delete reviews."""

    review = graphene.Field(ReviewNode)
    deleted = graphene.Boolean()

    class Input:
        id = graphene.String(required=True)

    @classmethod
    def mutate_and_get_payload(cls, args, context, info):
        try:

# Path: app/reviews/models.py
# class Review(TimestampMixin):
#     """Model representing ratings and comments on served menu items."""
# 
#     EXCELLENT = 5
#     GOOD = 4
#     FAIR = 3
#     POOR = 2
#     TERRIBLE = 1
# 
#     RATINGS = (
#         (EXCELLENT, 'EXCELLENT'),
#         (GOOD, 'GOOD'),
#         (FAIR, 'FAIR'),
#         (POOR, 'POOR'),
#         (TERRIBLE, 'TERRIBLE')
#     )
# 
#     # Make nullable for anonymity of reviewers.
#     user = models.ForeignKey(
#         User, on_delete=models.SET_NULL, blank=True, null=True
#     )
#     # anonymity_id is just a hashed unique identifier for the reviewer used
#     # as a check prevent multiple reviews from one person
#     anonymity_id = models.CharField(blank=True, null=True, max_length=250)
#     serving = models.ForeignKey(Serving, on_delete=models.CASCADE)
#     value = models.PositiveSmallIntegerField(choices=RATINGS)
#     comment = models.TextField(blank=True)
# 
#     def __str__(self):
#         return '{}\'s review of {}'.format(
#             self.user or self.anonymity_id, self.serving
#         )
# 
#     def clean(self):
#         if self.user:
#             if self.__class__.objects.filter(
#                 user=self.user, serving=self.serving
#             ).exists():
#                 raise ValidationError(_('user and serving must be unique'))
#         if self.anonymity_id:
#             if self.__class__.objects.filter(
#                 anonymity_id=self.anonymity_id, serving=self.serving
#             ).exists():
#                 raise ValidationError(
#                     _('anonymity_id and serving must be unique')
#                 )
#         super().clean()
# 
#     def save(self, *args, **kwargs):
#         self.clean()
#         return super().save(*args, **kwargs)
# 
# Path: app/timetables/models.py
# class Serving(TimestampMixin):
#     """Model representing already served menu."""
# 
#     public_id = HashidField(
#         alphabet='0123456789abcdefghijklmnopqrstuvwxyz',
#         default=timestamp_seconds,
#         unique=True
#     )
#     menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
#     vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
#     date_served = models.DateField()
# 
#     def __str__(self):
#         return '{} served on {}'.format(self.menu_item, self.date_served)
# 
#     class Meta:
#         unique_together = ('menu_item', 'vendor', 'date_served')
# 
# Path: app/api/cruds/utils.py
# def get_errors(e):
#     # transform django errors to redux errors
#     # django: {"key1": [value1], {"key2": [value2]}}
#     # redux: ["key1", "value1", "key2", "value2"]
#     fields = e.message_dict.keys()
#     messages = ['; '.join(m) for m in e.message_dict.values()]
#     errors = [i for pair in zip(fields, messages) for i in pair]
#     return errors
# 
# def get_object(object_name, relayId, otherwise=None):
#     try:
#         return object_name.objects.get(pk=from_global_id(relayId)[1])
#     except:
#         return otherwise
# 
# def load_object(instance, args, exception=['id']):
#     if instance:
#         [setattr(instance, key, value) for key, value in args.items() if key not in exception]
# 
#     return instance


# Path: app/api/cruds/review_crud.py
from django.core.exceptions import ValidationError
from graphene_django import DjangoObjectType
from django_filters import OrderingFilter, FilterSet
from app.reviews.models import Review
from app.timetables.models import Serving
from .utils import get_errors, get_object, load_object
import graphene

    class Input:
        id = graphene.String(required=True)
        value = graphene.String(required=True)
        comment = graphene.String(required=False)

    @classmethod
    def mutate_and_get_payload(cls, args, context, info):
        review = get_object(Review, args.get('id'))
        review = load_object(review, args)
        try:
            if review:
                review.full_clean()
                review.save()
            return cls(review=review)
        except ValidationError as e:
            return cls(review=review, errors=get_errors(e))


class DeleteReview(graphene.relay.ClientIDMutation):
    """API functionality to delete reviews."""

    review = graphene.Field(ReviewNode)
    deleted = graphene.Boolean()

    class Input:
        id = graphene.String(required=True)

    @classmethod
    def mutate_and_get_payload(cls, args, context, info):
        try:

            review = get_object(Review, args.get('id'))