From e3f3efdf3b5e5b1e85bd0f2e8b7dbea261184a67 Mon Sep 17 00:00:00 2001 From: Prince Kumar Date: Sun, 6 Oct 2024 19:01:54 +0530 Subject: [PATCH] Fixed bugs --- api/utils/rebate_checker.py | 24 ++++++---- api/views.py | 26 +++++----- messWebsite/settings.py | 4 +- qrscan/admin.py | 23 +++++++-- qrscan/migrations/0002_meal_high_tea.py | 18 +++++++ qrscan/migrations/0003_messtimings.py | 22 +++++++++ .../0004_messtiming_delete_messtimings.py | 25 ++++++++++ qrscan/models.py | 41 ++++++++++++---- qrscan/templates/mess_card.html | 40 +++++++++------- qrscan/tests.py | 3 -- requirements.txt | 47 ++++--------------- 11 files changed, 178 insertions(+), 95 deletions(-) create mode 100644 qrscan/migrations/0002_meal_high_tea.py create mode 100644 qrscan/migrations/0003_messtimings.py create mode 100644 qrscan/migrations/0004_messtiming_delete_messtimings.py diff --git a/api/utils/rebate_checker.py b/api/utils/rebate_checker.py index ce79f8c..b2d211d 100644 --- a/api/utils/rebate_checker.py +++ b/api/utils/rebate_checker.py @@ -1,20 +1,26 @@ from django.utils import timezone -from home.models.students import Student, LongRebate, TodayRebate, Allocation +from home.models.students import Student, LongRebate, Rebate, Allocation def is_student_on_rebate(student: Student, allocation: Allocation): """ This function checks if the student is on rebate or not """ - long_rebate = LongRebate.objects.filter(email=student) today = timezone.localtime().date() - rebate_exists = TodayRebate.objects.filter(allocation_id=allocation.id).exists() - - if rebate_exists: + # Check if there is a TodayRebate for the given allocation + if Rebate.objects.filter( + allocation_id=allocation, + start_date__lte=today, + end_date__gte=today, + approved=True + ).exists(): return True - for r in long_rebate: - if r.start_date <= today <= r.end_date and r.approved: - return True - return False + # Check if there is an approved LongRebate for the student within the date range + return LongRebate.objects.filter( + email=student, + start_date__lte=today, + end_date__gte=today, + approved=True + ).exists() diff --git a/api/views.py b/api/views.py index bbac696..5944a67 100644 --- a/api/views.py +++ b/api/views.py @@ -7,7 +7,7 @@ from drf_yasg.utils import swagger_auto_schema from home.models import Allocation, Period -from qrscan.models import MessCard, Meal +from qrscan.models import MessCard, Meal, MessTiming from .permissions import IsStaff from .serializers import ( AllocationSerializer, PeriodSerializer, AllocationDetailSerializer, @@ -15,10 +15,6 @@ ) from .utils.rebate_checker import is_student_on_rebate -# Constants -BREAKFAST_END_TIME = timezone.datetime.strptime('11:00:00', '%H:%M:%S').time() -LUNCH_END_TIME = timezone.datetime.strptime('15:00:00', '%H:%M:%S').time() - class LogoutView(APIView): """ View to handle user logout. @@ -106,12 +102,15 @@ class QRVerifyUpdateView(APIView): permission_classes = [IsStaff] def _get_meal_type(self, time): - if time < BREAKFAST_END_TIME: - return 'breakfast' - elif time < LUNCH_END_TIME: - return 'lunch' - else: - return 'dinner' + meal_types = ['breakfast', 'lunch', 'high_tea', 'dinner'] + for meal_type in meal_types: + try: + meal_timing = MessTiming.objects.get(meal_type=meal_type) + if meal_timing.start_time <= time <= meal_timing.end_time: + return meal_type + except MessTiming.DoesNotExist: + raise ValueError(f"{meal_type.capitalize()} timings not found.") + return None def _filter_valid_cards(self, cards, meal_type): valid_cards = [] @@ -131,6 +130,8 @@ def _is_meal_recorded(self, card, meal_type): return True elif meal_type == 'lunch' and card.meal_set.filter(date=today, lunch=True).exists(): return True + elif meal_type == 'high_tea' and card.meal_set.filter(date=today, high_tea=True).exists(): + return True elif meal_type == 'dinner' and card.meal_set.filter(date=today, dinner=True).exists(): return True return False @@ -174,7 +175,6 @@ def post(self, request): date = timezone.localtime().date() time = timezone.localtime().time() meal, _ = Meal.objects.get_or_create(mess_card=card, date=date) - is_rebate = is_student_on_rebate(card.student, card.allocation) if card.allocation.period.end_date <= date: return Response({"success": False, "detail": "Not registered for current Period.", "mess_card": card_return_data}, status=status.HTTP_403_FORBIDDEN) @@ -182,7 +182,7 @@ def post(self, request): if card.allocation.caterer.name != request.user.username: return Response({"success": False, "detail": "Wrong caterer.", "mess_card": card_return_data}, status=status.HTTP_403_FORBIDDEN) - if is_rebate: + if is_student_on_rebate(card.student, card.allocation): return Response({"success": False, "detail": "Student is on rebate.", "mess_card": card_return_data}, status=status.HTTP_403_FORBIDDEN) meal_type = self._get_meal_type(time) diff --git a/messWebsite/settings.py b/messWebsite/settings.py index 1bb4096..31b80a3 100644 --- a/messWebsite/settings.py +++ b/messWebsite/settings.py @@ -18,9 +18,9 @@ SECRET_KEY = env("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True +DEBUG = env.bool("DEBUG", default=False) -ALLOWED_HOSTS = ["diningfee.iiti.ac.in", "127.0.0.1", "103.159.214.171", "*"] +ALLOWED_HOSTS = ["diningfee.iiti.ac.in", "127.0.0.1", "103.159.214.171"] CSRF_TRUSTED_ORIGINS = ["http://diningfee.iiti.ac.in", "https://diningfee.iiti.ac.in"] # Application definition diff --git a/qrscan/admin.py b/qrscan/admin.py index a909548..9fd8137 100644 --- a/qrscan/admin.py +++ b/qrscan/admin.py @@ -1,7 +1,8 @@ from django.contrib import admin -from .models import MessCard, Meal +from .models import MessCard, Meal, MessTiming # Admin configuration for MessCard model +@admin.register(MessCard) class MessCardAdmin(admin.ModelAdmin): list_display = ['id', 'allocation', 'student'] list_display_links = ['id', 'allocation', 'student'] @@ -11,7 +12,9 @@ class MessCardAdmin(admin.ModelAdmin): ordering = ['id'] list_per_page = 25 + # Admin configuration for Meal model +@admin.register(Meal) class MealAdmin(admin.ModelAdmin): list_display = ['id', 'mess_card', 'date', 'breakfast', 'lunch', 'dinner'] list_display_links = ['id', 'mess_card'] @@ -21,6 +24,18 @@ class MealAdmin(admin.ModelAdmin): ordering = ['date', 'id'] list_per_page = 25 -# Registering models with the admin site -admin.site.register(MessCard, MessCardAdmin) -admin.site.register(Meal, MealAdmin) + +# Admin configuration for MessTimings model +@admin.register(MessTiming) +class MessTimingsAdmin(admin.ModelAdmin): + list_display = ['meal_type', 'start_time', 'end_time'] + list_display_links = ['meal_type'] + search_fields = ('meal_type',) + list_filter = ('meal_type',) + ordering = ['meal_type'] + + def start_time(self, obj): + return obj.start_time.strftime('%H:%M') + + def end_time(self, obj): + return obj.end_time.strftime('%H:%M') diff --git a/qrscan/migrations/0002_meal_high_tea.py b/qrscan/migrations/0002_meal_high_tea.py new file mode 100644 index 0000000..854432d --- /dev/null +++ b/qrscan/migrations/0002_meal_high_tea.py @@ -0,0 +1,18 @@ +# Generated by Django 5.0.8 on 2024-10-06 12:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('qrscan', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='meal', + name='high_tea', + field=models.BooleanField(default=False, help_text='This contains the high tea status'), + ), + ] diff --git a/qrscan/migrations/0003_messtimings.py b/qrscan/migrations/0003_messtimings.py new file mode 100644 index 0000000..83163d9 --- /dev/null +++ b/qrscan/migrations/0003_messtimings.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.8 on 2024-10-06 13:00 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('qrscan', '0002_meal_high_tea'), + ] + + operations = [ + migrations.CreateModel( + name='MessTimings', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('meal_type', models.CharField(choices=[('breakfast', 'Breakfast'), ('lunch', 'Lunch'), ('high_tea', 'High Tea'), ('dinner', 'Dinner')], help_text='This contains the meal type', max_length=10)), + ('start_time', models.TimeField(blank=True, help_text='This contains the start time', null=True)), + ('end_time', models.TimeField(blank=True, help_text='This contains the end time', null=True)), + ], + ), + ] diff --git a/qrscan/migrations/0004_messtiming_delete_messtimings.py b/qrscan/migrations/0004_messtiming_delete_messtimings.py new file mode 100644 index 0000000..c48000c --- /dev/null +++ b/qrscan/migrations/0004_messtiming_delete_messtimings.py @@ -0,0 +1,25 @@ +# Generated by Django 5.0.8 on 2024-10-06 13:14 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('qrscan', '0003_messtimings'), + ] + + operations = [ + migrations.CreateModel( + name='MessTiming', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('meal_type', models.CharField(choices=[('breakfast', 'Breakfast'), ('lunch', 'Lunch'), ('high_tea', 'High Tea'), ('dinner', 'Dinner')], help_text='This contains the meal type', max_length=10, unique=True)), + ('start_time', models.TimeField(blank=True, help_text='This contains the start time', null=True)), + ('end_time', models.TimeField(blank=True, help_text='This contains the end time', null=True)), + ], + ), + migrations.DeleteModel( + name='MessTimings', + ), + ] diff --git a/qrscan/models.py b/qrscan/models.py index 2c1afda..4d2e216 100644 --- a/qrscan/models.py +++ b/qrscan/models.py @@ -2,7 +2,6 @@ from io import BytesIO from PIL import Image import qrcode -import secrets from django.core.files import File from django.db import models @@ -10,10 +9,6 @@ from home.models import Allocation, Student -def generate_secret_key(): - return secrets.token_hex(32) - - class MessCard(models.Model): id = models.UUIDField( primary_key=True, @@ -106,6 +101,10 @@ class Meal(models.Model): help_text="This contains the lunch status", default=False ) + high_tea = models.BooleanField( + help_text="This contains the high tea status", + default=False + ) dinner = models.BooleanField( help_text="This contains the dinner status", default=False @@ -117,7 +116,31 @@ class Meta: def __str__(self): return f"{self.mess_card.allocation.student_id} - {self.date}" - def save(self, *args, **kwargs): - if not self.mess_card: - self.mess_card = MessCard.objects.get(allocation=self.mess_card.allocation) - super().save(*args, **kwargs) + +class MessTiming(models.Model): + MEAL_TYPES = [ + ('breakfast', 'Breakfast'), + ('lunch', 'Lunch'), + ('high_tea', 'High Tea'), + ('dinner', 'Dinner') + ] + + meal_type = models.CharField( + max_length=10, + choices=MEAL_TYPES, + help_text="This contains the meal type", + unique=True, + ) + start_time = models.TimeField( + help_text="This contains the start time", + null=True, + blank=True + ) + end_time = models.TimeField( + help_text="This contains the end time", + null=True, + blank=True + ) + + def __str__(self): + return f"{self.meal_type} Timings" diff --git a/qrscan/templates/mess_card.html b/qrscan/templates/mess_card.html index a062cd3..cf536e2 100644 --- a/qrscan/templates/mess_card.html +++ b/qrscan/templates/mess_card.html @@ -6,7 +6,6 @@ rel="stylesheet" /> - {% endblock %} {%block body%}
@@ -26,7 +25,9 @@
{{ student.name }}
Roll Number: {{ student.roll_no }}
Email: {{ user.email }}
Department: {{ student.department }}
- Hostel and Room: {{ student.hostel }} {{ student.room_no }}
+ Hostel and Room: {{ student.hostel }} {{ student.room_no }}
QR Code{{ student.name }} width="100%" />
-
www.reallygreatsite.com
- +
- +
diff --git a/qrscan/tests.py b/qrscan/tests.py index 7ce503c..e69de29 100644 --- a/qrscan/tests.py +++ b/qrscan/tests.py @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/requirements.txt b/requirements.txt index 18467e0..6cc8ea5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,44 +1,13 @@ APScheduler==3.10.4 -asgiref==3.8.1 -certifi==2024.8.30 -cffi==1.17.1 -charset-normalizer==3.3.2 cloudinary==1.41.0 -cryptography==43.0.1 -defusedxml==0.7.1 -diff-match-patch==20230430 Django==5.0.8 -django-admin-logs==1.0.2 -django-allauth==0.54.0 -django-apscheduler==0.7.0 -django-cloudinary-storage==0.3.0 -django-environ==0.10.0 -django-import-export==3.2.0 +django_allauth==0.54.0 +django_apscheduler==0.7.0 +django_environ==0.10.0 +django_import_export==3.2.0 djangorestframework==3.15.2 -drf-yasg==1.21.7 -et-xmlfile==1.1.0 -gunicorn==22.0.0 -idna==3.10 -inflection==0.5.1 -oauthlib==3.2.2 -odfpy==1.4.1 -openpyxl==3.1.5 -packaging==24.1 -pillow==10.4.0 -pycparser==2.22 -PyJWT==2.9.0 -python3-openid==3.2.0 -pytz==2024.2 -PyYAML==6.0.2 +drf_yasg==1.21.7 +pandas==2.2.3 +Pillow==10.4.0 qrcode==8.0 -requests==2.32.3 -requests-oauthlib==2.0.0 -six==1.16.0 -sqlparse==0.5.1 -tablib==3.6.1 -tzlocal==5.2 -uritemplate==4.1.1 -urllib3==2.2.3 -whitenoise==6.4.0 -xlrd==2.0.1 -xlwt==1.3.0 +Requests==2.32.3