diff --git a/account/serializers.py b/account/serializers.py index 4df4e89..5810f1d 100644 --- a/account/serializers.py +++ b/account/serializers.py @@ -248,7 +248,7 @@ class JuniorSerializer(serializers.ModelSerializer): """Meta info""" model = Junior fields = ['id', 'auth_token', 'refresh_token', 'email', 'first_name', 'last_name', 'country_code', - 'phone', 'gender', 'dob', 'guardian_code', 'referral_code','is_active', + 'phone', 'gender', 'dob', 'guardian_code', 'referral_code','is_active', 'is_password_set', 'is_complete_profile', 'created_at', 'image', 'updated_at', 'user_type', 'country_name','is_invited'] class EmailVerificationSerializer(serializers.ModelSerializer): diff --git a/account/templates/templated_email/junior_notification_email.email b/account/templates/templated_email/junior_notification_email.email index ea9c214..9f489ce 100644 --- a/account/templates/templated_email/junior_notification_email.email +++ b/account/templates/templated_email/junior_notification_email.email @@ -15,7 +15,7 @@

- You are receiving this email for join the ZOD bank platform. Please use {{ url }} link to join the platform. + You are receiving this email for joining the ZOD bank platform. Please use {{ url }} link to join the platform.
Your credentials are:- username = {{email}} and password {{password}}

Below are the steps to complete the account and how to use this platform.

diff --git a/base/constants.py b/base/constants.py index d8ca8a8..29da8db 100644 --- a/base/constants.py +++ b/base/constants.py @@ -24,7 +24,7 @@ NUMBER = { 'sixteen': 16, 'seventeen': 17, 'eighteen': 18, 'nineteen': 19, 'twenty': 20, 'twenty_one': 21, 'twenty_two': 22,'twenty_three': 23, 'twenty_four': 24, 'twenty_five': 25, 'thirty': 30, 'forty': 40, 'fifty': 50, 'sixty': 60, 'seventy': 70, 'eighty': 80, 'ninty': 90, - 'ninety_nine': 99, 'hundred': 100, + 'ninety_nine': 99, 'hundred': 100, 'thirty_six_hundred': 3600 } diff --git a/guardian/migrations/0016_juniortask_completed_on_juniortask_rejected_on_and_more.py b/guardian/migrations/0016_juniortask_completed_on_juniortask_rejected_on_and_more.py new file mode 100644 index 0000000..2223e0e --- /dev/null +++ b/guardian/migrations/0016_juniortask_completed_on_juniortask_rejected_on_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.2 on 2023-07-18 07:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('guardian', '0015_alter_guardian_options_alter_juniortask_options'), + ] + + operations = [ + migrations.AddField( + model_name='juniortask', + name='completed_on', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='juniortask', + name='rejected_on', + field=models.DateTimeField(blank=True, null=True), + ), + migrations.AddField( + model_name='juniortask', + name='requested_on', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/guardian/models.py b/guardian/models.py index 1746c44..b4a31dd 100644 --- a/guardian/models.py +++ b/guardian/models.py @@ -108,6 +108,12 @@ class JuniorTask(models.Model): is_active = models.BooleanField(default=True) """Task is approved or not""" is_approved = models.BooleanField(default=False) + """request task on particular date""" + requested_on = models.DateTimeField(auto_now_add=False, null=True, blank=True) + """reject task on particular date""" + rejected_on = models.DateTimeField(auto_now_add=False, null=True, blank=True) + """complete task on particular date""" + completed_on = models.DateTimeField(auto_now_add=False, null=True, blank=True) """Profile created and updated time""" created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) diff --git a/guardian/serializers.py b/guardian/serializers.py index ae96969..9459334 100644 --- a/guardian/serializers.py +++ b/guardian/serializers.py @@ -6,6 +6,7 @@ from rest_framework import serializers from rest_framework_simplejwt.tokens import RefreshToken from django.db import transaction from django.contrib.auth.models import User +from datetime import datetime, time """Import Django app""" # Import guardian's model, # Import junior's model, @@ -23,6 +24,8 @@ from junior.serializers import JuniorDetailSerializer from base.messages import ERROR_CODE, SUCCESS_CODE from base.constants import NUMBER, JUN, ZOD, GRD from junior.models import Junior, JuniorPoints +from .utils import real_time, convert_timedelta_into_datetime + # In this serializer file @@ -201,11 +204,27 @@ class TaskDetailsSerializer(serializers.ModelSerializer): """Task detail serializer""" junior = JuniorDetailSerializer() + remaining_time = serializers.SerializerMethodField('get_remaining_time') + + def get_remaining_time(self, obj): + """ remaining time to complete task""" + due_date_datetime = datetime.combine(obj.due_date, datetime.max.time()) + # fetch real time + current_datetime = real_time() + # Perform the subtraction + if due_date_datetime > current_datetime: + time_difference = due_date_datetime - current_datetime + time_only = convert_timedelta_into_datetime(time_difference) + return str(time_difference.days) + ' days ' + str(time_only) + return str(NUMBER['zero']) + ' days ' + '00:00:00:00000' + + class Meta(object): """Meta info""" model = JuniorTask fields = ['id', 'guardian', 'task_name', 'task_description', 'points', 'due_date','default_image', 'image', - 'junior', 'task_status', 'is_active', 'created_at','updated_at'] + 'requested_on', 'rejected_on', 'completed_on', + 'junior', 'task_status', 'is_active', 'remaining_time', 'created_at','updated_at'] class TopJuniorSerializer(serializers.ModelSerializer): @@ -303,12 +322,14 @@ class ApproveTaskSerializer(serializers.ModelSerializer): instance.task_status = str(NUMBER['five']) instance.is_approved = True junior_data.total_task_points = junior_data.total_task_points + instance.points + instance.completed_on = datetime.today() junior_data.save() else: # reject the task instance.task_status = str(NUMBER['three']) instance.is_approved = False junior_data.total_task_points = junior_data.total_task_points - instance.points + instance.rejected_on = datetime.today() junior_data.save() instance.save() return instance diff --git a/guardian/utils.py b/guardian/utils.py index c3f9f39..8619b66 100644 --- a/guardian/utils.py +++ b/guardian/utils.py @@ -5,6 +5,12 @@ import oss2 from django.conf import settings """Import tempfile""" import tempfile +# Import date time module's function +from datetime import datetime, time +# Import real time client module +import ntplib +# import Number constant +from base.constants import NUMBER # Define upload image on # ali baba cloud @@ -13,6 +19,8 @@ import tempfile # then check bucket name # then upload on ali baba # bucket and reform the image url""" +# fetch real time data without depend on system time +# convert time delta into date time object def upload_image_to_alibaba(image, filename): """upload image on oss alibaba bucket""" @@ -30,3 +38,22 @@ def upload_image_to_alibaba(image, filename): new_filename = filename.replace(' ', '%20') return f"https://{settings.ALIYUN_OSS_BUCKET_NAME}.{settings.ALIYUN_OSS_ENDPOINT}/{new_filename}" +def real_time(): + # Fetch real time. + # time is not depend on system time + # Get the current datetime + ntp_client = ntplib.NTPClient() + ntp_server = 'pool.ntp.org' + response = ntp_client.request(ntp_server) + current_datetime = datetime.fromtimestamp(response.tx_time) + return current_datetime + +def convert_timedelta_into_datetime(time_difference): + # convert timedelta into datetime format + hours = time_difference.seconds // NUMBER['thirty_six_hundred'] + minutes = (time_difference.seconds // NUMBER['sixty']) % NUMBER['sixty'] + seconds = time_difference.seconds % NUMBER['sixty'] + microseconds = time_difference.microseconds + # Create a new time object with the extracted time components + time_only = time(hours, minutes, seconds, microseconds) + return time_only diff --git a/guardian/views.py b/guardian/views.py index 3450be7..ec14ef7 100644 --- a/guardian/views.py +++ b/guardian/views.py @@ -119,9 +119,16 @@ class TaskListAPIView(viewsets.ModelViewSet): def list(self, request, *args, **kwargs): """Create guardian profile""" status_value = self.request.GET.get('status') - if str(status_value) == '0': + search = self.request.GET.get('search') + if search and str(status_value) == '0': + queryset = JuniorTask.objects.filter(guardian__user=request.user, + task_name__icontains=search).order_by('due_date', 'created_at') + elif search and str(status_value) != '0': + queryset = JuniorTask.objects.filter(guardian__user=request.user,task_name__icontains=search, + task_status=status_value).order_by('due_date', 'created_at') + if search is None and str(status_value) == '0': queryset = JuniorTask.objects.filter(guardian__user=request.user).order_by('due_date', 'created_at') - else: + elif search is None and str(status_value) != '0': queryset = JuniorTask.objects.filter(guardian__user=request.user, task_status=status_value).order_by('due_date','created_at') paginator = self.pagination_class() diff --git a/junior/migrations/0014_junior_is_password_set.py b/junior/migrations/0014_junior_is_password_set.py new file mode 100644 index 0000000..a71e6c0 --- /dev/null +++ b/junior/migrations/0014_junior_is_password_set.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.2 on 2023-07-18 09:28 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('junior', '0013_alter_junior_options_alter_juniorpoints_options'), + ] + + operations = [ + migrations.AddField( + model_name='junior', + name='is_password_set', + field=models.BooleanField(default=True), + ), + ] diff --git a/junior/models.py b/junior/models.py index 41dddc8..f4ef488 100644 --- a/junior/models.py +++ b/junior/models.py @@ -63,6 +63,8 @@ class Junior(models.Model): is_invited = models.BooleanField(default=False) # Profile activity""" is_active = models.BooleanField(default=True) + # check password is set or not + is_password_set = models.BooleanField(default=True) # junior profile is complete or not""" is_complete_profile = models.BooleanField(default=False) # passcode of the junior profile""" diff --git a/junior/serializers.py b/junior/serializers.py index 013cd58..ef1b5de 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -277,12 +277,13 @@ class AddJuniorSerializer(serializers.ModelSerializer): relationship=validated_data.get('relationship'), junior_code=generate_code(JUN, user_data.id), referral_code=generate_code(ZOD, user_data.id), - referral_code_used=guardian_data.referral_code) + referral_code_used=guardian_data.referral_code, + is_password_set=False, is_verified=True) """Generate otp""" otp_value = generate_otp() expiry_time = timezone.now() + timezone.timedelta(days=1) UserEmailOtp.objects.create(email=email, otp=otp_value, - user_type='1', expired_at=expiry_time) + user_type='1', expired_at=expiry_time, is_verified=True) """Send email to the register user""" send_otp_email(email, otp_value) """Notification email""" diff --git a/junior/views.py b/junior/views.py index 0e1de75..50e42be 100644 --- a/junior/views.py +++ b/junior/views.py @@ -197,9 +197,16 @@ class JuniorTaskListAPIView(viewsets.ModelViewSet): def list(self, request, *args, **kwargs): """Create guardian profile""" status_value = self.request.GET.get('status') - if str(status_value) == '0': + search = self.request.GET.get('search') + if search and str(status_value) == '0': + queryset = JuniorTask.objects.filter(junior__auth=request.user, + task_name__icontains=search).order_by('due_date', 'created_at') + elif search and str(status_value) != '0': + queryset = JuniorTask.objects.filter(junior__auth=request.user, task_name__icontains=search, + task_status=status_value).order_by('due_date', 'created_at') + if search is None and str(status_value) == '0': queryset = JuniorTask.objects.filter(junior__auth=request.user).order_by('due_date', 'created_at') - else: + elif search is None and str(status_value) != '0': queryset = JuniorTask.objects.filter(junior__auth=request.user, task_status=status_value).order_by('due_date','created_at') paginator = self.pagination_class() diff --git a/zod_bank/settings.py b/zod_bank/settings.py index b107ffd..9961b80 100644 --- a/zod_bank/settings.py +++ b/zod_bank/settings.py @@ -104,11 +104,12 @@ REST_FRAMEWORK = { 'rest_framework.authentication.BasicAuthentication', 'rest_framework_simplejwt.authentication.JWTAuthentication',], 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', - 'PAGE_SIZE': 5, + 'PAGE_SIZE': 10, } # define jwt token SIMPLE_JWT = { - 'ACCESS_TOKEN_LIFETIME': timedelta(hours=2, minutes=59, seconds=59, microseconds=999999), + # 'ACCESS_TOKEN_LIFETIME': timedelta(hours=2, minutes=59, seconds=59, microseconds=999999), + 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5), 'REFRESH_TOKEN_LIFETIME': timedelta(hours=71, minutes=59, seconds=59, microseconds=999999), } # Database