From bc5440bf8f7cf018457ff974a006e32a33ec30a6 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Mon, 12 Jul 2021 21:52:20 +0530 Subject: [PATCH 01/98] Model Changes --- server/api/__init__.py | 0 server/api/admin.py | 3 +++ server/api/apps.py | 5 +++++ server/api/migrations/__init__.py | 0 server/api/models.py | 3 +++ server/api/tests.py | 3 +++ server/api/views.py | 3 +++ server/attendance/models.py | 9 +++++++-- server/attendance/serializers.py | 18 ++++++++++++++++++ server/attendance/views.py | 4 ++++ 10 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 server/api/__init__.py create mode 100644 server/api/admin.py create mode 100644 server/api/apps.py create mode 100644 server/api/migrations/__init__.py create mode 100644 server/api/models.py create mode 100644 server/api/tests.py create mode 100644 server/api/views.py create mode 100644 server/attendance/serializers.py diff --git a/server/api/__init__.py b/server/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/api/admin.py b/server/api/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/server/api/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/server/api/apps.py b/server/api/apps.py new file mode 100644 index 0000000..d87006d --- /dev/null +++ b/server/api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ApiConfig(AppConfig): + name = 'api' diff --git a/server/api/migrations/__init__.py b/server/api/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/api/models.py b/server/api/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/server/api/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/server/api/tests.py b/server/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/server/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/server/api/views.py b/server/api/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/server/api/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/server/attendance/models.py b/server/attendance/models.py index 6446089..708984f 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -14,12 +14,17 @@ def __str__(self): return f'{self.sheet_created} -> {self.verified}' -class Attendance(models.Model): +class Gunmen(models.Model): first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) + vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + + + +class Attendance(models.Model): entry_time = models.DateTimeField(default=datetime.now) exit_time = models.DateTimeField(blank=True,null=True) - vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + gunmen = models.ForeignKey(Gunmen, on_delete=models.SET_NULL, null=True, blank=True) added_by = models.ForeignKey(User, on_delete=models.SET_NULL,null=True, blank=True) branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) attendance_sheet = models.ForeignKey(AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py new file mode 100644 index 0000000..0a2bc7a --- /dev/null +++ b/server/attendance/serializers.py @@ -0,0 +1,18 @@ +from rest_framework import serializers +from .models import Attendance + + +class AttendanceSerializer(serializers.ModelSerializer): + class Meta: + model = Attendance + fields = ('first_name', 'last_name', 'entry_time', 'exit_time', 'vendor') + + # first_name = models.CharField(max_length=200) + # last_name = models.CharField(max_length=200) + # entry_time = models.DateTimeField(default=datetime.now) + # exit_time = mod:wq + # els.DateTimeField(blank=True,null=True) + # vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + # added_by = models.ForeignKey(User, on_delete=models.SET_NULL,null=True, blank=True) + # branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) + # attendance_sheet = models.ForeignKey(AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True) diff --git a/server/attendance/views.py b/server/attendance/views.py index 91ea44a..f2562ea 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -1,3 +1,7 @@ from django.shortcuts import render # Create your views here. + +# ListView for Gunmen +# ListView for VEhicles + From 049e9e9b0527810669d5441c311907de15273586 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Mon, 12 Jul 2021 21:59:43 +0530 Subject: [PATCH 02/98] updated requirements.txt --- server/requirements.txt | Bin 214 -> 498 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/requirements.txt b/server/requirements.txt index e896f9c3d30ddc9a931e7bbd8bf929cbca322263..1c1c05bb028b613a7ed5f5efb484b68b5ff03710 100644 GIT binary patch literal 498 zcmb7ByAFat5S-e?PvHXiZ0xM8EKIB~3cdk35&|Eu&h9CiXk#`TlAGC?-Qj+-aM{_O^HMwXoCgTSScp?NlHHJ0u2@0Cn71!oW~rl)GT<5B$p`1 U=lf#Rn#${c$?cNzo9Qoo03nM^!2kdN literal 214 zcmZvWyAFde3;_513sw^7WAWChQ-?~OBQP{H5Nbz4^y{0Tjvdcu+2>^NOg&-^H5kF(0`35aNn>22*IeKJGarzcp&v(r1q{8RQ)n$3lp?DD&#)(k&_SKC|izPvk=g From 3659ebbfee60b5e3d3fb4b826c58a5ac1c4683fe Mon Sep 17 00:00:00 2001 From: mustankap Date: Mon, 12 Jul 2021 22:51:40 +0530 Subject: [PATCH 03/98] models serializer added --- Pipfile | 11 +++++ server/attendance/admin.py | 12 ++++-- .../migrations/0002_auto_20210712_1636.py | 41 +++++++++++++++++++ .../migrations/0003_auto_20210712_1712.py | 23 +++++++++++ server/attendance/models.py | 14 ++----- server/attendance/serializers.py | 15 +++---- server/attendance/views.py | 18 +++++++- server/vendors/migrations/0002_gunmen.py | 23 +++++++++++ server/vendors/models.py | 13 +++++- server/vendors/serializers.py | 16 ++++++++ 10 files changed, 161 insertions(+), 25 deletions(-) create mode 100644 Pipfile create mode 100644 server/attendance/migrations/0002_auto_20210712_1636.py create mode 100644 server/attendance/migrations/0003_auto_20210712_1712.py create mode 100644 server/vendors/migrations/0002_gunmen.py create mode 100644 server/vendors/serializers.py diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..5d44a48 --- /dev/null +++ b/Pipfile @@ -0,0 +1,11 @@ +[[source]] +url = "https://pypi.python.org/simple" +verify_ssl = true +name = "pypi" + +[packages] + +[dev-packages] + +[requires] +python_version = "3.8" diff --git a/server/attendance/admin.py b/server/attendance/admin.py index 91d72c3..c433734 100644 --- a/server/attendance/admin.py +++ b/server/attendance/admin.py @@ -7,11 +7,16 @@ class AttendanceSheetAdmin(admin.ModelAdmin): list_display_links = ('id', 'sheet_created') list_per_page = 20 +class GunmenAdmin(admin.ModelAdmin): + list_display = ('id', 'first_name','last_name', 'vendor') + list_display_links = ('id', 'vendor') + search_fields = ('first_name', 'last_name', 'vendor') + list_per_page = 20 class AttendanceAdmin(admin.ModelAdmin): - list_display = ('id', 'first_name', 'last_name','entry_time', 'exit_time', 'vendor', 'branch_id') - list_display_links = ('id', 'first_name', 'last_name') - search_fields = ('first_name', 'last_name','vendor') + list_display = ('id', 'gunmen','entry_time', 'exit_time', 'branch_id') + list_display_links = ('id', 'gunmen') + search_fields = ('gunmen',) list_per_page = 20 class IssueAdmin(admin.ModelAdmin): @@ -22,3 +27,4 @@ class IssueAdmin(admin.ModelAdmin): admin.site.register(Attendance, AttendanceAdmin) admin.site.register(AttendanceSheet, AttendanceSheetAdmin) admin.site.register(Issue, IssueAdmin) +admin.site.register(Gunmen, GunmenAdmin) diff --git a/server/attendance/migrations/0002_auto_20210712_1636.py b/server/attendance/migrations/0002_auto_20210712_1636.py new file mode 100644 index 0000000..06bf869 --- /dev/null +++ b/server/attendance/migrations/0002_auto_20210712_1636.py @@ -0,0 +1,41 @@ +# Generated by Django 3.0.4 on 2021-07-12 16:36 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('vendors', '0001_initial'), + ('attendance', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='attendance', + name='first_name', + ), + migrations.RemoveField( + model_name='attendance', + name='last_name', + ), + migrations.RemoveField( + model_name='attendance', + name='vendor', + ), + migrations.CreateModel( + name='Gunmen', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=200)), + ('last_name', models.CharField(max_length=200)), + ('vendor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vendors.Vendor')), + ], + ), + migrations.AddField( + model_name='attendance', + name='gunmen', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='attendance.Gunmen'), + ), + ] diff --git a/server/attendance/migrations/0003_auto_20210712_1712.py b/server/attendance/migrations/0003_auto_20210712_1712.py new file mode 100644 index 0000000..73f2f14 --- /dev/null +++ b/server/attendance/migrations/0003_auto_20210712_1712.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.4 on 2021-07-12 17:12 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('vendors', '0002_gunmen'), + ('attendance', '0002_auto_20210712_1636'), + ] + + operations = [ + migrations.AlterField( + model_name='attendance', + name='gunmen', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vendors.Gunmen'), + ), + migrations.DeleteModel( + name='Gunmen', + ), + ] diff --git a/server/attendance/models.py b/server/attendance/models.py index 708984f..e189393 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -1,6 +1,6 @@ from django.db import models from django.contrib.auth.models import User -from vendors.models import Vendor +from vendors.models import Vendor, Gunmen from users.models import Branch from datetime import datetime @@ -14,13 +14,6 @@ def __str__(self): return f'{self.sheet_created} -> {self.verified}' -class Gunmen(models.Model): - first_name = models.CharField(max_length=200) - last_name = models.CharField(max_length=200) - vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) - - - class Attendance(models.Model): entry_time = models.DateTimeField(default=datetime.now) exit_time = models.DateTimeField(blank=True,null=True) @@ -29,8 +22,9 @@ class Attendance(models.Model): branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) attendance_sheet = models.ForeignKey(AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True) - def __str__(self) -> str: - return f'{self.first_name} {self.last_name}' + def __str__(self): + return f'{self.gunmen.first_name} {self.gunmen.last_name}' + class Issue(models.Model): comment = models.CharField(max_length=200) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 0a2bc7a..5ffbd4a 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,18 +1,13 @@ from rest_framework import serializers + +from vendors.serializers import VendorSerializer, GunmenSerializer from .models import Attendance class AttendanceSerializer(serializers.ModelSerializer): + gunmen = GunmenSerializer() + class Meta: model = Attendance - fields = ('first_name', 'last_name', 'entry_time', 'exit_time', 'vendor') + fields = ['gunmen', 'entry_time', 'exit_time'] - # first_name = models.CharField(max_length=200) - # last_name = models.CharField(max_length=200) - # entry_time = models.DateTimeField(default=datetime.now) - # exit_time = mod:wq - # els.DateTimeField(blank=True,null=True) - # vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) - # added_by = models.ForeignKey(User, on_delete=models.SET_NULL,null=True, blank=True) - # branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) - # attendance_sheet = models.ForeignKey(AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True) diff --git a/server/attendance/views.py b/server/attendance/views.py index f2562ea..cf0e041 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -1,7 +1,23 @@ from django.shortcuts import render +from rest_framework import mixins +from rest_framework import generics +from attendance.serializers import AttendanceSerializer +from attendance.models import Attendance # Create your views here. # ListView for Gunmen -# ListView for VEhicles +class GunmenList(generics.ListAPIView): + serializer_class = GunmenSerializer + queryset = Gunmen.objects.all() + + +class AttendanceList(generics.ListAPIView): + serializer_class = AttendanceSerializer + queryset = Attendance.objects.all() + + + +# ListView for Vehicles + diff --git a/server/vendors/migrations/0002_gunmen.py b/server/vendors/migrations/0002_gunmen.py new file mode 100644 index 0000000..f4ac8df --- /dev/null +++ b/server/vendors/migrations/0002_gunmen.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.4 on 2021-07-12 17:12 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('vendors', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Gunmen', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=200)), + ('last_name', models.CharField(max_length=200)), + ('vendor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vendors.Vendor')), + ], + ), + ] diff --git a/server/vendors/models.py b/server/vendors/models.py index 2c7f93c..ef59f5b 100644 --- a/server/vendors/models.py +++ b/server/vendors/models.py @@ -2,6 +2,7 @@ from django.contrib.auth.models import User from datetime import datetime + class Vendor(models.Model): name = models.CharField(max_length=200) address = models.CharField(max_length=1000) @@ -12,4 +13,14 @@ class Vendor(models.Model): created_at = models.DateTimeField(default=datetime.now) def __str__(self): - return f'{self.name} -> {self.email}' \ No newline at end of file + return f'{self.name} -> {self.email}' + + +class Gunmen(models.Model): + first_name = models.CharField(max_length=200) + last_name = models.CharField(max_length=200) + vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + + def __str__(self) -> str: + return f'{self.first_name} {self.last_name}' + diff --git a/server/vendors/serializers.py b/server/vendors/serializers.py new file mode 100644 index 0000000..5d395a5 --- /dev/null +++ b/server/vendors/serializers.py @@ -0,0 +1,16 @@ +from rest_framework import serializers + +from .models import Vendor, Gunmen + +class VendorSerializer(serializers.ModelSerializer): + class Meta: + model = Vendor + fields = ['name', 'address','email','contact','officer_incharge', 'created_by', 'created_at'] + + +class GunmenSerializer(serializers.ModelSerializer): + vendor = VendorSerializer() + class Meta: + model = Gunmen + fields = ['first_name', 'last_name', 'vendor'] + From 3da0131aed909da8d82c6163614749db373da792 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Mon, 12 Jul 2021 23:01:59 +0530 Subject: [PATCH 04/98] update gitignore and add db.sqlite3 --- .gitignore | 8 ++------ server/db.sqlite3 | Bin 0 -> 221184 bytes 2 files changed, 2 insertions(+), 6 deletions(-) create mode 100644 server/db.sqlite3 diff --git a/.gitignore b/.gitignore index db3884f..96e233c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,8 @@ *.pyc __pycache__/ local_settings.py -db.sqlite3 -db.sqlite3-journal +# db.sqlite3 +# db.sqlite3-journal media # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ @@ -167,7 +167,6 @@ sketch # End of https://www.toptal.com/developers/gitignore/api/django,react {"mode":"full","isActive":false} -<<<<<<< HEAD /client/node_modules # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. @@ -194,6 +193,3 @@ sketch npm-debug.log* yarn-debug.log* yarn-error.log* -======= -client/node_modules ->>>>>>> 41c413222912585d191bff8f01499aa1ade3307f diff --git a/server/db.sqlite3 b/server/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..0cc41ab79c1f95ce132b8ea2e4cdf9a05fe2711b GIT binary patch literal 221184 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 Date: Mon, 12 Jul 2021 23:34:38 +0530 Subject: [PATCH 05/98] Basic API routes --- server/attendance/urls.py | 9 +++++++++ server/attendance/views.py | 29 ++++++++++++++++++++--------- server/server/urls.py | 4 +++- server/vendors/urls.py | 10 ++++++++++ server/vendors/views.py | 31 ++++++++++++++++++++++++++++++- 5 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 server/attendance/urls.py create mode 100644 server/vendors/urls.py diff --git a/server/attendance/urls.py b/server/attendance/urls.py new file mode 100644 index 0000000..3fe37af --- /dev/null +++ b/server/attendance/urls.py @@ -0,0 +1,9 @@ +from django.urls import path +from rest_framework.urlpatterns import format_suffix_patterns +from . import views + +urlpatterns = [ + path('', views.AttendanceList.as_view()), +] + +urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/server/attendance/views.py b/server/attendance/views.py index cf0e041..261e9f3 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -3,21 +3,32 @@ from rest_framework import generics from attendance.serializers import AttendanceSerializer from attendance.models import Attendance +from vendors.models import Gunmen +from vendors.serializers import GunmenSerializer -# Create your views here. -# ListView for Gunmen -class GunmenList(generics.ListAPIView): - serializer_class = GunmenSerializer +class GunmenList(mixins.ListModelMixin, + mixins.CreateModelMixin, + generics.GenericAPIView): queryset = Gunmen.objects.all() + serializer_class = GunmenSerializer + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) -class AttendanceList(generics.ListAPIView): - serializer_class = AttendanceSerializer - queryset = Attendance.objects.all() + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) - -# ListView for Vehicles +class AttendanceList(mixins.ListModelMixin, + mixins.CreateModelMixin, + generics.GenericAPIView): + queryset = Attendance.objects.all() + serializer_class = AttendanceSerializer + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) diff --git a/server/server/urls.py b/server/server/urls.py index c8321c8..2c83226 100644 --- a/server/server/urls.py +++ b/server/server/urls.py @@ -14,7 +14,7 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import path, include from rest_framework_simplejwt.views import ( TokenObtainPairView, TokenRefreshView, @@ -24,4 +24,6 @@ path('admin/', admin.site.urls), path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), + path('api/attendance/', include('attendance.urls')), + path('api/vendor/', include('vendors.urls')), ] diff --git a/server/vendors/urls.py b/server/vendors/urls.py new file mode 100644 index 0000000..f8d5da3 --- /dev/null +++ b/server/vendors/urls.py @@ -0,0 +1,10 @@ +from django.urls import path +from rest_framework.urlpatterns import format_suffix_patterns +from . import views + +urlpatterns = [ + path('gunmen/', views.GunmenList.as_view()), + path('vendor/', views.VendorList.as_view()), +] + +urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/server/vendors/views.py b/server/vendors/views.py index 91ea44a..0704904 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -1,3 +1,32 @@ from django.shortcuts import render +from rest_framework import mixins +from rest_framework import generics +from .models import Vendor, Gunmen +from .serializers import VendorSerializer, GunmenSerializer + + +class VendorList(mixins.ListModelMixin, + mixins.CreateModelMixin, + generics.GenericAPIView): + queryset = Vendor.objects.all() + serializer_class = VendorSerializer + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + + +class GunmenList(mixins.ListModelMixin, + mixins.CreateModelMixin, + generics.GenericAPIView): + queryset = Gunmen.objects.all() + serializer_class = GunmenSerializer + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) -# Create your views here. From 4e2cf6de2213284d606738bf33c4e169fdd285f7 Mon Sep 17 00:00:00 2001 From: mustankap Date: Tue, 13 Jul 2021 00:47:53 +0530 Subject: [PATCH 06/98] --- server/db.sqlite3 | Bin 221184 -> 221184 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 0cc41ab79c1f95ce132b8ea2e4cdf9a05fe2711b..b1b479e1dd933dedcb0d0c0d84270d6c5584b2d1 100644 GIT binary patch delta 110 zcmV-!0FnQIzzu-F4UiiFIguPg1vvmNKiRQlre6XLgtIXqdJO^rKC?j(Isvo7Zb$(F z54W=saIOylC6SRKv)q5^9}YP>F*Q0eGA=kbI5{yfgVLXe(w_mh(w_o2paKuWw+ui7 Qx(@*#kwF``;!gt}5a6vOyZ`_I delta 89 zcmV-f0H*(dzzu-F4UiiFG?5%b1vCIIPkpgureCu$Ah-^*!fr?bvk`#O53}5V=pPO@ vIx;vqF)}VOIXO5nGlSBfhti(`x6+>iIG_Rm2)7JC1G*29pd7d2PXitht*;;n From 2e8a30caebd6e33ee61bc3eb07b6ce2d377cd00b Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Tue, 13 Jul 2021 11:29:23 +0530 Subject: [PATCH 07/98] User Serializers and Views --- server/attendance/views.py | 13 ------------- server/db.sqlite3 | Bin 221184 -> 221184 bytes server/server/urls.py | 1 + server/users/serializers.py | 14 ++++++++++++++ server/users/urls.py | 12 ++++++++++++ server/users/views.py | 33 +++++++++++++++++++++++++++++++-- server/vendors/serializers.py | 1 - 7 files changed, 58 insertions(+), 16 deletions(-) create mode 100644 server/users/serializers.py create mode 100644 server/users/urls.py diff --git a/server/attendance/views.py b/server/attendance/views.py index 261e9f3..6a61edf 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -7,19 +7,6 @@ from vendors.serializers import GunmenSerializer -class GunmenList(mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView): - queryset = Gunmen.objects.all() - serializer_class = GunmenSerializer - - def get(self, request, *args, **kwargs): - return self.list(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) - - class AttendanceList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 0cc41ab79c1f95ce132b8ea2e4cdf9a05fe2711b..3d8a3cf6e98a2215d6364ac1d6d21746a4a593a7 100644 GIT binary patch delta 1059 zcma)5U1$_n7`^vSHklio`4U^RYtts_eVPv`+;eMD}4p5Q6#^2?#ik}$>XIonA*eY2i;E;}iiCr768kx@NrPMyjX<&0W1jiRJZ z77J>!@@UM1cSePf66=V>WHq2DYD7}cc4D`^e7_{vC7)rIKovn1ZdV%f7vM`j(}zEF zG^yM!?P*{Me*?iFf5X!c557Xm2JldL**HfAUzoJ9+4*!^T9mC)3k!j97=ipX&G~ zSFk3GJ_p>L(KV9OjBH?dJST@_sXY`G+oiBOYcv*C4r+PLGG+wqC<;?=a~q}M9p%x5 zfu_wO#}F-*GsX^RMoQQ7<&_1op>N#O>+LWItRr|1>y^gof1sW+UhHy`%JYld<9Z59 z2v*=GELGWa_zGm@yPGK7La<>U^c2?N0j$AY_#1B7E?)*;4MQs-QiS>Z|+tw(Y2&NO3+Ur+va@D4Q~ zOKK<_l3l^aPm9ADZEQqOi80}{m^Som%Cfh|#csp2CWJ99r;A?;Vz2hj$3DkbK})4f z-Lk~NGiL^Ch{{rjv<=e|-9j2x0%4^?k(4*2cJn5s)2!9Gy{ES7jl>i=5RFK(s!DDa zAEDR#p5RS=-`38rFJoWz=Vd$>x9{^41TWx;9pAsuTuVHNWijz!=WV;^E3rNU9q_hPAIXTtl!5*Q(pPm@2fkF!47|%UgaYQe90jEe)>#tJNgL delta 400 zcmZoTz}s+ucY-vd$wV1vRucw2|JscybLGVu7#Mi@J~8vZ*zsi$hWMkyN!@z%M zvtYv|{>^vlH3WbHQ4IW1K;;4a0*%UyybO(+j-2AW+MJw@ypwb1hl?307@AudSy&kw z=^0vDS{NE9rsQVkO};f>Nl?$g(7@EdhzsZ)M*i;%{NI7*zUANieLe377B>F74BPn@ zFz)4_xIkk1-Sv#>0&M(`8TkM3f9L/', views.UserDetail.as_view()), +] + +urlpatterns = format_suffix_patterns(urlpatterns) + + diff --git a/server/users/views.py b/server/users/views.py index 91ea44a..da18f6e 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -1,3 +1,32 @@ -from django.shortcuts import render +from django.contrib.auth.models import User +from users.serializers import UserSerializer +from rest_framework import mixins +from rest_framework import generics -# Create your views here. +class UserList(mixins.ListModelMixin, + mixins.CreateModelMixin, + generics.GenericAPIView): + queryset = User.objects.all() + serializer_class = UserSerializer + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + +class UserDetail(mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView): + queryset = User.objects.all() + serializer_class = UserSerializer + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) diff --git a/server/vendors/serializers.py b/server/vendors/serializers.py index 5d395a5..28fb802 100644 --- a/server/vendors/serializers.py +++ b/server/vendors/serializers.py @@ -1,5 +1,4 @@ from rest_framework import serializers - from .models import Vendor, Gunmen class VendorSerializer(serializers.ModelSerializer): From bdd75f2ce6c2fe2c6190ab0253d1331879e1213f Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 13 Jul 2021 11:30:52 +0530 Subject: [PATCH 08/98] cosmetic changes --- server/attendance/views.py | 13 ++++++------- server/vendors/views.py | 13 ++++++------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 261e9f3..12475b7 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -7,9 +7,9 @@ from vendors.serializers import GunmenSerializer -class GunmenList(mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView): +class GunmenList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): queryset = Gunmen.objects.all() serializer_class = GunmenSerializer @@ -20,9 +20,9 @@ def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) -class AttendanceList(mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView): +class AttendanceList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): queryset = Attendance.objects.all() serializer_class = AttendanceSerializer @@ -31,4 +31,3 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) - diff --git a/server/vendors/views.py b/server/vendors/views.py index 0704904..773156e 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -5,9 +5,9 @@ from .serializers import VendorSerializer, GunmenSerializer -class VendorList(mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView): +class VendorList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): queryset = Vendor.objects.all() serializer_class = VendorSerializer @@ -18,9 +18,9 @@ def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) -class GunmenList(mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView): +class GunmenList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): queryset = Gunmen.objects.all() serializer_class = GunmenSerializer @@ -29,4 +29,3 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) - From d41dc09e2aaf71df12727de219e32579f40d4ee1 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 13 Jul 2021 11:44:22 +0530 Subject: [PATCH 09/98] region and branch serializers --- server/attendance/views.py | 6 +++--- server/users/serializers.py | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 064204d..8410aae 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -7,9 +7,9 @@ from vendors.serializers import GunmenSerializer -class AttendanceList(mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView): +class AttendanceList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): queryset = Attendance.objects.all() serializer_class = AttendanceSerializer diff --git a/server/users/serializers.py b/server/users/serializers.py index f071eee..94d0da9 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -1,14 +1,32 @@ from rest_framework import serializers from django.contrib.auth.models import User +from .models import Profile, Region, Branch class UserSerializer(serializers.ModelSerializer): class Meta: model = User - fields = ('id', 'first_name', 'last_name', 'username', 'email') + fields = ("id", "first_name", "last_name", "username", "email") class ProfileSerializer(serializers.ModelSerializer): class Meta: model = Profile - fields = [] + fields = ["user", "is_superuser", "is_incharge"] + + +class RegionSerializer(serializers.ModelSerializer): + regional_officer = UserSerializer() + + class Meta: + model = Region + fields = ["name", "address", "regional_officer"] + + +class BranchSerializer(serializers.ModelSerializer): + branch_manager = UserSerializer() + region = RegionSerializer() + + class Meta: + model = Branch + fields = ["name", "address", "branch_manager", "region"] From 7de8f6fa5fdbcb43fcacd8d56515da2f35812ebb Mon Sep 17 00:00:00 2001 From: mustankap Date: Tue, 13 Jul 2021 11:49:11 +0530 Subject: [PATCH 10/98] changes in views --- server/users/serializers.py | 7 +++++++ server/users/views.py | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/server/users/serializers.py b/server/users/serializers.py index f071eee..41cbf2e 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -12,3 +12,10 @@ class ProfileSerializer(serializers.ModelSerializer): class Meta: model = Profile fields = [] + +class BranchSerializer(serializers.ModelSerializer): + class Meta: + model = Branch + fields = ('branch_name','address','branch_manager','region_id' ) + + diff --git a/server/users/views.py b/server/users/views.py index bbbae90..6a9cc12 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -32,7 +32,7 @@ def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) class BranchList(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView): - queryset = User.objects.all() + queryset = Branch.objects.all() serializer_class = UserSerializer def get(self, request, *args, **kwargs): @@ -45,7 +45,7 @@ class BranchDetail(mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView): - queryset = User.objects.all() + queryset = Branch.objects.all() serializer_class = UserSerializer def get(self, request, *args, **kwargs): From ebc5e36bc128999390f43d19b1715ab541ec391a Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 13 Jul 2021 11:51:30 +0530 Subject: [PATCH 11/98] Branch and Region Views and urls --- server/users/urls.py | 10 +++--- server/users/views.py | 75 +++++++++++++++++++++++++++++++++---------- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/server/users/urls.py b/server/users/urls.py index faf8e00..2e02f82 100644 --- a/server/users/urls.py +++ b/server/users/urls.py @@ -3,10 +3,12 @@ from . import views urlpatterns = [ - path('', views.UserList.as_view()), - path('/', views.UserDetail.as_view()), + path("user/", views.UserList.as_view()), + path("user//", views.UserDetail.as_view()), + path("branch/", views.BranchList.as_view()), + path("branch//", views.BranchDetail.as_view()), + path("region/", views.RegionList.as_view()), + path("region//", views.RegionDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) - - diff --git a/server/users/views.py b/server/users/views.py index bbbae90..a038e21 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -1,11 +1,12 @@ from django.contrib.auth.models import User +from .models import Branch, Region +from .serializers import BranchSerializer, RegionSerializer from users.serializers import UserSerializer from rest_framework import mixins from rest_framework import generics -class UserList(mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView): + +class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer @@ -15,10 +16,13 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) -class UserDetail(mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView): + +class UserDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): queryset = User.objects.all() serializer_class = UserSerializer @@ -31,9 +35,12 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) -class BranchList(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView): - queryset = User.objects.all() - serializer_class = UserSerializer + +class BranchList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): + queryset = Branch.objects.all() + serializer_class = BranchSerializer def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -41,12 +48,47 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) -class BranchDetail(mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView): - queryset = User.objects.all() - serializer_class = UserSerializer + +class BranchDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Branch.objects.all() + serializer_class = BranchSerializer + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) + + +class RegionList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): + queryset = Region.objects.all() + serializer_class = RegionSerializer + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + + +class RegionDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Region.objects.all() + serializer_class = RegionSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) @@ -56,4 +98,3 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) - \ No newline at end of file From 7c0c1a3d1f5aceaa6a53d62636b24f23cd1bbad4 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 13 Jul 2021 12:02:05 +0530 Subject: [PATCH 12/98] updated requirements.txt --- server/requirements.txt | Bin 498 -> 542 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/requirements.txt b/server/requirements.txt index 1c1c05bb028b613a7ed5f5efb484b68b5ff03710..db441620d6210d042846242dadaa4335d413499a 100644 GIT binary patch delta 32 mcmeywJdb6 Date: Tue, 13 Jul 2021 12:02:47 +0530 Subject: [PATCH 13/98] Filters --- server/server/settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/server/settings.py b/server/server/settings.py index c5c9404..fd04857 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -40,6 +40,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'django-filters', 'users.apps.UsersConfig', 'vendors.apps.VendorsConfig', 'attendance.apps.AttendanceConfig', @@ -160,4 +161,5 @@ 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], + 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] } From be0ef937f32ddbf884ee0f6faa2541bfdb4d195e Mon Sep 17 00:00:00 2001 From: mustankap Date: Tue, 13 Jul 2021 12:25:53 +0530 Subject: [PATCH 14/98] changes --- server/db.sqlite3 | Bin 221184 -> 221184 bytes server/server/settings.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index b1b479e1dd933dedcb0d0c0d84270d6c5584b2d1..b0e5a532c2ad23c44946a29f9c80a31419a12639 100644 GIT binary patch delta 762 zcmaiy?@Lor7{|}Kr|mj*=W%AGW$h|Lg>2oOUGLqlAk9Lekp6%QyX#)&+IBVPre)$V zA>UOB?WGyMkGL-ey$I@W6TAobUHJpXYo}Zq}Wf zb>BUN+waw%!tIYQPkX)KL2gxaxS{nK2 z^#uP85DY7#B;T5!%Fj<>MtN93@B_ZXS38r1Le&HO5}Xc#aRr}$`v@Pc=AnpS6E@%* ztidPv07c7_dj)h4abdnxoTW1PtMnm_(t7)`o%GCU-i0FIYsM}Y z6Is9~D!#xrQCO9jKPW3frm$2d-LIMHc%P8adbM=?!ce28>xSN_3PZ!gmnzzv`L#J* zTevxg#~aExSVXW6i#E(0?62V*$Xn<7(_*_re*Gt|v6UNJ1K7${aFk%V+nc}@Hi4Ac n9|L9(EW>k{DbSPTKC~Sn5&WBy{S!R-&+(3Axx(^!a-`}Pk?q-t delta 375 zcmV--0f_#9zzu-F4UiiFIguPg0XeZ?p&uUr000dR@&ga)4}Ll4-vB_Y;R`U54W=sfUXY#C6SRKv)q5>9}zMjF*!OhH99gfE;u(h zIWaMV(w~>op8+xu1`pi;5Bm@G5AP4@591Hrvk`#F50~Aq0Vfa!590t2{15jJ@(=9~ z=nvzw5rEGR2?PTP0R{vE2?3Mr-xv@E4q^Zg#1DTDD-P=pq7GuSF(6J30zL+p?al!h zw|ve4h#>|65AXmF@Uszs<`0+f{{a-Y1Rw$e5Qhd30=EVb1O6`x0T1E;58@BQ006fR VKm(Q!k)R?0ACW;Dx8hF&9uV Date: Tue, 13 Jul 2021 12:33:31 +0530 Subject: [PATCH 15/98] added filters --- server/vendors/views.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/vendors/views.py b/server/vendors/views.py index 773156e..2cbcd90 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -3,6 +3,7 @@ from rest_framework import generics from .models import Vendor, Gunmen from .serializers import VendorSerializer, GunmenSerializer +from django_filters.rest_framework import DjangoFilterBackend class VendorList( @@ -23,6 +24,8 @@ class GunmenList( ): queryset = Gunmen.objects.all() serializer_class = GunmenSerializer + filter_backends = [DjangoFilterBackend] + filterset_fields = ["first_name", "last_name"] def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) From 1330bdd79daf114de6cf20007b9d12110c65a576 Mon Sep 17 00:00:00 2001 From: mustankap Date: Tue, 13 Jul 2021 14:17:06 +0530 Subject: [PATCH 16/98] --- server/db.sqlite3 | Bin 221184 -> 221184 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index b0e5a532c2ad23c44946a29f9c80a31419a12639..480aa5a7e95dd858af54d6b7b3643a1f277b5f89 100644 GIT binary patch delta 147 zcmZoTz}s+ucY-vd^F$eEM(2$Q3*&itTNs#l+!*){@woB0Z8lV};Mwe!W5>wCz`$s? z*-^lXk)z3)k=3__)p7EJdWFre^28Z=`L{DL@lRslpTvKM|ITK?h8F(Glj>E0S{PI( yPE>5ZQ{R54o^kt~dM4Ea-28`uYL_tZKjL4qoyUQBJ3mO7{6t6T?T`GK0;RaKaM83~!r)O@GD{Z2jO z_B-`Vst341j^$s%!2gK<@OB;t=I#9Qa?Fm5Mg~TPx(4RDM&=3zW>zLhZeiN~$e&qG F007DuN Date: Tue, 13 Jul 2021 21:44:44 +0530 Subject: [PATCH 17/98] added CRUD for gunmen and vendors --- server/db.sqlite3 | Bin 221184 -> 221184 bytes server/vendors/urls.py | 6 ++++-- server/vendors/views.py | 40 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index b0e5a532c2ad23c44946a29f9c80a31419a12639..ac988cc755421324fd8e781c9a6e61f17e5447fd 100644 GIT binary patch delta 679 zcmZoTz}s+ucY-vd>qHr6R#yf+|Jscyi{vFvG4sFVSK;5qzmPwMzk$Dyzn|Zm--_?l zW;um5e7Ztn%$kg4sd*{+MaA(Dnn_3;Ni4lIFE=%hMOK2@k#o9Y2a_m!aYkxt3IDap z!uo2AT$8Qz=dds^FbFr_(%*hdpHZtof{Xts1OIRSul(=%PXn#K&VP~rDF0*ryPE|Y zR`Lt6GBYxAbAd=MPB5Ee`t|jUxlF|R}+J3l+IBsIEPDKRA_ zHATrvp}Mv8Z)cyt*g>Qh`@9?vNBA99N$NR$VECNj1Sp=B>_yYiZ^}rYa delta 269 zcmZoTz}s+ucY-vd(?l6(Rwo8M`/", views.GunmenDetail.as_view()), + path("vendor/", views.VendorList.as_view()), + path("vendor//", views.VendorDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/server/vendors/views.py b/server/vendors/views.py index 2cbcd90..9bdb220 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -19,16 +19,54 @@ def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) +class VendorDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Vendor.objects.all() + serializer_class = VendorSerializer + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) + + class GunmenList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView ): queryset = Gunmen.objects.all() serializer_class = GunmenSerializer filter_backends = [DjangoFilterBackend] - filterset_fields = ["first_name", "last_name"] + filterset_fields = ["first_name", "last_name", "vendor"] def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) + + +class GunmenDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Gunmen.objects.all() + serializer_class = GunmenSerializer + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) From 271239facda21fa76cee34b799f44bd7b07c8544 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 13 Jul 2021 22:17:34 +0530 Subject: [PATCH 18/98] updated filters --- server/attendance/serializers.py | 34 ++++++++++++++++++++++++++++---- server/attendance/urls.py | 3 ++- server/attendance/views.py | 19 ++++++++++++++++++ server/vendors/views.py | 5 ++++- 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 5ffbd4a..9961365 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,13 +1,39 @@ +from django.db.models import fields from rest_framework import serializers - +from users.serializers import BranchSerializer, UserSerializer from vendors.serializers import VendorSerializer, GunmenSerializer -from .models import Attendance +from .models import Attendance, AttendanceSheet, Issue + + +class AttendanceSheetSerializer(serializers.ModelSerializer): + class Meta: + model = AttendanceSheet + fields = ["sheet_created", "invoice", "verified"] class AttendanceSerializer(serializers.ModelSerializer): gunmen = GunmenSerializer() - + attendance_sheet = AttendanceSheetSerializer() + branch = BranchSerializer() + added_by = UserSerializer() + class Meta: model = Attendance - fields = ['gunmen', 'entry_time', 'exit_time'] + fields = [ + "gunmen", + "entry_time", + "exit_time", + "branch", + "added_by", + "attendance_sheet", + ] + +class IssueSerializer(serializers.ModelSerializer): + reverted_by = UserSerializer() + vendor = VendorSerializer() + sheet = AttendanceSheetSerializer() + + class Meta: + model = Issue + fields = ["comment", "reverted_by", "vendor", "sheet", "created_at"] diff --git a/server/attendance/urls.py b/server/attendance/urls.py index 3fe37af..c0f5ccf 100644 --- a/server/attendance/urls.py +++ b/server/attendance/urls.py @@ -3,7 +3,8 @@ from . import views urlpatterns = [ - path('', views.AttendanceList.as_view()), + path("", views.AttendanceList.as_view()), + path("/", views.AttendanceDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/server/attendance/views.py b/server/attendance/views.py index 8410aae..61afd9a 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -18,3 +18,22 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) + + +class AttendanceDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Attendance.objects.all() + serializer_class = AttendanceSerializer + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) diff --git a/server/vendors/views.py b/server/vendors/views.py index 9bdb220..3989b8b 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -4,6 +4,7 @@ from .models import Vendor, Gunmen from .serializers import VendorSerializer, GunmenSerializer from django_filters.rest_framework import DjangoFilterBackend +from rest_framework import filters class VendorList( @@ -43,7 +44,9 @@ class GunmenList( ): queryset = Gunmen.objects.all() serializer_class = GunmenSerializer - filter_backends = [DjangoFilterBackend] + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + # filter_backends = [DjangoFilterBackend] + search_fields = ["^first_name", "^last_name"] filterset_fields = ["first_name", "last_name", "vendor"] def get(self, request, *args, **kwargs): From 6de7a9d3c3bb2fb0d884918372ce39ccc8b9ea75 Mon Sep 17 00:00:00 2001 From: mustankap Date: Tue, 13 Jul 2021 23:06:52 +0530 Subject: [PATCH 19/98] added filters --- server/attendance/models.py | 2 +- server/attendance/serializers.py | 2 +- server/attendance/views.py | 2 +- server/users/models.py | 1 + server/users/views.py | 13 +++++++++---- server/vendors/models.py | 2 +- server/vendors/views.py | 18 ++++++++++++++++-- 7 files changed, 30 insertions(+), 10 deletions(-) diff --git a/server/attendance/models.py b/server/attendance/models.py index e189393..11b9822 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -4,7 +4,7 @@ from users.models import Branch from datetime import datetime - + class AttendanceSheet(models.Model): sheet_created = models.DateField(default=datetime.now) invoice = models.FileField(blank=True, null=True, upload_to='invoice') diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 9961365..77fd24e 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -9,7 +9,7 @@ class AttendanceSheetSerializer(serializers.ModelSerializer): class Meta: model = AttendanceSheet fields = ["sheet_created", "invoice", "verified"] - + class AttendanceSerializer(serializers.ModelSerializer): gunmen = GunmenSerializer() diff --git a/server/attendance/views.py b/server/attendance/views.py index 61afd9a..d0dc181 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -6,7 +6,7 @@ from vendors.models import Gunmen from vendors.serializers import GunmenSerializer - + class AttendanceList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView ): diff --git a/server/users/models.py b/server/users/models.py index f168758..8f133d3 100644 --- a/server/users/models.py +++ b/server/users/models.py @@ -31,3 +31,4 @@ class Branch(models.Model): def __str__(self) -> str: return f'{self.name} -> {self.region}' + \ No newline at end of file diff --git a/server/users/views.py b/server/users/views.py index a038e21..939cee1 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -1,15 +1,14 @@ from django.contrib.auth.models import User from .models import Branch, Region -from .serializers import BranchSerializer, RegionSerializer -from users.serializers import UserSerializer +from .serializers import BranchSerializer, RegionSerializer , UserSerializer from rest_framework import mixins from rest_framework import generics - +from django_filters.rest_framework import DjangoFilterBackend class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer - + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -41,6 +40,9 @@ class BranchList( ): queryset = Branch.objects.all() serializer_class = BranchSerializer + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^name", "^address"] + filterset_fields = ["name", "address", "branch_manager", "region"] def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -73,6 +75,9 @@ class RegionList( ): queryset = Region.objects.all() serializer_class = RegionSerializer + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^name", "^address"] + filterset_fields = ["name", "address", "regional_officer"] def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) diff --git a/server/vendors/models.py b/server/vendors/models.py index ef59f5b..a6f9d32 100644 --- a/server/vendors/models.py +++ b/server/vendors/models.py @@ -15,7 +15,7 @@ class Vendor(models.Model): def __str__(self): return f'{self.name} -> {self.email}' - + class Gunmen(models.Model): first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) diff --git a/server/vendors/views.py b/server/vendors/views.py index 3989b8b..5d81724 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -12,7 +12,21 @@ class VendorList( ): queryset = Vendor.objects.all() serializer_class = VendorSerializer - + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + # filter_backends = [DjangoFilterBackend] + search_fields = ["^name", + "^address", + "^contact", + "^officer_incharge"] + filterset_fields = [ + "name", + "address", + "email", + "contact", + "officer_incharge", + "created_by", + "created_at" + ] def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -55,7 +69,7 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) - + class GunmenDetail( mixins.RetrieveModelMixin, mixins.UpdateModelMixin, From 7fcaa4fcf08f08a0a9a6d00167a9b9a31d15876e Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 13 Jul 2021 23:10:08 +0530 Subject: [PATCH 20/98] CRUD on nested serializers --- server/attendance/serializers.py | 37 ++++++++++++++++++++++--- server/db.sqlite3 | Bin 221184 -> 221184 bytes server/users/serializers.py | 30 ++++++++++++++++++--- server/vendors/serializers.py | 45 ++++++++++++++++++++++++++++--- 4 files changed, 102 insertions(+), 10 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 9961365..6df47f6 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,3 +1,6 @@ +from django.contrib.auth.models import User +from users.models import Branch +from vendors.models import Gunmen from django.db.models import fields from rest_framework import serializers from users.serializers import BranchSerializer, UserSerializer @@ -5,6 +8,24 @@ from .models import Attendance, AttendanceSheet, Issue +class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): + def __init__(self, **kwargs): + self.serializer = kwargs.pop("serializer", None) + if self.serializer is not None and not issubclass( + self.serializer, serializers.Serializer + ): + raise TypeError('"serializer" is not a valid serializer class') + super().__init__(**kwargs) + + def use_pk_only_optimization(self): + return False if self.serializer else True + + def to_representation(self, instance): + if self.serializer: + return self.serializer(instance, context=self.context).data + return super().to_representation(instance) + + class AttendanceSheetSerializer(serializers.ModelSerializer): class Meta: model = AttendanceSheet @@ -12,10 +33,18 @@ class Meta: class AttendanceSerializer(serializers.ModelSerializer): - gunmen = GunmenSerializer() - attendance_sheet = AttendanceSheetSerializer() - branch = BranchSerializer() - added_by = UserSerializer() + gunmen = RelatedFieldAlternative( + queryset=Gunmen.objects.all(), serializer=GunmenSerializer + ) + attendance_sheet = RelatedFieldAlternative( + queryset=AttendanceSheet.objects.all(), serializer=AttendanceSheetSerializer + ) + branch = RelatedFieldAlternative( + queryset=Branch.objects.all(), serializer=BranchSerializer + ) + added_by = RelatedFieldAlternative( + queryset=User.objects.all(), serializer=UserSerializer + ) class Meta: model = Attendance diff --git a/server/db.sqlite3 b/server/db.sqlite3 index ac988cc755421324fd8e781c9a6e61f17e5447fd..947fea31cd17ad39e9491511e2f283724940758a 100644 GIT binary patch delta 213 zcmZoTz}s+ucY-vd=R_H2M$e526ZP2GWhIy$Ij1XjFo`zv=x^uIXZ&%1pN+qViT@V= z3I5IebNPGtH!CWv)Cm@z9cGbOX2IJ1aJgq4*+UYs$vw74WO4=9kG z2oz?TzWG0+tqKDJ4?8P^uqY=`ZC-wU5*Pm;1~&fN4E*2uKk?t@f5ZQb|G{R#hU5II zEX4L-fBK9J+yC1$-;!r!n0_msSq%WC C9X3b+ delta 139 zcmZoTz}s+ucY-vd>qHr6M%RrA6ZP0wWF?p#Ij1XjFo`zv=x^uIXZ&%1hlPJL1OEs9 zTl^>ZH*XefSj<0t^M6KL1wKYr22pX&yu{qp91y|9z`(%5|AvA85C3=mPyBCyO7HNq rvNAI=GEM$?U$~t`fN4960P`>X>Hp%H*tWAcFkh8t>h5t1>GV diff --git a/server/users/serializers.py b/server/users/serializers.py index 94d0da9..254431d 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -3,6 +3,24 @@ from .models import Profile, Region, Branch +class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): + def __init__(self, **kwargs): + self.serializer = kwargs.pop("serializer", None) + if self.serializer is not None and not issubclass( + self.serializer, serializers.Serializer + ): + raise TypeError('"serializer" is not a valid serializer class') + super().__init__(**kwargs) + + def use_pk_only_optimization(self): + return False if self.serializer else True + + def to_representation(self, instance): + if self.serializer: + return self.serializer(instance, context=self.context).data + return super().to_representation(instance) + + class UserSerializer(serializers.ModelSerializer): class Meta: model = User @@ -16,7 +34,9 @@ class Meta: class RegionSerializer(serializers.ModelSerializer): - regional_officer = UserSerializer() + regional_officer = RelatedFieldAlternative( + queryset=User.objects.all(), serializer=UserSerializer + ) class Meta: model = Region @@ -24,8 +44,12 @@ class Meta: class BranchSerializer(serializers.ModelSerializer): - branch_manager = UserSerializer() - region = RegionSerializer() + branch_manager = RelatedFieldAlternative( + queryset=User.objects.all(), serializer=UserSerializer + ) + region = RelatedFieldAlternative( + queryset=Region.objects.all(), serializer=RegionSerializer + ) class Meta: model = Branch diff --git a/server/vendors/serializers.py b/server/vendors/serializers.py index 28fb802..15c7c6c 100644 --- a/server/vendors/serializers.py +++ b/server/vendors/serializers.py @@ -1,15 +1,54 @@ from rest_framework import serializers from .models import Vendor, Gunmen + +class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): + def __init__(self, **kwargs): + self.serializer = kwargs.pop("serializer", None) + if self.serializer is not None and not issubclass( + self.serializer, serializers.Serializer + ): + raise TypeError('"serializer" is not a valid serializer class') + super().__init__(**kwargs) + + def use_pk_only_optimization(self): + return False if self.serializer else True + + def to_representation(self, instance): + if self.serializer: + return self.serializer(instance, context=self.context).data + return super().to_representation(instance) + + class VendorSerializer(serializers.ModelSerializer): class Meta: model = Vendor - fields = ['name', 'address','email','contact','officer_incharge', 'created_by', 'created_at'] + fields = [ + "name", + "address", + "email", + "contact", + "officer_incharge", + "created_by", + "created_at", + ] class GunmenSerializer(serializers.ModelSerializer): - vendor = VendorSerializer() + # vendor = VendorSerializer() + vendor = RelatedFieldAlternative( + queryset=Vendor.objects.all(), serializer=VendorSerializer + ) + class Meta: model = Gunmen - fields = ['first_name', 'last_name', 'vendor'] + fields = ["first_name", "last_name", "vendor"] + # def create(self, validated_data): + # vendor_data = validated_data.pop("vendor") + # vendor_data = Vendor.objects.filter(vendor_data) + # print(vendor_data) + # gunman = Gunmen.objects.create(**validated_data) + # # for track_data in tracks_data: + # # Track.objects.create(album=album, **track_data) + # return gunman From 868d7d11807fa96665c0e2d578a747604599c930 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 13 Jul 2021 23:12:58 +0530 Subject: [PATCH 21/98] import headers --- server/attendance/views.py | 8 +++++--- server/users/views.py | 6 ++++-- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index d0dc181..a8d7205 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -3,10 +3,12 @@ from rest_framework import generics from attendance.serializers import AttendanceSerializer from attendance.models import Attendance -from vendors.models import Gunmen -from vendors.serializers import GunmenSerializer - +# from vendors.models import Gunmen +# from vendors.serializers import GunmenSerializer +from rest_framework import filters + + class AttendanceList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView ): diff --git a/server/users/views.py b/server/users/views.py index 939cee1..deb05e1 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -1,14 +1,16 @@ from django.contrib.auth.models import User from .models import Branch, Region -from .serializers import BranchSerializer, RegionSerializer , UserSerializer +from .serializers import BranchSerializer, RegionSerializer, UserSerializer from rest_framework import mixins from rest_framework import generics from django_filters.rest_framework import DjangoFilterBackend +from rest_framework import filters + class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer - + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) From 0809b49c8333a9aa0e8df750cfc835f15fe1eb66 Mon Sep 17 00:00:00 2001 From: mustankap Date: Tue, 13 Jul 2021 23:14:12 +0530 Subject: [PATCH 22/98] import filter mod --- server/users/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/server/users/views.py b/server/users/views.py index 939cee1..cd8a61a 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -4,6 +4,7 @@ from rest_framework import mixins from rest_framework import generics from django_filters.rest_framework import DjangoFilterBackend +from rest_framework import filter class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = User.objects.all() From c3c562b22d73c51ebeb5b41ccc03d0ef602a9f86 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 13 Jul 2021 23:24:17 +0530 Subject: [PATCH 23/98] added and updated serializers --- server/attendance/serializers.py | 15 +++++++++++---- server/db.sqlite3 | Bin 221184 -> 221184 bytes 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index aed6b31..892c9c3 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,3 +1,4 @@ +from vendors.models import Vendor from django.contrib.auth.models import User from users.models import Branch from vendors.models import Gunmen @@ -30,7 +31,7 @@ class AttendanceSheetSerializer(serializers.ModelSerializer): class Meta: model = AttendanceSheet fields = ["sheet_created", "invoice", "verified"] - + class AttendanceSerializer(serializers.ModelSerializer): gunmen = RelatedFieldAlternative( @@ -59,9 +60,15 @@ class Meta: class IssueSerializer(serializers.ModelSerializer): - reverted_by = UserSerializer() - vendor = VendorSerializer() - sheet = AttendanceSheetSerializer() + reverted_by = RelatedFieldAlternative( + queryset=User.objects.all(), serializer=UserSerializer + ) + vendor = RelatedFieldAlternative( + queryset=Vendor.objects.all(), serializer=VendorSerializer + ) + sheet = RelatedFieldAlternative( + queryset=AttendanceSheet.objects.all(), serializer=AttendanceSheetSerializer + ) class Meta: model = Issue diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 947fea31cd17ad39e9491511e2f283724940758a..ca81af1cb422a5f6d3888ad9514974e09caa1293 100644 GIT binary patch delta 267 zcmWlRF-yZh7(nm4OWRy&^0m}}MZt(V)?5-Kw2O#ie?+aeLYJgN*FwR?p@ZU(N!;wv zNirNbWpt9xPF8d(&8(#@fRkbRPFFq4Rb%KPUkvc#NNsZYl`xPjzeF zAcXAj-grFl`#t|=(9N--G7rMTdujl^ODvgKup8I$j}&o2@e4mN!e^Y}B&v;uh+3&Y z41@QFqreY>>u|P#TV?yzWx4_VS1K#W@O1@MC`S;ps!DN9FvGR1nCu4)g>j&aabDg= z6w}gA@v|ZD2+m79K#i=-J LwQP@u%PtfDq((?6 delta 190 zcmZoTz}s+ucY-vd=R_H2M$e52%jMab`Csy@@bB8pr@+F`cx|$<{&H3c4rX)C>53gp zqM{5SAk0~onwOGaR2&bXn_ud0f2q$XaX<(t$;RKq#D9zb1pj9Kx%@r+n-vvS@=Xp9 zxG=rvKVupT4?8Qv_HX|g`93UX31CuK%yK}0gOUFa0}vT)=TTsO%|9`Kb^4!pCVoc4 k?K}p|uYi2E?SJf;M1& From 95382a2ec7de6101778fd74527aa783292c790d3 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Tue, 13 Jul 2021 23:32:54 +0530 Subject: [PATCH 24/98] user serializer and model updates --- server/users/serializers.py | 15 +++++++++------ server/vendors/models.py | 1 + server/vendors/serializers.py | 3 +-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/server/users/serializers.py b/server/users/serializers.py index 254431d..dfdcb55 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -21,18 +21,21 @@ def to_representation(self, instance): return super().to_representation(instance) -class UserSerializer(serializers.ModelSerializer): - class Meta: - model = User - fields = ("id", "first_name", "last_name", "username", "email") - - class ProfileSerializer(serializers.ModelSerializer): class Meta: model = Profile fields = ["user", "is_superuser", "is_incharge"] +class UserSerializer(serializers.ModelSerializer): + profile = RelatedFieldAlternative( + queryset=Profile.objects.all(), serializer=ProfileSerializer + ) + class Meta: + model = User + fields = ("id", "first_name", "last_name", "username", "email") + + class RegionSerializer(serializers.ModelSerializer): regional_officer = RelatedFieldAlternative( queryset=User.objects.all(), serializer=UserSerializer diff --git a/server/vendors/models.py b/server/vendors/models.py index a6f9d32..bdce035 100644 --- a/server/vendors/models.py +++ b/server/vendors/models.py @@ -19,6 +19,7 @@ def __str__(self): class Gunmen(models.Model): first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) + email = models.EmailField() vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: diff --git a/server/vendors/serializers.py b/server/vendors/serializers.py index 15c7c6c..c2e8e05 100644 --- a/server/vendors/serializers.py +++ b/server/vendors/serializers.py @@ -35,14 +35,13 @@ class Meta: class GunmenSerializer(serializers.ModelSerializer): - # vendor = VendorSerializer() vendor = RelatedFieldAlternative( queryset=Vendor.objects.all(), serializer=VendorSerializer ) class Meta: model = Gunmen - fields = ["first_name", "last_name", "vendor"] + fields = ["first_name", "last_name", "email", "vendor"] # def create(self, validated_data): # vendor_data = validated_data.pop("vendor") From 14b8a3a56f46df00767734ef082e4a949677dec2 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Tue, 13 Jul 2021 23:47:32 +0530 Subject: [PATCH 25/98] Serializers update --- server/attendance/serializers.py | 5 +++-- server/db.sqlite3 | Bin 221184 -> 221184 bytes server/users/serializers.py | 4 ++-- server/vendors/serializers.py | 3 ++- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 892c9c3..674e07c 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -30,7 +30,7 @@ def to_representation(self, instance): class AttendanceSheetSerializer(serializers.ModelSerializer): class Meta: model = AttendanceSheet - fields = ["sheet_created", "invoice", "verified"] + fields = ["id", "sheet_created", "invoice", "verified"] class AttendanceSerializer(serializers.ModelSerializer): @@ -50,6 +50,7 @@ class AttendanceSerializer(serializers.ModelSerializer): class Meta: model = Attendance fields = [ + "id", "gunmen", "entry_time", "exit_time", @@ -72,4 +73,4 @@ class IssueSerializer(serializers.ModelSerializer): class Meta: model = Issue - fields = ["comment", "reverted_by", "vendor", "sheet", "created_at"] + fields = ["id", "comment", "reverted_by", "vendor", "sheet", "created_at"] diff --git a/server/db.sqlite3 b/server/db.sqlite3 index ca81af1cb422a5f6d3888ad9514974e09caa1293..c99532f7562db18c229c2da4396635f17fa43e80 100644 GIT binary patch delta 1181 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 Date: Wed, 14 Jul 2021 08:39:51 +0530 Subject: [PATCH 26/98] add cors to settings --- server/server/settings.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/server/settings.py b/server/server/settings.py index 47401da..90c56dc 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -40,7 +40,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', - 'django_filters', + 'corsheaders', 'users.apps.UsersConfig', 'vendors.apps.VendorsConfig', 'attendance.apps.AttendanceConfig', @@ -49,6 +49,7 @@ MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', + 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', @@ -161,5 +162,4 @@ 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], - 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'] } From b56bc517e2172d2155153c7661aa50cffc92bb8a Mon Sep 17 00:00:00 2001 From: mishrakeshav Date: Wed, 14 Jul 2021 09:57:50 +0530 Subject: [PATCH 27/98] update --- server/db.sqlite3 | Bin 221184 -> 221184 bytes server/users/serializers.py | 7 ++++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index c99532f7562db18c229c2da4396635f17fa43e80..ba2015adad6e0ef149f10a98df269151515ca95f 100644 GIT binary patch delta 1305 zcmb7E?Q2_A7(XxfHo1}HNn=a7W?Qn5vPsu8xk;LrPOuYabT>{x8?0d$)1eX(f&u1m+z#I<0GtMoT1i)Os0N#r;!OAuKMQJFjG= zw4Rrx=%has53=E}CF=RP>}2MR(pyD;=JdOTS>@QVx;hg&zM{^~omx;L@4c^uRx-g; zW7){eSiL;+<~z%JH26wU)AJR1My}|2tt#iY=YU>(RWBE1ZB?EKs7g%=N}=&!Y&;Y( zSVw}%kd!hF5o#U82E4E^B8~|RUVGv4+_0%;CdVw`36-H;Zr{G_bM?(^tR@7u5Ilpe z?qIVAFW9Jv`&dZ#*;V^5HVTgr{0_guBc|{@czB92M@>mMiUrQ_LE#C4KbV&%Oz8*M z$58=OLl8;@!ER_c9wN8}Cmjzvt?wKSnF?qcMpm(apW_rwh9?8ja5NE*giO$9F8DHe z)`Y6!OL{N(vYJ{@bhbR>JFZpqs<$K;Ro@Y>Z&u#&0QimL0re%K^7n2BRp5T0XZR4WjVhhvHO$lpEkv-}NLoJR9u2ijfPS#Gdi+{x1UmJ8?7PzzBKClHpK@aY*t9lC#nVc-9 y955wsO75TSW$WVJpPsLpgxh3EyNTc)++_9};5k62ciT(a^P?ae_ui%loPPm=PGT1T delta 344 zcmZoTz}s+ucY-vd-b5K^M!k&*3+2Tb7#KMCV;K2g@?YWK#lMh0hQEQokiUOpqYMA! z7=0B*9zkY#&cxD^jQG;x)FK7}VPN1CfktIUUWP_ZM^15GZB9-{-pM)h!^Mmh3@xk-jjasL z^$aa742>Ev%BS!x34E*1L#=hm>{Cz#|hs`Vx{>U#nAh78G zi@;)*4GN1{8bDV4WZ?e^RP>%-kd={@frEn+qW2F2{~xe0JJ2X*W=_sc8(0)TM(A&A YU}8A{)cA;j{}E8d4gT$q{F&th05zOxJ^%m! diff --git a/server/users/serializers.py b/server/users/serializers.py index 3cdf284..8a800ad 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -33,7 +33,12 @@ class UserSerializer(serializers.ModelSerializer): ) class Meta: model = User - fields = ("id", "first_name", "last_name", "username", "email") + fields = ( + "id", "first_name", "last_name", + "username", "email", 'profile', + 'is_staff', 'is_active', 'is_superuser', + 'last_login', 'date_joined' + ) class RegionSerializer(serializers.ModelSerializer): From 2dccc5cea20e52cec428fef4c9a34a8cc1f2c6d1 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 14 Jul 2021 14:46:43 +0530 Subject: [PATCH 28/98] nm --- server/db.sqlite3 | Bin 221184 -> 225280 bytes .../vendors/migrations/0003_gunmen_email.py | 20 ++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 server/vendors/migrations/0003_gunmen_email.py diff --git a/server/db.sqlite3 b/server/db.sqlite3 index ca81af1cb422a5f6d3888ad9514974e09caa1293..72c50f647b8076c61bcc56d7daa8e43a4d5cfda2 100644 GIT binary patch delta 938 zcmaiyO-vI(6vyZ7Zg;!=*lodft;Dpbm#Qthtw0MgLPFGog%~^#50+vJT}!v51w0u_ zW4s8)2E!y06Hi`@MzWDTcmWb6UQ8q*iXTu8dhtNi#E)R2TPTS!2C{i?W;XMG|KH5K z{H!%!vfiw*pFs#U>QSo)=us#h4Z@k}?%TXo(w7d8RnIPVX@apy1iPfR+NRiWqsxG5 z>RN{rN<5RziJ};c_6;fNgc41pV{(5$3`jn)(I*8xQm9D^H%XGeAs7e+8&qzeoi=>o zR=8$F;z~|3)}y;Mxx54mi%r2S3#T+0c>6!&5qU)e~4SO zj#}DHUrjXIWt?J`nUnM*!wj`S`3WBs&^kWc0#CKMemFs5a|B*sp$(qkJ zJKh2hNVU&!gHV^)v!E@uL!I4ce2qBNi_8a2*O+I_b$ZxfqArs2WSD3}y?hrp&w0zA zPJz&5u^7^NyCG|&EOYP>ze~b+dA46m%W#e~>9?B{I(#rH;R|VSYHR&)8Z`45@e07C zLWvYL>Ms21xJ6PnnqNiy2LFx!%zxrP@T;nQK<4q4-_V0gJmC}=ie!N-Ct}lkD|sGU zh#wo95qG4(iSNts2ER{%TU#3^+>3k4 z1!!&o@z425zMJ=Q-?;^yUFAmn42>KPHWHTyGD;@X^WP2$1Vi=G5m9W?8;Yips~RGg zVzMsD$ys7IMZJMWZUG|cq1<3h(G{tfuB*sK{^`ZPoQ_d6s&PSNIFXIVl)+Rc6&pL!sopTJh!Hm!C7Y%ZUvp3n(h+nO!HSWezaSC;(&2(R(0 delta 473 zcmZp8z}s+ucY?H_HvRYv-o*+fnuWKyg*Wdi*GW!fZ=9Cg=?If z`J@EdnD6m@+H7dBf=^6Hj9HVhEHy7Bzo&lix9G zO#kh|xM%uCH^!;kKYKCuF|lx~F+SM*lU0~YLV@!;)n?G?&GEUcXVLUf| zyDQ_*?U(!*^#wuh7hp(Z;Qh}V!gG*YnX8R6lj8>aG4^h@GFC2@WadN6mP{@{1t2hO z;zWz>X$g!)94w7|D(utmWH9!!G)XD5Z_mwS3}N2>-ht7cnUQNV;{#@c?JNrz|M-jW z@_%Ar4AF{vQ6?&4LA){L^dyGbZUua^{v6mn7yDXBK5A79#6pKkB(e7j1rR%aI$Wn+r*T|xm`1l@jB!7N4-pPmjGP2h1LK7 diff --git a/server/vendors/migrations/0003_gunmen_email.py b/server/vendors/migrations/0003_gunmen_email.py new file mode 100644 index 0000000..a55d112 --- /dev/null +++ b/server/vendors/migrations/0003_gunmen_email.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.4 on 2021-07-13 18:18 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('vendors', '0002_gunmen'), + ] + + operations = [ + migrations.AddField( + model_name='gunmen', + name='email', + field=models.EmailField(default=django.utils.timezone.now, max_length=254), + preserve_default=False, + ), + ] From 28ce552ebff2376eef97ca815b4f86f313adbb02 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 14 Jul 2021 14:48:47 +0530 Subject: [PATCH 29/98] upadte settings.py --- server/server/settings.py | 129 +++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 66 deletions(-) diff --git a/server/server/settings.py b/server/server/settings.py index 90c56dc..dbfec5e 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -12,7 +12,7 @@ from pathlib import Path from datetime import timedelta -import os +import os # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -22,7 +22,7 @@ # See https://docs.djangoproject.com/en/3.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'm7+v4@(z0^_4@c(7o48%d1n7$hy=rbr2@p)zv%6ta4*j2s&btq' +SECRET_KEY = "m7+v4@(z0^_4@c(7o48%d1n7$hy=rbr2@p)zv%6ta4*j2s&btq" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -33,58 +33,59 @@ # Application definition INSTALLED_APPS = [ - 'jazzmin', - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'corsheaders', - 'users.apps.UsersConfig', - 'vendors.apps.VendorsConfig', - 'attendance.apps.AttendanceConfig', + "jazzmin", + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "django_filters", + "corsheaders", + "users.apps.UsersConfig", + "vendors.apps.VendorsConfig", + "attendance.apps.AttendanceConfig", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'corsheaders.middleware.CorsMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "corsheaders.middleware.CorsMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'server.urls' +ROOT_URLCONF = "server.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.debug', - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.debug", + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'server.wsgi.application' +WSGI_APPLICATION = "server.wsgi.application" # Database # https://docs.djangoproject.com/en/3.1/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR,'db.sqlite3'), + "default": { + "ENGINE": "django.db.backends.sqlite3", + "NAME": os.path.join(BASE_DIR, "db.sqlite3"), } } @@ -94,16 +95,16 @@ AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] @@ -111,9 +112,9 @@ # Internationalization # https://docs.djangoproject.com/en/3.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -125,41 +126,37 @@ # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.1/howto/static-files/ -STATIC_URL = '/static/' +STATIC_URL = "/static/" -MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +MEDIA_ROOT = os.path.join(BASE_DIR, "media") -MEDIA_URL = '/media/' +MEDIA_URL = "/media/" - - -CORS_ALLOWED_ORIGINS = [ - "http://localhost:3000" -] +CORS_ALLOWED_ORIGINS = ["http://localhost:3000"] SIMPLE_JWT = { - 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=1), - 'REFRESH_TOKEN_LIFETIME': timedelta(days=10), - 'ROTATE_REFRESH_TOKENS': True, - 'BLACKLIST_AFTER_ROTATION': False, - 'ALGORITHM': 'HS256', - 'SIGNING_KEY': SECRET_KEY, - 'VERIFYING_KEY': None, - 'AUTH_HEADER_TYPES': ('JWT',), - 'USER_ID_FIELD': 'id', - 'USER_ID_CLAIM': 'user_id', - 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), - 'TOKEN_TYPE_CLAIM': 'token_type', + "ACCESS_TOKEN_LIFETIME": timedelta(minutes=1), + "REFRESH_TOKEN_LIFETIME": timedelta(days=10), + "ROTATE_REFRESH_TOKENS": True, + "BLACKLIST_AFTER_ROTATION": False, + "ALGORITHM": "HS256", + "SIGNING_KEY": SECRET_KEY, + "VERIFYING_KEY": None, + "AUTH_HEADER_TYPES": ("JWT",), + "USER_ID_FIELD": "id", + "USER_ID_CLAIM": "user_id", + "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), + "TOKEN_TYPE_CLAIM": "token_type", } REST_FRAMEWORK = { - 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema', - 'DEFAULT_PERMISSION_CLASSES': [ - 'rest_framework.permissions.AllowAny', + "DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.coreapi.AutoSchema", + "DEFAULT_PERMISSION_CLASSES": [ + "rest_framework.permissions.AllowAny", ], - 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'rest_framework_simplejwt.authentication.JWTAuthentication', + "DEFAULT_AUTHENTICATION_CLASSES": [ + "rest_framework_simplejwt.authentication.JWTAuthentication", ], } From 1ea79bbce737e467e2595996ebf0c05bcbd09337 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 14 Jul 2021 14:54:51 +0530 Subject: [PATCH 30/98] update ProfileSerializer --- server/users/serializers.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/server/users/serializers.py b/server/users/serializers.py index 8a800ad..47dd3ca 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -24,20 +24,28 @@ def to_representation(self, instance): class ProfileSerializer(serializers.ModelSerializer): class Meta: model = Profile - fields = ["user", "is_superuser", "is_incharge"] + fields = ["is_superuser", "is_incharge"] class UserSerializer(serializers.ModelSerializer): profile = RelatedFieldAlternative( queryset=Profile.objects.all(), serializer=ProfileSerializer ) + class Meta: model = User fields = ( - "id", "first_name", "last_name", - "username", "email", 'profile', - 'is_staff', 'is_active', 'is_superuser', - 'last_login', 'date_joined' + "id", + "first_name", + "last_name", + "username", + "email", + "profile", + "is_staff", + "is_active", + "is_superuser", + "last_login", + "date_joined", ) From 92e285f4ffbe3d0719daad620f19eaf7faad0068 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 14 Jul 2021 15:06:21 +0530 Subject: [PATCH 31/98] update attendance api --- server/attendance/urls.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/attendance/urls.py b/server/attendance/urls.py index c0f5ccf..07e069c 100644 --- a/server/attendance/urls.py +++ b/server/attendance/urls.py @@ -3,8 +3,8 @@ from . import views urlpatterns = [ - path("", views.AttendanceList.as_view()), - path("/", views.AttendanceDetail.as_view()), + path("attendance/", views.AttendanceList.as_view()), + path("attendance//", views.AttendanceDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) From 78083e109abb984729960e5b396fbc824e7b980e Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Wed, 14 Jul 2021 16:27:04 +0530 Subject: [PATCH 32/98] Attendance redundant update removed --- server/attendance/serializers.py | 3 +++ server/attendance/views.py | 42 ++++++++++++++++++++++++++++++- server/db.sqlite3 | Bin 225280 -> 225280 bytes 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 674e07c..207568c 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,3 +1,4 @@ +from datetime import date from vendors.models import Vendor from django.contrib.auth.models import User from users.models import Branch @@ -58,6 +59,8 @@ class Meta: "added_by", "attendance_sheet", ] + + class IssueSerializer(serializers.ModelSerializer): diff --git a/server/attendance/views.py b/server/attendance/views.py index a8d7205..70326c7 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -1,6 +1,9 @@ +from datetime import datetime +from users.models import Branch from django.shortcuts import render from rest_framework import mixins from rest_framework import generics +from rest_framework.response import Response from attendance.serializers import AttendanceSerializer from attendance.models import Attendance @@ -19,7 +22,25 @@ def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) + new_attendance = AttendanceSerializer(data=request.data) + if new_attendance.is_valid(): + today = datetime.now() + attendance = Attendance.objects.filter( + entry_time__year =today.date().year, + entry_time__month =today.date().month, + entry_time__day =today.date().day, + gunmen = new_attendance.data['gunmen']['id'], + branch = new_attendance.data['branch']['id'] + ).first() + + if attendance: + attendance.entry_time = today + if 'exit_time' in new_attendance.data: + attendance.exit_time = new_attendance.data.get('exit_time') + attendance.save() + return Response(data = AttendanceSerializer(attendance).data) + else: + return self.create(request, *args, **kwargs) class AttendanceDetail( @@ -39,3 +60,22 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) + + + + # today = date.today() + # attendance = Attendance.objects.filter( + # entry_time__year =today.year, + # entry_time__month =today.month, + # entry_time__day =today.day, + # ).first() + + + # print(attendance) + + # if attendance: + # new_attendance = AttendanceSerializer(request.data) + # if new_attendance.is_valid(): + # attendance + # attendance.save() + # else: diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 72c50f647b8076c61bcc56d7daa8e43a4d5cfda2..073fbb3b1fe7f275f31cf168022f135bbf3a9775 100644 GIT binary patch delta 2701 zcmb`JTWB0r7{_Nao9@nD=G)D!ZL&!w+ddeQPR}`WW@cv!ts6_*mnb4q#MY9Ki@C?d z5MrrQ+EnqO+889FNUV>kB1Ov|x>3wctj< z4T9?hs{|_rD+J30%LG$`NkI_QN>lvy3GpW`7@N8DhP;CnxmSWe;1~E2zK3sEc~{^w z_y|6Lc~GK#gD{W;w7=U*ooK!vF7M+(f6X0(VbC6eM>#2 zwyKqp%aNBO0}(6yXLvrJOFkO*aYmJLsfL8C$^;R-1vy(V)iLrc>0t-EzT;pkDAukivZt7`xw3;^dJT^nu1y^qW2eCLZ%$3knqrn&h~jL4 zc+;z1)3Y7RMHY4g-p-A}Ym$9cUB2uDd)PHBLT$$ltl|9!Gi@CmogEoZKX~ZSer?AF z9@Eey2U6JPp$4@HG1<^>ZJw0@+dJ3ug!*6tc0Ga(zL(evA-4C1^ueK__LTuGRm_LR zRs5`HVgnT9O{^e-Wsi@po%pN)3A}1bsTG%QC`gO z*-eO;6E?Zal(J$9Gq6EyWZKACW~7Q6Z1t$)*obBejqOR*=d}kX3Q^Cp4eSz(NP)6) zqPK&%<*Gii4b!ETjSB`D@HM|!fa#gUz{KL4<<^)30f}Nh_DsiMPX~Js6f8x+_v5Pt z+-SUP28d;vmQ}F&fq+2?-Z{UjP`{5}69a1^hDV!y&R!P(vf@2bV1@FL1aBMbt zyD|ow>Xh6+U5o@iszUtqbnig*%-mf{3oEW!f)C*g9ETye8=AGUv|6l*#)ARhJ1s*N%l|~whxrQr3#2ud7o4RyUCE@GZ zp_28|)o3Wp5hUs{UvvbmZoS`O1tSMcVTcpNVdK`SjV?lNWg|2(8qux&`5ImG=tiHf z$Ls4IaC-*4M$bYnY37pD<5Z9)_{0Z_IKvCBkV6_zxDz4UFw?tqP*}1AUnt`pZ+I3k zk84~YD=Zew>>=%SDm*}Nig|RXuj-mQsk-z2ne)E>`B zTP>S%foi{FT|Uz4C6s?#2qE1A0-jFD Date: Wed, 14 Jul 2021 16:27:55 +0530 Subject: [PATCH 33/98] nm --- server/attendance/views.py | 1 + server/db.sqlite3 | Bin 225280 -> 225280 bytes 2 files changed, 1 insertion(+) diff --git a/server/attendance/views.py b/server/attendance/views.py index a8d7205..9b65501 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -1,4 +1,5 @@ from django.shortcuts import render +from django.utils.translation import override from rest_framework import mixins from rest_framework import generics from attendance.serializers import AttendanceSerializer diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 72c50f647b8076c61bcc56d7daa8e43a4d5cfda2..4a04a016b051b4de80b8d7e77280dff1413ed9d4 100644 GIT binary patch delta 990 zcmZ{jPe>F|9LML)xNGCi%y*|KC_OBShUt!P-u&6!Auz2|hwhS58|y(N-PF2>tQgd_ z=&%P*b?IV%WWgnZ?4XyzBnrZyF!GQ_1VMVpL+{N-;<_>Lfr0Pm`+M`=o2fN@YE8f0 zNc!$HohE&AmsTxe-VM4Qk@_1OUFD4~(wJ{EF(ctOe&GjRVFT~+221#Yk66G{l<*J_ za1S#jGk+B)A_^gf88RLcA&roFNG)Wnxb&EG^X^#*JJ`lge8*Sb`U$IehZVf!GhW~s z<}ruak~uYvmO4cxra)W(0)~Jtpb5l^D+|PHGh@7T5e0M@-;DdlWur;|px@McwH<9y zo7T>0$71WT*^-@@jum`Um3olWiAoq{c9N!&wwthN;J5*EEywrl6!orL8yn9Kj}49{ zhO+tW*r1`fapAT9-=nsl@vjez=CZ@%iJ_69?D&A8FbJ!4*D6$v^IWc_D&xc~F^U;g z(m%%zJkQGb%uW05Ugwk^Ivqq+t3JyPY{&8`b?p>)it=l6v|#v}h}YT$8hF&A4r5N* z*}n^CVxhNx408j=vphS^7~SWcpJ>kJas#>MATcpHdBLdfZ4fo>#m~#+(5?PuQtn@t zpEO7Lh2RfA{8b!By(CEuQI1GN9JQ<{s@lL`Wo%b&&~Er}&G7u1ti`oTr$o8g$(!FI zSuezo_)a{{R Date: Wed, 14 Jul 2021 16:32:59 +0530 Subject: [PATCH 34/98] Issue CRUD routes --- server/attendance/views.py | 44 ++++++++++++++++++++++++------------- server/db.sqlite3 | Bin 225280 -> 225280 bytes 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 70326c7..70e626b 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -4,8 +4,8 @@ from rest_framework import mixins from rest_framework import generics from rest_framework.response import Response -from attendance.serializers import AttendanceSerializer -from attendance.models import Attendance +from attendance.serializers import AttendanceSerializer, IssueSerializer +from attendance.models import Attendance, Issue # from vendors.models import Gunmen # from vendors.serializers import GunmenSerializer @@ -62,20 +62,34 @@ def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) +class IssueList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): + queryset = Issue.objects.all() + serializer_class = IssueSerializer + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + + +class IssueDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Issue.objects.all() + serializer_class = IssueSerializer - # today = date.today() - # attendance = Attendance.objects.filter( - # entry_time__year =today.year, - # entry_time__month =today.month, - # entry_time__day =today.day, - # ).first() + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) - # print(attendance) + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) - # if attendance: - # new_attendance = AttendanceSerializer(request.data) - # if new_attendance.is_valid(): - # attendance - # attendance.save() - # else: diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 073fbb3b1fe7f275f31cf168022f135bbf3a9775..28dbd7085ef81ab6c6bf6863350701415e4d2e49 100644 GIT binary patch delta 248 zcmZp8z}xVEcY-uy$Ne9r}!-%`f%aU+Ob%f2q$TeL#qv{~iPXAO7$BpZMSM zzu>iK4m$(?1^(6iz5Mz7f&4oB?Ayfxm_PC{DT_|mi)R++ ov9K~S*E2A)G&M72nywSiEXi$dWooErXl!U?YPdZho_T`+07SJ;NB{r; delta 214 zcmZp8z}xVEcY-uy`9v9K#`28`9r}zS%`f%aU+Ob%f2q$TeL#qf|1ksqAO7$BpZMSM zzui}Z1hXN From 563cb4f7dd4fcdba02b5bf70da5b79e1497ab53f Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Wed, 14 Jul 2021 16:34:00 +0530 Subject: [PATCH 35/98] issue urls --- server/attendance/urls.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/attendance/urls.py b/server/attendance/urls.py index 07e069c..565f17a 100644 --- a/server/attendance/urls.py +++ b/server/attendance/urls.py @@ -5,6 +5,8 @@ urlpatterns = [ path("attendance/", views.AttendanceList.as_view()), path("attendance//", views.AttendanceDetail.as_view()), + path("issue/", views.IssueList.as_view()), + path("issue//", views.IssueDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) From a5cc4ba7ca0bd246c1563ad252dec39238ecf8e9 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 14 Jul 2021 16:43:47 +0530 Subject: [PATCH 36/98] nm --- server/attendance/views.py | 19 ++++++++----------- server/db.sqlite3 | Bin 225280 -> 225280 bytes server/vendors/urls.py | 2 ++ 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index cbc8806..960cd11 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -27,19 +27,19 @@ def post(self, request, *args, **kwargs): if new_attendance.is_valid(): today = datetime.now() attendance = Attendance.objects.filter( - entry_time__year =today.date().year, - entry_time__month =today.date().month, - entry_time__day =today.date().day, - gunmen = new_attendance.data['gunmen']['id'], - branch = new_attendance.data['branch']['id'] + entry_time__year=today.date().year, + entry_time__month=today.date().month, + entry_time__day=today.date().day, + gunmen=new_attendance.data["gunmen"]["id"], + branch=new_attendance.data["branch"]["id"], ).first() if attendance: attendance.entry_time = today - if 'exit_time' in new_attendance.data: - attendance.exit_time = new_attendance.data.get('exit_time') + if "exit_time" in new_attendance.data: + attendance.exit_time = new_attendance.data.get("exit_time") attendance.save() - return Response(data = AttendanceSerializer(attendance).data) + return Response(data=AttendanceSerializer(attendance).data) else: return self.create(request, *args, **kwargs) @@ -62,8 +62,6 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) - - # today = date.today() # attendance = Attendance.objects.filter( # entry_time__year =today.year, @@ -71,7 +69,6 @@ def delete(self, request, *args, **kwargs): # entry_time__day =today.day, # ).first() - # print(attendance) # if attendance: diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 4a04a016b051b4de80b8d7e77280dff1413ed9d4..49d1f85a721d58759656a5656fa9136cbc3422bf 100644 GIT binary patch delta 259 zcmZp8z}xVEcY-uy%tRSy#+Z!>9r}zM%`f%aU+Ob%f2q$TeSnLZ{}TiMAO7$BpSJUT zV0ywY!@|tT$N?gln3*{_xfmE2(3S9`DcQ_;fLQ>=AO&U|27Lh8^^O0-c0L2*pk)f`Exvrs!f}xp} jv8k1*k)DO6iMgRAvW%gX0Yt{s%)r2adHd>k=1>6u0gycP delta 235 zcmZp8z}xVEcY-uykBc9r}#y%`f%aU+Ob%f2q$TeSnLJ|2qT!AO7$BFShf2 zV0ywY!@$76%F4pb$;iaa%*n|G`ia`p@I1Ks*vg;fFlkI#4%#Zll zfCjNKv2Oon&&&rhU^N5(1^(6iHrx3EnB(}TyT=2CjjfC=^~?+njLj`sfXY>;JH#`K X@)%i}8t4H94UCMKwy%z74ix|ZjpaC% diff --git a/server/vendors/urls.py b/server/vendors/urls.py index 1b196d4..12d52f6 100644 --- a/server/vendors/urls.py +++ b/server/vendors/urls.py @@ -5,6 +5,8 @@ urlpatterns = [ path("gunmen/", views.GunmenList.as_view()), path("gunmen//", views.GunmenDetail.as_view()), + path("vehicle/", views.VehicleList.as_view()), + path("vehicle//", views.VehicleDetail.as_view()), path("vendor/", views.VendorList.as_view()), path("vendor//", views.VendorDetail.as_view()), ] From 4406c6fec4270f6187814a3bdaed1e585ec8ccbe Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Wed, 14 Jul 2021 16:51:46 +0530 Subject: [PATCH 37/98] Vehicle Model Added --- server/db.sqlite3 | Bin 225280 -> 229376 bytes server/vendors/admin.py | 10 +++++- server/vendors/migrations/0004_vehicle.py | 23 +++++++++++++ server/vendors/models.py | 9 +++++ server/vendors/serializers.py | 19 ++++++----- server/vendors/urls.py | 2 ++ server/vendors/views.py | 39 ++++++++++++++++++++-- 7 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 server/vendors/migrations/0004_vehicle.py diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 28dbd7085ef81ab6c6bf6863350701415e4d2e49..3622be10a912349fd9e29bdc9f5892c85f748db8 100644 GIT binary patch delta 1334 zcmZuwZ)h837{B-KlFKFS`?Ota+J?$CX{#Zoxy!#c*D#E0-A1*Y?Xcn;UD90FbX~gC z*iN?5WEN4J%yO`UL1D!&4v{*Jaefg8DnbXXU!)*Xru!f&6xo-4QSrSrH(BuDeUA5e ze((D{@ALeAr3dw;68^~3xJ*%0KUvndvie*EE#EnF6Y7VFuSKXQww+&BxrPYMuj{D> zg^z~YZIq`wwW#E?^9yf^q8OcARAzEhb4pkYOF^+OC`AQHlBI|oiS z`4H>zSjnm{0sZ0OPQ(D-Qn}|lXuL&`pWx;uU@4EMT2~dS|1#o5Owu)|awiH7SJ^e^ znsAYug>RgrO)Tn0u$WVptVbl9S>#8MRpykUVmSv6oKrLD{MpA&xsgRa1nF$nf+ckI zRH4Wu@tVqgUvS_Jd>em^*GQ@k+-hSGf@H-GRIFUF3H|QwOXZ;14HTttrvBSHz3!rG zir?o?I5r$ToMankKV@5(%P5Ndl^)($UG3MV&!8>m%Fr<9?(0ME`L&S@YBzp;pYEa! ze;(~1g8&vB#=Em5UhD#`a1DJ}tI^wn=bI<32ZoV# z#6%qk=P^z`z&)uP6L;XTa6*FMd;wETZc9xjitH_jv0~7dzo>J?k-WZ8cKifDQ_ delta 596 zcmXAmVMtR^6vyAW@44&VwtKd6$`Ijg+J`~54b$eZ&@d2+3i`01V2-&Zft#yk3?!Z= zeQ1k{2VE!#gT7YE!(Ly?vPf94`XYtF8V({M3hHyzopJde&i$PO=YQ_ib*9%{w>mvV zNszy_!ozpMAri?mjc3-Lsn;zK~6Gu?pZe_Fxqs;91l$ zk2mos##n{@Vl}pGM#49kkJTg}WYd=uiJ5eEB6s0p;@qX|R60wI%Dx-~j96#@qDDS6 z=4E0^n>|@5h`wYtl}Rka$WgXp&<{;=keMsBV{^T&pCl$_ zBuBS;jlQKN+f0k9q~tYukc>(hJk8cvuz7?PNxEZr@5j$)%-v0#N3l!&cX$Luw$5-Kz9H13WUkWthzCx|aIt)bHcKrPh8h*y_ z_!aA>M_fAE+ItdSPzR@|MZZZaGR9gdvg_)1A~>u*mGQf1ItR_y7O^ diff --git a/server/vendors/admin.py b/server/vendors/admin.py index eba28dc..7a1cac5 100644 --- a/server/vendors/admin.py +++ b/server/vendors/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin from django.db import models -from .models import Vendor +from .models import Vendor, Vehicle class VendorAdmin(admin.ModelAdmin): list_display = ('id', 'name','address','email', 'contact', 'officer_incharge', 'created_at') @@ -9,5 +9,13 @@ class VendorAdmin(admin.ModelAdmin): search_fields = ('id', 'name', 'email', 'officer_incharge') list_per_page = 20 + +class VehicleAdmin(admin.ModelAdmin): + list_display = ('id', 'model_name', 'number_plate', 'vendor') + list_display_links = ('vendor', ) + search_fields = ('id', 'model_name', 'vendor', 'number_plate') + list_per_page = 20 + admin.site.register(Vendor, VendorAdmin) +admin.site.register(Vehicle, VehicleAdmin) diff --git a/server/vendors/migrations/0004_vehicle.py b/server/vendors/migrations/0004_vehicle.py new file mode 100644 index 0000000..d47b0bb --- /dev/null +++ b/server/vendors/migrations/0004_vehicle.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.4 on 2021-07-14 11:13 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('vendors', '0003_gunmen_email'), + ] + + operations = [ + migrations.CreateModel( + name='Vehicle', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('model_name', models.CharField(max_length=200)), + ('number_plate', models.CharField(max_length=200)), + ('vendor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vendors.Vendor')), + ], + ), + ] diff --git a/server/vendors/models.py b/server/vendors/models.py index bdce035..f42078f 100644 --- a/server/vendors/models.py +++ b/server/vendors/models.py @@ -25,3 +25,12 @@ class Gunmen(models.Model): def __str__(self) -> str: return f'{self.first_name} {self.last_name}' + +class Vehicle(models.Model): + model_name = models.CharField(max_length=200) + number_plate = models.CharField(max_length=200) + vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + + def __str__(self) -> str: + return f'{self.model_name} -> {self.number_plate}' + diff --git a/server/vendors/serializers.py b/server/vendors/serializers.py index 3e51a1d..a38d88c 100644 --- a/server/vendors/serializers.py +++ b/server/vendors/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from .models import Vendor, Gunmen +from .models import Vehicle, Vendor, Gunmen class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): @@ -44,11 +44,12 @@ class Meta: model = Gunmen fields = ["id", "first_name", "last_name", "email", "vendor"] - # def create(self, validated_data): - # vendor_data = validated_data.pop("vendor") - # vendor_data = Vendor.objects.filter(vendor_data) - # print(vendor_data) - # gunman = Gunmen.objects.create(**validated_data) - # # for track_data in tracks_data: - # # Track.objects.create(album=album, **track_data) - # return gunman + +class VehicleSerializer(serializers.ModelSerializer): + vendor = RelatedFieldAlternative( + queryset=Vendor.objects.all(), serializer=VendorSerializer + ) + + class Meta: + model = Vehicle + fields = ["id", "model_name", "number_plate", "vendor"] \ No newline at end of file diff --git a/server/vendors/urls.py b/server/vendors/urls.py index 1b196d4..82bccb5 100644 --- a/server/vendors/urls.py +++ b/server/vendors/urls.py @@ -7,6 +7,8 @@ path("gunmen//", views.GunmenDetail.as_view()), path("vendor/", views.VendorList.as_view()), path("vendor//", views.VendorDetail.as_view()), + path("vehicle/", views.VehicleList.as_view()), + path("vehicle//", views.VehicleDetail.as_view()), ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/server/vendors/views.py b/server/vendors/views.py index 5d81724..d5ad351 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -1,8 +1,8 @@ from django.shortcuts import render from rest_framework import mixins from rest_framework import generics -from .models import Vendor, Gunmen -from .serializers import VendorSerializer, GunmenSerializer +from .models import Vehicle, Vendor, Gunmen +from .serializers import VehicleSerializer, VendorSerializer, GunmenSerializer from django_filters.rest_framework import DjangoFilterBackend from rest_framework import filters @@ -59,7 +59,6 @@ class GunmenList( queryset = Gunmen.objects.all() serializer_class = GunmenSerializer filter_backends = [DjangoFilterBackend, filters.SearchFilter] - # filter_backends = [DjangoFilterBackend] search_fields = ["^first_name", "^last_name"] filterset_fields = ["first_name", "last_name", "vendor"] @@ -87,3 +86,37 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) + +class VehicleList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): + queryset = Vehicle.objects.all() + serializer_class = VehicleSerializer + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^model_name", "^number_plate"] + filterset_fields = ["model_name", "vendor", "number_plate"] + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + + +class VehicleDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Vehicle.objects.all() + serializer_class = VehicleSerializer + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) From aec5e9a390f92e9e688f369d7dc3354ef2bb58f8 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 14 Jul 2021 16:52:49 +0530 Subject: [PATCH 38/98] nm --- server/attendance/views.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 7eef3e2..39c036f 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -62,16 +62,6 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) -<<<<<<< HEAD - # today = date.today() - # attendance = Attendance.objects.filter( - # entry_time__year =today.year, - # entry_time__month =today.month, - # entry_time__day =today.day, - # ).first() - - # print(attendance) -======= class IssueList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView @@ -103,5 +93,3 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) ->>>>>>> 4406c6fec4270f6187814a3bdaed1e585ec8ccbe - From 43deafdb2fabf11bdfb8720d5a03d669d5f35878 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 14 Jul 2021 16:53:29 +0530 Subject: [PATCH 39/98] nm --- server/vendors/urls.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/server/vendors/urls.py b/server/vendors/urls.py index 6598639..82bccb5 100644 --- a/server/vendors/urls.py +++ b/server/vendors/urls.py @@ -5,8 +5,6 @@ urlpatterns = [ path("gunmen/", views.GunmenList.as_view()), path("gunmen//", views.GunmenDetail.as_view()), - path("vehicle/", views.VehicleList.as_view()), - path("vehicle//", views.VehicleDetail.as_view()), path("vendor/", views.VendorList.as_view()), path("vendor//", views.VendorDetail.as_view()), path("vehicle/", views.VehicleList.as_view()), From 2e558148b7210feb06b4e2fa1765bf292e0a2b7b Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Thu, 15 Jul 2021 00:09:22 +0530 Subject: [PATCH 40/98] added pagination and user search filters --- server/attendance/admin.py | 33 +++++++----- server/attendance/serializers.py | 2 - server/attendance/views.py | 23 ++++++++ server/db.sqlite3 | Bin 225280 -> 237568 bytes server/users/admin.py | 17 +++--- .../migrations/0003_auto_20210714_2341.py | 25 +++++++++ server/users/models.py | 38 ++++++++----- server/users/serializers.py | 4 +- server/users/views.py | 38 +++++++++++++ server/vendors/admin.py | 23 +++++--- server/vendors/views.py | 50 +++++++++++++----- 11 files changed, 193 insertions(+), 60 deletions(-) create mode 100644 server/users/migrations/0003_auto_20210714_2341.py diff --git a/server/attendance/admin.py b/server/attendance/admin.py index c433734..93b8a79 100644 --- a/server/attendance/admin.py +++ b/server/attendance/admin.py @@ -1,28 +1,33 @@ from django.contrib import admin -from .models import * +from .models import * + class AttendanceSheetAdmin(admin.ModelAdmin): - list_display = ('id', 'sheet_created') - list_display_links = ('id', 'sheet_created') + list_display = ("id", "sheet_created") + list_display_links = ("id", "sheet_created") list_per_page = 20 + class GunmenAdmin(admin.ModelAdmin): - list_display = ('id', 'first_name','last_name', 'vendor') - list_display_links = ('id', 'vendor') - search_fields = ('first_name', 'last_name', 'vendor') - list_per_page = 20 + list_display = ("id", "first_name", "last_name", "vendor") + list_display_links = ("id", "vendor") + search_fields = ("first_name", "last_name", "vendor") + list_per_page = 20 + class AttendanceAdmin(admin.ModelAdmin): - list_display = ('id', 'gunmen','entry_time', 'exit_time', 'branch_id') - list_display_links = ('id', 'gunmen') - search_fields = ('gunmen',) - list_per_page = 20 + list_display = ("id", "gunmen", "entry_time", "exit_time", "branch_id") + list_display_links = ("id", "gunmen") + search_fields = ("gunmen",) + list_per_page = 20 + class IssueAdmin(admin.ModelAdmin): - list_display = ('id', 'comment', 'vendor', 'reverted_by', 'sheet', 'created_at') - list_display_links = ('id','comment') - list_per_page = 20 + list_display = ("id", "comment", "vendor", "reverted_by", "sheet", "created_at") + list_display_links = ("id", "comment") + list_per_page = 20 + admin.site.register(Attendance, AttendanceAdmin) admin.site.register(AttendanceSheet, AttendanceSheetAdmin) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 207568c..901fc5b 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -59,8 +59,6 @@ class Meta: "added_by", "attendance_sheet", ] - - class IssueSerializer(serializers.ModelSerializer): diff --git a/server/attendance/views.py b/server/attendance/views.py index 39c036f..be5ee98 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -7,17 +7,39 @@ from rest_framework.response import Response from attendance.serializers import AttendanceSerializer, IssueSerializer from attendance.models import Attendance, Issue +from rest_framework.pagination import PageNumberPagination +from rest_framework.response import Response # from vendors.models import Gunmen # from vendors.serializers import GunmenSerializer from rest_framework import filters +class CustomPagination(PageNumberPagination): + page_size = 2 + page_size_query_param = "page_size" + max_page_size = 1000 + + def get_paginated_response(self, data): + return Response( + { + "links": { + "next": self.get_next_link(), + "previous": self.get_previous_link(), + }, + "count": self.page.paginator.count, + "page_size": self.page_size, + "results": data, + } + ) + + class AttendanceList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView ): queryset = Attendance.objects.all() serializer_class = AttendanceSerializer + pagination_class = CustomPagination def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -68,6 +90,7 @@ class IssueList( ): queryset = Issue.objects.all() serializer_class = IssueSerializer + pagination_class = CustomPagination def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 49d1f85a721d58759656a5656fa9136cbc3422bf..44c1ea87e4d7b5ca6e3b973224c07c074aea53c9 100644 GIT binary patch delta 2049 zcmah~e`phT6#stjF1cK;y>FUTVvTm!t2K?aZ7x6BBrRfR>knpA-TXCOIg{qvrY32U z{!+v>vFZj^wl27njiO@%CkX0-1_U>88*B>I{WTB~QP|iRRrZGncChayO)*v27w+YI z?|r`Sec!wHK1n_-P2S)>F_*~z055(DYjSFh1Im~8eU3_fShs{P#nQ|K)3m`sF{hbe zrp>U58Mm7?z+BTdDo2BZi6NWK=9EU|{!mX?w%hDty{)-kbn>FxD~evbt-;l7_lQj` z%QV2$(l#Td zCt8VS(3j|altgj#Hu7?}xPQ0@$jD_fqU|JCq3(f+iOOS=l#4FK5`(>=u$;ctu&LHy zCM`^nx|}5IVQ|17?HiQ*!AK}7g$MhLX>Vf_Y)!`-D=Bmh7}M#-RS>1GHFj9cdR!yK z-2rHpdyK>Wi*BQP=sG%!PM}@rAnHdVcL%lO%be%R-=NH9IA6E*mnIi zGsg_+KG2@kJl6!MUx*Z(fg}c~>$9n;S~9iTr_3HFgzWVX2_KcUM&WNT+q)0e(Anby zu!Vs7417r1v_^Capi^1hS$G0z)rhoF`QjoBkw$b*p)bK|0-ei>m*6;pM&-iya5rgW zH!1WDY+yIxn=faB0V4z2kYzt);G*$xcwL?bJbR+kDdzf=-B|c=@+^WAMU1!?1kHKyHl_BF+_6!&0WzGvq-0fT0oKv z^KDXV&^`m`84xmM$-j_Z2Wg%vojW_3Bz}h+eH!RgPmZA0w6QAZA$^0U$CfSp4&UZ&J36cYq>KsLw5<-NTp?V$1M~A(7!&-fQlJzHN@U`=2aV)`lgpbpvx;i*9HtY|C z<(Iu;@S;~i>DmvMYI6LXZYyzVBZHU|Bqb%oN;WzY3CIa47WNM-PkW(RsULuQ#`Q7U z)M#t)r%Fm))LTx7}T2uPRQs$o87E`D}|&0*`8ig(!m6GpL;GgR9Hz zMJTT)s;b=@Pl^lC%Kd)m&AvNHT&^ZtwX=A*h`5dp&|cc8oyC7zQSG?UssXU3zK9~% z`=h){nfyFuu4=&;tGI|WRaBlu7jWJ@u9!wuTwYVa@g9t;u2Y%SROlHMh2IO1?9nWd z{0LLxF@PSSAJEt6Sk|zP96{BUWZS~b+h1W)N;RhkBFnNjyU4Y?L7iSqW9ky{Q-w$M ZZ-Q=751_C!KDret8QHuwu0bKbSvf z&YbKco_*oDT<+^4gfvT4N`X|axH$w}caL62Pf(_743FIXu4ks|4cS3s%4I+EHUzOo{7gtlBq;`=v2ISI5n6| zspkBaAAh({N~Qa^v6`_4NSx?S^`_(9iNXF@jt252Ujlj+O zjj>w4CU0}TL~xle;VS+SpWt)+4W}`Whwv=+VG#G&zLO8Ry|l9u80U+o+PYqn2i#t4 zuL2f!o2J^4k#8$^+vYDBMPqs!;d7pGy-mWfZnq6QU>d_K1h1gL|7~A(9F-cjAI$av z!@hUkZFoaQU|XcAIkL57OQ@we&}9E}BNSj^K5MFfuUPNk_UyvG(FW&#gp(fPuGS{h zKh=E6h(lA3vpLp6_mCbu%;$Lh%KFlgtHokiO!q*oN?SHsH}iCpRZ^h5xjKinYFS+! zj2$`MeQY2(d@3p1dU7b;)BjykwfkT!+8HxCqr3LStkFCzHDh|v+BHcnN4@?#+_L-y z8i7iyvp^4O609$)uZOX;b*Dfp!LTl-V6FA4K%a|024Oo@ str: - return f'{self.name} -> {self.region}' - \ No newline at end of file + return f"{self.name} -> {self.region}" + + +class Profile(models.Model): + GENDER_CHOICES = ( + ("M", "Male"), + ("F", "Female"), + ("O", "Other"), + ) + user = models.OneToOneField(User, on_delete=models.CASCADE) + gender = models.CharField(max_length=6, choices=GENDER_CHOICES, unique=True) + branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) + is_superuser = models.BooleanField(default=False) + is_incharge = models.BooleanField(default=False) + + def __str__(self): + return f"{self.user.username} Profile" diff --git a/server/users/serializers.py b/server/users/serializers.py index 47dd3ca..ecaf33b 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -22,9 +22,11 @@ def to_representation(self, instance): class ProfileSerializer(serializers.ModelSerializer): + # branch = RelatedFieldAlternative(queryset=Branch.objects.all()) + class Meta: model = Profile - fields = ["is_superuser", "is_incharge"] + fields = ["id", "gender", "branch", "is_superuser", "is_incharge"] class UserSerializer(serializers.ModelSerializer): diff --git a/server/users/views.py b/server/users/views.py index deb05e1..89211e2 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -5,11 +5,46 @@ from rest_framework import generics from django_filters.rest_framework import DjangoFilterBackend from rest_framework import filters +from rest_framework.pagination import PageNumberPagination +from rest_framework.response import Response + + +class CustomPagination(PageNumberPagination): + page_size = 2 + page_size_query_param = "page_size" + max_page_size = 1000 + + def get_paginated_response(self, data): + return Response( + { + "links": { + "next": self.get_next_link(), + "previous": self.get_previous_link(), + }, + "count": self.page.paginator.count, + "page_size": self.page_size, + "results": data, + } + ) class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = User.objects.all() serializer_class = UserSerializer + pagination_class = CustomPagination + + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^first_name", "^last_name", "^username", "^email"] + filterset_fields = [ + "first_name", + "last_name", + "username", + "email", + "profile__gender", + "is_staff", + "is_active", + "is_superuser", + ] def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -42,6 +77,7 @@ class BranchList( ): queryset = Branch.objects.all() serializer_class = BranchSerializer + pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^name", "^address"] filterset_fields = ["name", "address", "branch_manager", "region"] @@ -77,6 +113,8 @@ class RegionList( ): queryset = Region.objects.all() serializer_class = RegionSerializer + pagination_class = CustomPagination + filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^name", "^address"] filterset_fields = ["name", "address", "regional_officer"] diff --git a/server/vendors/admin.py b/server/vendors/admin.py index 7a1cac5..f4b15d0 100644 --- a/server/vendors/admin.py +++ b/server/vendors/admin.py @@ -3,19 +3,28 @@ from .models import Vendor, Vehicle + class VendorAdmin(admin.ModelAdmin): - list_display = ('id', 'name','address','email', 'contact', 'officer_incharge', 'created_at') - list_display_links = ('id', 'name') - search_fields = ('id', 'name', 'email', 'officer_incharge') + list_display = ( + "id", + "name", + "address", + "email", + "contact", + "officer_incharge", + "created_at", + ) + list_display_links = ("id", "name") + search_fields = ("id", "name", "email", "officer_incharge") list_per_page = 20 class VehicleAdmin(admin.ModelAdmin): - list_display = ('id', 'model_name', 'number_plate', 'vendor') - list_display_links = ('vendor', ) - search_fields = ('id', 'model_name', 'vendor', 'number_plate') + list_display = ("id", "model_name", "number_plate", "vendor") + list_display_links = ("vendor",) + search_fields = ("id", "model_name", "vendor", "number_plate") list_per_page = 20 + admin.site.register(Vendor, VendorAdmin) admin.site.register(Vehicle, VehicleAdmin) - diff --git a/server/vendors/views.py b/server/vendors/views.py index d5ad351..7e37892 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -5,6 +5,27 @@ from .serializers import VehicleSerializer, VendorSerializer, GunmenSerializer from django_filters.rest_framework import DjangoFilterBackend from rest_framework import filters +from rest_framework.pagination import PageNumberPagination +from rest_framework.response import Response + + +class CustomPagination(PageNumberPagination): + page_size = 2 + page_size_query_param = "page_size" + max_page_size = 1000 + + def get_paginated_response(self, data): + return Response( + { + "links": { + "next": self.get_next_link(), + "previous": self.get_previous_link(), + }, + "count": self.page.paginator.count, + "page_size": self.page_size, + "results": data, + } + ) class VendorList( @@ -12,21 +33,19 @@ class VendorList( ): queryset = Vendor.objects.all() serializer_class = VendorSerializer + pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] - # filter_backends = [DjangoFilterBackend] - search_fields = ["^name", - "^address", - "^contact", - "^officer_incharge"] + search_fields = ["^name", "^address", "^contact", "^officer_incharge"] filterset_fields = [ - "name", - "address", - "email", - "contact", - "officer_incharge", - "created_by", - "created_at" + "name", + "address", + "email", + "contact", + "officer_incharge", + "created_by", + "created_at", ] + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -58,6 +77,7 @@ class GunmenList( ): queryset = Gunmen.objects.all() serializer_class = GunmenSerializer + pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^first_name", "^last_name"] filterset_fields = ["first_name", "last_name", "vendor"] @@ -68,7 +88,7 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) - + class GunmenDetail( mixins.RetrieveModelMixin, mixins.UpdateModelMixin, @@ -87,11 +107,13 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) + class VehicleList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView ): queryset = Vehicle.objects.all() serializer_class = VehicleSerializer + pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^model_name", "^number_plate"] filterset_fields = ["model_name", "vendor", "number_plate"] @@ -102,7 +124,7 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) - + class VehicleDetail( mixins.RetrieveModelMixin, mixins.UpdateModelMixin, From 948b59f5f46befb714a19aa3d041c2707965eab4 Mon Sep 17 00:00:00 2001 From: mustankap Date: Thu, 15 Jul 2021 15:50:56 +0530 Subject: [PATCH 41/98] time query range filter --- .vscode/settings.json | 3 +++ server/attendance/models.py | 2 +- server/attendance/views.py | 23 ++++++++++++++++++++--- server/users/views.py | 6 +++--- server/vendors/views.py | 8 ++++---- 5 files changed, 31 insertions(+), 11 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..de288e1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.formatting.provider": "black" +} \ No newline at end of file diff --git a/server/attendance/models.py b/server/attendance/models.py index 11b9822..e29460c 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -12,7 +12,7 @@ class AttendanceSheet(models.Model): def __str__(self): return f'{self.sheet_created} -> {self.verified}' - + class Attendance(models.Model): entry_time = models.DateTimeField(default=datetime.now) diff --git a/server/attendance/views.py b/server/attendance/views.py index be5ee98..6b9d3cc 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -7,12 +7,14 @@ from rest_framework.response import Response from attendance.serializers import AttendanceSerializer, IssueSerializer from attendance.models import Attendance, Issue +from django_filters.rest_framework import DjangoFilterBackend from rest_framework.pagination import PageNumberPagination +from rest_framework import filters from rest_framework.response import Response +import datetime # from vendors.models import Gunmen # from vendors.serializers import GunmenSerializer -from rest_framework import filters class CustomPagination(PageNumberPagination): @@ -35,11 +37,26 @@ def get_paginated_response(self, data): class AttendanceList( - mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView + mixins.ListModelMixin, + mixins.CreateModelMixin, + generics.GenericAPIView, + filters.FilterSet, ): queryset = Attendance.objects.all() serializer_class = AttendanceSerializer pagination_class = CustomPagination + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^gunmen__first_name", "^gunmen__last_name"] + filterset_fields = { + "entry_time": ["exact"], + "exit_time": ["exact"], + "gunmen": ["exact"], + "added_by": ["exact"], + "branch": ["exact"], + "attendance_sheet": ["exact"], + } + + ordering_fields = "__all__" def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -65,7 +82,6 @@ def post(self, request, *args, **kwargs): else: return self.create(request, *args, **kwargs) - class AttendanceDetail( mixins.RetrieveModelMixin, mixins.UpdateModelMixin, @@ -91,6 +107,7 @@ class IssueList( queryset = Issue.objects.all() serializer_class = IssueSerializer pagination_class = CustomPagination + ordering_fields = "__all__" def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) diff --git a/server/users/views.py b/server/users/views.py index 89211e2..37469dd 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -45,7 +45,7 @@ class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericA "is_active", "is_superuser", ] - + ordering_fields = '__all__' def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -81,7 +81,7 @@ class BranchList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^name", "^address"] filterset_fields = ["name", "address", "branch_manager", "region"] - + ordering_fields = '__all__' def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -118,7 +118,7 @@ class RegionList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^name", "^address"] filterset_fields = ["name", "address", "regional_officer"] - + ordering_fields = '__all__' def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) diff --git a/server/vendors/views.py b/server/vendors/views.py index 7e37892..ca0d1c2 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -45,7 +45,7 @@ class VendorList( "created_by", "created_at", ] - + ordering_fields = '__all__' def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -61,7 +61,7 @@ class VendorDetail( ): queryset = Vendor.objects.all() serializer_class = VendorSerializer - + ordering_fields = '__all__' def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) @@ -81,7 +81,7 @@ class GunmenList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^first_name", "^last_name"] filterset_fields = ["first_name", "last_name", "vendor"] - + ordering_fields = '__all__' def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -117,7 +117,7 @@ class VehicleList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^model_name", "^number_plate"] filterset_fields = ["model_name", "vendor", "number_plate"] - + ordering_fields = '__all__' def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) From fa1c482e488fdd75274c309b1e235463d8a7129f Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Fri, 16 Jul 2021 00:24:32 +0530 Subject: [PATCH 42/98] added user create and update for nested serializers --- .gitignore | 1 + requests.http | 1 + server/attendance/views.py | 7 ++- server/db.sqlite3 | Bin 237568 -> 249856 bytes server/users/apps.py | 8 +-- .../migrations/0004_auto_20210715_1603.py | 25 +++++++++ .../migrations/0005_auto_20210715_1604.py | 27 ++++++++++ .../migrations/0006_auto_20210715_1609.py | 18 +++++++ server/users/models.py | 4 +- server/users/serializers.py | 49 ++++++++++++++++-- server/users/signals.py | 24 +++++---- server/users/views.py | 2 + 12 files changed, 148 insertions(+), 18 deletions(-) create mode 100644 requests.http create mode 100644 server/users/migrations/0004_auto_20210715_1603.py create mode 100644 server/users/migrations/0005_auto_20210715_1604.py create mode 100644 server/users/migrations/0006_auto_20210715_1609.py diff --git a/.gitignore b/.gitignore index 96e233c..b750978 100644 --- a/.gitignore +++ b/.gitignore @@ -193,3 +193,4 @@ sketch npm-debug.log* yarn-debug.log* yarn-error.log* +/requests.txt \ No newline at end of file diff --git a/requests.http b/requests.http new file mode 100644 index 0000000..0391eb8 --- /dev/null +++ b/requests.http @@ -0,0 +1 @@ +PUT http://localhost:8000/api/users/user HTTP/1.1 \ No newline at end of file diff --git a/server/attendance/views.py b/server/attendance/views.py index be5ee98..05baa1a 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -9,10 +9,12 @@ from attendance.models import Attendance, Issue from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response +from django_filters.rest_framework import DjangoFilterBackend +from rest_framework import filters +from rest_framework.pagination import PageNumberPagination # from vendors.models import Gunmen # from vendors.serializers import GunmenSerializer -from rest_framework import filters class CustomPagination(PageNumberPagination): @@ -40,6 +42,9 @@ class AttendanceList( queryset = Attendance.objects.all() serializer_class = AttendanceSerializer pagination_class = CustomPagination + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^gunmen__first_name", "^gunmen__last_name"] + filterset_fields = ["gunmen", "branch"] def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 44c1ea87e4d7b5ca6e3b973224c07c074aea53c9..d116515a45ce3a96f0be361fe6f0f934540be16a 100644 GIT binary patch delta 6005 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 S|8vO4FuqBj7@osI=l=kSVNk{Z diff --git a/server/users/apps.py b/server/users/apps.py index f910dd7..1e547f5 100644 --- a/server/users/apps.py +++ b/server/users/apps.py @@ -1,8 +1,8 @@ - from django.apps import AppConfig class UsersConfig(AppConfig): - name = 'users' - def ready(self): - import users.signals \ No newline at end of file + name = "users" + + # def ready(self): + # import users.signals diff --git a/server/users/migrations/0004_auto_20210715_1603.py b/server/users/migrations/0004_auto_20210715_1603.py new file mode 100644 index 0000000..6cd4039 --- /dev/null +++ b/server/users/migrations/0004_auto_20210715_1603.py @@ -0,0 +1,25 @@ +# Generated by Django 3.0.4 on 2021-07-15 10:33 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('users', '0003_auto_20210714_2341'), + ] + + operations = [ + migrations.RemoveField( + model_name='profile', + name='id', + ), + migrations.AlterField( + model_name='profile', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/server/users/migrations/0005_auto_20210715_1604.py b/server/users/migrations/0005_auto_20210715_1604.py new file mode 100644 index 0000000..90cf79e --- /dev/null +++ b/server/users/migrations/0005_auto_20210715_1604.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.4 on 2021-07-15 10:34 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('users', '0004_auto_20210715_1603'), + ] + + operations = [ + migrations.AddField( + model_name='profile', + name='id', + field=models.AutoField(auto_created=True, default=1, primary_key=True, serialize=False, verbose_name='ID'), + preserve_default=False, + ), + migrations.AlterField( + model_name='profile', + name='user', + field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/server/users/migrations/0006_auto_20210715_1609.py b/server/users/migrations/0006_auto_20210715_1609.py new file mode 100644 index 0000000..c6e4cdf --- /dev/null +++ b/server/users/migrations/0006_auto_20210715_1609.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.4 on 2021-07-15 10:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0005_auto_20210715_1604'), + ] + + operations = [ + migrations.AlterField( + model_name='profile', + name='gender', + field=models.CharField(choices=[('M', 'Male'), ('F', 'Female'), ('O', 'Other')], max_length=6), + ), + ] diff --git a/server/users/models.py b/server/users/models.py index 56bb8ff..5cc96bd 100644 --- a/server/users/models.py +++ b/server/users/models.py @@ -1,5 +1,7 @@ from django.db import models from django.contrib.auth.models import User +from django.db.models.signals import post_save +from django.dispatch import receiver # Create your models here. @@ -35,7 +37,7 @@ class Profile(models.Model): ("O", "Other"), ) user = models.OneToOneField(User, on_delete=models.CASCADE) - gender = models.CharField(max_length=6, choices=GENDER_CHOICES, unique=True) + gender = models.CharField(max_length=6, choices=GENDER_CHOICES) branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) is_superuser = models.BooleanField(default=False) is_incharge = models.BooleanField(default=False) diff --git a/server/users/serializers.py b/server/users/serializers.py index ecaf33b..b55cc02 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -30,9 +30,12 @@ class Meta: class UserSerializer(serializers.ModelSerializer): - profile = RelatedFieldAlternative( - queryset=Profile.objects.all(), serializer=ProfileSerializer - ) + # profile = RelatedFieldAlternative( + # queryset=Profile.objects.all(), serializer=ProfileSerializer + # ) + profile = ProfileSerializer(required=False) + # password = serializers.CharField(write_only=True, required=False) + # confirm_password = serializers.CharField(write_only=True, required=False) class Meta: model = User @@ -50,6 +53,46 @@ class Meta: "date_joined", ) + def create(self, validated_data): + user_data = validated_data.copy() + profile_data = validated_data.pop("profile") + user = User.objects.create(**validated_data) + profile = Profile.objects.create(user=user, **profile_data) + profile.save() + return user + + def update(self, instance, validated_data): + if "first_name" in validated_data: + instance.first_name = validated_data["first_name"] + if "last_name" in validated_data: + instance.last_name = validated_data["last_name"] + if "email" in validated_data: + instance.email = validated_data["email"] + if "username" in validated_data: + instance.username = validated_data["username"] + profile = Profile.objects.filter(user=instance).first() + if "profile" in validated_data: + profile_data = validated_data.pop("profile") + if profile: + if "gender`" in profile_data: + profile.gender = profile_data["gender"] + if "branch" in profile_data: + profile.branch = profile_data["branch"] + if "is_superuser" in profile_data: + profile.is_superuser = profile_data["is_superuser"] + if profile.is_superuser: + profile.is_incharge = profile.is_superuser + if "is_incharge" in profile_data: + profile.is_incharge = profile_data["is_incharge"] + if profile.is_incharge == False: + profile.is_superuser = False + profile.save() + else: + profile = Profile.objects.create(user=instance, **profile_data) + profile.save() + instance.save() + return instance + class RegionSerializer(serializers.ModelSerializer): regional_officer = RelatedFieldAlternative( diff --git a/server/users/signals.py b/server/users/signals.py index 492c8c7..e513185 100644 --- a/server/users/signals.py +++ b/server/users/signals.py @@ -1,17 +1,23 @@ from django.db.models.signals import post_save from django.contrib.auth.models import User from django.dispatch import receiver -from .models import Profile +from .models import Profile - -@receiver(post_save,sender = User) -def created_profile(sender,instance,created,**kwargs): +@receiver(post_save, sender=User) +def created_profile(sender, instance, created, **kwargs): if created: - Profile.objects.create(user =instance) - + profile_data = instance.pop("profile") + # create profile + Profile.objects.get_or_create( + user=instance, + gender=profile_data["gender"], + branch=profile_data["branch"], + # etc... + ) + # Profile.objects.create(user=instance) -@receiver(post_save,sender = User) -def save_profile(sender,instance,**kwargs): - instance.profile.save() \ No newline at end of file +@receiver(post_save, sender=User) +def save_profile(sender, instance, **kwargs): + instance.profile.save() diff --git a/server/users/views.py b/server/users/views.py index 89211e2..5f54e74 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -7,6 +7,7 @@ from rest_framework import filters from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response +from rest_framework import status class CustomPagination(PageNumberPagination): @@ -29,6 +30,7 @@ def get_paginated_response(self, data): class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): + # permission_classes = (IsAuthenticatedOrWriteOnly,) queryset = User.objects.all() serializer_class = UserSerializer pagination_class = CustomPagination From 13fdbada74549d632321be3cb3bf1aa75cce47fd Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Fri, 16 Jul 2021 00:31:50 +0530 Subject: [PATCH 43/98] debugging --- server/attendance/views.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index a8f9dbb..ef17901 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -11,13 +11,7 @@ from rest_framework.pagination import PageNumberPagination from rest_framework import filters from rest_framework.response import Response -<<<<<<< HEAD -from django_filters.rest_framework import DjangoFilterBackend -from rest_framework import filters -from rest_framework.pagination import PageNumberPagination -======= -import datetime ->>>>>>> 948b59f5f46befb714a19aa3d041c2707965eab4 +from datetime import datetime # from vendors.models import Gunmen # from vendors.serializers import GunmenSerializer @@ -46,7 +40,7 @@ class AttendanceList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView, - filters.FilterSet, + # filters.FilterSet, ): queryset = Attendance.objects.all() serializer_class = AttendanceSerializer @@ -88,6 +82,7 @@ def post(self, request, *args, **kwargs): else: return self.create(request, *args, **kwargs) + class AttendanceDetail( mixins.RetrieveModelMixin, mixins.UpdateModelMixin, From 4151822922ce46710d8d7bcdab0ce946e381d455 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Fri, 16 Jul 2021 16:48:24 +0530 Subject: [PATCH 44/98] Generate password and send mail --- server/db.sqlite3 | Bin 249856 -> 249856 bytes server/server/settings.py | 8 ++++++++ server/users/serializers.py | 31 +++++++++++++++++++++++++------ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index d116515a45ce3a96f0be361fe6f0f934540be16a..a59f2d2f589e250b2f681b658e67d04a5ffd640a 100644 GIT binary patch delta 2333 zcma)-TZkJ~7{@c4md#|FJ-gIeO?I2T#B17QZYMJnDK?wkO|zRxve|5s8PS@1W|B#= z$>h=nn{Fux`eLcDh^T!M#fMf`2>M{XJP1+{go=eC_41(Af(Tw7d~jyE*3xaY^YC#< zzWMP#|L;HN96tk&p8+q}kWWvI`FDP5a0T9YJNJ%j#BLci+L3fiDIIAw^Ns1#54t}_ zMmB$R+c49B<)mTwW6R0S$%(GzsS}S4?Bq`F^felpZjG#T7}zLQ8~7@0QB1qs5;JhM z%TnboFRygNG7q_cAPTb;F*55Tc&UtY$%HJ#1&ND?OJS*uane#p`#&7uNlrRFQMX{Ct)>n6iOKaVp+K&hU9rX7bv!F z^d06}@g!Rol3hQa3^#-%EC1bzUc50Kadj(c(1OA#)T z!Z8v%@ff08b^1zgV)JU%ikJpK-vBOy{^n@?E%1QD$RYn{fqsF%<`PYyzAJ|)uDv>tU8rb=H9wv+G1FL#E0&&97IvlQqPog1>#7vlqR6Zfisx; zIDCtVxlTP)B*jM55m~{76-JD%bi1{7rr~t@-EA0U+zo{#6N=z=ciQD>t;9Ja%)x)Q zhj6PJ9(_+Pyt;x5%2E91GK02l8G?-MKCe(L( zoeHr~pi=FIDlY8s)uK(Q9bJk=l2GCn7ZOY1Rk|AIm{dD0M+ASBsw_u(*pjR$&4a2O zLX~qjYA7#BxhRIEF?M})^8ZDJ3XxERpYyR|Wz`WZuBJn5_h>TPZ7)}y^Yor6|G+S(h4UH9qU;xGoCatvPjviE_cbC`f)^PmTw1 zM}V2>R3Yvr>G)x8B^|+%;Z&3yAz?Kvmy7q-{*99@LVE5 zROY#ZO1`Q1ifOTWb6_wpL3kE_~$hTuR%aez2;Z-;v|-;?RZRkim$} z&a2NM;|7Ca2t1E~Kf#OOdGHE&7hC{8gKxl>;C1kUdW6WpXEN?Vv~O^FYe7tHEvQM0 zdZ6EMb__M{Mf7dh{`p_&>zH0`dbMtp&mu3Wkf%2W&mrV4a13-o15`i(JgrK$UWeFp zh)svsbcjud*mQ`^x^eP6a@=S~XEp{uR3YYb<`d>P`X~A_I-{O*~J8JNa?#Utu za&u_(^H+6|fiz7KB-E_g`22Ik`uMVvE)*u3N?K_(r=EP~nJ0JH2A*q?%RMcFXeGz9?HYe1gomi#q{pP**~TWvTPTGc}dbm zPz)ppl2AF+4x4em?LWJ5nuQROxaNV@ZN1U`z%7>PaEw%M2@i>>?S$HX;QkHd0?Ob($Z6jknJuyAkuV*X#rRYj)$_3H6Hm!~nhp zpY(SfGWLOepV4_adZFbdE>n!e*-5RcEtby delta 394 zcmXAi-z!657{}jd@0pz~&UY(6cKm2(l9n*dg$pT5E-3jEP!tIZYge)~DOa>~?&e&$ zH_pY2n`z}nyHb;j5xX;1Qn+#9MLo~+eR`fg-*3`F(!yQ~W%gS~oEg?Txp6Xk+UwQp zd^|ui@%8zs_}bj6KiwJ5liPj{xAfJJmSErD~y5Yh%DW@tgQv++8nw&^{pJK8WayR@(ziA4VOZ>H}KJM2Ve zmwfnQ3JMGbyy6MBxRurd9Iq^0IPO*%bN>OSS>=uESTtQ0b%`O1JlMDT%;_8{=E^Z0 z$Y08IWvSox#l~T#a+Kt{=fQMc%2Uud@;G{QlM2)zKCTI)wF;^X-}u5isxt8&JJoL;wH) diff --git a/server/server/settings.py b/server/server/settings.py index dbfec5e..fceecf8 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -160,3 +160,11 @@ "rest_framework_simplejwt.authentication.JWTAuthentication", ], } + +EMAIL_BACKEND ='django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = 'smtp.gmail.com' +EMAIL_USE_TLS = True +EMAIL_PORT = 587 +# TODO: Setup the email and password +EMAIL_HOST_USER = '' +EMAIL_HOST_PASSWORD = '' \ No newline at end of file diff --git a/server/users/serializers.py b/server/users/serializers.py index b55cc02..5c1523b 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -1,5 +1,8 @@ +from secrets import token_hex +from django.core.mail import send_mail from rest_framework import serializers from django.contrib.auth.models import User +from django.contrib.auth.hashers import make_password from .models import Profile, Region, Branch @@ -22,7 +25,7 @@ def to_representation(self, instance): class ProfileSerializer(serializers.ModelSerializer): - # branch = RelatedFieldAlternative(queryset=Branch.objects.all()) + branch = RelatedFieldAlternative(queryset=Branch.objects.all()) class Meta: model = Profile @@ -34,8 +37,6 @@ class UserSerializer(serializers.ModelSerializer): # queryset=Profile.objects.all(), serializer=ProfileSerializer # ) profile = ProfileSerializer(required=False) - # password = serializers.CharField(write_only=True, required=False) - # confirm_password = serializers.CharField(write_only=True, required=False) class Meta: model = User @@ -54,11 +55,18 @@ class Meta: ) def create(self, validated_data): - user_data = validated_data.copy() profile_data = validated_data.pop("profile") - user = User.objects.create(**validated_data) + random_password = token_hex(6).upper() + encoded_password = make_password(random_password) + user = User.objects.create(**validated_data, password=encoded_password) profile = Profile.objects.create(user=user, **profile_data) - profile.save() + + # mail( + # subject='CMS Login Credentials', + # message=f'Username: {user.username} Password: {random_password}', + # to_mail= [user.email], + # ) + return user def update(self, instance, validated_data): @@ -115,3 +123,14 @@ class BranchSerializer(serializers.ModelSerializer): class Meta: model = Branch fields = ["id", "name", "address", "branch_manager", "region"] + + + +def mail(subject, message, to_mail): + send_mail( + subject, + message, + from_email=None, + recipient_list = [to_mail], + fail_silently=False, + ) \ No newline at end of file From 4a6fcfb70062ac06e7d3fcbc998bead046abb558 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Fri, 16 Jul 2021 17:04:41 +0530 Subject: [PATCH 45/98] simplify update --- server/users/serializers.py | 42 +++++++++++++------------------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/server/users/serializers.py b/server/users/serializers.py index 5c1523b..021af33 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -70,34 +70,22 @@ def create(self, validated_data): return user def update(self, instance, validated_data): - if "first_name" in validated_data: - instance.first_name = validated_data["first_name"] - if "last_name" in validated_data: - instance.last_name = validated_data["last_name"] - if "email" in validated_data: - instance.email = validated_data["email"] - if "username" in validated_data: - instance.username = validated_data["username"] + instance.first_name = validated_data.get("first_name", instance.first_name) + instance.last_name = validated_data.get("last_name", instance.last_name) + instance.email = validated_data.get("email", instance.email) + instance.username = validated_data.get("username", instance.username) + profile = Profile.objects.filter(user=instance).first() - if "profile" in validated_data: - profile_data = validated_data.pop("profile") - if profile: - if "gender`" in profile_data: - profile.gender = profile_data["gender"] - if "branch" in profile_data: - profile.branch = profile_data["branch"] - if "is_superuser" in profile_data: - profile.is_superuser = profile_data["is_superuser"] - if profile.is_superuser: - profile.is_incharge = profile.is_superuser - if "is_incharge" in profile_data: - profile.is_incharge = profile_data["is_incharge"] - if profile.is_incharge == False: - profile.is_superuser = False - profile.save() - else: - profile = Profile.objects.create(user=instance, **profile_data) - profile.save() + profile_data = validated_data.pop("profile") + if profile: + profile.gender = profile_data.get("gender", profile.gender) + profile.branch = profile_data.get("branch", profile.branch) + profile.is_superuser = profile_data.get("is_superuser", profile.is_superuser) + profile.is_incharge = profile_data.get("is_incharge", profile.is_incharge) + profile.save() + else: + profile = Profile.objects.create(user=instance, **profile_data) + profile.save() instance.save() return instance From b4ee2cfbf7623828ba3e19a80b9fdcc873b77027 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Fri, 16 Jul 2021 20:42:17 +0530 Subject: [PATCH 46/98] nm --- server/attendance/views.py | 1 - server/db.sqlite3 | Bin 249856 -> 249856 bytes server/users/serializers.py | 6 ++++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index ef17901..cd69d75 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -11,7 +11,6 @@ from rest_framework.pagination import PageNumberPagination from rest_framework import filters from rest_framework.response import Response -from datetime import datetime # from vendors.models import Gunmen # from vendors.serializers import GunmenSerializer diff --git a/server/db.sqlite3 b/server/db.sqlite3 index d116515a45ce3a96f0be361fe6f0f934540be16a..2dd48b3c9dadf93bc5220d0c68cb3205a6fd12f6 100644 GIT binary patch delta 138 zcmZozz~8Wde}XjQ{E0HojPo}pEbM3D*I;1Y%sN4tpM`;e!DF({{A+ON0TuK_Ax3D0k`hI0}>EXKQ3zk diff --git a/server/users/serializers.py b/server/users/serializers.py index b55cc02..00bece3 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -52,11 +52,13 @@ class Meta: "last_login", "date_joined", ) + # extra_kwargs = {"password": {"write_only": True}} def create(self, validated_data): - user_data = validated_data.copy() + # password = validated_data.pop("password") profile_data = validated_data.pop("profile") user = User.objects.create(**validated_data) + # user.set_password(password) profile = Profile.objects.create(user=user, **profile_data) profile.save() return user @@ -74,7 +76,7 @@ def update(self, instance, validated_data): if "profile" in validated_data: profile_data = validated_data.pop("profile") if profile: - if "gender`" in profile_data: + if "gender" in profile_data: profile.gender = profile_data["gender"] if "branch" in profile_data: profile.branch = profile_data["branch"] From 65f6b60f756a2f14046fc37a97d40b1ce9e4a085 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Fri, 16 Jul 2021 22:21:04 +0530 Subject: [PATCH 47/98] attendance date range filtering --- server/attendance/views.py | 53 ++++++++++++++++++++++++------------- server/db.sqlite3 | Bin 249856 -> 249856 bytes server/server/settings.py | 2 +- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index ef17901..78f22e0 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -59,28 +59,43 @@ class AttendanceList( ordering_fields = "__all__" def get(self, request, *args, **kwargs): - return self.list(request, *args, **kwargs) + params = request.query_params + start_date = params.get('start_date', datetime.min) + end_date = params.get('end_date', datetime.max) + + queryset = self.filter_queryset(self.get_queryset()) + queryset = queryset.filter(entry_time__date__range=[start_date, end_date]) + + page = self.paginate_queryset(queryset) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + + serializer = self.get_serializer(queryset, many=True) + return Response(serializer.data) + def post(self, request, *args, **kwargs): new_attendance = AttendanceSerializer(data=request.data) - if new_attendance.is_valid(): - today = datetime.now() - attendance = Attendance.objects.filter( - entry_time__year=today.date().year, - entry_time__month=today.date().month, - entry_time__day=today.date().day, - gunmen=new_attendance.data["gunmen"]["id"], - branch=new_attendance.data["branch"]["id"], - ).first() - - if attendance: - attendance.entry_time = today - if "exit_time" in new_attendance.data: - attendance.exit_time = new_attendance.data.get("exit_time") - attendance.save() - return Response(data=AttendanceSerializer(attendance).data) - else: - return self.create(request, *args, **kwargs) + if not new_attendance.is_valid(): + return Response(data='invalid request') + + today = datetime.now() + attendance = Attendance.objects.filter( + entry_time__year=today.date().year, + entry_time__month=today.date().month, + entry_time__day=today.date().day, + gunmen=new_attendance.data["gunmen"]["id"], + branch=new_attendance.data["branch"]["id"], + ).first() + + if attendance: + attendance.entry_time = today + attendance.exit_time = new_attendance.data.get("exit_time", attendance.exit_time) + attendance.save() + return Response(data=AttendanceSerializer(attendance).data) + else: + return self.create(request, *args, **kwargs) class AttendanceDetail( diff --git a/server/db.sqlite3 b/server/db.sqlite3 index a59f2d2f589e250b2f681b658e67d04a5ffd640a..141f0c209378eb348ad2828aaae64eb2e83c37a9 100644 GIT binary patch delta 1871 zcma)+ZERCj7{~AF-Dq#O+ovN88Qsg>))6OJdtck$5|pmnx=n7o%>iM!Kv_%IZC$%{ zb8881GyCGp2c(HjNW>Wz4JHIg4UHzcg+&sL$r417D8`^Bf*OzyNCGjQ+ioaBqshtX z$?bW5&;LBn|D5SLn4W{9CUp7LayPns_P~5qC2d$Pfa`$Z19%hc@EDB1PB;o%;7h|b z!*ZsYIc3;XvYD)>o(m2KqNDNs`QM5%(nY1u9zdmq@%~_NEQPG4Ml)SPRw4iRSpWX< zcyP2XwZ-}bqEemK2+HqGU9xUK>oeD_CRR@tw-AQ&^lWhpPU0wj_JwU^p)yPyIC zQXV}h@q;1Oo)jn9*hI`8Wu=jT-!Yiz_cnzj#nUD#P0bTMo;Ja^r;S(mWn9`1zt6 zMZ5K<_2txyxK1GoW{h<-F;h?I%4oZea-}{xzHutNx4pYN*wq?qk2IQ-t#V(dGPKja zH_As3IyeVwcZawxM`vI}Xm9k!xr44YDZ&eTeDUq=(FDt}1O9Lz7>q@tqrn}ah(A1J z>5E2IkIUI|$8|U**&?&DotI{CqyMIWj-?ilZ@rXGyB)3e(aw?G z)2I+j^HE|P}TzHpK#N_<9hLZi{sFpl6ZjKg$BKNo_Hda?}V&t12&#OckMmro~d zk!Gk*Yv<5Yde{aMxWEeaxawC7=>rR>U^AEtNra$Qor`MJSzoQrG?Vt6Mjztn#7u5A4gdXmR$T?ZT!b_rH7dg-Pa3na)GX8krPP1(jz(D`-62u=}rloJGD!YzCqdOHzCn6@@lmkMY_&#FRP zq0wMGzE&m23oD~P8ems*v!W_Xkez~5p~rLt_XxO`DVe?rT7oDb5mj+6ra{IGS|p8| z^sr38efS-2!>{lYd=KBk6}SY;cz*`c?<}B->@QWCO|f+dZW3@4fBq3l02LC|v~D#c zXFE5iDd@mk9?jIDDKNfOuxP}8-p7fudWO6W>HGUNkS$`#-*QVGe%R&-xCTowpEc|t zUxTVj()GZKkG_UvddWw+FcNE5m3|D{tVl-)0-~tDjF+o}$U1rHfl!fQS!Zrk(7DoF zCEzLsd=9nMXdPiHr5aXTu9`fQH~a%voQshK46ay;fIILrdTLp;fBeIUPj7G6){x28!5(ORD$Vh?7 z*JQa*$27rjX2wSm#920-ob6H@6HzKAJB2(!G?9=;0+pgv^B>A0Dz!a~15*Dsk@4DOSIVMF~Cp!cTn17kt8dEQ*uIh+1v3k$qjJl=8Ul&>sl)DVMuC*S-Jyb48Q!M8ZcgByNt;E5h84>XX!pUQAN| zrqXn7DHZC7$cBV9e8m!8;ThVvhlYp@z#G@;L2FP&XI*IxU98}<5PE}-I;+m|e3RZr OwBv%D=AAYjw*CU@@u4OF diff --git a/server/server/settings.py b/server/server/settings.py index fceecf8..92bcc3c 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -167,4 +167,4 @@ EMAIL_PORT = 587 # TODO: Setup the email and password EMAIL_HOST_USER = '' -EMAIL_HOST_PASSWORD = '' \ No newline at end of file +EMAIL_HOST_PASSWORD = '' From 001436ed41d4a660848d4345b132128a4d5b9734 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Fri, 16 Jul 2021 22:40:42 +0530 Subject: [PATCH 48/98] nm --- .gitignore | 3 ++- server/attendance/views.py | 6 +++--- server/db.sqlite3 | Bin 249856 -> 249856 bytes server/users/serializers.py | 40 ++++++------------------------------ server/users/views.py | 11 ++++++---- server/vendors/views.py | 14 ++++++++----- 6 files changed, 27 insertions(+), 47 deletions(-) diff --git a/.gitignore b/.gitignore index b750978..a7a2e58 100644 --- a/.gitignore +++ b/.gitignore @@ -193,4 +193,5 @@ sketch npm-debug.log* yarn-debug.log* yarn-error.log* -/requests.txt \ No newline at end of file +/requests.txt +/requests.http \ No newline at end of file diff --git a/server/attendance/views.py b/server/attendance/views.py index cd69d75..7d997e8 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -17,7 +17,7 @@ class CustomPagination(PageNumberPagination): - page_size = 2 + page_size = 10 page_size_query_param = "page_size" max_page_size = 1000 @@ -47,8 +47,8 @@ class AttendanceList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^gunmen__first_name", "^gunmen__last_name"] filterset_fields = { - "entry_time": ["exact"], - "exit_time": ["exact"], + "entry_time": ["gte", "lte", "exact", "gt", "lt"], + "exit_time": ["gte", "lte", "exact", "gt", "lt"], "gunmen": ["exact"], "added_by": ["exact"], "branch": ["exact"], diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 2dd48b3c9dadf93bc5220d0c68cb3205a6fd12f6..ce3f570a24833c9ddf0cfec3962ec27f391fa31f 100644 GIT binary patch delta 849 zcmaixPe>F|9LL|A*?+U>{+hN$9K~HNBawCI&7U22gqY2Pm!$CEB_yp~hHQ4-)%=qp zyV!O&_Aq!63+iH&vCu$=%)Ci-6a*+f5DahN^ZUK;=e^%6u0e4P zmRs=pgVuh${$lh|xa~4(2pqcL3t)H!4?%$@$ioOM!+F>Z99G&R?*l=$neJj{(%IC+ zL{>~U3}&Sp-B=q_AucR)JptK?&4-bXc-P~dH2$&Q_Cys*?q zxd%(`q>>*`^p4+9q(nlRpPkCYCujA!DS19OFU~2(oqXkM)`dBdj}TcEc~z2o6e%tc zWvLHW_m@8wB6bgleH2&-EZDEGxpn9~M-SrvWmA>?0u^TCC$otli1&_Gt)o>O!ZZhI z)4PU63et9L7kJz>#(vJc{T#2@#e(VGaEb*hxq$}&b7pB17irGFVtU`$1^u6|bgDy* zEG#aL_@m7xeuqQW&m9cz1`Mx}{k0;5TI{1egG(A_5E}}gZ5NqglAF$^kCTX^@I;XW zKAxByvmY{}Pv0dc4k8FDQB*Ph@+##zb;bvK2!6va_yOPHGkk&%uxA^#z}(x!-S=J8 zV;8O2)80mK0NYlBMq3bWqm#Iv`0ry;*1;9J!-*b3@C|lh3!Z`rMYsh+cC-qGkk5mH zEYq&*q9NLgW{A!VLf$$S3_;fg%@C^CQ^&+0x=u8sI#`y1vS!FmZ_rhP lk|F7mW=K^?*PvswWwEL)NY$t#tGj}@1|3!1^dv`*{sAto<(>cl delta 320 zcmZozz~8Wde}XjQ{E0HojPo}pERvUvXW-^%WZ{3w&&a=ve<8m)zc_y(zYqTeel`AU z{F?;}9`Z5rPiE8?Wt5yOu5YR;D9WtKQI?vQl3!FDpI(}mo0`Ypz#zm~TAT_LC@9KL z%gjmLT&O?UfQ^yw5Ch+#&58;;_&A!Z8CiW>SRE%ns8`thDo=`$jgkKj1OJ`Pf(@7W zH{Ypek{2{pFf_0-wzM)a(6cZ$wlFtsem`&f`+1C_jLee!+0)qGECTH;0!+(U1egst82KMD01?M_9tY;_{1X?*Z-3;^tR%3R>>>>>> 4a6fcfb70062ac06e7d3fcbc998bead046abb558 profile = Profile.objects.create(user=user, **profile_data) # mail( @@ -74,7 +67,7 @@ def create(self, validated_data): # message=f'Username: {user.username} Password: {random_password}', # to_mail= [user.email], # ) - + return user def update(self, instance, validated_data): @@ -84,38 +77,18 @@ def update(self, instance, validated_data): instance.username = validated_data.get("username", instance.username) profile = Profile.objects.filter(user=instance).first() -<<<<<<< HEAD - if "profile" in validated_data: - profile_data = validated_data.pop("profile") - if profile: - if "gender" in profile_data: - profile.gender = profile_data["gender"] - if "branch" in profile_data: - profile.branch = profile_data["branch"] - if "is_superuser" in profile_data: - profile.is_superuser = profile_data["is_superuser"] - if profile.is_superuser: - profile.is_incharge = profile.is_superuser - if "is_incharge" in profile_data: - profile.is_incharge = profile_data["is_incharge"] - if profile.is_incharge == False: - profile.is_superuser = False - profile.save() - else: - profile = Profile.objects.create(user=instance, **profile_data) - profile.save() -======= profile_data = validated_data.pop("profile") if profile: profile.gender = profile_data.get("gender", profile.gender) profile.branch = profile_data.get("branch", profile.branch) - profile.is_superuser = profile_data.get("is_superuser", profile.is_superuser) + profile.is_superuser = profile_data.get( + "is_superuser", profile.is_superuser + ) profile.is_incharge = profile_data.get("is_incharge", profile.is_incharge) profile.save() else: profile = Profile.objects.create(user=instance, **profile_data) profile.save() ->>>>>>> 4a6fcfb70062ac06e7d3fcbc998bead046abb558 instance.save() return instance @@ -143,12 +116,11 @@ class Meta: fields = ["id", "name", "address", "branch_manager", "region"] - def mail(subject, message, to_mail): send_mail( subject, message, from_email=None, - recipient_list = [to_mail], + recipient_list=[to_mail], fail_silently=False, - ) \ No newline at end of file + ) diff --git a/server/users/views.py b/server/users/views.py index 3b5b02f..3feca77 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -11,7 +11,7 @@ class CustomPagination(PageNumberPagination): - page_size = 2 + page_size = 10 page_size_query_param = "page_size" max_page_size = 1000 @@ -47,7 +47,8 @@ class UserList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericA "is_active", "is_superuser", ] - ordering_fields = '__all__' + ordering_fields = "__all__" + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -83,7 +84,8 @@ class BranchList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^name", "^address"] filterset_fields = ["name", "address", "branch_manager", "region"] - ordering_fields = '__all__' + ordering_fields = "__all__" + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -120,7 +122,8 @@ class RegionList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^name", "^address"] filterset_fields = ["name", "address", "regional_officer"] - ordering_fields = '__all__' + ordering_fields = "__all__" + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) diff --git a/server/vendors/views.py b/server/vendors/views.py index ca0d1c2..b0d257e 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -10,7 +10,7 @@ class CustomPagination(PageNumberPagination): - page_size = 2 + page_size = 10 page_size_query_param = "page_size" max_page_size = 1000 @@ -45,7 +45,8 @@ class VendorList( "created_by", "created_at", ] - ordering_fields = '__all__' + ordering_fields = "__all__" + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -61,7 +62,8 @@ class VendorDetail( ): queryset = Vendor.objects.all() serializer_class = VendorSerializer - ordering_fields = '__all__' + ordering_fields = "__all__" + def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) @@ -81,7 +83,8 @@ class GunmenList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^first_name", "^last_name"] filterset_fields = ["first_name", "last_name", "vendor"] - ordering_fields = '__all__' + ordering_fields = "__all__" + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) @@ -117,7 +120,8 @@ class VehicleList( filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^model_name", "^number_plate"] filterset_fields = ["model_name", "vendor", "number_plate"] - ordering_fields = '__all__' + ordering_fields = "__all__" + def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) From 0025b826f7849dc53edddf654cc7535a44694979 Mon Sep 17 00:00:00 2001 From: mustankap Date: Fri, 16 Jul 2021 23:06:25 +0530 Subject: [PATCH 49/98] date- range --- server/attendance/views.py | 13 +++++++------ server/db.sqlite3 | Bin 249856 -> 249856 bytes 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index ef17901..310f57a 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -47,15 +47,16 @@ class AttendanceList( pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^gunmen__first_name", "^gunmen__last_name"] + filterset_fields = { - "entry_time": ["exact"], - "exit_time": ["exact"], - "gunmen": ["exact"], - "added_by": ["exact"], - "branch": ["exact"], + "entry_time": ['gte', 'lte', 'exact', 'gt', 'lt'], + "exit_time" : ['gte', 'lte', 'exact', 'gt', 'lt'], + "gunmen" : ["exact"], + "added_by" : ["exact"], + "branch" : ["exact"], "attendance_sheet": ["exact"], } - + ordering_fields = "__all__" def get(self, request, *args, **kwargs): diff --git a/server/db.sqlite3 b/server/db.sqlite3 index a59f2d2f589e250b2f681b658e67d04a5ffd640a..07d0c58cad3f6768a0d510a40e2db7b4bb320277 100644 GIT binary patch delta 1099 zcmaiyUuY9a7{F(Cnl_uJ`C3FuNUhuD6hxZL?qstjh0~mAL*;g3OGS)IyJp+CZS%*} zKbMGDyguH8XW;TCJt)UL9Gns~B8Z~+;Dh=if+#-t=1Z%-wurkaMX8D~%nUQX`SE@8 zee;VjzX+ED`0<}T`(2MwaPN!j=Hm7quWz{p-U5c(@HeQ?4X5B&xC}etxo^4NCp__O z>GG3Z{MpI8St!koudh`c+KR<$cPNVa>PRSu`P%gfytV!;M5%{(hmh}n$AWjre!s_i z?9u>nX$!8nTA-9=*i>nzGFOgBXQx=0p0dpRi7+)Qx!HoA$SPWLIIJZG&!v;YEOmHT z*5pB^Rfd_K7@g4*GfFBsC~K9>Z~C-W)~3_5)!ssYl=X7;W3Du+A3kt0ozu#xG%2WUIYSQak;1A< z>kGMg&O_h|f-CR}8uhN?0_^&UX!u9T5C^LMkrV1KFZz3ZpS3iqNWXJe8{AdQaYO{A z*0zZEwn7{RK(YOAeYJ_ZxWxyei(uT|=gc0Vmi!;zv1z^5cFm#FFb29!bKuafjwT#v z!U4fKS|Xy`sD=bN7#DdIhaI~y<~OpIB2Ly!jmaz+RV67ZNx3s~ zr;WTYV-$4RN>;}BS}C)z5}7WPO{=)+Zz3@!iym8vVHLru?OlO3gjxvZ#hXPA zcizApdDr@_+k@OkAc*(W@jcRM6Ke?88XkdsfZEzP2aR@0-Z!^yyUmsmynzR>)bQ;i zf5G-%62}{neBGO*_8>*#w(=>0r*=pWVIYLvh%t=#&BcwxXk^3W)LV@)B}P@TqnXod f1g~wuGY|#biu~RD?)3&}*55dh`SRcYDUyj#lVvD& delta 316 zcmXYqu}cC`9LMkX-mAO1yx%#9l+v9Ljovw^^7wU?>@cr`TvwXY&y#N~t7&epZQ$r!1CkH3TXbeQw5FpDi9M-j_Yb9Qdf*Yq%KnSenix( z9?=L&1z%B$sCR*EiEe^_RJFy+!Th3;DP-~mH?NZOLLfe>n8iK_vuhDtzQ zx`dk$Rk+&yLkq|&x6q;1Op&Yo5T)#iCX4qln4VKi Date: Fri, 16 Jul 2021 23:32:03 +0530 Subject: [PATCH 50/98] Bulk Update --- server/attendance/views.py | 73 +++++++++++++++++++++++++------------ server/db.sqlite3 | Bin 249856 -> 249856 bytes 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 78f22e0..bd01704 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -1,19 +1,19 @@ from datetime import datetime from users.models import Branch -from django.shortcuts import render +from django.shortcuts import get_object_or_404, render from django.utils.translation import override from rest_framework import mixins from rest_framework import generics from rest_framework.response import Response from attendance.serializers import AttendanceSerializer, IssueSerializer -from attendance.models import Attendance, Issue +from attendance.models import Attendance, AttendanceSheet, Issue from django_filters.rest_framework import DjangoFilterBackend from rest_framework.pagination import PageNumberPagination from rest_framework import filters from rest_framework.response import Response from datetime import datetime - -# from vendors.models import Gunmen +from vendors.models import Gunmen +from users.models import User # from vendors.serializers import GunmenSerializer @@ -76,26 +76,51 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): - new_attendance = AttendanceSerializer(data=request.data) - if not new_attendance.is_valid(): - return Response(data='invalid request') - - today = datetime.now() - attendance = Attendance.objects.filter( - entry_time__year=today.date().year, - entry_time__month=today.date().month, - entry_time__day=today.date().day, - gunmen=new_attendance.data["gunmen"]["id"], - branch=new_attendance.data["branch"]["id"], - ).first() - - if attendance: - attendance.entry_time = today - attendance.exit_time = new_attendance.data.get("exit_time", attendance.exit_time) - attendance.save() - return Response(data=AttendanceSerializer(attendance).data) - else: - return self.create(request, *args, **kwargs) + data = request.data + branch_id = data.get('branch') + added_by_id = data.get('added_by') + gunmen_ids = data.get('gunmen_id') + attendance_sheet = data.get('attendance_sheet') + + + result = [] + + for gunmen_id in gunmen_ids: + data = { + 'gunmen': gunmen_id, + 'branch':branch_id, + 'added_by':added_by_id, + 'attendance_sheet': attendance_sheet + } + print(data) + new_attendance = AttendanceSerializer(data=data) + if not new_attendance.is_valid(): + return Response(data='invalid request') + + today = datetime.now() + attendance = Attendance.objects.filter( + entry_time__year=today.date().year, + entry_time__month=today.date().month, + entry_time__day=today.date().day, + gunmen=new_attendance.data["gunmen"]["id"], + branch=new_attendance.data["branch"]["id"], + ).first() + + if attendance: + attendance.entry_time = today + attendance.exit_time = new_attendance.data.get("exit_time", attendance.exit_time) + attendance.save() + result.append(AttendanceSerializer(attendance).data) + else: + gunmen_ = get_object_or_404(Gunmen, pk=data.pop('gunmen')) + added_by_ = get_object_or_404(User, pk=data.pop('added_by')) + branch_ = get_object_or_404(Branch, pk=data.pop('branch')) + attendance_sheet_ = get_object_or_404(AttendanceSheet, pk=data.pop('attendance_sheet')) + attendance = Attendance(gunmen=gunmen_, added_by=added_by_, branch=branch_, attendance_sheet=attendance_sheet_) + attendance.save() + result.append(AttendanceSerializer(attendance).data) + + return Response(data=result) class AttendanceDetail( diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 141f0c209378eb348ad2828aaae64eb2e83c37a9..1e0b87735a862e1962f8b4e33b87471382c0a637 100644 GIT binary patch delta 990 zcmaKqPe>GD7{=$DZ)SH#bKlj})mCZSW!*M)cK+=AX<5j%Ac8KPLv(S}2;4O{J1F8( z&{^>?9XeP99Xgb(un<93hq{Da@=!=!M58=xhXV7^_swi1C=Sdshk2gg^L@N;X$eY8 zFdstIg^u&6x;*soWb0+7!N0=6H$eUscmM_j;RXzp+rsz#e7g@D$X*^oEr?%S6EC9p zVlb)cP+}UH{ZCU1PM}*Od8;s492}d6R-SDJVvNK?r4{zF+1@TeI^OX_C7^2!uxz9?JuOS3dRCJqDdpZn4HrkPt22?DWsO*oba-ZVcA!4g-$e=WLkL=0ONoY_ zQcXp52};-+En1`h8L1j18>5iep%8^aG$W-bE=0EH-=WsZo3|)?`WOd04D7*g_z64Z z#?l6qcfJGzkGTN*)z8Bg1HYgOKVS>~kiQ?Ho5KR)sc=*<6_&$D=&U2-;9;8~s67gU zZ4y|A_5%S1u^0$jC_NkCC617#JaR)&q MPa&0!0*(&-1tYuTsQ>@~ delta 335 zcmZozz~8Wde}XjQ^@%dhjMq0NERq+CXW->K&%*zbpOJqT|3ZFqesTUnexJ<}3Ul}- zE|8vlUeBFTWwN-wshOZCvnFR*YF9)AOa5NBy|Do~)HC_gPTCzV%- zS&<{Lv?L=wy(qu5fPrChlfDJ31P8M@=k$#UjH1m~^tWHpXEZ2aR^iv2&c1-rWqaTP z#$!OMB&HkeXJnbKyPoknP|j&O`vykO&4LA=_(0;U)7|$o?qybCKRliN08l(opqPF8 z;p2>s8rxY4nEvu_Wn^Ohu$<)qqrh^O049OOEC&Qc82SG&0Fe;`1A`$D8vwD+X2FIh z{L}x$Gx77n#ZbgKma{l83$QZspJ(9Ttf(-VZ*zixG2`^}@yw=djQn>Q`0oOZxXi!( JZa%Ye0ss Date: Fri, 16 Jul 2021 23:32:17 +0530 Subject: [PATCH 51/98] cm --- server/attendance/models.py | 30 ++++++++++++++++++------------ server/attendance/views.py | 1 + 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/server/attendance/models.py b/server/attendance/models.py index e29460c..9fbc245 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -4,34 +4,40 @@ from users.models import Branch from datetime import datetime - + class AttendanceSheet(models.Model): sheet_created = models.DateField(default=datetime.now) - invoice = models.FileField(blank=True, null=True, upload_to='invoice') + invoice = models.FileField(blank=True, null=True, upload_to="invoice") verified = models.BooleanField(default=False) def __str__(self): - return f'{self.sheet_created} -> {self.verified}' - + return f"{self.sheet_created} -> {self.verified}" + class Attendance(models.Model): entry_time = models.DateTimeField(default=datetime.now) - exit_time = models.DateTimeField(blank=True,null=True) + exit_time = models.DateTimeField(blank=True, null=True) gunmen = models.ForeignKey(Gunmen, on_delete=models.SET_NULL, null=True, blank=True) - added_by = models.ForeignKey(User, on_delete=models.SET_NULL,null=True, blank=True) + added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) - attendance_sheet = models.ForeignKey(AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True) + attendance_sheet = models.ForeignKey( + AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True + ) def __str__(self): - return f'{self.gunmen.first_name} {self.gunmen.last_name}' + return f"{self.gunmen.first_name} {self.gunmen.last_name}" class Issue(models.Model): comment = models.CharField(max_length=200) vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) - reverted_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) - sheet = models.ForeignKey(AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True) + reverted_by = models.ForeignKey( + User, on_delete=models.SET_NULL, null=True, blank=True + ) + sheet = models.ForeignKey( + AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True + ) created_at = models.DateTimeField(default=datetime.now) - + def __str__(self) -> str: - return f'{self.comment} {self.vendor} {self.reverted_by} -> {self.sheet}' + return f"{self.comment} {self.vendor} {self.reverted_by} -> {self.sheet}" diff --git a/server/attendance/views.py b/server/attendance/views.py index a4f3564..648fa5d 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -75,6 +75,7 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): + new_attendance = AttendanceSerializer(data=request.data) if not new_attendance.is_valid(): return Response(data='invalid request') From 15d06af652c2a92943dc850e43f5e7685952a57b Mon Sep 17 00:00:00 2001 From: mustankap Date: Fri, 16 Jul 2021 23:32:54 +0530 Subject: [PATCH 52/98] views --- server/attendance/views.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 2aad017..5602a3f 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -47,22 +47,22 @@ class AttendanceList( pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] search_fields = ["^gunmen__first_name", "^gunmen__last_name"] - + filterset_fields = { - "entry_time": ['gte', 'lte', 'exact', 'gt', 'lt'], - "exit_time" : ['gte', 'lte', 'exact', 'gt', 'lt'], - "gunmen" : ["exact"], - "added_by" : ["exact"], - "branch" : ["exact"], + "entry_time": ["gte", "lte", "exact", "gt", "lt"], + "exit_time": ["gte", "lte", "exact", "gt", "lt"], + "gunmen": ["exact"], + "added_by": ["exact"], + "branch": ["exact"], "attendance_sheet": ["exact"], } - + ordering_fields = "__all__" def get(self, request, *args, **kwargs): params = request.query_params - start_date = params.get('start_date', datetime.min) - end_date = params.get('end_date', datetime.max) + start_date = params.get("start_date", datetime.min) + end_date = params.get("end_date", datetime.max) queryset = self.filter_queryset(self.get_queryset()) queryset = queryset.filter(entry_time__date__range=[start_date, end_date]) @@ -75,11 +75,10 @@ def get(self, request, *args, **kwargs): serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) - def post(self, request, *args, **kwargs): new_attendance = AttendanceSerializer(data=request.data) if not new_attendance.is_valid(): - return Response(data='invalid request') + return Response(data="invalid request") today = datetime.now() attendance = Attendance.objects.filter( @@ -92,7 +91,9 @@ def post(self, request, *args, **kwargs): if attendance: attendance.entry_time = today - attendance.exit_time = new_attendance.data.get("exit_time", attendance.exit_time) + attendance.exit_time = new_attendance.data.get( + "exit_time", attendance.exit_time + ) attendance.save() return Response(data=AttendanceSerializer(attendance).data) else: From 5516a5864c3a57adba0d3c1ef3d54b213f48d10d Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Mon, 19 Jul 2021 20:21:34 +0530 Subject: [PATCH 53/98] update models --- server/attendance/views.py | 75 ++++++++++++++------------------------ server/vendors/models.py | 21 +++++++---- 2 files changed, 41 insertions(+), 55 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 0fd9b68..3f998a7 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -11,14 +11,10 @@ from rest_framework.pagination import PageNumberPagination from rest_framework import filters from rest_framework.response import Response -<<<<<<< HEAD - -# from vendors.models import Gunmen -======= from datetime import datetime from vendors.models import Gunmen from users.models import User ->>>>>>> b4b10e5d4df72134348f9b3daf03058aa5552c01 + # from vendors.serializers import GunmenSerializer @@ -65,8 +61,8 @@ class AttendanceList( def get(self, request, *args, **kwargs): params = request.query_params - start_date = params.get('start_date', datetime.min) - end_date = params.get('end_date', datetime.max) + start_date = params.get("start_date", datetime.min) + end_date = params.get("end_date", datetime.max) queryset = self.filter_queryset(self.get_queryset()) queryset = queryset.filter(entry_time__date__range=[start_date, end_date]) @@ -79,51 +75,26 @@ def get(self, request, *args, **kwargs): serializer = self.get_serializer(queryset, many=True) return Response(serializer.data) - def post(self, request, *args, **kwargs): -<<<<<<< HEAD - - new_attendance = AttendanceSerializer(data=request.data) - if not new_attendance.is_valid(): - return Response(data='invalid request') - - today = datetime.now() - attendance = Attendance.objects.filter( - entry_time__year=today.date().year, - entry_time__month=today.date().month, - entry_time__day=today.date().day, - gunmen=new_attendance.data["gunmen"]["id"], - branch=new_attendance.data["branch"]["id"], - ).first() - - if attendance: - attendance.entry_time = today - attendance.exit_time = new_attendance.data.get("exit_time", attendance.exit_time) - attendance.save() - return Response(data=AttendanceSerializer(attendance).data) - else: - return self.create(request, *args, **kwargs) -======= data = request.data - branch_id = data.get('branch') - added_by_id = data.get('added_by') - gunmen_ids = data.get('gunmen_id') - attendance_sheet = data.get('attendance_sheet') - + branch_id = data.get("branch") + added_by_id = data.get("added_by") + gunmen_ids = data.get("gunmen_id") + attendance_sheet = data.get("attendance_sheet") result = [] for gunmen_id in gunmen_ids: data = { - 'gunmen': gunmen_id, - 'branch':branch_id, - 'added_by':added_by_id, - 'attendance_sheet': attendance_sheet + "gunmen": gunmen_id, + "branch": branch_id, + "added_by": added_by_id, + "attendance_sheet": attendance_sheet, } print(data) new_attendance = AttendanceSerializer(data=data) if not new_attendance.is_valid(): - return Response(data='invalid request') + return Response(data="invalid request") today = datetime.now() attendance = Attendance.objects.filter( @@ -136,20 +107,28 @@ def post(self, request, *args, **kwargs): if attendance: attendance.entry_time = today - attendance.exit_time = new_attendance.data.get("exit_time", attendance.exit_time) + attendance.exit_time = new_attendance.data.get( + "exit_time", attendance.exit_time + ) attendance.save() result.append(AttendanceSerializer(attendance).data) else: - gunmen_ = get_object_or_404(Gunmen, pk=data.pop('gunmen')) - added_by_ = get_object_or_404(User, pk=data.pop('added_by')) - branch_ = get_object_or_404(Branch, pk=data.pop('branch')) - attendance_sheet_ = get_object_or_404(AttendanceSheet, pk=data.pop('attendance_sheet')) - attendance = Attendance(gunmen=gunmen_, added_by=added_by_, branch=branch_, attendance_sheet=attendance_sheet_) + gunmen_ = get_object_or_404(Gunmen, pk=data.pop("gunmen")) + added_by_ = get_object_or_404(User, pk=data.pop("added_by")) + branch_ = get_object_or_404(Branch, pk=data.pop("branch")) + attendance_sheet_ = get_object_or_404( + AttendanceSheet, pk=data.pop("attendance_sheet") + ) + attendance = Attendance( + gunmen=gunmen_, + added_by=added_by_, + branch=branch_, + attendance_sheet=attendance_sheet_, + ) attendance.save() result.append(AttendanceSerializer(attendance).data) return Response(data=result) ->>>>>>> b4b10e5d4df72134348f9b3daf03058aa5552c01 class AttendanceDetail( diff --git a/server/vendors/models.py b/server/vendors/models.py index f42078f..973a47c 100644 --- a/server/vendors/models.py +++ b/server/vendors/models.py @@ -9,28 +9,35 @@ class Vendor(models.Model): email = models.EmailField() contact = models.CharField(max_length=20) officer_incharge = models.CharField(max_length=100) - created_by = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True) + created_by = models.ForeignKey( + User, on_delete=models.SET_NULL, blank=True, null=True + ) created_at = models.DateTimeField(default=datetime.now) - + def __str__(self): - return f'{self.name} -> {self.email}' + return f"{self.name} -> {self.email}" + - class Gunmen(models.Model): + GUNMEN_TYPES = ( + ("M", "Male"), + ("F", "Female"), + ("O", "Other"), + ) first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) email = models.EmailField() vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: - return f'{self.first_name} {self.last_name}' + return f"{self.first_name} {self.last_name}" class Vehicle(models.Model): + model_name = models.CharField(max_length=200) number_plate = models.CharField(max_length=200) vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: - return f'{self.model_name} -> {self.number_plate}' - + return f"{self.model_name} -> {self.number_plate}" From 87cdd5bcbbd94a676d12007ae2d7fd8da1c59599 Mon Sep 17 00:00:00 2001 From: mustankap Date: Mon, 19 Jul 2021 22:46:58 +0530 Subject: [PATCH 54/98] trip model --- server/attendance/models.py | 96 ++++++++++++++++++++++++------------ server/db.sqlite3 | Bin 249856 -> 0 bytes server/vendors/models.py | 18 ++++--- 3 files changed, 75 insertions(+), 39 deletions(-) delete mode 100644 server/db.sqlite3 diff --git a/server/attendance/models.py b/server/attendance/models.py index 9fbc245..2ccaec8 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -1,43 +1,75 @@ from django.db import models from django.contrib.auth.models import User -from vendors.models import Vendor, Gunmen +from vendors.models import Vendor, Custodian, Vehicle from users.models import Branch from datetime import datetime +generate_token = lambda: token_hex(6).upper() -class AttendanceSheet(models.Model): - sheet_created = models.DateField(default=datetime.now) - invoice = models.FileField(blank=True, null=True, upload_to="invoice") - verified = models.BooleanField(default=False) +class Trip(models.Model): + vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, null=True, blank=True) + custodian_1 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True) + custodian_2 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True) + custodian_3 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True) + start_loc = models.DecimalField(max_digits=13, decimal_places=10, null=True, blank=True) + end_loc = models.DecimalField(max_digits=13, decimal_places=10, null=True, blank=True) + trip_code = models.CharField(max_length=6, default=generate_token) + entry_time = models.DateTimeField(default=datetime.now) + branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) + exit_time = models.DateTimeField(blank=True, null=True) def __str__(self): - return f"{self.sheet_created} -> {self.verified}" + return f"{self.vehicle}: {self.custodian_1}, {self.custodian_2}, {self.custodian_3}" -class Attendance(models.Model): - entry_time = models.DateTimeField(default=datetime.now) - exit_time = models.DateTimeField(blank=True, null=True) - gunmen = models.ForeignKey(Gunmen, on_delete=models.SET_NULL, null=True, blank=True) - added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) - branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) - attendance_sheet = models.ForeignKey( - AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True - ) - def __str__(self): - return f"{self.gunmen.first_name} {self.gunmen.last_name}" - - -class Issue(models.Model): - comment = models.CharField(max_length=200) - vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) - reverted_by = models.ForeignKey( - User, on_delete=models.SET_NULL, null=True, blank=True - ) - sheet = models.ForeignKey( - AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True - ) - created_at = models.DateTimeField(default=datetime.now) - - def __str__(self) -> str: - return f"{self.comment} {self.vendor} {self.reverted_by} -> {self.sheet}" + + + + + + + + + + + + + +# class AttendanceSheet(models.Model): +# sheet_created = models.DateField(default=datetime.now) +# invoice = models.FileField(blank=True, null=True, upload_to="invoice") +# verified = models.BooleanField(default=False) +# +# def __str__(self): +# return f"{self.sheet_created} -> {self.verified}" +# +# +# class Attendance(models.Model): +# entry_time = models.DateTimeField(default=datetime.now) +# exit_time = models.DateTimeField(blank=True, null=True) +# gunmen = models.ForeignKey(Gunmen, on_delete=models.SET_NULL, null=True, blank=True) +# added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) +# branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) +# attendance_sheet = models.ForeignKey( +# AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True +# ) +# +# def __str__(self): +# return f"{self.gunmen.first_name} {self.gunmen.last_name}" +# +# +# class Issue(models.Model): +# comment = models.CharField(max_length=200) +# vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) +# reverted_by = models.ForeignKey( +# User, on_delete=models.SET_NULL, null=True, blank=True +# ) +# sheet = models.ForeignKey( +# AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True +# ) +# created_at = models.DateTimeField(default=datetime.now) +# +# def __str__(self) -> str: +# return f"{self.comment} {self.vendor} {self.reverted_by} -> {self.sheet}" +# \ No newline at end of file diff --git a/server/db.sqlite3 b/server/db.sqlite3 deleted file mode 100644 index 07d0c58cad3f6768a0d510a40e2db7b4bb320277..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 249856 zcmeI53wRsZb(k>(NDw4|OFg()E%g8)X(cR0avm5ws9k%xB&4N8fD%PYBAqQV0EQqa zJSYI9NNw#D+TA2g(loWxr2P^%PMSW_IE|CKNz)`v>oi|#r;eR8cIz~8)22;gr&-(S z7u(+|`V>R&5Yib~Bd*@kQ! zXM5J~x7lnThu>%5_agk-;r9dZ>ww?J57#)@9tsA zyAK`6?lxunncS!V)^3n~U)>(#9-KaqxfW+rd?qW2a+)_Hr;X51_xNd(H9~TaW)AEd zgp@@MID5tmT{C9s8k0z-T&k(1TB^3YsnU=V*Fur78cMUSG2}>xJ~2vD-L#nOHl%6% zv{V2yZ+M)(-7)R~F}lR4($+wxoK;IoQBCoJl9nQ}V)TYl%iFyh450(6KCmay0}bN> z!3Ve9PT%x2_wvP>k}hcDl#PCt7)Df$xuvzlqdT!Q{oH)qJfE}*QminM`18=AIknBSZQ)%c2kdUTLx5 zv$S-PnKYN2Tbi4mpI^~4(Uo6JG95MP=izQ=pX#=Az z*VUot+k_q}3^XmTdoTla!zp?J^+wDw^`SneZ*-Ka-)RBLm^06u-M~E*ENcu#+v7PX zIs1HDvr{42sMt7${&!u-_d%c^>JOD$#8mQ%aMzm~%D zbPQgAn!)-C=k!fZat{B;_|vXNgWKR~i%)ca}gk9o`9XS}_h-}HQs=ZeSX{yFzu z_vGN84*t`@cMTpH_}IWJ12Y3&*KfJL-*wA%vj6i?8Gn!f5-kJUZK)HU5~C9W+!YW)k>gNj(o{!E<+e&iwUlD}039m|5vX`^#A2!3 zZfU4vWnL7+!o?>nl|${7rB0RkNJtEaE*`T~mMoP+DNzc+p1Xw+^Op}v;I8y|ukFOy z>8h&TWdO!PDqqUi@=Bp&B|#Kq=~-W|ZTRvuT{VKdklNa0I~tpn^3Ja5u0pk=23{6q zVdgQ=kZ5S&Q%a%MxMRciYf?pJCsj~Ox!QWWlE_3X24?V=he64*u7r>2O4z<8+h3xW z$onaZ@?g!SqoC+ULs8VMsIk?wpPn!nBwjrNdR}PgiRgN^l|ml)KnSLkY&NAKRX0E8hy<}WEwh}Y|5Lp&W`YaB|JkwL!+;G2v0);8&mtB zjYgxOU5(kNzXhevK;paWQwzHR~^*slMkx~S{#qxF&uXb02Mo=fb zQ9AF)&$@eUqZg-@8r(+7DzMlDJ=W1Dri6&lv4f&gC?rIl9ccB6_i{mvtG`_zCg$3

`NO*=ppM7*v_r2EvGDm_G4|G-f0s3IiF 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 diff --git a/server/vendors/models.py b/server/vendors/models.py index 973a47c..9af1324 100644 --- a/server/vendors/models.py +++ b/server/vendors/models.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.auth.models import User +from django.core.validators import RegexValidator from datetime import datetime @@ -18,23 +19,26 @@ def __str__(self): return f"{self.name} -> {self.email}" -class Gunmen(models.Model): - GUNMEN_TYPES = ( - ("M", "Male"), - ("F", "Female"), - ("O", "Other"), +class Custodian(models.Model): + CUSTODIAN_TYPE_CHOICES = ( + ("C", "Custodian"), + ("G", "Gunmen"), ) first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) + custodian_type = models.CharField(max_length=1, default='C', choices=CUSTODIAN_TYPE_CHOICES) email = models.EmailField() + phone_regex = RegexValidator( + regex=r'^\+?1?\d{9,15}$', + message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.") + phone_number = models.CharField(validators=[phone_regex], max_length=15, blank=True) vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: - return f"{self.first_name} {self.last_name}" + return f"{self.first_name} {self.last_name} -> {self.custodian_type}" class Vehicle(models.Model): - model_name = models.CharField(max_length=200) number_plate = models.CharField(max_length=200) vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) From b081e1978452291560f2f423378177cadd6d8402 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Mon, 19 Jul 2021 23:21:07 +0530 Subject: [PATCH 55/98] Custodian and Trip models Update --- server/attendance/admin.py | 17 +++++---- server/attendance/migrations/0004_trip.py | 36 ++++++++++++++++++++ server/attendance/models.py | 25 ++++++++++++-- server/db.sqlite3 | Bin 249856 -> 274432 bytes server/vendors/admin.py | 14 +++++--- server/vendors/migrations/0005_custodian.py | 27 +++++++++++++++ server/vendors/models.py | 29 ++++++++++++++-- 7 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 server/attendance/migrations/0004_trip.py create mode 100644 server/vendors/migrations/0005_custodian.py diff --git a/server/attendance/admin.py b/server/attendance/admin.py index 93b8a79..925ed3f 100644 --- a/server/attendance/admin.py +++ b/server/attendance/admin.py @@ -3,18 +3,21 @@ from .models import * +class TripAdmin(admin.ModelAdmin): + list_display = ( + "id", "vehicle", "custodian_1", "custodian_2", "custodian_3", + "entry_time", "exit_time", "start_location", "end_location", "branch_id", "added_by") + list_display_links = ("id", "custodian_1", "custodian_2", "custodian_3") + search_fields = ("id", "vehicle", "custodian_1", "custodian_2", "custodian_3") + list_per_page = 20 + + class AttendanceSheetAdmin(admin.ModelAdmin): list_display = ("id", "sheet_created") list_display_links = ("id", "sheet_created") list_per_page = 20 -class GunmenAdmin(admin.ModelAdmin): - list_display = ("id", "first_name", "last_name", "vendor") - list_display_links = ("id", "vendor") - search_fields = ("first_name", "last_name", "vendor") - list_per_page = 20 - class AttendanceAdmin(admin.ModelAdmin): list_display = ("id", "gunmen", "entry_time", "exit_time", "branch_id") @@ -30,6 +33,6 @@ class IssueAdmin(admin.ModelAdmin): admin.site.register(Attendance, AttendanceAdmin) +admin.site.register(Trip, TripAdmin) admin.site.register(AttendanceSheet, AttendanceSheetAdmin) admin.site.register(Issue, IssueAdmin) -admin.site.register(Gunmen, GunmenAdmin) diff --git a/server/attendance/migrations/0004_trip.py b/server/attendance/migrations/0004_trip.py new file mode 100644 index 0000000..8406957 --- /dev/null +++ b/server/attendance/migrations/0004_trip.py @@ -0,0 +1,36 @@ +# Generated by Django 3.0.4 on 2021-07-19 17:44 + +import datetime +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0006_auto_20210715_1609'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('vendors', '0005_custodian'), + ('attendance', '0003_auto_20210712_1712'), + ] + + operations = [ + migrations.CreateModel( + name='Trip', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('trip_code', models.CharField(blank=True, max_length=6, null=True)), + ('entry_time', models.DateTimeField(default=datetime.datetime.now)), + ('exit_time', models.DateTimeField(blank=True, null=True)), + ('start_location', models.CharField(max_length=100)), + ('end_location', models.CharField(max_length=100)), + ('added_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ('branch', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.Branch')), + ('custodian_1', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='custodian_1', to='vendors.Custodian')), + ('custodian_2', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='custodian_2', to='vendors.Custodian')), + ('custodian_3', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='custodian_3', to='vendors.Custodian')), + ('vehicle', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vendors.Vehicle')), + ], + ), + ] diff --git a/server/attendance/models.py b/server/attendance/models.py index e29460c..2dfa9c5 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -1,10 +1,31 @@ from django.db import models from django.contrib.auth.models import User -from vendors.models import Vendor, Gunmen +from vendors.models import Vehicle, Vendor, Gunmen, Custodian from users.models import Branch from datetime import datetime - +class Trip(models.Model): + trip_code = models.CharField(max_length=6, blank=True, null=True) + + vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, null=True, blank=True) + custodian_1 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_1') + custodian_2 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_2') + custodian_3 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_3') + + entry_time = models.DateTimeField(blank=True,null=True) + exit_time = models.DateTimeField(blank=True,null=True) + + start_location = models.CharField(max_length=100) + end_location = models.CharField(max_length=100) + + added_by = models.ForeignKey(User, on_delete=models.SET_NULL,null=True, blank=True) + branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) + + def __str__(self): + return f"{self.vehicle}: {self.custodian_1}, {self.custodian_2}, {self.custodian_3}" + + + class AttendanceSheet(models.Model): sheet_created = models.DateField(default=datetime.now) invoice = models.FileField(blank=True, null=True, upload_to='invoice') diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 1e0b87735a862e1962f8b4e33b87471382c0a637..1c3c3a1797d5399da73d0ab22428b04d31facb87 100644 GIT binary patch delta 6160 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 delta 10296 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 biri_}^UP~mYi8pU7wLN$eT^Z00M+<^7B~Kf diff --git a/server/vendors/admin.py b/server/vendors/admin.py index f4b15d0..a14131b 100644 --- a/server/vendors/admin.py +++ b/server/vendors/admin.py @@ -1,7 +1,5 @@ from django.contrib import admin -from django.db import models - -from .models import Vendor, Vehicle +from .models import * class VendorAdmin(admin.ModelAdmin): @@ -19,12 +17,20 @@ class VendorAdmin(admin.ModelAdmin): list_per_page = 20 +class CustodianAdmin(admin.ModelAdmin): + list_display = ("id", "first_name", "last_name", "custodian_type", "email", "phone_number", "vendor") + list_display_links = ("id", "vendor", "custodian_type") + search_fields = ("first_name", "last_name", "vendor", "custodian_type") + list_per_page = 20 + + + class VehicleAdmin(admin.ModelAdmin): list_display = ("id", "model_name", "number_plate", "vendor") list_display_links = ("vendor",) search_fields = ("id", "model_name", "vendor", "number_plate") list_per_page = 20 - +admin.site.register(Custodian, CustodianAdmin) admin.site.register(Vendor, VendorAdmin) admin.site.register(Vehicle, VehicleAdmin) diff --git a/server/vendors/migrations/0005_custodian.py b/server/vendors/migrations/0005_custodian.py new file mode 100644 index 0000000..7d81434 --- /dev/null +++ b/server/vendors/migrations/0005_custodian.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.4 on 2021-07-19 17:39 + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('vendors', '0004_vehicle'), + ] + + operations = [ + migrations.CreateModel( + name='Custodian', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('custodian_type', models.CharField(choices=[('C', 'Custodian'), ('G', 'Gunmen')], default='C', max_length=1)), + ('first_name', models.CharField(max_length=200)), + ('last_name', models.CharField(max_length=200)), + ('email', models.EmailField(max_length=254)), + ('phone_number', models.CharField(blank=True, max_length=17, validators=[django.core.validators.RegexValidator(message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.", regex='^\\+?1?\\d{9,15}$')])), + ('vendor', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vendors.Vendor')), + ], + ), + ] diff --git a/server/vendors/models.py b/server/vendors/models.py index f42078f..70722db 100644 --- a/server/vendors/models.py +++ b/server/vendors/models.py @@ -1,4 +1,5 @@ from django.db import models +from django.core.validators import RegexValidator from django.contrib.auth.models import User from datetime import datetime @@ -15,15 +16,27 @@ class Vendor(models.Model): def __str__(self): return f'{self.name} -> {self.email}' - -class Gunmen(models.Model): + +class Custodian(models.Model): + CUSTODIAN_TYPE_CHOICES = [ + ('C', 'Custodian'), + ('G', 'Gunmen') + ] + custodian_type = models.CharField(max_length=1, default='C', choices=CUSTODIAN_TYPE_CHOICES) + first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) + email = models.EmailField() + phone_regex = RegexValidator( + regex=r'^\+?1?\d{9,15}$', + message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.") + phone_number = models.CharField(validators=[phone_regex], max_length=17, blank=True) + vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: - return f'{self.first_name} {self.last_name}' + return f'{self.custodian_type}: {self.first_name} {self.last_name}' class Vehicle(models.Model): @@ -34,3 +47,13 @@ class Vehicle(models.Model): def __str__(self) -> str: return f'{self.model_name} -> {self.number_plate}' + +class Gunmen(models.Model): + first_name = models.CharField(max_length=200) + last_name = models.CharField(max_length=200) + email = models.EmailField() + vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + + def __str__(self) -> str: + return f'{self.first_name} {self.last_name}' + From 0f49f9dcb8b9b4558b78a542b72c38d568c75a55 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Mon, 19 Jul 2021 23:27:49 +0530 Subject: [PATCH 56/98] models update --- .../migrations/0005_auto_20210719_1756.py | 18 ++++ server/attendance/models.py | 93 ++++++------------ server/db.sqlite3 | Bin 0 -> 278528 bytes 3 files changed, 46 insertions(+), 65 deletions(-) create mode 100644 server/attendance/migrations/0005_auto_20210719_1756.py create mode 100644 server/db.sqlite3 diff --git a/server/attendance/migrations/0005_auto_20210719_1756.py b/server/attendance/migrations/0005_auto_20210719_1756.py new file mode 100644 index 0000000..5682b8e --- /dev/null +++ b/server/attendance/migrations/0005_auto_20210719_1756.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.4 on 2021-07-19 17:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('attendance', '0004_trip'), + ] + + operations = [ + migrations.AlterField( + model_name='trip', + name='entry_time', + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/server/attendance/models.py b/server/attendance/models.py index 9f6f5e5..089c7b9 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -25,76 +25,39 @@ def __str__(self): return f"{self.vehicle}: {self.custodian_1}, {self.custodian_2}, {self.custodian_3}" - class AttendanceSheet(models.Model): sheet_created = models.DateField(default=datetime.now) - invoice = models.FileField(blank=True, null=True, upload_to='invoice') + invoice = models.FileField(blank=True, null=True, upload_to="invoice") verified = models.BooleanField(default=False) -class Trip(models.Model): - vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, null=True, blank=True) - custodian_1 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True) - custodian_2 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True) - custodian_3 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True) - start_loc = models.DecimalField(max_digits=13, decimal_places=10, null=True, blank=True) - end_loc = models.DecimalField(max_digits=13, decimal_places=10, null=True, blank=True) - trip_code = models.CharField(max_length=6, default=generate_token) - entry_time = models.DateTimeField(default=datetime.now) - branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) - exit_time = models.DateTimeField(blank=True, null=True) - def __str__(self): - return f"{self.vehicle}: {self.custodian_1}, {self.custodian_2}, {self.custodian_3}" - - - - - - - - - - - - - + return f"{self.sheet_created} -> {self.verified}" +class Attendance(models.Model): + entry_time = models.DateTimeField(default=datetime.now) + exit_time = models.DateTimeField(blank=True, null=True) + gunmen = models.ForeignKey(Gunmen, on_delete=models.SET_NULL, null=True, blank=True) + added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) + branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) + attendance_sheet = models.ForeignKey( + AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True + ) -# class AttendanceSheet(models.Model): -# sheet_created = models.DateField(default=datetime.now) -# invoice = models.FileField(blank=True, null=True, upload_to="invoice") -# verified = models.BooleanField(default=False) -# -# def __str__(self): -# return f"{self.sheet_created} -> {self.verified}" -# -# -# class Attendance(models.Model): -# entry_time = models.DateTimeField(default=datetime.now) -# exit_time = models.DateTimeField(blank=True, null=True) -# gunmen = models.ForeignKey(Gunmen, on_delete=models.SET_NULL, null=True, blank=True) -# added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) -# branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) -# attendance_sheet = models.ForeignKey( -# AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True -# ) -# -# def __str__(self): -# return f"{self.gunmen.first_name} {self.gunmen.last_name}" -# -# -# class Issue(models.Model): -# comment = models.CharField(max_length=200) -# vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) -# reverted_by = models.ForeignKey( -# User, on_delete=models.SET_NULL, null=True, blank=True -# ) -# sheet = models.ForeignKey( -# AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True -# ) -# created_at = models.DateTimeField(default=datetime.now) -# -# def __str__(self) -> str: -# return f"{self.comment} {self.vendor} {self.reverted_by} -> {self.sheet}" -# \ No newline at end of file + def __str__(self): + return f"{self.gunmen.first_name} {self.gunmen.last_name}" + + +class Issue(models.Model): + comment = models.CharField(max_length=200) + vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + reverted_by = models.ForeignKey( + User, on_delete=models.SET_NULL, null=True, blank=True + ) + sheet = models.ForeignKey( + AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True + ) + created_at = models.DateTimeField(default=datetime.now) + + def __str__(self) -> str: + return f"{self.comment} {self.vendor} {self.reverted_by} -> {self.sheet}" diff --git a/server/db.sqlite3 b/server/db.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..4ad07d39f9f5217ae1bf247030c0c5d5c9234141 GIT binary patch literal 278528 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 XC^-?5rEub0EOAawOs0~dL`weu@Y5~~ literal 0 HcmV?d00001 From 77a8e2a58ecaee18020863a62c5e5debc0276848 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Mon, 19 Jul 2021 23:38:29 +0530 Subject: [PATCH 57/98] Added Custodian Serializer --- server/attendance/serializers.py | 2 +- server/vendors/serializers.py | 22 ++++++++++++++++++++-- server/vendors/urls.py | 2 ++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 901fc5b..7eb8ce0 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -2,7 +2,7 @@ from vendors.models import Vendor from django.contrib.auth.models import User from users.models import Branch -from vendors.models import Gunmen +from vendors.models import Gunmen, Custodian from django.db.models import fields from rest_framework import serializers from users.serializers import BranchSerializer, UserSerializer diff --git a/server/vendors/serializers.py b/server/vendors/serializers.py index a38d88c..d0a5a20 100644 --- a/server/vendors/serializers.py +++ b/server/vendors/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from .models import Vehicle, Vendor, Gunmen +from .models import Vehicle, Vendor, Gunmen, Custodian class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): @@ -45,6 +45,24 @@ class Meta: fields = ["id", "first_name", "last_name", "email", "vendor"] +class CustodianSerializer(serializers.ModelSerializer): + vendor = RelatedFieldAlternative( + queryset=Vendor.objects.all(), serializer=VendorSerializer + ) + + class Meta: + model = Custodian + fields = [ + "id", + "custodian_type", + "first_name", + "last_name", + "email", + "phone_number", + "vendor", + ] + + class VehicleSerializer(serializers.ModelSerializer): vendor = RelatedFieldAlternative( queryset=Vendor.objects.all(), serializer=VendorSerializer @@ -52,4 +70,4 @@ class VehicleSerializer(serializers.ModelSerializer): class Meta: model = Vehicle - fields = ["id", "model_name", "number_plate", "vendor"] \ No newline at end of file + fields = ["id", "model_name", "number_plate", "vendor"] diff --git a/server/vendors/urls.py b/server/vendors/urls.py index 82bccb5..bec52c5 100644 --- a/server/vendors/urls.py +++ b/server/vendors/urls.py @@ -5,6 +5,8 @@ urlpatterns = [ path("gunmen/", views.GunmenList.as_view()), path("gunmen//", views.GunmenDetail.as_view()), + path("custodian/", views.CustodianList.as_view()), + path("custodian//", views.CustodianDetail.as_view()), path("vendor/", views.VendorList.as_view()), path("vendor//", views.VendorDetail.as_view()), path("vehicle/", views.VehicleList.as_view()), From 01c5d3d79538f9e3ed0f914f3273782b8bbe37d7 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Mon, 19 Jul 2021 23:41:25 +0530 Subject: [PATCH 58/98] views for Trip and Custodian --- server/attendance/views.py | 68 ++++++++++++++++++++++++++++++++------ server/vendors/views.py | 54 +++++++++++++++++++++++++++--- 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index d28b8fc..950553f 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -1,21 +1,22 @@ from datetime import datetime -from users.models import Branch -from django.shortcuts import get_object_or_404, render -from django.utils.translation import override + +from django.shortcuts import get_object_or_404 + from rest_framework import mixins from rest_framework import generics -from rest_framework.response import Response -from attendance.serializers import AttendanceSerializer, IssueSerializer -from attendance.models import Attendance, AttendanceSheet, Issue -from django_filters.rest_framework import DjangoFilterBackend -from rest_framework.pagination import PageNumberPagination from rest_framework import filters + from rest_framework.response import Response -from datetime import datetime +from rest_framework.pagination import PageNumberPagination +from django_filters.rest_framework import DjangoFilterBackend + +from attendance.serializers import AttendanceSerializer, IssueSerializer, TripSerializer + +from users.models import Branch +from attendance.models import Attendance, AttendanceSheet, Issue, Trip from vendors.models import Gunmen from users.models import User -# from vendors.serializers import GunmenSerializer class CustomPagination(PageNumberPagination): @@ -37,6 +38,53 @@ def get_paginated_response(self, data): ) +class TripList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): + queryset = Trip.objects.all() + serializer_class = TripSerializer + pagination_class = CustomPagination + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^gunmen__first_name", "^gunmen__last_name"] + + filterset_fields = { + "entry_time": ["gte", "lte", "exact", "gt", "lt"], + "exit_time": ["gte", "lte", "exact", "gt", "lt"], + "custodian_1": ["exact"], + "custodian_2": ["exact"], + "custodian_3": ["exact"], + "vehicle": ["exact"], + "added_by": ["exact"], + "branch": ["exact"], + } + ordering_fields = "__all__" + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + + +class TripDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Trip.objects.all() + serializer_class = IssueSerializer + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) + + class AttendanceList( mixins.ListModelMixin, mixins.CreateModelMixin, diff --git a/server/vendors/views.py b/server/vendors/views.py index b0d257e..8af2582 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -1,13 +1,13 @@ -from django.shortcuts import render from rest_framework import mixins from rest_framework import generics -from .models import Vehicle, Vendor, Gunmen -from .serializers import VehicleSerializer, VendorSerializer, GunmenSerializer -from django_filters.rest_framework import DjangoFilterBackend from rest_framework import filters +from django_filters.rest_framework import DjangoFilterBackend from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response +from .models import Vehicle, Vendor, Gunmen +from .serializers import VehicleSerializer, VendorSerializer, GunmenSerializer + class CustomPagination(PageNumberPagination): page_size = 10 @@ -28,6 +28,52 @@ def get_paginated_response(self, data): ) +class CustodianList( + mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView +): + queryset = Custodian.objects.all() + serializer_class = CustodianSerializer + pagination_class = CustomPagination + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^first_name", "^last_name", "^phone_number", "^vendor"] + filterset_fields = [ + "custodian_type", + "first_name", + "last_name", + "email", + "phone_number", + "vendor", + ] + ordering_fields = "__all__" + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + + +class CustodianDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = Custodian.objects.all() + serializer_class = CustodianSerializer + ordering_fields = "__all__" + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) + + + class VendorList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView ): From a2b915ec560ab1453532e7857e56ffa3ebafb541 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Mon, 19 Jul 2021 23:44:35 +0530 Subject: [PATCH 59/98] Added custodian serializeer --- server/attendance/serializers.py | 41 +++++++++++++++++++++++++++++++- server/attendance/urls.py | 4 +++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 7eb8ce0..e9c656e 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,4 +1,6 @@ from datetime import date +from server.vendors.models import Vehicle +from server.vendors.serializers import CustodianSerializer, VehicleSerializer from vendors.models import Vendor from django.contrib.auth.models import User from users.models import Branch @@ -7,7 +9,7 @@ from rest_framework import serializers from users.serializers import BranchSerializer, UserSerializer from vendors.serializers import VendorSerializer, GunmenSerializer -from .models import Attendance, AttendanceSheet, Issue +from .models import Attendance, AttendanceSheet, Issue, Trip class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): @@ -61,6 +63,43 @@ class Meta: ] +class TripSerializer(serializers.ModelSerializer): + vehicle = RelatedFieldAlternative( + queryset=Vehicle.objects.all(), serializer=VehicleSerializer + ) + custodian_1 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer + ) + custodian_2 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer + ) + custodian_3 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer + ) + branch = RelatedFieldAlternative( + queryset=Branch.objects.all(), serializer=BranchSerializer + ) + added_by = RelatedFieldAlternative( + queryset=User.objects.all(), serializer=UserSerializer + ) + + class Meta: + model = Attendance + fields = [ + "id", + "vehicle", + "custodian_1", + "custodian_2", + "custodian_3", + "entry_time", + "exit_time", + "start_location", + "end_location", + "branch", + "added_by", + ] + + class IssueSerializer(serializers.ModelSerializer): reverted_by = RelatedFieldAlternative( queryset=User.objects.all(), serializer=UserSerializer diff --git a/server/attendance/urls.py b/server/attendance/urls.py index 565f17a..5134b97 100644 --- a/server/attendance/urls.py +++ b/server/attendance/urls.py @@ -5,7 +5,9 @@ urlpatterns = [ path("attendance/", views.AttendanceList.as_view()), path("attendance//", views.AttendanceDetail.as_view()), - path("issue/", views.IssueList.as_view()), + path("trip/", views.TripList.as_view()), + path("trip//", views.AttendanceDetail.as_view()), + path("issue/", views.TripList.as_view()), path("issue//", views.IssueDetail.as_view()), ] From 0312707524ca8bf57104560d40424ac0d806dcb8 Mon Sep 17 00:00:00 2001 From: mustankap Date: Mon, 19 Jul 2021 23:45:43 +0530 Subject: [PATCH 60/98] changes --- server/attendance/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index d28b8fc..2693a7e 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -36,7 +36,6 @@ def get_paginated_response(self, data): } ) - class AttendanceList( mixins.ListModelMixin, mixins.CreateModelMixin, From 6ed2dd6107a45206e460d2cd208d408b6d4fc3b6 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Mon, 19 Jul 2021 23:53:24 +0530 Subject: [PATCH 61/98] update filterfields etc. --- server/attendance/views.py | 18 +++++++++++++----- server/vendors/views.py | 18 ++++++++++++++---- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 950553f..015c423 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -18,7 +18,6 @@ from users.models import User - class CustomPagination(PageNumberPagination): page_size = 10 page_size_query_param = "page_size" @@ -38,14 +37,22 @@ def get_paginated_response(self, data): ) -class TripList( - mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView -): +class TripList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): queryset = Trip.objects.all() serializer_class = TripSerializer pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] - search_fields = ["^gunmen__first_name", "^gunmen__last_name"] + search_fields = [ + "^custodian_1__first_name", + "^custodian_1__last_name", + "^custodian_2__first_name", + "^custodian_2__last_name", + "^custodian_3__first_name", + "^custodian_3__last_name", + "^vehicle__number_plate", + "^vehicle__model_name", + "^vendor__name", + ] filterset_fields = { "entry_time": ["gte", "lte", "exact", "gt", "lt"], @@ -54,6 +61,7 @@ class TripList( "custodian_2": ["exact"], "custodian_3": ["exact"], "vehicle": ["exact"], + "vendor": ["exact"], "added_by": ["exact"], "branch": ["exact"], } diff --git a/server/vendors/views.py b/server/vendors/views.py index 8af2582..b342d04 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -5,8 +5,13 @@ from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response -from .models import Vehicle, Vendor, Gunmen -from .serializers import VehicleSerializer, VendorSerializer, GunmenSerializer +from .models import Custodian, Vehicle, Vendor, Gunmen +from .serializers import ( + VehicleSerializer, + VendorSerializer, + GunmenSerializer, + CustodianSerializer, +) class CustomPagination(PageNumberPagination): @@ -35,7 +40,13 @@ class CustodianList( serializer_class = CustodianSerializer pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] - search_fields = ["^first_name", "^last_name", "^phone_number", "^vendor"] + search_fields = [ + "^first_name", + "^last_name", + "^phone_number", + "^email", + "^vendor__name", + ] filterset_fields = [ "custodian_type", "first_name", @@ -73,7 +84,6 @@ def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) - class VendorList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView ): From 805388ea041d76ee56ce15816894a99b6f01d93a Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Mon, 19 Jul 2021 23:54:13 +0530 Subject: [PATCH 62/98] upadte --- server/attendance/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index e9c656e..d2c6c08 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -84,7 +84,7 @@ class TripSerializer(serializers.ModelSerializer): ) class Meta: - model = Attendance + model = Trip fields = [ "id", "vehicle", From 3d67ddc0b744d50b8a959755706fd078a95338f2 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Mon, 19 Jul 2021 23:56:38 +0530 Subject: [PATCH 63/98] nm --- server/attendance/serializers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index d2c6c08..5a53b30 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,6 +1,6 @@ from datetime import date -from server.vendors.models import Vehicle -from server.vendors.serializers import CustodianSerializer, VehicleSerializer +from vendors.models import Vehicle +from vendors.serializers import CustodianSerializer, VehicleSerializer from vendors.models import Vendor from django.contrib.auth.models import User from users.models import Branch From e0377177c85473d57d0caa61e80a02c01abc2253 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Tue, 20 Jul 2021 20:48:42 +0530 Subject: [PATCH 64/98] custodian code --- server/attendance/models.py | 6 ++++++ server/attendance/serializers.py | 27 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/server/attendance/models.py b/server/attendance/models.py index 089c7b9..37ba828 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -9,8 +9,14 @@ class Trip(models.Model): vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, null=True, blank=True) custodian_1 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_1') + custodian_1_code = models.CharField(max_length=6) + custodian_2 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_2') + custodian_2_code = models.CharField(max_length=6) + custodian_3 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_3') + custodian_3_code = models.CharField(max_length=6) + entry_time = models.DateTimeField(blank=True,null=True) exit_time = models.DateTimeField(blank=True,null=True) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index d2c6c08..38b0a8a 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,15 +1,12 @@ -from datetime import date -from server.vendors.models import Vehicle -from server.vendors.serializers import CustodianSerializer, VehicleSerializer -from vendors.models import Vendor -from django.contrib.auth.models import User -from users.models import Branch -from vendors.models import Gunmen, Custodian -from django.db.models import fields +from secrets import token_hex + from rest_framework import serializers from users.serializers import BranchSerializer, UserSerializer -from vendors.serializers import VendorSerializer, GunmenSerializer +from vendors.serializers import VendorSerializer, GunmenSerializer, CustodianSerializer, VehicleSerializer + from .models import Attendance, AttendanceSheet, Issue, Trip +from users.models import Branch, User +from vendors.models import Gunmen, Custodian, Vendor, Vehicle class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): @@ -99,6 +96,18 @@ class Meta: "added_by", ] + def create(self, validated_data): + validated_data['trip_code'] = token_hex(6).upper() + # TODO: Send Mail/Msg and send trip code and otp code + validated_data['custodian_1_code'] = token_hex(6).upper() + validated_data['custodian_2_code'] = token_hex(6).upper() + validated_data['custodian_3_code'] = token_hex(6).upper() + + return super().create(validated_data) + + def update(self, instance, validated_data): + return super().update(instance, validated_data) + class IssueSerializer(serializers.ModelSerializer): reverted_by = RelatedFieldAlternative( From f297aec07bd8883bf81c4f65bf296f5366f9bb02 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Tue, 20 Jul 2021 22:29:48 +0530 Subject: [PATCH 65/98] views for Trips --- .../migrations/0006_auto_20210720_1620.py | 28 +++++++++++++++++ server/attendance/models.py | 10 +++--- server/attendance/serializers.py | 29 ++++++++++++------ server/attendance/views.py | 5 +-- server/db.sqlite3 | Bin 278528 -> 278528 bytes 5 files changed, 55 insertions(+), 17 deletions(-) create mode 100644 server/attendance/migrations/0006_auto_20210720_1620.py diff --git a/server/attendance/migrations/0006_auto_20210720_1620.py b/server/attendance/migrations/0006_auto_20210720_1620.py new file mode 100644 index 0000000..43b488d --- /dev/null +++ b/server/attendance/migrations/0006_auto_20210720_1620.py @@ -0,0 +1,28 @@ +# Generated by Django 3.0.4 on 2021-07-20 16:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('attendance', '0005_auto_20210719_1756'), + ] + + operations = [ + migrations.AddField( + model_name='trip', + name='custodian_1_code', + field=models.CharField(blank=True, max_length=6, null=True), + ), + migrations.AddField( + model_name='trip', + name='custodian_2_code', + field=models.CharField(blank=True, max_length=6, null=True), + ), + migrations.AddField( + model_name='trip', + name='custodian_3_code', + field=models.CharField(blank=True, max_length=6, null=True), + ), + ] diff --git a/server/attendance/models.py b/server/attendance/models.py index 37ba828..d9f0e53 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -9,20 +9,20 @@ class Trip(models.Model): vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, null=True, blank=True) custodian_1 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_1') - custodian_1_code = models.CharField(max_length=6) + custodian_1_code = models.CharField(max_length=6, blank=True, null=True) custodian_2 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_2') - custodian_2_code = models.CharField(max_length=6) + custodian_2_code = models.CharField(max_length=6, blank=True, null=True) custodian_3 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_3') - custodian_3_code = models.CharField(max_length=6) + custodian_3_code = models.CharField(max_length=6, blank=True, null=True) entry_time = models.DateTimeField(blank=True,null=True) exit_time = models.DateTimeField(blank=True,null=True) - start_location = models.CharField(max_length=100) - end_location = models.CharField(max_length=100) + start_location = models.CharField(max_length=300, blank=True,null=True) + end_location = models.CharField(max_length=300, blank=True,null=True) added_by = models.ForeignKey(User, on_delete=models.SET_NULL,null=True, blank=True) branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 38b0a8a..847485d 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,6 +1,7 @@ from secrets import token_hex from rest_framework import serializers +from rest_framework.response import Response from users.serializers import BranchSerializer, UserSerializer from vendors.serializers import VendorSerializer, GunmenSerializer, CustodianSerializer, VehicleSerializer @@ -96,17 +97,25 @@ class Meta: "added_by", ] - def create(self, validated_data): - validated_data['trip_code'] = token_hex(6).upper() - # TODO: Send Mail/Msg and send trip code and otp code - validated_data['custodian_1_code'] = token_hex(6).upper() - validated_data['custodian_2_code'] = token_hex(6).upper() - validated_data['custodian_3_code'] = token_hex(6).upper() - - return super().create(validated_data) + # def create(self, validated_data): + # validated_data['trip_code'] = token_hex(6).upper() + + # custodian_1 = validated_data.get('custodian_1') + # custodian_2 = validated_data.get('custodian_2') + # custodian_3 = validated_data.get('custodian_3') + + # if custodian_1 and custodian_2 and custodian_1 == custodian_2: return Response('!! ERR !!: The custodian ids cannot be same') + # if custodian_1 and custodian_3 and custodian_1 == custodian_3: return Response('!! ERR !!: The custodian ids cannot be same') + # if custodian_3 and custodian_2 and custodian_3 == custodian_2: return Response('!! ERR !!: The custodian ids cannot be same') + + # if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() + # if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() + # if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() + + # return super().create(validated_data) - def update(self, instance, validated_data): - return super().update(instance, validated_data) + # def update(self, instance, validated_data): + # return super().update(instance, validated_data) class IssueSerializer(serializers.ModelSerializer): diff --git a/server/attendance/views.py b/server/attendance/views.py index 015c423..631bdce 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -51,7 +51,6 @@ class TripList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericA "^custodian_3__last_name", "^vehicle__number_plate", "^vehicle__model_name", - "^vendor__name", ] filterset_fields = { @@ -61,7 +60,6 @@ class TripList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericA "custodian_2": ["exact"], "custodian_3": ["exact"], "vehicle": ["exact"], - "vendor": ["exact"], "added_by": ["exact"], "branch": ["exact"], } @@ -116,6 +114,7 @@ class AttendanceList( ordering_fields = "__all__" + def get(self, request, *args, **kwargs): params = request.query_params start_date = params.get("start_date", datetime.min) @@ -186,6 +185,8 @@ def post(self, request, *args, **kwargs): result.append(AttendanceSerializer(attendance).data) return Response(data=result) + + class AttendanceDetail( diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 4ad07d39f9f5217ae1bf247030c0c5d5c9234141..b985bf46881d9d1bef1b67559b75956f0379cc41 100644 GIT binary patch delta 3820 zcma)8e{37o9l!IPW1pM&*-cXCx1G??q)x8y-n*Yh?cz92nvVQx-KGiaEH^ez(!>r< zQc75txYD%kk1@7Wd(Z;vhQtscV2wm44b*j;G=$h6ohCZ|SZV1bU~K9@V`u_td*?Wg zW3s`?es}kM-}ianAD{RA-pY!5WySqyy?Y-;Q9b0pe*OMO9k_NM#rHjHB_bAlXikK{ zXW(DpBkd+sD)0$I2I5vXKZY*%!ftE2Wa$Il%}M+LvqNc zFVzT}CLqF!2>ZPHl^UsN0`UsODw2DfbbGB>G$HV+rm9%_dZRvEt8JQq5)vgP*q}dI zyQgRZ@(7BOjJxago3(Ib0;#;FD58eC>hzs;Mdl)f7d26ov{0>ne_fHeNamp^i&))X zqd#9K7eR@Aso%SVuC6X#V`BBqyFsruI7Ns^d!CP(R_wSQ9DLS8~xg%~nc%F`N*#b>8d<{8;oDQbjUB+rU|&g(4_ ztGp;71xfnvyt~u_ps4UzCDGL?K$Zf|S1Is;^WWeqcnO?!z6vJ6U7!!B;4lErcfp^W z*H)W-=bX!xF2+x95G}fpnVMsOmuck|=M$Ov=bV5|Z%; z`>&ygX2BAFa3i7q)8c1ibs!!PfiR>j~*EJA36SjnBTlmV94fX zZ4gCK$fY|sbj`-5X84KpY)Lgj0g*6VAXS#u&Rjfqk!H8sz;z1T27e}9=ipQDG59-ppTON9Ag==_ z%W$;K9Lmf=|Jyq?+iexsC_?{ZV2AS$&a=*e3X}A|tXN*MIjA7Wdi*rUl~}C=B#~F4 zC?ZYBb2mDhjwfcIuXCSoVE@sh!6Qe>74U_~Z~Y`dUu-_!;p+?d`W92OiB$f5Fr7-= z_i#%r9#6zu0=|b&pFZa9E#sES=EBx{lZGV=swxWIxpSA>^k9y+ump&^$I20$`Ymxt z;ZR9w(i1w29fg}=~wIUVGMS1PHK;{xe zM+IRX4PKzY3xsVy1>ZbKc4+MMH+yitMnz!(jpRE+zIjRzwZb)-jz>#-w-i9wWH${y zC+uEzuiOE4^2#tA=UAmztSMBJtyFt6**8~O^Yq-H=A~b;uCgMW$~=zg zf(4wXz#HH^apDoM%v9mJ~Vy z+-jBSmIZv8JGA6+<63Q6xd9yJX|?42eEC1#A3s{g-X>LoxcW9|tS7G4`?)-e4~ESO z4t>G30Kc+gVO^J5$ld^L4Ro2Q$mP$?TH7jUmPFP~Y{>0M?nQz6A7X}Rt$zLv>oWuE zV8F-u@WZL>Z{l`UGI1BaZ?INo*iaxZh+?DyNQ+S=Ir znIBr-qg9%vUZY;qM_jt4>;(C&{(!waa+X=9nd+?Dc*4inklHCgoqrpkElJTtlNyIt9B zHjm#=KcX087nr-~F5~L=Ew#qE3(Tki&RD9AwlkLI%eE(&?^ujCpJW{4LUe-E#}?no zSY~1}mT8mQeS?SZy|=^HQlLc?eFYu-1)a+mpJL*4X)tqzek0=fq}-v_nhHtEE#Ng< zh9%cHEV;&EF$qwTxrXA*QQVhlaGZI57~rSCZ@`1VPfk!HSU$kGs8))q_HZ0Wnn`PG zs~pCfq6%_ImZZr+i zZsXK$R-$(rFYabV`mW2jce5|hbdB+72m3SHW2l|%Tl5YC@a%3nXt)p1mBs+i{*|sa p)IIF$u55p{%I3kCKBFzfj?W}=AA-h5=a}bSf$SaN{=x^+e*q(8(AEF| delta 1891 zcmah~TTB#J7~Zop!0ZYPE8ue9MMcGhVdk7Ub7n|rLBJKvE+qm6d>|`OSYX+8Szujj zSWMdV!KSn)_MjxD#nfIjv4K|l(nQmwx3p;=TKm>&pW4Qznx>{nedutDyZF$P%*;98 z_s@5}|DXA1l1WE0>6kBds1}Q*#XPpg@@qAyShYyrcQZ_g7w@kT&Emh}Bk`elf5j1* z5v}#J^r4u~RSJM+<<&UzciQ>960?JTF@}UxXxmZpih@>LbfJ$RA{iQh7E|H)nV}hEC z=-!f4yF`)=A`|_HlLkw)6e&$IG+9^VBfIEIiMI1eNi<2vilSoLP%5Xv*f10w(%I78 zX|M{RrfGC#TQt-NQe^t~Hdv97h6p8PRVgA^(xIUuL?_BTX|Sg227&b2HW=#=Lxujj z4OSK1EHteuPZxn0BZ%qA@_i}VssypFYYM$o?oNYc!@#;hzb@aK0wc-5NFge2TealslcCV^I)gbgv zg^>m$qA5tHl`f?sRnja3QFNKhusExl0)wI8#8ZNbtefuX8!lIhAe0P4)l`*!?%FRs z5rmRXbVb#3#BPgS++z`c6TcU4i#Nmz;+!}l?h(DBZnj;P*q)!qc|c$)Hqsv%iiU!d zlfm#rOODg*!*y^t8lH+|@8Vpx_2ty$P}FSQ{I&i~8BUQyfH}rNeu-me4(Aa9v6xww zz{J2%e=Hh|6lHTnVE10O7SbDaRWS1SyT1}28X{p-2*kB5f~0aph$!BB8G8i<)r zCM%caub%0VhcTWWJ~bL6(_=H?z`$r!(=|9g9iNH~$!1afExx#~Wh~y;(l_Q0bt`^v zC-!?=Rp0TxabH)@Sclh#eXu*>gPk+}u3p^N)rxvYsXP42v4sD)Pw|hA$^JxB+;`kR zV)BU&Z*Rgk+8gf+`EZA~Q}vCGgnV5-r8m(HO&qsP$PH#|E48v-E5r4V5UGbmGIW_3 za5-{UbpM~_u*jB_+ha1x$fSfy+$I@b9%6=?(j71@kWLRLeWTDxaH_zyhVGy zTRrL_25#*>IjE1fw{31tYB!(w#^wstFkY|c`l&G#2#!kw;n0TDlwd`Z5H=tJ+POEE z9=MloW&Wkhjy3kjPRp?vKBMHdsk9R#z9f7p*M0$Q7@?eVOYATWQppIef(P zkHw|C?us1yNy`qQ!6K@;J95PpXuzVW;d$&B6jZpzZ>K+zM8)Z9PC;(kAcYURr4yyUEOt%zYYM$KK1bL04p1- l;qL&z4%PApK_hdtgM5~(<$nhjHYV|3+?4r0MaNU`)_+n}@vr~@ From f77e7d86f280f547daa955b39f187af889bc3894 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Tue, 20 Jul 2021 22:30:19 +0530 Subject: [PATCH 66/98] nm --- server/db.sqlite3 | Bin 278528 -> 278528 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 4ad07d39f9f5217ae1bf247030c0c5d5c9234141..c957a67df122b019bd6fbf5ed853523f26536a6e 100644 GIT binary patch delta 280 zcmZo@5Nv1=oFL6;K2gS*)to`kzjkBFf_M%l-WCSFL%c1U6%{IYHJYrMSbbYq9aE~( zEmI8)bJLTH^NlhrQj; p8%_Xfc*MZ}2&mx(znm Date: Tue, 20 Jul 2021 22:38:41 +0530 Subject: [PATCH 67/98] nm --- server/attendance/serializers.py | 29 ++++++++++++++++------------- server/attendance/views.py | 25 ++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 8b8cee6..08b4ce1 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,9 +1,12 @@ -from secrets import token_hex - from rest_framework import serializers from rest_framework.response import Response from users.serializers import BranchSerializer, UserSerializer -from vendors.serializers import VendorSerializer, GunmenSerializer, CustodianSerializer, VehicleSerializer +from vendors.serializers import ( + VendorSerializer, + GunmenSerializer, + CustodianSerializer, + VehicleSerializer, +) from .models import Attendance, AttendanceSheet, Issue, Trip from users.models import Branch, User @@ -98,19 +101,19 @@ class Meta: ] # def create(self, validated_data): - # validated_data['trip_code'] = token_hex(6).upper() + # validated_data['trip_code'] = token_hex(6).upper() - # custodian_1 = validated_data.get('custodian_1') - # custodian_2 = validated_data.get('custodian_2') - # custodian_3 = validated_data.get('custodian_3') + # custodian_1 = validated_data.get('custodian_1') + # custodian_2 = validated_data.get('custodian_2') + # custodian_3 = validated_data.get('custodian_3') - # if custodian_1 and custodian_2 and custodian_1 == custodian_2: return Response('!! ERR !!: The custodian ids cannot be same') - # if custodian_1 and custodian_3 and custodian_1 == custodian_3: return Response('!! ERR !!: The custodian ids cannot be same') - # if custodian_3 and custodian_2 and custodian_3 == custodian_2: return Response('!! ERR !!: The custodian ids cannot be same') + # if custodian_1 and custodian_2 and custodian_1 == custodian_2: return Response('!! ERR !!: The custodian ids cannot be same') + # if custodian_1 and custodian_3 and custodian_1 == custodian_3: return Response('!! ERR !!: The custodian ids cannot be same') + # if custodian_3 and custodian_2 and custodian_3 == custodian_2: return Response('!! ERR !!: The custodian ids cannot be same') - # if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() - # if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() - # if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() + # if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() + # if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() + # if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() # return super().create(validated_data) diff --git a/server/attendance/views.py b/server/attendance/views.py index 631bdce..c78a950 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -1,4 +1,5 @@ from datetime import datetime +from secrets import token_hex from django.shortcuts import get_object_or_404 @@ -69,6 +70,26 @@ def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): + # validated_data = request.data + # validated_data["trip_code"] = token_hex(6).upper() + + # custodian_1 = validated_data.get("custodian_1") + # custodian_2 = validated_data.get("custodian_2") + # custodian_3 = validated_data.get("custodian_3") + + # if custodian_1 and custodian_2 and custodian_1 == custodian_2: + # return Response("!! ERR !!: The custodian ids cannot be same") + # if custodian_1 and custodian_3 and custodian_1 == custodian_3: + # return Response("!! ERR !!: The custodian ids cannot be same") + # if custodian_3 and custodian_2 and custodian_3 == custodian_2: + # return Response("!! ERR !!: The custodian ids cannot be same") + + # if custodian_1: + # validated_data["custodian_1_code"] = token_hex(6).upper() + # if custodian_2: + # validated_data["custodian_2_code"] = token_hex(6).upper() + # if custodian_3: + # validated_data["custodian_3_code"] = token_hex(6).upper() return self.create(request, *args, **kwargs) @@ -85,6 +106,7 @@ def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): @@ -114,7 +136,6 @@ class AttendanceList( ordering_fields = "__all__" - def get(self, request, *args, **kwargs): params = request.query_params start_date = params.get("start_date", datetime.min) @@ -185,8 +206,6 @@ def post(self, request, *args, **kwargs): result.append(AttendanceSerializer(attendance).data) return Response(data=result) - - class AttendanceDetail( From 4fda84d8c2c7acf2236bb13777b86501966e5ded Mon Sep 17 00:00:00 2001 From: mustankap Date: Tue, 20 Jul 2021 22:53:59 +0530 Subject: [PATCH 68/98] custodians and serializers --- server/attendance/models.py | 2 ++ server/attendance/serializers.py | 42 ++++++++++++++++++------------- server/db.sqlite3 | Bin 278528 -> 278528 bytes 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/server/attendance/models.py b/server/attendance/models.py index 37ba828..93d3f70 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -1,5 +1,6 @@ from django.db import models from django.contrib.auth.models import User +from django.db.models.fields import NullBooleanField from vendors.models import Vehicle, Vendor, Gunmen, Custodian from users.models import Branch from datetime import datetime @@ -8,6 +9,7 @@ class Trip(models.Model): trip_code = models.CharField(max_length=6, blank=True, null=True) vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, null=True, blank=True) + custodian_1 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_1') custodian_1_code = models.CharField(max_length=6) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 38b0a8a..da109dc 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -61,24 +61,30 @@ class Meta: class TripSerializer(serializers.ModelSerializer): - vehicle = RelatedFieldAlternative( - queryset=Vehicle.objects.all(), serializer=VehicleSerializer - ) - custodian_1 = RelatedFieldAlternative( - queryset=Custodian.objects.all(), serializer=CustodianSerializer - ) - custodian_2 = RelatedFieldAlternative( - queryset=Custodian.objects.all(), serializer=CustodianSerializer - ) - custodian_3 = RelatedFieldAlternative( - queryset=Custodian.objects.all(), serializer=CustodianSerializer - ) - branch = RelatedFieldAlternative( - queryset=Branch.objects.all(), serializer=BranchSerializer - ) - added_by = RelatedFieldAlternative( - queryset=User.objects.all(), serializer=UserSerializer - ) + # vehicle = RelatedFieldAlternative( + # queryset=Vehicle.objects.all(), serializer=VehicleSerializer + # ) + # custodian_1 = RelatedFieldAlternative( + # queryset=Custodian.objects.all(), serializer=CustodianSerializer + # ) + # custodian_2 = RelatedFieldAlternative( + # queryset=Custodian.objects.all(), serializer=CustodianSerializer + # ) + # custodian_3 = RelatedFieldAlternative( + # queryset=Custodian.objects.all(), serializer=CustodianSerializer + # ) + # branch = RelatedFieldAlternative( + # queryset=Branch.objects.all(), serializer=BranchSerializer + # ) + # added_by = RelatedFieldAlternative( + # queryset=User.objects.all(), serializer=UserSerializer + # ) + vehicle = VehicleSerializer(required=False) + custodian_1 =CustodianSerializer(required=False) + custodian_2 = CustodianSerializer(required=False) + custodian_3 = CustodianSerializer(required=False) + branch = BranchSerializer(required=False) + added_by = UserSerializer(required=False) class Meta: model = Trip diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 4ad07d39f9f5217ae1bf247030c0c5d5c9234141..71c2efe9388303693d3fd63881272dabb2c94e82 100644 GIT binary patch delta 3710 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 Date: Tue, 20 Jul 2021 22:55:33 +0530 Subject: [PATCH 69/98] trip create successful --- server/attendance/serializers.py | 46 +++++++++++++++++++++---------- server/attendance/urls.py | 4 +-- server/attendance/views.py | 2 +- server/db.sqlite3 | Bin 278528 -> 278528 bytes 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 847485d..72f4d7c 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,4 +1,5 @@ from secrets import token_hex +from typing_extensions import Required from rest_framework import serializers from rest_framework.response import Response @@ -81,6 +82,13 @@ class TripSerializer(serializers.ModelSerializer): queryset=User.objects.all(), serializer=UserSerializer ) + # vehicle = VehicleSerializer(required=False) + # custodian_1 =CustodianSerializer(required=False) + # custodian_2 = CustodianSerializer(required=False) + # custodian_3 = CustodianSerializer(required=False) + # branch = BranchSerializer(required=False) + # added_by = UserSerializer(required=False) + class Meta: model = Trip fields = [ @@ -97,25 +105,35 @@ class Meta: "added_by", ] - # def create(self, validated_data): - # validated_data['trip_code'] = token_hex(6).upper() + def create(self, validated_data): + validated_data['trip_code'] = token_hex(6).upper() - # custodian_1 = validated_data.get('custodian_1') - # custodian_2 = validated_data.get('custodian_2') - # custodian_3 = validated_data.get('custodian_3') + custodian_1 = validated_data.get('custodian_1') + custodian_2 = validated_data.get('custodian_2') + custodian_3 = validated_data.get('custodian_3') - # if custodian_1 and custodian_2 and custodian_1 == custodian_2: return Response('!! ERR !!: The custodian ids cannot be same') - # if custodian_1 and custodian_3 and custodian_1 == custodian_3: return Response('!! ERR !!: The custodian ids cannot be same') - # if custodian_3 and custodian_2 and custodian_3 == custodian_2: return Response('!! ERR !!: The custodian ids cannot be same') + if custodian_1 and custodian_2 and custodian_1 == custodian_2: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) + if custodian_1 and custodian_3 and custodian_1 == custodian_3: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) + if custodian_3 and custodian_2 and custodian_3 == custodian_2: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) - # if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() - # if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() - # if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() + if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() + if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() + if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() - # return super().create(validated_data) + return super().create(validated_data) - # def update(self, instance, validated_data): - # return super().update(instance, validated_data) + def update(self, instance, validated_data): + print(validated_data) + + custodian_1 = validated_data.get('custodian_1') + custodian_2 = validated_data.get('custodian_2') + custodian_3 = validated_data.get('custodian_3') + + if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() + if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() + if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() + + return super().update(instance, validated_data) class IssueSerializer(serializers.ModelSerializer): diff --git a/server/attendance/urls.py b/server/attendance/urls.py index 5134b97..2102df1 100644 --- a/server/attendance/urls.py +++ b/server/attendance/urls.py @@ -6,8 +6,8 @@ path("attendance/", views.AttendanceList.as_view()), path("attendance//", views.AttendanceDetail.as_view()), path("trip/", views.TripList.as_view()), - path("trip//", views.AttendanceDetail.as_view()), - path("issue/", views.TripList.as_view()), + path("trip//", views.TripDetail.as_view()), + path("issue/", views.IssueList.as_view()), path("issue//", views.IssueDetail.as_view()), ] diff --git a/server/attendance/views.py b/server/attendance/views.py index 631bdce..3e84a65 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -79,7 +79,7 @@ class TripDetail( generics.GenericAPIView, ): queryset = Trip.objects.all() - serializer_class = IssueSerializer + serializer_class = TripSerializer def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index b985bf46881d9d1bef1b67559b75956f0379cc41..c5487f1b6a62f66b244c2773213da3f1db1f923d 100644 GIT binary patch delta 169 zcmZo@5Nv1=oFL6;KT*b+(Y`UEHG#1;foW?3^St}h|M4@kZD(1){Fk4X|1bkH-(?2A z%lzg1+M5Lnj`Br>F$yq<8#9QCb8>Pra&oGws)hu41{fF_7#ZpsnCluDC>WYq8JSxd z8DyjurIvsQCSwa%M{^Tbb3<1nM?(WMCs$`e?{3nx=U3ui|&16Ly_=jq!2nP;#t UFfiCo4ivDQG=XI+3(FsS09vsu%m4rY delta 122 zcmZo@5Nv1=oFL6;H&Mo!(XKI}HG#1;foW?3^St{^44m5*FtZ47G4pFP@E_(c=hxmW zSRl(kUHd=t3|nhP0S0kn22pWNPEJM!PH|C&kRZ Date: Tue, 20 Jul 2021 23:59:45 +0530 Subject: [PATCH 70/98] Trip Update --- server/attendance/admin.py | 6 +- .../migrations/0007_auto_20210720_1801.py | 34 +++++++ .../migrations/0008_auto_20210720_1804.py | 28 ++++++ server/attendance/models.py | 13 ++- server/attendance/serializers.py | 95 ++++++++++-------- server/db.sqlite3 | Bin 278528 -> 282624 bytes server/vendors/urls.py | 1 + 7 files changed, 126 insertions(+), 51 deletions(-) create mode 100644 server/attendance/migrations/0007_auto_20210720_1801.py create mode 100644 server/attendance/migrations/0008_auto_20210720_1804.py diff --git a/server/attendance/admin.py b/server/attendance/admin.py index 925ed3f..fcfebff 100644 --- a/server/attendance/admin.py +++ b/server/attendance/admin.py @@ -20,9 +20,9 @@ class AttendanceSheetAdmin(admin.ModelAdmin): class AttendanceAdmin(admin.ModelAdmin): - list_display = ("id", "gunmen", "entry_time", "exit_time", "branch_id") - list_display_links = ("id", "gunmen") - search_fields = ("gunmen",) + list_display = ("id", "custodian", "entry_time", "exit_time", "branch_id") + list_display_links = ("id", "custodian") + search_fields = ("custodian",) list_per_page = 20 diff --git a/server/attendance/migrations/0007_auto_20210720_1801.py b/server/attendance/migrations/0007_auto_20210720_1801.py new file mode 100644 index 0000000..cb56610 --- /dev/null +++ b/server/attendance/migrations/0007_auto_20210720_1801.py @@ -0,0 +1,34 @@ +# Generated by Django 3.0.4 on 2021-07-20 18:01 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('vendors', '0005_custodian'), + ('attendance', '0006_auto_20210720_1620'), + ] + + operations = [ + migrations.RemoveField( + model_name='attendance', + name='gunmen', + ), + migrations.AddField( + model_name='attendance', + name='custodian', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vendors.Custodian'), + ), + migrations.AlterField( + model_name='trip', + name='end_location', + field=models.CharField(blank=True, max_length=300, null=True), + ), + migrations.AlterField( + model_name='trip', + name='start_location', + field=models.CharField(blank=True, max_length=300, null=True), + ), + ] diff --git a/server/attendance/migrations/0008_auto_20210720_1804.py b/server/attendance/migrations/0008_auto_20210720_1804.py new file mode 100644 index 0000000..0c07d6e --- /dev/null +++ b/server/attendance/migrations/0008_auto_20210720_1804.py @@ -0,0 +1,28 @@ +# Generated by Django 3.0.4 on 2021-07-20 18:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('attendance', '0007_auto_20210720_1801'), + ] + + operations = [ + migrations.AlterField( + model_name='trip', + name='custodian_1_code', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AlterField( + model_name='trip', + name='custodian_2_code', + field=models.CharField(blank=True, max_length=20, null=True), + ), + migrations.AlterField( + model_name='trip', + name='custodian_3_code', + field=models.CharField(blank=True, max_length=20, null=True), + ), + ] diff --git a/server/attendance/models.py b/server/attendance/models.py index 969185a..4c9d8f9 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -1,7 +1,6 @@ from django.db import models from django.contrib.auth.models import User -from django.db.models.fields import NullBooleanField -from vendors.models import Vehicle, Vendor, Gunmen, Custodian +from vendors.models import Vehicle, Vendor, Custodian from users.models import Branch from datetime import datetime @@ -11,13 +10,13 @@ class Trip(models.Model): vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, null=True, blank=True) custodian_1 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_1') - custodian_1_code = models.CharField(max_length=6, blank=True, null=True) + custodian_1_code = models.CharField(max_length=20, blank=True, null=True) custodian_2 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_2') - custodian_2_code = models.CharField(max_length=6, blank=True, null=True) + custodian_2_code = models.CharField(max_length=20, blank=True, null=True) custodian_3 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_3') - custodian_3_code = models.CharField(max_length=6, blank=True, null=True) + custodian_3_code = models.CharField(max_length=20, blank=True, null=True) entry_time = models.DateTimeField(blank=True,null=True) @@ -45,7 +44,7 @@ def __str__(self): class Attendance(models.Model): entry_time = models.DateTimeField(default=datetime.now) exit_time = models.DateTimeField(blank=True, null=True) - gunmen = models.ForeignKey(Gunmen, on_delete=models.SET_NULL, null=True, blank=True) + custodian = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True) added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) attendance_sheet = models.ForeignKey( @@ -53,7 +52,7 @@ class Attendance(models.Model): ) def __str__(self): - return f"{self.gunmen.first_name} {self.gunmen.last_name}" + return f"{self.custodian.first_name} {self.custodian.last_name}" class Issue(models.Model): diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 2dee63b..a2a9e42 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,5 +1,4 @@ from secrets import token_hex -from typing_extensions import Required from rest_framework import serializers from rest_framework.response import Response @@ -36,8 +35,8 @@ class Meta: class AttendanceSerializer(serializers.ModelSerializer): - gunmen = RelatedFieldAlternative( - queryset=Gunmen.objects.all(), serializer=GunmenSerializer + custdian = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer ) attendance_sheet = RelatedFieldAlternative( queryset=AttendanceSheet.objects.all(), serializer=AttendanceSheetSerializer @@ -53,7 +52,7 @@ class Meta: model = Attendance fields = [ "id", - "gunmen", + "custodian", "entry_time", "exit_time", "branch", @@ -63,37 +62,24 @@ class Meta: class TripSerializer(serializers.ModelSerializer): - # vehicle = RelatedFieldAlternative( - # queryset=Vehicle.objects.all(), serializer=VehicleSerializer - # ) - # custodian_1 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # custodian_2 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # custodian_3 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # branch = RelatedFieldAlternative( - # queryset=Branch.objects.all(), serializer=BranchSerializer - # ) - # added_by = RelatedFieldAlternative( - # queryset=User.objects.all(), serializer=UserSerializer - # ) - vehicle = VehicleSerializer(required=False) - custodian_1 =CustodianSerializer(required=False) - custodian_2 = CustodianSerializer(required=False) - custodian_3 = CustodianSerializer(required=False) - branch = BranchSerializer(required=False) - added_by = UserSerializer(required=False) - - # vehicle = VehicleSerializer(required=False) - # custodian_1 =CustodianSerializer(required=False) - # custodian_2 = CustodianSerializer(required=False) - # custodian_3 = CustodianSerializer(required=False) - # branch = BranchSerializer(required=False) - # added_by = UserSerializer(required=False) + vehicle = RelatedFieldAlternative( + queryset=Vehicle.objects.all(), serializer=VehicleSerializer + ) + custodian_1 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer + ) + custodian_2 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer, required=False + ) + custodian_3 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer + ) + branch = RelatedFieldAlternative( + queryset=Branch.objects.all(), serializer=BranchSerializer + ) + added_by = RelatedFieldAlternative( + queryset=User.objects.all(), serializer=UserSerializer + ) class Meta: model = Trip @@ -103,6 +89,9 @@ class Meta: "custodian_1", "custodian_2", "custodian_3", + "custodian_1_code", + "custodian_2_code", + "custodian_3_code", "entry_time", "exit_time", "start_location", @@ -129,15 +118,39 @@ def create(self, validated_data): return super().create(validated_data) def update(self, instance, validated_data): - print(validated_data) - custodian_1 = validated_data.get('custodian_1') custodian_2 = validated_data.get('custodian_2') custodian_3 = validated_data.get('custodian_3') - - if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() - if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() - if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() + custodian_1_code = validated_data.get('custodian_1_code') + custodian_2_code = validated_data.get('custodian_2_code') + custodian_3_code = validated_data.get('custodian_3_code') + + if custodian_1_code: + if custodian_1_code != instance.custodian_1_code: + return serializers.ValidationError({'error': 'Code does not match !'}) + else: + Attendance.objects.create( + custodian= custodian_1, + branch= instance.branch, + ) + + if custodian_2_code: + if custodian_2_code != instance.custodian_2_code: + return serializers.ValidationError({'error': 'Code does not match !'}) + else: + Attendance.objects.create( + custodian= custodian_2, + branch= instance.branch, + ) + + if custodian_3_code: + if custodian_3_code != instance.custodian_3_code: + return serializers.ValidationError({'error': 'Code does not match !'}) + else: + Attendance.objects.create( + custodian= custodian_3, + branch= instance.branch, + ) return super().update(instance, validated_data) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index c5487f1b6a62f66b244c2773213da3f1db1f923d..3e4d0dcc1b5d67c73fdf4559c42985ad38c88f98 100644 GIT binary patch delta 1240 zcmZ`(Z%iCT6yKRQ$KD=yH+R)z10^j5N?8w%+2y#s1EiclTPjv)i`vwNUV#XSp{U@W zC@EX9Vq+R8!W>kgni^@W+TvoKA3W(FS?h0XB|RA=(1p`hW<@&((80NhzRsSGL{EDsV=UU1 z=%qL&gMOC>z0xp4QHNnh zDp=}*y3?t4(E_@aMrkXh-X*%={hp3{zwo}7()0Sg3bmy5lAyBDcox2|XzYAwfouR% z;fupKF!o7VGb%jHjxaRGFlr8pRDF0r!UNuGo~nTy9Ca)?nn((M zh8&b5Ja#tnH zO1(T}hK*>LdFWor3%9`WJeh%8o)0}QxR=~#GXKatmznGQ#+fZYk}*T(=w9NVfo~;Y z^ObNYmg5(=EJFVr(iei{G=>K(ou8hDeE#AL3=?ac#rQ|#@U>!<$!fwxRx3X{4Qu(- z1RV1XJ#2+!)ilv?MPK5;)1507y{NmfN8)>|E6G`%m z#bh&AipghuRwI!Kjf|&%)W{-|S7UmAti|`PT>}@;>k_?fk7vq1xJ3Ey-+_A#fTFmB zCD0qv%Iw|{hdz~?97CDhEfPr;a&f1!yz(pMdkEoH336a01q? zzQqsY{d~upcn`0h26tN2?Ja~2#vh-C0$aW;+Wcan6ZT3sUKMB3~I2$F8m*h_ynxa{qN;`&8{F&pG0Trlhh}E518`c zKali3hJ2D*E(KIYEW{V@K+!gHOEexgx0v-65hK>18}$uFBwk-%7c*m#c=(};`nqsz qwY@7`C%8u7L4j(4DgjeK7rnefPmw&k|7pU=ZF;;nBb{M?A^!q115SYe delta 1011 zcmZuwUu;ul6u;khZtv}Fd+&G4EZ2cT-Ik?whPA7#9m2M5T<}43gW!|PD0a*NYnD0C z2WNU=lKC<>%XY3AB1RxcNSLX#i4hh7W1{gv_dw_7KYTD|F&iXGq9*!Xs>DQ3a!$^_ z?{{+keA!d}Y}P-%*54us!dA}z(B~76#41~a4cpJTxJzV9PN1Fr&VFUL*izm*<|5!%xvY|BbFyycqrvCp{H(Fl9hlTUWY4i`ww)!|ZpO5mtfYOB_wSj~ zXoa4;vY{mUAnwMAQ5wiytnVOIMT^GBwybqhRbaifz-X-!^pXECBPqYzpzihF>#4axba9r;pMQzCS|k;?fum5Ro^xlcPR~!$;`J z;*MA7Nu@AO#hG`+?}C>^_@n;yaWUj|ofo7-uJde{cGh##vrU;%yzYJSM{-Eq2d~i| zNrD4i7A|w39F-2_JN2JLupU2%od}Db*vAWcpem3RfgyXt>(-nL==ntT2#4&MJCaMY2H=Ef8pJ`H+dg-W`6S>Px9 z3tP_nv)?mZnFXIq1ftNwDUkF_68y$Am0c4+n-jD-_5!Qpm;SM)Jxz4MhzS8hQ52$J zVHs*`VhJ-Df7Fae&4y$&(%5FU$70)J8xw6CqlxxpW5jG|Ye#(l9a?b5`UzG>=x9O1afoZVu_B4DTKW2p_cB4^(I^;#XC88mloF^r8YSm5%s?S6HhRv diff --git a/server/vendors/urls.py b/server/vendors/urls.py index bec52c5..f73d86d 100644 --- a/server/vendors/urls.py +++ b/server/vendors/urls.py @@ -1,4 +1,5 @@ from django.urls import path +from rest_framework.generics import CreateAPIView from rest_framework.urlpatterns import format_suffix_patterns from . import views From f64a79692b4826c85400c52fe243213db72cc223 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 00:16:50 +0530 Subject: [PATCH 71/98] custodian hack --- .../migrations/0007_auto_20210720_2300.py | 23 ++++ server/attendance/serializers.py | 99 +++++++++--------- server/attendance/views.py | 58 ++++++---- server/db.sqlite3 | Bin 278528 -> 282624 bytes 4 files changed, 109 insertions(+), 71 deletions(-) create mode 100644 server/attendance/migrations/0007_auto_20210720_2300.py diff --git a/server/attendance/migrations/0007_auto_20210720_2300.py b/server/attendance/migrations/0007_auto_20210720_2300.py new file mode 100644 index 0000000..4f5c7e3 --- /dev/null +++ b/server/attendance/migrations/0007_auto_20210720_2300.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.4 on 2021-07-20 17:30 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('attendance', '0006_auto_20210720_1620'), + ] + + operations = [ + migrations.AlterField( + model_name='trip', + name='end_location', + field=models.CharField(blank=True, max_length=300, null=True), + ), + migrations.AlterField( + model_name='trip', + name='start_location', + field=models.CharField(blank=True, max_length=300, null=True), + ), + ] diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 0933c93..16457c4 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,5 +1,4 @@ from secrets import token_hex -from typing_extensions import Required from rest_framework import serializers from rest_framework.response import Response @@ -18,11 +17,14 @@ class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): def __init__(self, **kwargs): + self.serializer = kwargs.pop("serializer", None) if self.serializer is not None and not issubclass( self.serializer, serializers.Serializer ): raise TypeError('"serializer" is not a valid serializer class') + # if self.serializer: + # print(self.serializer) super().__init__(**kwargs) def use_pk_only_optimization(self): @@ -68,33 +70,26 @@ class Meta: class TripSerializer(serializers.ModelSerializer): - # vehicle = RelatedFieldAlternative( - # queryset=Vehicle.objects.all(), serializer=VehicleSerializer - # ) - # custodian_1 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # custodian_2 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # custodian_3 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # branch = RelatedFieldAlternative( - # queryset=Branch.objects.all(), serializer=BranchSerializer - # ) - # added_by = RelatedFieldAlternative( - # queryset=User.objects.all(), serializer=UserSerializer - # ) - vehicle = VehicleSerializer(required=False) - custodian_1 =CustodianSerializer(required=False) - custodian_2 = CustodianSerializer(required=False) - custodian_3 = CustodianSerializer(required=False) - branch = BranchSerializer(required=False) - added_by = UserSerializer(required=False) - + vehicle = RelatedFieldAlternative( + queryset=Vehicle.objects.all(), serializer=VehicleSerializer + ) + custodian_1 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer + ) + custodian_2 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer + ) + custodian_3 = RelatedFieldAlternative( + queryset=Custodian.objects.all(), serializer=CustodianSerializer + ) + branch = RelatedFieldAlternative( + queryset=Branch.objects.all(), serializer=BranchSerializer + ) + added_by = RelatedFieldAlternative( + queryset=User.objects.all(), serializer=UserSerializer + ) # vehicle = VehicleSerializer(required=False) - # custodian_1 =CustodianSerializer(required=False) + # custodian_1 = CustodianSerializer(required=False) # custodian_2 = CustodianSerializer(required=False) # custodian_3 = CustodianSerializer(required=False) # branch = BranchSerializer(required=False) @@ -117,32 +112,40 @@ class Meta: ] def create(self, validated_data): - validated_data['trip_code'] = token_hex(6).upper() - - custodian_1 = validated_data.get('custodian_1') - custodian_2 = validated_data.get('custodian_2') - custodian_3 = validated_data.get('custodian_3') - - if custodian_1 and custodian_2 and custodian_1 == custodian_2: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) - if custodian_1 and custodian_3 and custodian_1 == custodian_3: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) - if custodian_3 and custodian_2 and custodian_3 == custodian_2: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) + print(validated_data) + validated_data["trip_code"] = token_hex(6).upper() + + custodian_1 = validated_data.get("custodian_1") + custodian_2 = validated_data.get("custodian_2") + custodian_3 = validated_data.get("custodian_3") + + # if custodian_1 and custodian_2 and custodian_1 == custodian_2: + # raise serializers.ValidationError( + # {"error": "Same Custodian cannot be assigned twice"} + # ) + # if custodian_1 and custodian_3 and custodian_1 == custodian_3: + # raise serializers.ValidationError( + # {"error": "Same Custodian cannot be assigned twice"} + # ) + # if custodian_3 and custodian_2 and custodian_3 == custodian_2: + # raise serializers.ValidationError( + # {"error": "Same Custodian cannot be assigned twice"} + # ) + + # print(validated_data) + + if custodian_1: + validated_data["custodian_1_code"] = token_hex(6).upper() + if custodian_2 != custodian_2: + validated_data["custodian_2_code"] = token_hex(6).upper() + if custodian_3 != custodian_1: + validated_data["custodian_3_code"] = token_hex(6).upper() - if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() - if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() - if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() + print(validated_data) return super().create(validated_data) def update(self, instance, validated_data): - print(validated_data) - - custodian_1 = validated_data.get('custodian_1') - custodian_2 = validated_data.get('custodian_2') - custodian_3 = validated_data.get('custodian_3') - - if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() - if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() - if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() return super().update(instance, validated_data) diff --git a/server/attendance/views.py b/server/attendance/views.py index b78b4e0..2c7966c 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -11,12 +11,13 @@ from rest_framework.pagination import PageNumberPagination from django_filters.rest_framework import DjangoFilterBackend +from users.serializers import BranchSerializer, UserSerializer +from vendors.serializers import CustodianSerializer, VehicleSerializer from attendance.serializers import AttendanceSerializer, IssueSerializer, TripSerializer -from users.models import Branch +from users.models import Branch, User +from vendors.models import Custodian, Vehicle, Gunmen from attendance.models import Attendance, AttendanceSheet, Issue, Trip -from vendors.models import Gunmen -from users.models import User class CustomPagination(PageNumberPagination): @@ -70,26 +71,37 @@ def get(self, request, *args, **kwargs): return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): - # validated_data = request.data - # validated_data["trip_code"] = token_hex(6).upper() - - # custodian_1 = validated_data.get("custodian_1") - # custodian_2 = validated_data.get("custodian_2") - # custodian_3 = validated_data.get("custodian_3") - - # if custodian_1 and custodian_2 and custodian_1 == custodian_2: - # return Response("!! ERR !!: The custodian ids cannot be same") - # if custodian_1 and custodian_3 and custodian_1 == custodian_3: - # return Response("!! ERR !!: The custodian ids cannot be same") - # if custodian_3 and custodian_2 and custodian_3 == custodian_2: - # return Response("!! ERR !!: The custodian ids cannot be same") - - # if custodian_1: - # validated_data["custodian_1_code"] = token_hex(6).upper() - # if custodian_2: - # validated_data["custodian_2_code"] = token_hex(6).upper() - # if custodian_3: - # validated_data["custodian_3_code"] = token_hex(6).upper() + validated_data = request.data + print(request.data) + + # vehicle = validated_data.get("vehicle") + custodian_1 = validated_data.get("custodian_1") + custodian_2 = validated_data.get("custodian_2") + custodian_3 = validated_data.get("custodian_3") + # branch = validated_data.get("branch") + # added_by = validated_data.get("added_by") + + if custodian_1 and custodian_2 and custodian_1 == custodian_2: + return Response( + "!! ERR !!: The same custodian cannot be added more than once" + ) + if custodian_1 and custodian_3 and custodian_1 == custodian_3: + return Response( + "!! ERR !!: The same custodian cannot be added more than once" + ) + if custodian_3 and custodian_2 and custodian_3 == custodian_2: + return Response( + "!! ERR !!: The same custodian cannot be added more than once" + ) + + # print(request.data) + + if not custodian_2: + request.data["custodian_2"] = request.data["custodian_1"] + if not custodian_3: + request.data["custodian_3"] = request.data["custodian_1"] + + print(request.data) return self.create(request, *args, **kwargs) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index c957a67df122b019bd6fbf5ed853523f26536a6e..db93e0e1e911e537d9b16ba0b8288dcb14cd96ad 100644 GIT binary patch delta 4319 zcmc&%Yj6|S72e&udaP{eO12e;0nFOQ!Nx}3hjv#IV0$fO=K-W7Ve+Jkuoc_Hl89{c z7~;zEn9#JDl;Ge6%p;v2{*C-yns#1G;!{DI>W$LUNpKjBD~ zFG7vu~(w;mCcK8 z!;5F6lhGcyQ;CsG8?Ju3-0Xq~RB+?ZG_P->DAy9yFh>ERpPL3%^Y4%K^&}&M@ccmS z8v-lXP-zF{c*{Ok+5xuuO6x~gBGbAtlb#&v-jP)NL(zflTeiggQLo$^d-5qQp-DS? zdStJd`FYGlyX1UyB+(iE7@zqt z^|vKuGl9=S3$h|)et+!13FF<}%)wXL2;Ev?#iuEt-M{c<{3-qm{uBNKKAmxm9LJp| zMAI%S>Ft(mZ_f56(wDNNw;|GV42x*aY6JIK@mUIA!~e!t@n`rGfcrB(3t%U4Ig2>j zN;(Va%%mIt=egS}toGL^{1)Dc>l`0Djyb;TSZIF@T)5w!>bG)~j)xm*jw>LcFQBL% zRgyJT662A0f?v_Xue(!!NEOup9}Mt7Bau(UqfLBgb|UeE+Y?RsJ2F4mn~X*u-BlCm z?v8fX1o&OU!<$^Xg}iOq?AuZ^S>p=`eh*}nCMa?ay*P%w)l4vIXEA0Vw16Ube43`J zqBKXR0wwINrdfd0{KV4&lIqb^pI?#1IVKh&1X+U6SVRRiAS)h0(?mfnbXoyO>3s-5 zQuwZ-D5BrvmHaB8tu*#auG}=Aj%#;I7bu2TnZD+2%k&P z0kHsyTSXJ3#l?{X5BNwG{NfFsw%UQFG=7=FFGErt!cRN`XbT(V+G;tU?lX1)Ka$ab zfg-kv8mOvyB|-H=$>~nSdWLq2b4V)50YQOsOHzWy*B~Vz2`*zROcCNZTZSGnIoZ!C z{5h=u6_+__6XjmW5iaL>{Kg5^X`b__JO3!r9^o+xpTV!=vFtXHT8^v~c2_o3b3tIf zoTWFpXvvK?dxAJ*|*osUZn6vkoXXX7J$Kv>$vF{u{0-eDT0%%;`_}{L5o4_Gro5a{e(-)mdXu{bXqaaA3$!S&TXRpM3ghpGP;bc|Us|+OLOFSUnep%>s-=U*$!D1b#>6Cg(7>aN+o&I9 zs*UEu=r$IP8x4j&$~tJam+|roJ%2y(?4?R zZiUtYZ8fyHK|YDr?&%~HCqWi(9^`_+2ZQ&8^an!x1A6<~5MNU)_&3dqZ^%WCSr-9! zghKB4Sc)>ApJC4~GF>&zA2Kr;WcK3{_(r)}SU9$k)yHm7Iv^8IW#ZbnTO^Vj&Hz0%MPQeq8y^h7LA-d!c7!Dj{9LCA8y4cbR6o$J?Z5+ z3i)qNA>)*RDobz1m~Yn?^U2aslq?tLlcjAQSte)5@?}x7Jbq)cyptn~M#%DF(E^(K z|5cM*4M|tDASYEvQI#D0Xs(W`bIYMnyX;eRUr0^~gT2vY6nPb0lYM?&_xZeje<&#U zG+mN3h1|S{nE`+gqq;f(=ny-+?d?8&jRZ$C5MdA;o~4i|%Ryc8iNTOh^LZ7otcw5u delta 797 zcmZ8fT}V_x6uxt3cJJNm-aWgnW}3Mx_T#$ddehV--NK?5Q?{R{kY!6S%m03~R9wS+ zlG0Y4jZj0W2!qTUT#z2tALya7prQwZG$@i3^`#z?YL;Ax28MIy`{wYSGxPcHSp0rV z_ZCYo$8iVQj;!&X^sM+?E~B(n#~=brVWJ3r!gpAMCDl^b2z-89U=6G|SwsQBT%;;? zO;FKhBqp5TBuL?45#GWiJc2%Ghcl1@hary@3J^$fWpCoF5vh$B2RI8+OBJ%}EzvS| zih)j7NxBu|U1IrJUrj}=*H>O$S>vs$t%ya~g*L$I%8CZxh05BR^U33xBva(&4$d?s zcd&MvWVNH(&x<^09DD#xwfIMYY{N%TpsU)h&b589MJs#lN?!i%-2BX(3?(N|*^{Nd z848919`mjH#E0A}nP0aJhs@(4V*WQDA!GK)nbB#ou7Ly8!s%v6nW Date: Wed, 21 Jul 2021 00:19:30 +0530 Subject: [PATCH 72/98] attendance hack --- server/attendance/serializers.py | 62 +++++++++----------------------- 1 file changed, 17 insertions(+), 45 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 2c3a029..28a49c0 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -77,11 +77,7 @@ class TripSerializer(serializers.ModelSerializer): queryset=Custodian.objects.all(), serializer=CustodianSerializer ) custodian_2 = RelatedFieldAlternative( -<<<<<<< HEAD queryset=Custodian.objects.all(), serializer=CustodianSerializer -======= - queryset=Custodian.objects.all(), serializer=CustodianSerializer, required=False ->>>>>>> 551d02804b04960f7f3e228e635cc2425024c8ec ) custodian_3 = RelatedFieldAlternative( queryset=Custodian.objects.all(), serializer=CustodianSerializer @@ -92,15 +88,6 @@ class TripSerializer(serializers.ModelSerializer): added_by = RelatedFieldAlternative( queryset=User.objects.all(), serializer=UserSerializer ) -<<<<<<< HEAD - # vehicle = VehicleSerializer(required=False) - # custodian_1 = CustodianSerializer(required=False) - # custodian_2 = CustodianSerializer(required=False) - # custodian_3 = CustodianSerializer(required=False) - # branch = BranchSerializer(required=False) - # added_by = UserSerializer(required=False) -======= ->>>>>>> 551d02804b04960f7f3e228e635cc2425024c8ec class Meta: model = Trip @@ -129,21 +116,6 @@ def create(self, validated_data): custodian_2 = validated_data.get("custodian_2") custodian_3 = validated_data.get("custodian_3") - # if custodian_1 and custodian_2 and custodian_1 == custodian_2: - # raise serializers.ValidationError( - # {"error": "Same Custodian cannot be assigned twice"} - # ) - # if custodian_1 and custodian_3 and custodian_1 == custodian_3: - # raise serializers.ValidationError( - # {"error": "Same Custodian cannot be assigned twice"} - # ) - # if custodian_3 and custodian_2 and custodian_3 == custodian_2: - # raise serializers.ValidationError( - # {"error": "Same Custodian cannot be assigned twice"} - # ) - - # print(validated_data) - if custodian_1: validated_data["custodian_1_code"] = token_hex(6).upper() if custodian_2 != custodian_2: @@ -154,38 +126,38 @@ def create(self, validated_data): return super().create(validated_data) def update(self, instance, validated_data): - custodian_1 = validated_data.get('custodian_1') - custodian_2 = validated_data.get('custodian_2') - custodian_3 = validated_data.get('custodian_3') - custodian_1_code = validated_data.get('custodian_1_code') - custodian_2_code = validated_data.get('custodian_2_code') - custodian_3_code = validated_data.get('custodian_3_code') + custodian_1 = validated_data.get("custodian_1") + custodian_2 = validated_data.get("custodian_2") + custodian_3 = validated_data.get("custodian_3") + custodian_1_code = validated_data.get("custodian_1_code") + custodian_2_code = validated_data.get("custodian_2_code") + custodian_3_code = validated_data.get("custodian_3_code") if custodian_1_code: if custodian_1_code != instance.custodian_1_code: - return serializers.ValidationError({'error': 'Code does not match !'}) + return serializers.ValidationError({"error": "Code does not match !"}) else: Attendance.objects.create( - custodian= custodian_1, - branch= instance.branch, + custodian=custodian_1, + branch=instance.branch, ) - if custodian_2_code: + if custodian_2_code and custodian_2 != custodian_1: if custodian_2_code != instance.custodian_2_code: - return serializers.ValidationError({'error': 'Code does not match !'}) + return serializers.ValidationError({"error": "Code does not match !"}) else: Attendance.objects.create( - custodian= custodian_2, - branch= instance.branch, + custodian=custodian_2, + branch=instance.branch, ) - if custodian_3_code: + if custodian_3_code and custodian_3 != custodian_1: if custodian_3_code != instance.custodian_3_code: - return serializers.ValidationError({'error': 'Code does not match !'}) + return serializers.ValidationError({"error": "Code does not match !"}) else: Attendance.objects.create( - custodian= custodian_3, - branch= instance.branch, + custodian=custodian_3, + branch=instance.branch, ) return super().update(instance, validated_data) From 0e727196521b08d5dd5108d86d85454683d05456 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 00:28:23 +0530 Subject: [PATCH 73/98] nm --- .../migrations/0009_merge_20210721_0021.py | 14 +++++++++ server/attendance/serializers.py | 2 +- server/attendance/views.py | 29 +++++++++++++----- server/db.sqlite3 | Bin 282624 -> 282624 bytes 4 files changed, 37 insertions(+), 8 deletions(-) create mode 100644 server/attendance/migrations/0009_merge_20210721_0021.py diff --git a/server/attendance/migrations/0009_merge_20210721_0021.py b/server/attendance/migrations/0009_merge_20210721_0021.py new file mode 100644 index 0000000..103e6cd --- /dev/null +++ b/server/attendance/migrations/0009_merge_20210721_0021.py @@ -0,0 +1,14 @@ +# Generated by Django 3.0.4 on 2021-07-20 18:51 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('attendance', '0008_auto_20210720_1804'), + ('attendance', '0007_auto_20210720_2300'), + ] + + operations = [ + ] diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 28a49c0..d9bddfc 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -135,7 +135,7 @@ def update(self, instance, validated_data): if custodian_1_code: if custodian_1_code != instance.custodian_1_code: - return serializers.ValidationError({"error": "Code does not match !"}) + return serializers.ValidationError({"Error": "Code does not match !"}) else: Attendance.objects.create( custodian=custodian_1, diff --git a/server/attendance/views.py b/server/attendance/views.py index 2c7966c..51b8f4b 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -72,14 +72,10 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): validated_data = request.data - print(request.data) - # vehicle = validated_data.get("vehicle") custodian_1 = validated_data.get("custodian_1") custodian_2 = validated_data.get("custodian_2") custodian_3 = validated_data.get("custodian_3") - # branch = validated_data.get("branch") - # added_by = validated_data.get("added_by") if custodian_1 and custodian_2 and custodian_1 == custodian_2: return Response( @@ -94,14 +90,11 @@ def post(self, request, *args, **kwargs): "!! ERR !!: The same custodian cannot be added more than once" ) - # print(request.data) - if not custodian_2: request.data["custodian_2"] = request.data["custodian_1"] if not custodian_3: request.data["custodian_3"] = request.data["custodian_1"] - print(request.data) return self.create(request, *args, **kwargs) @@ -118,7 +111,29 @@ def get(self, request, *args, **kwargs): return self.retrieve(request, *args, **kwargs) def put(self, request, *args, **kwargs): + validated_data = request.data + + custodian_1 = validated_data.get("custodian_1") + custodian_2 = validated_data.get("custodian_2") + custodian_3 = validated_data.get("custodian_3") + if custodian_1 and custodian_2 and custodian_1 == custodian_2: + return Response( + "!! ERR !!: The same custodian cannot be added more than once" + ) + if custodian_1 and custodian_3 and custodian_1 == custodian_3: + return Response( + "!! ERR !!: The same custodian cannot be added more than once" + ) + if custodian_3 and custodian_2 and custodian_3 == custodian_2: + return Response( + "!! ERR !!: The same custodian cannot be added more than once" + ) + + if not custodian_2: + request.data["custodian_2"] = request.data["custodian_1"] + if not custodian_3: + request.data["custodian_3"] = request.data["custodian_1"] return self.update(request, *args, **kwargs) def delete(self, request, *args, **kwargs): diff --git a/server/db.sqlite3 b/server/db.sqlite3 index db93e0e1e911e537d9b16ba0b8288dcb14cd96ad..ae3939b0ef52c597ccb98ee04ace1c70cecaaeae 100644 GIT binary patch delta 2267 zcmcIlZERCj7{2FYz5QT4Ev}SpFiK|!WgWe@?cHrR*w(`MoG=2Yh)}vw1tUXX6JrAG zF2pUE0Na>nqGN=h(O?3m*v3SWUq(z^;E&25Abx~N5C%Ua1~s13%YbT$KMeQwJ-zqb z=brnX=Y7s|I*-~rkJ=BG+E)sK(8!{m1z^A8USF_yr7(N>t^(GB$u-srb>uGjjf|0N zDf=rOq@+gUXs^Z}IlZiL*b7-(VMzCjwuJ_<*6_O_omydQG3<#}6bRGjMicGr$+nG& zw$`L1Ns;)Lf0 zbhK|BA3=)CVJVbv1fvpGBZ}JaWd9zgyNsdoe#rn|?^ z+U6CKwSpDhK?SekVRWbPMB&Z}KTP<@a@%s+GR63fu~>Y{FpSe=Ew&G%5s_ieiB3fU z`wK?VMbTMV3HDdfZI!s3PQ{qe6Mblq)=$8bsp}>(QITMGW)$O95C$ZwT}9>mKOwS- z1SD@}!(nt1qFGu!{qP8K)7OSk57riGb#$x~ehsy`wD~P`%C>i@Hb-=-D(F$#6D=<% zvjorsUC;p{bf^y%XU=rNcLBZfGcr^6A+(BmZ=&zg6up2%t{g#lkFFR+74$DJE~Fy| zQ5z%pj)2H@f&4*klj|va=OyARKmb69kqIF7N&!U3WHPfWL~aS>78j-vX1CQW6eiCi zQdWm-f`^IH#13Hc2p(s!u`w15E75RcP@+rycxrk3rsVeIQg|N-7|_Fj3*-f%SS%c! z9|+Pn{diVW7T5@ELa{#LJ)o@clMez>bs$z9n;((_N-Wfku*}SJ02Bx7lpzUZgG8YZ;_t2v^ZT3#*_H zp|K)8#ik~&7StL< zXR8XdHT2XGRO)E$*wMaqXKp6czSC5K$5c5sX6h!#|yIASkwf9eCdJzUSkG z=Q+?2jdyp6X zDDvf^xmyO0DTCXUC!<&GOsYohaK#Vh>Tsv$q~`ADySSIv@|F63d^6AIPxJ}>p=@zV zr?ciIuPuGXav`W;UpI9p|0%C0-Y);2elp^xtlrMaeTCddM}p3=(-!5O66y;V;Hm_z z#FlaBAg%Z-!rg)v)e{L4v8g#8jr|sBZ;!>J5j@mI|I&}t>{dO&An7*SBTcP1nSw%` zN`aeHktzK0X@`zL`$hRaT#`av^VBaUvCee(IXJLSed=bE{ zrR;=L%ofX3&n6!cKjU?ixzX^k4(HL8qC)lfe57YFqK|p8m@$r5yQvcsy>QIB!`NyH zVttl0X~E(Y3|UiWUt*^M0o(LQCWL(>N^5&oXLkjy49P70V*gXkbQUJoE}Q zeD)fO|L?>=3g+vdZ!R=NX0m-2w z*MS*@IqGGF-{7UrxZ{zdItR5WZKHbGn)3k0!FjY!cvVkjCFu!c8rTvN#?Tnt#Lc

3bzQVo(8E>RaT|+Q~Bg8a8C(agU2=2$ixCsnbCF;9yVDX)|yhUp$RZE z<%-Pi^6#en1VtZbj|bCW*rm Date: Wed, 21 Jul 2021 01:46:06 +0530 Subject: [PATCH 74/98] Co-authored-by: RUiNtheExtinct --- server/attendance/serializers.py | 66 ++++++++++++++++++++----------- server/attendance/views.py | 3 -- server/db.sqlite3 | Bin 278528 -> 278528 bytes 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 2dee63b..a115d0a 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,10 +1,13 @@ from secrets import token_hex -from typing_extensions import Required - from rest_framework import serializers from rest_framework.response import Response from users.serializers import BranchSerializer, UserSerializer -from vendors.serializers import VendorSerializer, GunmenSerializer, CustodianSerializer, VehicleSerializer +from vendors.serializers import ( + VendorSerializer, + GunmenSerializer, + CustodianSerializer, + VehicleSerializer, +) from .models import Attendance, AttendanceSheet, Issue, Trip from users.models import Branch, User @@ -82,7 +85,7 @@ class TripSerializer(serializers.ModelSerializer): # queryset=User.objects.all(), serializer=UserSerializer # ) vehicle = VehicleSerializer(required=False) - custodian_1 =CustodianSerializer(required=False) + custodian_1 = CustodianSerializer(required=False) custodian_2 = CustodianSerializer(required=False) custodian_3 = CustodianSerializer(required=False) branch = BranchSerializer(required=False) @@ -112,32 +115,47 @@ class Meta: ] def create(self, validated_data): - validated_data['trip_code'] = token_hex(6).upper() - - custodian_1 = validated_data.get('custodian_1') - custodian_2 = validated_data.get('custodian_2') - custodian_3 = validated_data.get('custodian_3') - - if custodian_1 and custodian_2 and custodian_1 == custodian_2: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) - if custodian_1 and custodian_3 and custodian_1 == custodian_3: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) - if custodian_3 and custodian_2 and custodian_3 == custodian_2: raise serializers.ValidationError({'error': 'Same Custodian cannot be assigned twice'}) - - if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() - if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() - if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() + validated_data["trip_code"] = token_hex(6).upper() + + custodian_1 = validated_data.get("custodian_1") + custodian_2 = validated_data.get("custodian_2") + custodian_3 = validated_data.get("custodian_3") + + if custodian_1 and custodian_2 and custodian_1 == custodian_2: + raise serializers.ValidationError( + {"error": "Same Custodian cannot be assigned twice"} + ) + if custodian_1 and custodian_3 and custodian_1 == custodian_3: + raise serializers.ValidationError( + {"error": "Same Custodian cannot be assigned twice"} + ) + if custodian_3 and custodian_2 and custodian_3 == custodian_2: + raise serializers.ValidationError( + {"error": "Same Custodian cannot be assigned twice"} + ) + + if custodian_1: + validated_data["custodian_1_code"] = token_hex(6).upper() + if custodian_2: + validated_data["custodian_2_code"] = token_hex(6).upper() + if custodian_3: + validated_data["custodian_3_code"] = token_hex(6).upper() return super().create(validated_data) - + def update(self, instance, validated_data): print(validated_data) - custodian_1 = validated_data.get('custodian_1') - custodian_2 = validated_data.get('custodian_2') - custodian_3 = validated_data.get('custodian_3') + custodian_1 = validated_data.get("custodian_1") + custodian_2 = validated_data.get("custodian_2") + custodian_3 = validated_data.get("custodian_3") - if custodian_1: validated_data['custodian_1_code'] = token_hex(6).upper() - if custodian_2: validated_data['custodian_2_code'] = token_hex(6).upper() - if custodian_3: validated_data['custodian_3_code'] = token_hex(6).upper() + if custodian_1: + validated_data["custodian_1_code"] = token_hex(6).upper() + if custodian_2: + validated_data["custodian_2_code"] = token_hex(6).upper() + if custodian_3: + validated_data["custodian_3_code"] = token_hex(6).upper() return super().update(instance, validated_data) diff --git a/server/attendance/views.py b/server/attendance/views.py index 3e84a65..50d3692 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -114,7 +114,6 @@ class AttendanceList( ordering_fields = "__all__" - def get(self, request, *args, **kwargs): params = request.query_params start_date = params.get("start_date", datetime.min) @@ -185,8 +184,6 @@ def post(self, request, *args, **kwargs): result.append(AttendanceSerializer(attendance).data) return Response(data=result) - - class AttendanceDetail( diff --git a/server/db.sqlite3 b/server/db.sqlite3 index c5487f1b6a62f66b244c2773213da3f1db1f923d..75cfc4fc0331f4f6a8ee859fa696c3ab896e8089 100644 GIT binary patch delta 278 zcmZo@5Nv1=oFL8UG*QNx)rmpR{^rJ%1@RnAye$lThj?2y8!A-rsyA6PvHG^KIvQCT z73P$i<(lVP6qJ^yRVAC5RGOz|BpREVr{|;?Z+@A_$tY%SWo%$&YM^IfW^8F<*ksKJ z);jq?y~5^Kc~XoVO#Is!__y=l*(_MFnqO6g*_V-kvAIl}@6^AP=Y<<=YH4EHd})6B zrTL6N%(VT|d}gBwKywc>@IT@|3^aE;zpWgzBcqXlk)f`Eg|30If+1Wp*i}rj%#NJM T(q>jh##RPqdM1{}7KWApTLMuC delta 138 zcmZo@5Nv1=oFL6;KT*b+)t*7meZ|I<1@UZ*e1{nL4s8}J*ulrqWX;Ix+rsKN`9ZzH z=2v-AjBJejcNqBZY!+;|#J~AY{Y!aXGb Date: Wed, 21 Jul 2021 12:45:33 +0530 Subject: [PATCH 75/98] added Attendance Vehicle model --- server/attendance/admin.py | 22 ++++++- .../migrations/0010_trip_trip_start.py | 18 ++++++ .../migrations/0011_attendancevehicle.py | 31 +++++++++ server/attendance/models.py | 61 ++++++++++++++---- server/attendance/serializers.py | 11 +++- server/db.sqlite3 | Bin 282624 -> 299008 bytes 6 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 server/attendance/migrations/0010_trip_trip_start.py create mode 100644 server/attendance/migrations/0011_attendancevehicle.py diff --git a/server/attendance/admin.py b/server/attendance/admin.py index fcfebff..1eeba38 100644 --- a/server/attendance/admin.py +++ b/server/attendance/admin.py @@ -5,8 +5,18 @@ class TripAdmin(admin.ModelAdmin): list_display = ( - "id", "vehicle", "custodian_1", "custodian_2", "custodian_3", - "entry_time", "exit_time", "start_location", "end_location", "branch_id", "added_by") + "id", + "vehicle", + "custodian_1", + "custodian_2", + "custodian_3", + "entry_time", + "exit_time", + "start_location", + "end_location", + "branch_id", + "added_by", + ) list_display_links = ("id", "custodian_1", "custodian_2", "custodian_3") search_fields = ("id", "vehicle", "custodian_1", "custodian_2", "custodian_3") list_per_page = 20 @@ -18,7 +28,6 @@ class AttendanceSheetAdmin(admin.ModelAdmin): list_per_page = 20 - class AttendanceAdmin(admin.ModelAdmin): list_display = ("id", "custodian", "entry_time", "exit_time", "branch_id") list_display_links = ("id", "custodian") @@ -26,6 +35,13 @@ class AttendanceAdmin(admin.ModelAdmin): list_per_page = 20 +class AttendanceVehicleAdmin(admin.ModelAdmin): + list_display = ("id", "vehicle", "entry_time", "exit_time", "branch_id") + list_display_links = ("id", "vehicle") + search_fields = ("vehicle",) + list_per_page = 20 + + class IssueAdmin(admin.ModelAdmin): list_display = ("id", "comment", "vendor", "reverted_by", "sheet", "created_at") list_display_links = ("id", "comment") diff --git a/server/attendance/migrations/0010_trip_trip_start.py b/server/attendance/migrations/0010_trip_trip_start.py new file mode 100644 index 0000000..92be639 --- /dev/null +++ b/server/attendance/migrations/0010_trip_trip_start.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.4 on 2021-07-21 07:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('attendance', '0009_merge_20210721_0021'), + ] + + operations = [ + migrations.AddField( + model_name='trip', + name='trip_start', + field=models.BooleanField(default=False), + ), + ] diff --git a/server/attendance/migrations/0011_attendancevehicle.py b/server/attendance/migrations/0011_attendancevehicle.py new file mode 100644 index 0000000..7f4564c --- /dev/null +++ b/server/attendance/migrations/0011_attendancevehicle.py @@ -0,0 +1,31 @@ +# Generated by Django 3.0.4 on 2021-07-21 07:14 + +import datetime +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0006_auto_20210715_1609'), + ('vendors', '0005_custodian'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('attendance', '0010_trip_trip_start'), + ] + + operations = [ + migrations.CreateModel( + name='AttendanceVehicle', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('entry_time', models.DateTimeField(default=datetime.datetime.now)), + ('exit_time', models.DateTimeField(blank=True, null=True)), + ('added_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), + ('attendance_sheet', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='attendance.AttendanceSheet')), + ('branch', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='users.Branch')), + ('vehicle', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='vendors.Vehicle')), + ], + ), + ] diff --git a/server/attendance/models.py b/server/attendance/models.py index 4c9d8f9..3d8e74a 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -4,28 +4,49 @@ from users.models import Branch from datetime import datetime + class Trip(models.Model): trip_code = models.CharField(max_length=6, blank=True, null=True) + trip_start = models.BooleanField(default=False) - vehicle = models.ForeignKey(Vehicle, on_delete=models.SET_NULL, null=True, blank=True) + vehicle = models.ForeignKey( + Vehicle, on_delete=models.SET_NULL, null=True, blank=True + ) - custodian_1 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_1') + custodian_1 = models.ForeignKey( + Custodian, + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name="custodian_1", + ) custodian_1_code = models.CharField(max_length=20, blank=True, null=True) - custodian_2 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_2') + custodian_2 = models.ForeignKey( + Custodian, + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name="custodian_2", + ) custodian_2_code = models.CharField(max_length=20, blank=True, null=True) - custodian_3 = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True, related_name='custodian_3') + custodian_3 = models.ForeignKey( + Custodian, + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name="custodian_3", + ) custodian_3_code = models.CharField(max_length=20, blank=True, null=True) + entry_time = models.DateTimeField(blank=True, null=True) + exit_time = models.DateTimeField(blank=True, null=True) - entry_time = models.DateTimeField(blank=True,null=True) - exit_time = models.DateTimeField(blank=True,null=True) - - start_location = models.CharField(max_length=300, blank=True,null=True) - end_location = models.CharField(max_length=300, blank=True,null=True) + start_location = models.CharField(max_length=300, blank=True, null=True) + end_location = models.CharField(max_length=300, blank=True, null=True) - added_by = models.ForeignKey(User, on_delete=models.SET_NULL,null=True, blank=True) + added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self): @@ -44,7 +65,9 @@ def __str__(self): class Attendance(models.Model): entry_time = models.DateTimeField(default=datetime.now) exit_time = models.DateTimeField(blank=True, null=True) - custodian = models.ForeignKey(Custodian, on_delete=models.SET_NULL, null=True, blank=True) + custodian = models.ForeignKey( + Custodian, on_delete=models.SET_NULL, null=True, blank=True + ) added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) attendance_sheet = models.ForeignKey( @@ -55,6 +78,22 @@ def __str__(self): return f"{self.custodian.first_name} {self.custodian.last_name}" +class AttendanceVehicle(models.Model): + entry_time = models.DateTimeField(default=datetime.now) + exit_time = models.DateTimeField(blank=True, null=True) + vehicle = models.ForeignKey( + Vehicle, on_delete=models.SET_NULL, null=True, blank=True + ) + added_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True) + branch = models.ForeignKey(Branch, on_delete=models.SET_NULL, null=True, blank=True) + attendance_sheet = models.ForeignKey( + AttendanceSheet, on_delete=models.SET_NULL, null=True, blank=True + ) + + def __str__(self): + return f"{self.vehicle.model_name} -> {self.vehicle.number_plate}" + + class Issue(models.Model): comment = models.CharField(max_length=200) vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index d9bddfc..63e11af 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -43,7 +43,7 @@ class Meta: class AttendanceSerializer(serializers.ModelSerializer): - custdian = RelatedFieldAlternative( + custodian = RelatedFieldAlternative( queryset=Custodian.objects.all(), serializer=CustodianSerializer ) attendance_sheet = RelatedFieldAlternative( @@ -94,6 +94,8 @@ class Meta: fields = [ "id", "vehicle", + "trip_code", + "trip_start", "custodian_1", "custodian_2", "custodian_3", @@ -132,6 +134,13 @@ def update(self, instance, validated_data): custodian_1_code = validated_data.get("custodian_1_code") custodian_2_code = validated_data.get("custodian_2_code") custodian_3_code = validated_data.get("custodian_3_code") + trip_start = validated_data.get("trip_start") + + if trip_start: + Attendance.objects.create( + vehicle=custodian_1, + branch=instance.branch, + ) if custodian_1_code: if custodian_1_code != instance.custodian_1_code: diff --git a/server/db.sqlite3 b/server/db.sqlite3 index ae3939b0ef52c597ccb98ee04ace1c70cecaaeae..c01de348d6624336949cd8d64c5e16375267b2b8 100644 GIT binary patch delta 1991 zcmbVMUrbw77{90Il-m}#w=IFPf!n2|gN^~WEtj?+;DY@_!WhvZaj2!GchHTtfR(vq z3Rg&A4-&DuvqclOWcuWTvu4$YDLxwGoQugGmM~mmG(I4hC=Z(8x&1@OC_H$RdwP3+ zzwi9M?>oQyO<&VZU(>%+q3fq8s*Bv23)Czgvyqn#C*M$#SBU*x20Cw!y~o1Zg624_ zJ%I|&7c?jQ+7;zgN3D{oavt}`Vqzrdj|_=CZ?X7te<#I}(9o!8<*k-_-d=CDaJ;?6 z($pe28mvu%AUNA<$OgjB4R~K{A~cp>UXA%DVmrfmp{2>uU}<*n0pYBeNlJu^$OYs{C-Z_I3h;bTk{hpHMuF1_4SCQ*Ijqjn#FdS)h0 zKU1w>W)c>zpQ$>mM^sf~j-7kT#3gR@3!;Y$W&t^;9JSPN1I* ziRX7W#(M~XHlPoRqhd_l4SUk?(1<@WoCkJSAYcc2e=xW^)Wsrj80aQLiO)_y_Zsvv zeR2BkB^5Kw_?ZEwkEC|HxLgSV(0fy>C$+j$t7|5_G8bL}$?%FId9#dqKsB=iOYjbj zmf*LvK@cdaAcTEO@H&$8(i!~9QS@%1R4$3Mp|1`|ZFt#?O0l*MT`ZjImx8pRt`01S zNnD2>g5+i#E)?P^Gb+X&Gm0?sK|ywdV*h0~*^Q)b89rhUDdap93Ix>vLa0`6lm21< zCM4!l_zPPM)MPvPkrRCqAuyp-vTTp$`9<$6w@;(GeJyUqCSeRvg-%2#o;7To}? zas!TR7cvemr#nKvnGLxk@2du$Y{wM%I=S!wPN2&q3k_t=6#E5xmNh4tRan86bU+-iR7Xx)s|1kO30`HX2ZCi5uvs1DObr0lsTQ0$ofR;6&iN5ERT}lBEk0K`Hd|{636EWt9({TCGY$NZAYs~`Naw)#dZ}&H1{-5tFh`&)d~7@ za1(}pP*cuSX4E=Y6nIEG~^e#jYc4q1acG(9QJ{5)ALi)>-y z=Wc0~HbhBr<2i}SY;oiSMbgv@a(PVwn}ZJqns-RKQ&Ri$pX}{pn;OltFG=TUgUbcx zTVwvfDBidN%d+{&&)G9<$DhnAs_9H(_?x#CLUQmbd>P>BHF&znER{-UX~Xkmt~t|l zZT&vH2tx7@Amgt}8reAqBJ#W8|1}&v5U-k05gz*$4jPVe#(c8~cRqx-Kjsk!GzqY} G)$t#+YhVxn delta 834 zcmZvZTSyf_7{_PMH^(`<2Y2?Edb|*5vZ5aIl1ZB7jiV`6o)Dvq@&bYeM@;O&OmXQ! z3^Hqtp(hQr2cMD!7onnuUb2z{1rgG*m&iiA1YMvWnr%}E+S!?%`G4Ph`~S_1OvjB( z`zBI-O$ebH(JMs9;!VDlTO`E1#v!**2>UEXR6gH3$sjXk!Jz61voNhA##~6GNjS@R zoHu}jMoE4h_8EHqFw2xhx=)!!Y(rU8)=agaUom>s40E=;6@yQiF=%Cm>Fd3sm@_Ba zFa+f}gNDXL%@o<3YiYR*K_zU^h^@Sfy%vs+hNIXDM_tx@5?Ns9h;Is(DVc(2)L&eT z$K7l2)*4@dhhY6M;D(pCO~9Zcv+oGlI%2=r7q)KtMxtz=8!&dc2uK)&MYjt;l5DfU zwh`NAKiM}+c>o_+tb|1tmYmduCqUGA4~-yJ@4YT>$Y&%|Qas%>VkJdj83bFpceGA# zbnFya+pnMv_zQ)U^NWKZRhEk?EHwfz!8_WZ=Qs?dTrlkQj@Ij^ z9iiA3_Vb$_;;}McLkRemLQ)*OonOgvg5FI1O~P`iV|nWhT*Xlv>>fcVru1Lt9-+A> zcd-Y>l5E=Kx4mL^_P_95A_R}9KM=s<+15aS9D_Zq!KES%p#;AqVbL^A<3pQJ7FQ0t zx*gGw#*b`5UY31i$Nz5l6VSAx+QQm{)zu|c!2?BIoqe7C_P{3^i56FbRg~;hm#|a) M`6d+KFCb~Z0UvGLHvj+t From a663e49cbe4d214db55a842508169ce9441ffc9c Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 12:48:34 +0530 Subject: [PATCH 76/98] nm --- server/attendance/serializers.py | 77 -------------------------------- 1 file changed, 77 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 86a2451..8d562ec 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,8 +1,4 @@ from secrets import token_hex -<<<<<<< HEAD -======= - ->>>>>>> 0e727196521b08d5dd5108d86d85454683d05456 from rest_framework import serializers from rest_framework.response import Response from users.serializers import BranchSerializer, UserSerializer @@ -73,39 +69,6 @@ class Meta: class TripSerializer(serializers.ModelSerializer): -<<<<<<< HEAD - # vehicle = RelatedFieldAlternative( - # queryset=Vehicle.objects.all(), serializer=VehicleSerializer - # ) - # custodian_1 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # custodian_2 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # custodian_3 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # branch = RelatedFieldAlternative( - # queryset=Branch.objects.all(), serializer=BranchSerializer - # ) - # added_by = RelatedFieldAlternative( - # queryset=User.objects.all(), serializer=UserSerializer - # ) - vehicle = VehicleSerializer(required=False) - custodian_1 = CustodianSerializer(required=False) - custodian_2 = CustodianSerializer(required=False) - custodian_3 = CustodianSerializer(required=False) - branch = BranchSerializer(required=False) - added_by = UserSerializer(required=False) - - # vehicle = VehicleSerializer(required=False) - # custodian_1 =CustodianSerializer(required=False) - # custodian_2 = CustodianSerializer(required=False) - # custodian_3 = CustodianSerializer(required=False) - # branch = BranchSerializer(required=False) - # added_by = UserSerializer(required=False) -======= vehicle = RelatedFieldAlternative( queryset=Vehicle.objects.all(), serializer=VehicleSerializer ) @@ -124,7 +87,6 @@ class TripSerializer(serializers.ModelSerializer): added_by = RelatedFieldAlternative( queryset=User.objects.all(), serializer=UserSerializer ) ->>>>>>> 0e727196521b08d5dd5108d86d85454683d05456 class Meta: model = Trip @@ -148,38 +110,6 @@ class Meta: ] def create(self, validated_data): -<<<<<<< HEAD - validated_data["trip_code"] = token_hex(6).upper() - - custodian_1 = validated_data.get("custodian_1") - custodian_2 = validated_data.get("custodian_2") - custodian_3 = validated_data.get("custodian_3") - - if custodian_1 and custodian_2 and custodian_1 == custodian_2: - raise serializers.ValidationError( - {"error": "Same Custodian cannot be assigned twice"} - ) - if custodian_1 and custodian_3 and custodian_1 == custodian_3: - raise serializers.ValidationError( - {"error": "Same Custodian cannot be assigned twice"} - ) - if custodian_3 and custodian_2 and custodian_3 == custodian_2: - raise serializers.ValidationError( - {"error": "Same Custodian cannot be assigned twice"} - ) - - if custodian_1: - validated_data["custodian_1_code"] = token_hex(6).upper() - if custodian_2: - validated_data["custodian_2_code"] = token_hex(6).upper() - if custodian_3: - validated_data["custodian_3_code"] = token_hex(6).upper() - - return super().create(validated_data) - - def update(self, instance, validated_data): -======= ->>>>>>> 0e727196521b08d5dd5108d86d85454683d05456 print(validated_data) validated_data["trip_code"] = token_hex(6).upper() @@ -189,12 +119,6 @@ def update(self, instance, validated_data): if custodian_1: validated_data["custodian_1_code"] = token_hex(6).upper() -<<<<<<< HEAD - if custodian_2: - validated_data["custodian_2_code"] = token_hex(6).upper() - if custodian_3: - validated_data["custodian_3_code"] = token_hex(6).upper() -======= if custodian_2 != custodian_2: validated_data["custodian_2_code"] = token_hex(6).upper() if custodian_3 != custodian_1: @@ -243,7 +167,6 @@ def update(self, instance, validated_data): custodian=custodian_3, branch=instance.branch, ) ->>>>>>> 0e727196521b08d5dd5108d86d85454683d05456 return super().update(instance, validated_data) From f47410656862f77ade8bd2705e510d2b8acf7ee1 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 13:07:07 +0530 Subject: [PATCH 77/98] checkin and checkout --- server/attendance/serializers.py | 112 ++++++++++++++++++++++--------- 1 file changed, 80 insertions(+), 32 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 8d562ec..2d124af 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,3 +1,4 @@ +from datetime import datetime from secrets import token_hex from rest_framework import serializers from rest_framework.response import Response @@ -9,7 +10,7 @@ VehicleSerializer, ) -from .models import Attendance, AttendanceSheet, Issue, Trip +from .models import Attendance, AttendanceSheet, AttendanceVehicle, Issue, Trip from users.models import Branch, User from vendors.models import Gunmen, Custodian, Vendor, Vehicle @@ -135,38 +136,85 @@ def update(self, instance, validated_data): custodian_3_code = validated_data.get("custodian_3_code") trip_start = validated_data.get("trip_start") - if trip_start: - Attendance.objects.create( - vehicle=custodian_1, + if not instance.trip_start: + if custodian_1_code: + if custodian_1_code != instance.custodian_1_code: + return serializers.ValidationError( + {"Error": "Code does not match !"} + ) + else: + Attendance.objects.create( + custodian=custodian_1, + branch=instance.branch, + ) + AttendanceVehicle.objects.create( + vehicle=instance.vehicle, + branch=instance.branch, + ) + + if custodian_2_code and custodian_2 != custodian_1: + if custodian_2_code != instance.custodian_2_code: + return serializers.ValidationError( + {"error": "Code does not match !"} + ) + else: + Attendance.objects.create( + custodian=custodian_2, + branch=instance.branch, + ) + + if custodian_3_code and custodian_3 != custodian_1: + if custodian_3_code != instance.custodian_3_code: + return serializers.ValidationError( + {"error": "Code does not match !"} + ) + else: + Attendance.objects.create( + custodian=custodian_3, + branch=instance.branch, + ) + if instance.trip_start: + today = datetime.now() + attendance_1 = Attendance.objects.filter( + entry_time__year=today.date().year, + entry_time__month=today.date().month, + entry_time__day=today.date().day, + custodian=custodian_1, branch=instance.branch, - ) - - if custodian_1_code: - if custodian_1_code != instance.custodian_1_code: - return serializers.ValidationError({"Error": "Code does not match !"}) - else: - Attendance.objects.create( - custodian=custodian_1, - branch=instance.branch, - ) - - if custodian_2_code and custodian_2 != custodian_1: - if custodian_2_code != instance.custodian_2_code: - return serializers.ValidationError({"error": "Code does not match !"}) - else: - Attendance.objects.create( - custodian=custodian_2, - branch=instance.branch, - ) - - if custodian_3_code and custodian_3 != custodian_1: - if custodian_3_code != instance.custodian_3_code: - return serializers.ValidationError({"error": "Code does not match !"}) - else: - Attendance.objects.create( - custodian=custodian_3, - branch=instance.branch, - ) + ).first() + attendance_2 = Attendance.objects.filter( + entry_time__year=today.date().year, + entry_time__month=today.date().month, + entry_time__day=today.date().day, + custodian=custodian_2, + branch=instance.branch, + ).first() + attendance_3 = Attendance.objects.filter( + entry_time__year=today.date().year, + entry_time__month=today.date().month, + entry_time__day=today.date().day, + custodian=custodian_3, + branch=instance.branch, + ).first() + vehicle_attendance = AttendanceVehicle.objects.filter( + entry_time__year=today.date().year, + entry_time__month=today.date().month, + entry_time__day=today.date().day, + vehicle=instance.vehicle, + branch=instance.branch, + ).first() + if attendance_1: + attendance_1.exit_time = today + attendance_1.save() + if attendance_2: + attendance_2.exit_time = today + attendance_2.save() + if attendance_3: + attendance_3.exit_time = today + attendance_3.save() + if vehicle_attendance: + vehicle_attendance.exit_time = today + vehicle_attendance.save() return super().update(instance, validated_data) From ef0005d7d85a66b3208c4d8563917b629419ada0 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Wed, 21 Jul 2021 13:22:10 +0530 Subject: [PATCH 78/98] Attendance Vehicle models, views and urls --- server/attendance/admin.py | 1 + server/attendance/serializers.py | 34 +++++++++++++- server/attendance/urls.py | 2 + server/attendance/views.py | 73 ++++++++++++++++++++++++++----- server/db.sqlite3 | Bin 299008 -> 299008 bytes 5 files changed, 96 insertions(+), 14 deletions(-) diff --git a/server/attendance/admin.py b/server/attendance/admin.py index 1eeba38..d606991 100644 --- a/server/attendance/admin.py +++ b/server/attendance/admin.py @@ -49,6 +49,7 @@ class IssueAdmin(admin.ModelAdmin): admin.site.register(Attendance, AttendanceAdmin) +admin.site.register(AttendanceVehicle, AttendanceVehicleAdmin) admin.site.register(Trip, TripAdmin) admin.site.register(AttendanceSheet, AttendanceSheetAdmin) admin.site.register(Issue, IssueAdmin) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 8d562ec..14754d4 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -4,14 +4,14 @@ from users.serializers import BranchSerializer, UserSerializer from vendors.serializers import ( VendorSerializer, - GunmenSerializer, CustodianSerializer, VehicleSerializer, ) from .models import Attendance, AttendanceSheet, Issue, Trip from users.models import Branch, User -from vendors.models import Gunmen, Custodian, Vendor, Vehicle +from vendors.models import Custodian, Vendor, Vehicle +from attendance.models import AttendanceVehicle class RelatedFieldAlternative(serializers.PrimaryKeyRelatedField): @@ -41,6 +41,36 @@ class Meta: fields = ["id", "sheet_created", "invoice", "verified"] +class AttendanceVehicleSerializer(serializers.ModelSerializer): + vehicle = RelatedFieldAlternative( + queryset=Vehicle.objects.all(), serializer=VehicleSerializer + ) + attendance_sheet = RelatedFieldAlternative( + queryset=AttendanceSheet.objects.all(), serializer=AttendanceSheetSerializer + ) + branch = RelatedFieldAlternative( + queryset=Branch.objects.all(), serializer=BranchSerializer + ) + added_by = RelatedFieldAlternative( + queryset=User.objects.all(), serializer=UserSerializer + ) + + class Meta: + model = AttendanceVehicle + fields = [ + "id", + "vehicle", + "entry_time", + "exit_time", + "branch", + "added_by", + "attendance_sheet", + ] + + + + + class AttendanceSerializer(serializers.ModelSerializer): custodian = RelatedFieldAlternative( queryset=Custodian.objects.all(), serializer=CustodianSerializer diff --git a/server/attendance/urls.py b/server/attendance/urls.py index 2102df1..0a4b307 100644 --- a/server/attendance/urls.py +++ b/server/attendance/urls.py @@ -5,6 +5,8 @@ urlpatterns = [ path("attendance/", views.AttendanceList.as_view()), path("attendance//", views.AttendanceDetail.as_view()), + path("attendance/vehicle/", views.AttendanceVehicleList.as_view()), + path("attendance/vehicle//", views.AttendanceVehicleDetail.as_view()), path("trip/", views.TripList.as_view()), path("trip//", views.TripDetail.as_view()), path("issue/", views.IssueList.as_view()), diff --git a/server/attendance/views.py b/server/attendance/views.py index 51b8f4b..937f81c 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -13,11 +13,11 @@ from users.serializers import BranchSerializer, UserSerializer from vendors.serializers import CustodianSerializer, VehicleSerializer -from attendance.serializers import AttendanceSerializer, IssueSerializer, TripSerializer +from attendance.serializers import AttendanceSerializer, IssueSerializer, TripSerializer, AttendanceVehicleSerializer from users.models import Branch, User from vendors.models import Custodian, Vehicle, Gunmen -from attendance.models import Attendance, AttendanceSheet, Issue, Trip +from attendance.models import Attendance, AttendanceSheet, AttendanceVehicle, Issue, Trip class CustomPagination(PageNumberPagination): @@ -140,22 +140,72 @@ def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) -class AttendanceList( + +class AttendanceVehicleList( mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView, # filters.FilterSet, +): + queryset = AttendanceVehicle.objects.all() + serializer_class = AttendanceVehicleSerializer + pagination_class = CustomPagination + filter_backends = [DjangoFilterBackend, filters.SearchFilter] + search_fields = ["^vehicle__model_name", "^vehicle__number_plate"] + + filterset_fields = { + "entry_time": ["gte", "lte", "exact", "gt", "lt"], + "exit_time": ["gte", "lte", "exact", "gt", "lt"], + "vehicle": ["exact"], + "added_by": ["exact"], + "branch": ["exact"], + "attendance_sheet": ["exact"], + } + + ordering_fields = "__all__" + + def get(self, request, *args, **kwargs): + return self.list(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + return self.create(request, *args, **kwargs) + +class AttendanceVehicleDetail( + mixins.RetrieveModelMixin, + mixins.UpdateModelMixin, + mixins.DestroyModelMixin, + generics.GenericAPIView, +): + queryset = AttendanceVehicle.objects.all() + serializer_class = AttendanceVehicleSerializer + + def get(self, request, *args, **kwargs): + return self.retrieve(request, *args, **kwargs) + + def put(self, request, *args, **kwargs): + return self.update(request, *args, **kwargs) + + def delete(self, request, *args, **kwargs): + return self.destroy(request, *args, **kwargs) + + + + +class AttendanceList( + mixins.ListModelMixin, + mixins.CreateModelMixin, + generics.GenericAPIView, ): queryset = Attendance.objects.all() serializer_class = AttendanceSerializer pagination_class = CustomPagination filter_backends = [DjangoFilterBackend, filters.SearchFilter] - search_fields = ["^gunmen__first_name", "^gunmen__last_name"] + search_fields = ["^custodian__first_name", "^custodian__last_name"] filterset_fields = { "entry_time": ["gte", "lte", "exact", "gt", "lt"], "exit_time": ["gte", "lte", "exact", "gt", "lt"], - "gunmen": ["exact"], + "custodian": ["exact"], "added_by": ["exact"], "branch": ["exact"], "attendance_sheet": ["exact"], @@ -183,19 +233,18 @@ def post(self, request, *args, **kwargs): data = request.data branch_id = data.get("branch") added_by_id = data.get("added_by") - gunmen_ids = data.get("gunmen_id") + custodian_ids = data.get("custodian_id") attendance_sheet = data.get("attendance_sheet") result = [] - for gunmen_id in gunmen_ids: + for custodian_id in custodian_ids: data = { - "gunmen": gunmen_id, + "custodian": custodian_id, "branch": branch_id, "added_by": added_by_id, "attendance_sheet": attendance_sheet, } - print(data) new_attendance = AttendanceSerializer(data=data) if not new_attendance.is_valid(): return Response(data="invalid request") @@ -205,7 +254,7 @@ def post(self, request, *args, **kwargs): entry_time__year=today.date().year, entry_time__month=today.date().month, entry_time__day=today.date().day, - gunmen=new_attendance.data["gunmen"]["id"], + custodian=new_attendance.data["custodian"]["id"], branch=new_attendance.data["branch"]["id"], ).first() @@ -217,14 +266,14 @@ def post(self, request, *args, **kwargs): attendance.save() result.append(AttendanceSerializer(attendance).data) else: - gunmen_ = get_object_or_404(Gunmen, pk=data.pop("gunmen")) + custodian_ = get_object_or_404(Custodian, pk=data.pop("custodian")) added_by_ = get_object_or_404(User, pk=data.pop("added_by")) branch_ = get_object_or_404(Branch, pk=data.pop("branch")) attendance_sheet_ = get_object_or_404( AttendanceSheet, pk=data.pop("attendance_sheet") ) attendance = Attendance( - gunmen=gunmen_, + custodian=custodian_, added_by=added_by_, branch=branch_, attendance_sheet=attendance_sheet_, diff --git a/server/db.sqlite3 b/server/db.sqlite3 index c01de348d6624336949cd8d64c5e16375267b2b8..3442327d283a96b05aaf4b1e4defc1a207f4544a 100644 GIT binary patch delta 1168 zcmb7@UuauZ9LLYO_hjTIH}{*wZbG{1ZKL8=lit7i=g>y6oevRw7<-V}#pR|;nf|X$rHpLYNZi0RA+|XI=5b-?x9?toF zzQ5n^%kNChhNou3XFBP@vpb*n93=6XF*egmbubsO$)8ulNG3hoWrfHlb^`n3d{h z-xVU$m*P+D#+#&rY&jjG7^8)ed}X*glrM~xDnsS!uzxz-_YQ57+Z*$J`!t#Py+m0I zoRSCpUS9ln-;-}W%{;kNp6u{(r|1-muN@m5pQs%f&ySX>BPD0lenYQ1X5OeaDrFB1 zS*n)ISb9cJ#4RI{G_=M*`BPD57$f)|EsWv4Mriy1c0DHM=zmEvH);B%vf5~#l+}=a zU)zo+(^lHH-o7?dzcxelh#w0Cf8aN);T9IKiWPi^FYyJI8lkBV5cY_a%6>NneQs2w z`qDf#Id_?09rthtzv3q6e!w!m!PmIVx$^)MCF*yB&ka(2d4cvu{PGIHB97y6<%Tk& zysC5tE(8jJC*&1w*n)g=&@YiJ%w8%UvO!`)eiQTGG@tTR(KPrmNM8bDw^B z0}l>L|I&wxTP|+dw*I#kc{2m~a_ujr4I!m<;VZh|@Cvw2a2waTHCM2sL-3G?yQTIR znwSV(+eWcQu*UCyLI~7Dx&z+L4w~ZvyE?~a1$B<~ z3&A<23PDb+60CA!8C{*!OH3m1vk7f1g^_5U5m`Sk-D+=IOTH?8j2EMVmtqc#;}HDUK(N#R?LEmU~RHVP)jeZit(hLBsZ7Pgf=DJlo~4@!~_fW z*f!KXNrD!7kPyOR79psOXVFkl0$PLh&>oCX5D!Li#CLdy_dfmyf1%s9_q%a2caWz>oK0SG2Jvn&NT2cuNE&8&su*shPfQ z7|DD-ZKjguWZKBjXXaR`89IH+ud(5S3o_5m-!vA|)0xR^I>6WnP0b|Dshp8a&1Os^ zo10Qg{_q2;S}RM+A-fj7uDh8hPDIPQ=!w^hqaHh+eZkxes{|k6VAUQdEP@|rS7_;K zR`Gu89a(R}>b#`G0o7Y2XyFb{h^{D$8)C>?tryq4PW25a z=4Uo&xp&w|qszGF`j0$w^L_A4&Qu#d&Ncanb%HN=jdi*E5d0`RPfIhihn?0qzu>cZ Hw?F Date: Wed, 21 Jul 2021 13:37:04 +0530 Subject: [PATCH 79/98] checking celery --- server/attendance/models.py | 36 ++++++++++++++ server/attendance/serializers.py | 78 +------------------------------ server/requirements.txt | Bin 542 -> 880 bytes server/server/celeryapp.py | 15 ++++++ server/server/settings.py | 14 ++++++ 5 files changed, 66 insertions(+), 77 deletions(-) create mode 100644 server/server/celeryapp.py diff --git a/server/attendance/models.py b/server/attendance/models.py index 4c9d8f9..cdaf6bf 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -68,3 +68,39 @@ class Issue(models.Model): def __str__(self) -> str: return f"{self.comment} {self.vendor} {self.reverted_by} -> {self.sheet}" + +''' +class ScheduledReport(models.Model): + """ + Contains email subject and cron expression,to evaluate when the email has to be sent + """ + subject = models.CharField(max_length=200) + last_run_at = models.DateTimeField(null=True, blank=True) + next_run_at = models.DateTimeField(null=True, blank=True) + cron_expression = models.CharField(max_length=200) + def save(self, *args, **kwargs): + """ + function to evaluate "next_run_at" using the cron expression, so that it is updated once the report is sent. + """ + self.last_run_at = datetime.now() + iter = croniter(self.cron_expression, self.last_run_at) + self.next_run_at = iter.get_next(datetime) + super(ScheduledReport, self).save(*args, **kwargs) + def __unicode__(self): + return self.subject + +class ScheduledReportGroup(models.Model): + """ + Many to many mapping between reports which will be sent out in a + scheduled report + """ + report = models.ForeignKey(Report, related_name='report') + scheduled_report = models.ForeignKey(ScheduledReport, + related_name='relatedscheduledreport') +class ReportRecipient(models.Model): + """ + Stores all the recipients of the given scheduled report + """ + email = models.EmailField() + scheduled_report = models.ForeignKey(ScheduledReport, related_name='reportrecep') +''' \ No newline at end of file diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index e8d7ab5..20a0876 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -1,8 +1,4 @@ from secrets import token_hex -<<<<<<< HEAD -======= - ->>>>>>> 0e727196521b08d5dd5108d86d85454683d05456 from rest_framework import serializers from rest_framework.response import Response from users.serializers import BranchSerializer, UserSerializer @@ -73,39 +69,6 @@ class Meta: class TripSerializer(serializers.ModelSerializer): -<<<<<<< HEAD - # vehicle = RelatedFieldAlternative( - # queryset=Vehicle.objects.all(), serializer=VehicleSerializer - # ) - # custodian_1 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # custodian_2 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # custodian_3 = RelatedFieldAlternative( - # queryset=Custodian.objects.all(), serializer=CustodianSerializer - # ) - # branch = RelatedFieldAlternative( - # queryset=Branch.objects.all(), serializer=BranchSerializer - # ) - # added_by = RelatedFieldAlternative( - # queryset=User.objects.all(), serializer=UserSerializer - # ) - vehicle = VehicleSerializer(required=False) - custodian_1 = CustodianSerializer(required=False) - custodian_2 = CustodianSerializer(required=False) - custodian_3 = CustodianSerializer(required=False) - branch = BranchSerializer(required=False) - added_by = UserSerializer(required=False) - - # vehicle = VehicleSerializer(required=False) - # custodian_1 =CustodianSerializer(required=False) - # custodian_2 = CustodianSerializer(required=False) - # custodian_3 = CustodianSerializer(required=False) - # branch = BranchSerializer(required=False) - # added_by = UserSerializer(required=False) -======= vehicle = RelatedFieldAlternative( queryset=Vehicle.objects.all(), serializer=VehicleSerializer ) @@ -124,7 +87,6 @@ class TripSerializer(serializers.ModelSerializer): added_by = RelatedFieldAlternative( queryset=User.objects.all(), serializer=UserSerializer ) ->>>>>>> 0e727196521b08d5dd5108d86d85454683d05456 class Meta: model = Trip @@ -146,38 +108,6 @@ class Meta: ] def create(self, validated_data): -<<<<<<< HEAD - validated_data["trip_code"] = token_hex(6).upper() - - custodian_1 = validated_data.get("custodian_1") - custodian_2 = validated_data.get("custodian_2") - custodian_3 = validated_data.get("custodian_3") - - if custodian_1 and custodian_2 and custodian_1 == custodian_2: - raise serializers.ValidationError( - {"error": "Same Custodian cannot be assigned twice"} - ) - if custodian_1 and custodian_3 and custodian_1 == custodian_3: - raise serializers.ValidationError( - {"error": "Same Custodian cannot be assigned twice"} - ) - if custodian_3 and custodian_2 and custodian_3 == custodian_2: - raise serializers.ValidationError( - {"error": "Same Custodian cannot be assigned twice"} - ) - - if custodian_1: - validated_data["custodian_1_code"] = token_hex(6).upper() - if custodian_2: - validated_data["custodian_2_code"] = token_hex(6).upper() - if custodian_3: - validated_data["custodian_3_code"] = token_hex(6).upper() - - return super().create(validated_data) - - def update(self, instance, validated_data): -======= ->>>>>>> 0e727196521b08d5dd5108d86d85454683d05456 print(validated_data) validated_data["trip_code"] = token_hex(6).upper() @@ -187,12 +117,6 @@ def update(self, instance, validated_data): if custodian_1: validated_data["custodian_1_code"] = token_hex(6).upper() -<<<<<<< HEAD - if custodian_2: - validated_data["custodian_2_code"] = token_hex(6).upper() - if custodian_3: - validated_data["custodian_3_code"] = token_hex(6).upper() -======= if custodian_2 != custodian_2: validated_data["custodian_2_code"] = token_hex(6).upper() if custodian_3 != custodian_1: @@ -234,7 +158,6 @@ def update(self, instance, validated_data): custodian=custodian_3, branch=instance.branch, ) ->>>>>>> 0e727196521b08d5dd5108d86d85454683d05456 return super().update(instance, validated_data) @@ -253,3 +176,4 @@ class IssueSerializer(serializers.ModelSerializer): class Meta: model = Issue fields = ["id", "comment", "reverted_by", "vendor", "sheet", "created_at"] + diff --git a/server/requirements.txt b/server/requirements.txt index db441620d6210d042846242dadaa4335d413499a..e47ff0252e34b2786774820d39e3f861158af652 100644 GIT binary patch literal 880 zcmb7C$xeho5PfG8|G^)C050gknU-5ROJ-tXI)p&It*ZLx zJ41_iRM??FiF=+)g!aTZ#~I%Ee}_*ZNPLqEy11eV3YM8iS_Z{_>S$S`U%um+Qif)}%Z&`^a)jb~Zf@iB~)|#l>OM^WX z4}C=&5zp0HZ0Xvt7frb^jN64rbT$>gTlKDuj7Zn1_OE$tsio|4Q2sky%#Op=Othfi zrk}SQ-Cdfa$1m|-`w3K*Ha8!C1Er8q!!!JS)I@i5Qzl`RE3v6IbXPaWo6@Z-Y!_3e eV|#t~mdlblYi9czJX|;FkVRM_NA6!=9{USadw5|0 delta 7 OcmeysHjib491{QxF9K-* diff --git a/server/server/celeryapp.py b/server/server/celeryapp.py new file mode 100644 index 0000000..2cda441 --- /dev/null +++ b/server/server/celeryapp.py @@ -0,0 +1,15 @@ +'''from __future__ import absolute_import +import os +from celery import Celery + +# set the default Django settings module for the 'celery' program. +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") +from django.conf import settings + +app = Celery("project") +# Using a string here means the worker don't have to serialize +# the configuration object to child processes. +app.config_from_object("django.conf:settings") +# Load task modules from all registered Django app configs. +app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) +''' \ No newline at end of file diff --git a/server/server/settings.py b/server/server/settings.py index 92bcc3c..eeb1407 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -13,6 +13,7 @@ from pathlib import Path from datetime import timedelta import os +# import djcelery # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -34,6 +35,8 @@ INSTALLED_APPS = [ "jazzmin", + # "djcelery", + # "kombu.transport.django", "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", @@ -168,3 +171,14 @@ # TODO: Setup the email and password EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' + + + +''' +BROKER_URL = 'django://' +CELERY_ACCEPT_CONTENT = ['json'] +CELERY_TASK_SERIALIZER = 'json' +CELERY_RESULT_SERIALIZER = 'json' +CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend' +CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler" +djcelery.setup_loader()''' \ No newline at end of file From 809ec77286aad9019ea4e098f933cbc357b07b60 Mon Sep 17 00:00:00 2001 From: mustankap Date: Wed, 21 Jul 2021 14:03:54 +0530 Subject: [PATCH 80/98] no need of celery using django-crontab --- server/attendance/serializers.py | 30 ------------------------------ server/requirements.txt | Bin 880 -> 904 bytes server/server/celeryapp.py | 15 --------------- server/server/settings.py | 18 +++++------------- server/users/serializers.py | 10 ++++++++++ 5 files changed, 15 insertions(+), 58 deletions(-) delete mode 100644 server/server/celeryapp.py diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index dfeb019..e89e281 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -164,35 +164,6 @@ def update(self, instance, validated_data): custodian_1_code = validated_data.get("custodian_1_code") custodian_2_code = validated_data.get("custodian_2_code") custodian_3_code = validated_data.get("custodian_3_code") -<<<<<<< HEAD - - if custodian_1_code: - if custodian_1_code != instance.custodian_1_code: - return serializers.ValidationError({"Error": "Code does not match !"}) - else: - Attendance.objects.create( - custodian=custodian_1, - branch=instance.branch, - ) - - if custodian_2_code and custodian_2 != custodian_1: - if custodian_2_code != instance.custodian_2_code: - return serializers.ValidationError({"error": "Code does not match !"}) - else: - Attendance.objects.create( - custodian=custodian_2, - branch=instance.branch, - ) - - if custodian_3_code and custodian_3 != custodian_1: - if custodian_3_code != instance.custodian_3_code: - return serializers.ValidationError({"error": "Code does not match !"}) - else: - Attendance.objects.create( - custodian=custodian_3, - branch=instance.branch, - ) -======= trip_start = validated_data.get("trip_start") if not instance.trip_start: @@ -274,7 +245,6 @@ def update(self, instance, validated_data): if vehicle_attendance: vehicle_attendance.exit_time = today vehicle_attendance.save() ->>>>>>> 6f4814a7afb93950a67ea00a4864645f81b5cd80 return super().update(instance, validated_data) diff --git a/server/requirements.txt b/server/requirements.txt index e47ff0252e34b2786774820d39e3f861158af652..dc1e2ae8804c5930f3a4d277d6487aa95dde66c2 100644 GIT binary patch delta 55 tcmeys*1^6(iHTX6L1D5YlO~wU)jZB7MdLxrAn7+$o4W`AJBLPQ%3t<2N delta 31 ncmeBR|G>6EiD|MLlg8vACX2~^Oa_w=G3iYH#AG$ufH?vHq7e!a diff --git a/server/server/celeryapp.py b/server/server/celeryapp.py deleted file mode 100644 index 2cda441..0000000 --- a/server/server/celeryapp.py +++ /dev/null @@ -1,15 +0,0 @@ -'''from __future__ import absolute_import -import os -from celery import Celery - -# set the default Django settings module for the 'celery' program. -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings") -from django.conf import settings - -app = Celery("project") -# Using a string here means the worker don't have to serialize -# the configuration object to child processes. -app.config_from_object("django.conf:settings") -# Load task modules from all registered Django app configs. -app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) -''' \ No newline at end of file diff --git a/server/server/settings.py b/server/server/settings.py index eeb1407..222c980 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -13,7 +13,7 @@ from pathlib import Path from datetime import timedelta import os -# import djcelery + # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -35,8 +35,7 @@ INSTALLED_APPS = [ "jazzmin", - # "djcelery", - # "kombu.transport.django", + 'django_crontab', "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", @@ -172,13 +171,6 @@ EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' - - -''' -BROKER_URL = 'django://' -CELERY_ACCEPT_CONTENT = ['json'] -CELERY_TASK_SERIALIZER = 'json' -CELERY_RESULT_SERIALIZER = 'json' -CELERY_RESULT_BACKEND = 'djcelery.backends.database:DatabaseBackend' -CELERYBEAT_SCHEDULER = "djcelery.schedulers.DatabaseScheduler" -djcelery.setup_loader()''' \ No newline at end of file +CRONJOBS = [ + ('0 0 20 * *', 'users.cron.mail_attendance') +] diff --git a/server/users/serializers.py b/server/users/serializers.py index 094ce99..f42f7e6 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -124,3 +124,13 @@ def mail(subject, message, to_mail): recipient_list=[to_mail], fail_silently=False, ) + + +def mail_attendance(subject, message, to_mail): + send_mail( + subject, + message, + from_email=None, + recipient_list=[to_mail], + fail_silently=False, + ) \ No newline at end of file From 173167f63779ef4c310eeb5bf429542db320c4a5 Mon Sep 17 00:00:00 2001 From: mustankap Date: Wed, 21 Jul 2021 14:04:31 +0530 Subject: [PATCH 81/98] update --- server/attendance/models.py | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/server/attendance/models.py b/server/attendance/models.py index 8444b22..3d8e74a 100644 --- a/server/attendance/models.py +++ b/server/attendance/models.py @@ -107,39 +107,3 @@ class Issue(models.Model): def __str__(self) -> str: return f"{self.comment} {self.vendor} {self.reverted_by} -> {self.sheet}" - -''' -class ScheduledReport(models.Model): - """ - Contains email subject and cron expression,to evaluate when the email has to be sent - """ - subject = models.CharField(max_length=200) - last_run_at = models.DateTimeField(null=True, blank=True) - next_run_at = models.DateTimeField(null=True, blank=True) - cron_expression = models.CharField(max_length=200) - def save(self, *args, **kwargs): - """ - function to evaluate "next_run_at" using the cron expression, so that it is updated once the report is sent. - """ - self.last_run_at = datetime.now() - iter = croniter(self.cron_expression, self.last_run_at) - self.next_run_at = iter.get_next(datetime) - super(ScheduledReport, self).save(*args, **kwargs) - def __unicode__(self): - return self.subject - -class ScheduledReportGroup(models.Model): - """ - Many to many mapping between reports which will be sent out in a - scheduled report - """ - report = models.ForeignKey(Report, related_name='report') - scheduled_report = models.ForeignKey(ScheduledReport, - related_name='relatedscheduledreport') -class ReportRecipient(models.Model): - """ - Stores all the recipients of the given scheduled report - """ - email = models.EmailField() - scheduled_report = models.ForeignKey(ScheduledReport, related_name='reportrecep') -''' \ No newline at end of file From 9844ebdfbe368c0ce4cdc57d41918c8c266dd73c Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 16:09:56 +0530 Subject: [PATCH 82/98] update attendance checks --- server/attendance/serializers.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/server/attendance/serializers.py b/server/attendance/serializers.py index 84b0876..5322c5e 100644 --- a/server/attendance/serializers.py +++ b/server/attendance/serializers.py @@ -67,9 +67,6 @@ class Meta: "added_by", "attendance_sheet", ] - - - class AttendanceSerializer(serializers.ModelSerializer): @@ -165,8 +162,13 @@ def update(self, instance, validated_data): custodian_2_code = validated_data.get("custodian_2_code") custodian_3_code = validated_data.get("custodian_3_code") trip_start = validated_data.get("trip_start") + if trip_start and trip_start == True and instance.trip_start == False: + AttendanceVehicle.objects.create( + vehicle=instance.vehicle, + branch=instance.branch, + ) - if not instance.trip_start: + if instance.trip_start == False and not trip_start: if custodian_1_code: if custodian_1_code != instance.custodian_1_code: return serializers.ValidationError( @@ -177,10 +179,6 @@ def update(self, instance, validated_data): custodian=custodian_1, branch=instance.branch, ) - AttendanceVehicle.objects.create( - vehicle=instance.vehicle, - branch=instance.branch, - ) if custodian_2_code and custodian_2 != custodian_1: if custodian_2_code != instance.custodian_2_code: @@ -203,7 +201,7 @@ def update(self, instance, validated_data): custodian=custodian_3, branch=instance.branch, ) - if instance.trip_start: + if instance.trip_start == False: today = datetime.now() attendance_1 = Attendance.objects.filter( entry_time__year=today.date().year, From 6fe582904acb353539c90abc1a162865c05fc8c2 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Wed, 21 Jul 2021 16:23:23 +0530 Subject: [PATCH 83/98] Queryset to CSV file --- .gitignore | 1 + server/attendance/utils.py | 103 +++++++++++++++++++++++++++++++++++++ server/attendance/views.py | 8 ++- 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 server/attendance/utils.py diff --git a/.gitignore b/.gitignore index a7a2e58..fea2160 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ local_settings.py # db.sqlite3 # db.sqlite3-journal media +csvstorage/ # If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ # in your Git repository. Update and uncomment the following line accordingly. diff --git a/server/attendance/utils.py b/server/attendance/utils.py new file mode 100644 index 0000000..5291355 --- /dev/null +++ b/server/attendance/utils.py @@ -0,0 +1,103 @@ +import pandas as pd +import os +import csv +from django.conf import settings +from django.utils.text import slugify + +BASE_DIR = settings.BASE_DIR + + +def get_model_field_names(model, ignore_fields=['content_object']): + ''' + ::param model is a Django model class + ::param ignore_fields is a list of field names to ignore by default + This method gets all model field names (as strings) and returns a list + of them ignoring the ones we know don't work (like the 'content_object' field) + ''' + model_fields = model._meta.get_fields() + model_field_names = list(set([f.name for f in model_fields if f.name not in ignore_fields])) + return model_field_names + + +def get_lookup_fields(model, fields=None): + ''' + ::param model is a Django model class + ::param fields is a list of field name strings. + This method compares the lookups we want vs the lookups + that are available. It ignores the unavailable fields we passed. + ''' + model_field_names = get_model_field_names(model) + if fields is not None: + ''' + we'll iterate through all the passed field_names + and verify they are valid by only including the valid ones + ''' + lookup_fields = [] + for x in fields: + if "__" in x: + # the __ is for ForeignKey lookups + lookup_fields.append(x) + elif x in model_field_names: + lookup_fields.append(x) + else: + ''' + No field names were passed, use the default model fields + ''' + lookup_fields = model_field_names + return lookup_fields + +def qs_to_dataset(qs, fields=None): + ''' + ::param qs is any Django queryset + ::param fields is a list of field name strings, ignoring non-model field names + This method is the final step, simply calling the fields we formed on the queryset + and turning it into a list of dictionaries with key/value pairs. + ''' + + lookup_fields = get_lookup_fields(qs.model, fields=fields) + return list(qs.values(*lookup_fields)) + + +def convert_to_dataframe(qs, fields=None, index=None): + ''' + ::param qs is an QuerySet from Django + ::fields is a list of field names from the Model of the QuerySet + ::index is the preferred index column we want our dataframe to be set to + + Using the methods from above, we can easily build a dataframe + from this data. + ''' + lookup_fields = get_lookup_fields(qs.model, fields=fields) + index_col = None + if index in lookup_fields: + index_col = index + elif "id" in lookup_fields: + index_col = 'id' + values = qs_to_dataset(qs, fields=fields) + df = pd.DataFrame.from_records(values, columns=lookup_fields, index=index_col) + return df + +def qs_to_local_csv(qs, fields=None, path=None, filename=None): + if path is None: + path = os.path.join(os.path.dirname(BASE_DIR), 'csvstorage') + print(path) + if not os.path.exists(path): + ''' + CSV storage folder doesn't exist, make it! + ''' + os.mkdir(path) + if filename is None: + model_name = slugify(qs.model.__name__) + filename = "{}.csv".format(model_name) + filepath = os.path.join(path, filename) + lookups = get_lookup_fields(qs.model, fields=fields) + dataset = qs_to_dataset(qs, fields) + rows_done = 0 + with open(filepath, 'w') as my_file: + writer = csv.DictWriter(my_file, fieldnames=lookups) + writer.writeheader() + for data_item in dataset: + writer.writerow(data_item) + rows_done += 1 + print("{} rows completed".format(rows_done)) + diff --git a/server/attendance/views.py b/server/attendance/views.py index 937f81c..40c2a94 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -18,7 +18,7 @@ from users.models import Branch, User from vendors.models import Custodian, Vehicle, Gunmen from attendance.models import Attendance, AttendanceSheet, AttendanceVehicle, Issue, Trip - +from attendance.utils import qs_to_local_csv class CustomPagination(PageNumberPagination): page_size = 10 @@ -214,6 +214,12 @@ class AttendanceList( ordering_fields = "__all__" def get(self, request, *args, **kwargs): + + qs = Attendance.objects.all() + + qs_to_local_csv(qs, fields=['id', 'custodian__first_name', 'custodian__last_name', 'entry_time', 'exit_time']) + + params = request.query_params start_date = params.get("start_date", datetime.min) end_date = params.get("end_date", datetime.max) From d350fcfc4c54ca4d28746f472e3c98bd5be06444 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Wed, 21 Jul 2021 17:54:25 +0530 Subject: [PATCH 84/98] scheduled updates --- server/attendance/cron.py | 15 +++++++++++++++ server/attendance/utils.py | 10 +++++----- server/attendance/views.py | 6 +----- server/db.sqlite3 | Bin 299008 -> 299008 bytes server/server/settings.py | 9 +++++++++ 5 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 server/attendance/cron.py diff --git a/server/attendance/cron.py b/server/attendance/cron.py new file mode 100644 index 0000000..1a2b93d --- /dev/null +++ b/server/attendance/cron.py @@ -0,0 +1,15 @@ +from attendance.models import Attendance +from attendance.utils import qs_to_local_csv +from django.conf import settings +import os +from datetime import datetime + +BASE_DIR = settings.BASE_DIR + + +def send_attendance_report(): + qs = Attendance.objects.all() + qs_to_local_csv( + qs, + fields=['id', 'custodian__first_name', 'custodian__last_name', 'entry_time', 'exit_time']) + diff --git a/server/attendance/utils.py b/server/attendance/utils.py index 5291355..fcf8964 100644 --- a/server/attendance/utils.py +++ b/server/attendance/utils.py @@ -3,6 +3,7 @@ import csv from django.conf import settings from django.utils.text import slugify +from datetime import datetime BASE_DIR = settings.BASE_DIR @@ -77,7 +78,7 @@ def convert_to_dataframe(qs, fields=None, index=None): df = pd.DataFrame.from_records(values, columns=lookup_fields, index=index_col) return df -def qs_to_local_csv(qs, fields=None, path=None, filename=None): +def qs_to_local_csv(qs, fields=None, path=None): if path is None: path = os.path.join(os.path.dirname(BASE_DIR), 'csvstorage') print(path) @@ -86,9 +87,9 @@ def qs_to_local_csv(qs, fields=None, path=None, filename=None): CSV storage folder doesn't exist, make it! ''' os.mkdir(path) - if filename is None: - model_name = slugify(qs.model.__name__) - filename = "{}.csv".format(model_name) + model_name = slugify(qs.model.__name__) + today = datetime.today() + filename = "{}_{}_{}.csv".format(model_name, today.month, today.year) filepath = os.path.join(path, filename) lookups = get_lookup_fields(qs.model, fields=fields) dataset = qs_to_dataset(qs, fields) @@ -99,5 +100,4 @@ def qs_to_local_csv(qs, fields=None, path=None, filename=None): for data_item in dataset: writer.writerow(data_item) rows_done += 1 - print("{} rows completed".format(rows_done)) diff --git a/server/attendance/views.py b/server/attendance/views.py index 40c2a94..449f816 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -215,11 +215,7 @@ class AttendanceList( def get(self, request, *args, **kwargs): - qs = Attendance.objects.all() - - qs_to_local_csv(qs, fields=['id', 'custodian__first_name', 'custodian__last_name', 'entry_time', 'exit_time']) - - + params = request.query_params start_date = params.get("start_date", datetime.min) end_date = params.get("end_date", datetime.max) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 3442327d283a96b05aaf4b1e4defc1a207f4544a..c92e69a656fdc187f4937db2c8d729778393372c 100644 GIT binary patch delta 703 zcmZ{iPiPZC6vlUUR_*HUeA|?wB@s6*#)EW|olUyw68wXB^Xf_bM`Ar%tP&&?6FjIV zEfMx4?ahOP5Q+w=5K(%mRS^Uci50vkB~%3M!3fRC9rc!O715)+7=m9i;sYN`KX>kcpaRqzXM>fk&v8Z0t3wlCpYqQ#E zE#9d7+L6dHRXU8_`-!UZ6t_oH?kKlSn|s{$xNEs?#u?9~{bMi4uEYU7(8j}Bd(7im zi>I?`?m9ksNrny@Iqg4#Q(2EY7I(&-4CndFQ{22%yl|p4e6~tB#!iP)d@M$VUJ`P$u_*kpT^f@&uL?tKTaJ=H)qiLCYb$hXvwMs7 hO^Um%1}?1P2fjWql=tZGEf;(hN(0JrvkOHj{|1WOr?UV6 delta 266 zcmV+l0rmcXpb~(f5|A4KV38a{0bsFU!ygBg4!jPX4tujPFgy;EW-hA%3zHHraupN_ zVRUq5Ze(F@V`X1-a%pfFBLg>+p)MAKuP?W+F9B6>8Ve7<01x{Q^$+h4=?}jT;}6{r z*AL4N#ShW55rCl&m%pz8MH&ka$^Z}i5BCr95A6@=591Hs57`gY56=(Evk`!-50}cn z0XiBB4BY?^!Vh^5B@W;YpAKFQ8x5@uWDO<^-Lo+uzYK@n%mKIE%mOEKrv#t^Ag2UC z0uZMJzyc5k0T1H<596~DfY}cP8vzIaGne7t0~ELXj{^vB3;_@P01x~CMF0Q*KeZ49 Q+YguBn*$NI{0{^KfO?-@PXGV_ diff --git a/server/server/settings.py b/server/server/settings.py index 92bcc3c..cb49091 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -33,6 +33,7 @@ # Application definition INSTALLED_APPS = [ + "django_crontab", "jazzmin", "django.contrib.admin", "django.contrib.auth", @@ -161,6 +162,14 @@ ], } +# Run once a month at midnight of the first day of the month +# 0 0 20 * * + +# for now once every 5 minutes +CRONJOBS = [ + ('*/10 * * * *', 'attendance.cron.send_attendance_report') +] + EMAIL_BACKEND ='django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.gmail.com' EMAIL_USE_TLS = True From e692d656c29e6a05099e37806f3071205f1c6233 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 22:10:57 +0530 Subject: [PATCH 85/98] prettify backend code --- server/attendance/apps.py | 2 +- server/attendance/cron.py | 12 +++++++--- server/attendance/utils.py | 49 ++++++++++++++++++++------------------ server/attendance/views.py | 21 +++++++++++----- server/manage.py | 4 ++-- server/server/asgi.py | 2 +- server/server/settings.py | 14 +++++------ server/server/urls.py | 12 +++++----- server/server/wsgi.py | 2 +- server/vendors/admin.py | 12 ++++++++-- server/vendors/apps.py | 2 +- server/vendors/models.py | 26 ++++++++++---------- 12 files changed, 90 insertions(+), 68 deletions(-) diff --git a/server/attendance/apps.py b/server/attendance/apps.py index 177ba15..c5eba55 100644 --- a/server/attendance/apps.py +++ b/server/attendance/apps.py @@ -2,4 +2,4 @@ class AttendanceConfig(AppConfig): - name = 'attendance' + name = "attendance" diff --git a/server/attendance/cron.py b/server/attendance/cron.py index 1a2b93d..708b5e7 100644 --- a/server/attendance/cron.py +++ b/server/attendance/cron.py @@ -10,6 +10,12 @@ def send_attendance_report(): qs = Attendance.objects.all() qs_to_local_csv( - qs, - fields=['id', 'custodian__first_name', 'custodian__last_name', 'entry_time', 'exit_time']) - + qs, + fields=[ + "id", + "custodian__first_name", + "custodian__last_name", + "entry_time", + "exit_time", + ], + ) diff --git a/server/attendance/utils.py b/server/attendance/utils.py index fcf8964..930c64a 100644 --- a/server/attendance/utils.py +++ b/server/attendance/utils.py @@ -8,31 +8,33 @@ BASE_DIR = settings.BASE_DIR -def get_model_field_names(model, ignore_fields=['content_object']): - ''' +def get_model_field_names(model, ignore_fields=["content_object"]): + """ ::param model is a Django model class ::param ignore_fields is a list of field names to ignore by default - This method gets all model field names (as strings) and returns a list + This method gets all model field names (as strings) and returns a list of them ignoring the ones we know don't work (like the 'content_object' field) - ''' + """ model_fields = model._meta.get_fields() - model_field_names = list(set([f.name for f in model_fields if f.name not in ignore_fields])) + model_field_names = list( + set([f.name for f in model_fields if f.name not in ignore_fields]) + ) return model_field_names def get_lookup_fields(model, fields=None): - ''' + """ ::param model is a Django model class ::param fields is a list of field name strings. This method compares the lookups we want vs the lookups that are available. It ignores the unavailable fields we passed. - ''' + """ model_field_names = get_model_field_names(model) if fields is not None: - ''' + """ we'll iterate through all the passed field_names and verify they are valid by only including the valid ones - ''' + """ lookup_fields = [] for x in fields: if "__" in x: @@ -41,51 +43,53 @@ def get_lookup_fields(model, fields=None): elif x in model_field_names: lookup_fields.append(x) else: - ''' + """ No field names were passed, use the default model fields - ''' + """ lookup_fields = model_field_names return lookup_fields + def qs_to_dataset(qs, fields=None): - ''' + """ ::param qs is any Django queryset ::param fields is a list of field name strings, ignoring non-model field names This method is the final step, simply calling the fields we formed on the queryset and turning it into a list of dictionaries with key/value pairs. - ''' - + """ + lookup_fields = get_lookup_fields(qs.model, fields=fields) return list(qs.values(*lookup_fields)) def convert_to_dataframe(qs, fields=None, index=None): - ''' + """ ::param qs is an QuerySet from Django ::fields is a list of field names from the Model of the QuerySet ::index is the preferred index column we want our dataframe to be set to - + Using the methods from above, we can easily build a dataframe from this data. - ''' + """ lookup_fields = get_lookup_fields(qs.model, fields=fields) index_col = None if index in lookup_fields: index_col = index elif "id" in lookup_fields: - index_col = 'id' + index_col = "id" values = qs_to_dataset(qs, fields=fields) df = pd.DataFrame.from_records(values, columns=lookup_fields, index=index_col) return df + def qs_to_local_csv(qs, fields=None, path=None): if path is None: - path = os.path.join(os.path.dirname(BASE_DIR), 'csvstorage') + path = os.path.join(os.path.dirname(BASE_DIR), "csvstorage") print(path) if not os.path.exists(path): - ''' + """ CSV storage folder doesn't exist, make it! - ''' + """ os.mkdir(path) model_name = slugify(qs.model.__name__) today = datetime.today() @@ -94,10 +98,9 @@ def qs_to_local_csv(qs, fields=None, path=None): lookups = get_lookup_fields(qs.model, fields=fields) dataset = qs_to_dataset(qs, fields) rows_done = 0 - with open(filepath, 'w') as my_file: + with open(filepath, "w") as my_file: writer = csv.DictWriter(my_file, fieldnames=lookups) writer.writeheader() for data_item in dataset: writer.writerow(data_item) rows_done += 1 - diff --git a/server/attendance/views.py b/server/attendance/views.py index 449f816..206637d 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -13,13 +13,25 @@ from users.serializers import BranchSerializer, UserSerializer from vendors.serializers import CustodianSerializer, VehicleSerializer -from attendance.serializers import AttendanceSerializer, IssueSerializer, TripSerializer, AttendanceVehicleSerializer +from attendance.serializers import ( + AttendanceSerializer, + IssueSerializer, + TripSerializer, + AttendanceVehicleSerializer, +) from users.models import Branch, User from vendors.models import Custodian, Vehicle, Gunmen -from attendance.models import Attendance, AttendanceSheet, AttendanceVehicle, Issue, Trip +from attendance.models import ( + Attendance, + AttendanceSheet, + AttendanceVehicle, + Issue, + Trip, +) from attendance.utils import qs_to_local_csv + class CustomPagination(PageNumberPagination): page_size = 10 page_size_query_param = "page_size" @@ -140,7 +152,6 @@ def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) - class AttendanceVehicleList( mixins.ListModelMixin, mixins.CreateModelMixin, @@ -170,6 +181,7 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) + class AttendanceVehicleDetail( mixins.RetrieveModelMixin, mixins.UpdateModelMixin, @@ -189,8 +201,6 @@ def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) - - class AttendanceList( mixins.ListModelMixin, mixins.CreateModelMixin, @@ -215,7 +225,6 @@ class AttendanceList( def get(self, request, *args, **kwargs): - params = request.query_params start_date = params.get("start_date", datetime.min) end_date = params.get("end_date", datetime.max) diff --git a/server/manage.py b/server/manage.py index 8b46ee6..9856e02 100644 --- a/server/manage.py +++ b/server/manage.py @@ -6,7 +6,7 @@ def main(): """Run administrative tasks.""" - os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings') + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings") try: from django.core.management import execute_from_command_line except ImportError as exc: @@ -18,5 +18,5 @@ def main(): execute_from_command_line(sys.argv) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/server/server/asgi.py b/server/server/asgi.py index 501c9a9..cfe3f88 100644 --- a/server/server/asgi.py +++ b/server/server/asgi.py @@ -11,6 +11,6 @@ from django.core.asgi import get_asgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings") application = get_asgi_application() diff --git a/server/server/settings.py b/server/server/settings.py index cb49091..a092df0 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -162,18 +162,16 @@ ], } -# Run once a month at midnight of the first day of the month +# Run once a month at midnight of the first day of the month # 0 0 20 * * # for now once every 5 minutes -CRONJOBS = [ - ('*/10 * * * *', 'attendance.cron.send_attendance_report') -] +CRONJOBS = [("*/10 * * * *", "attendance.cron.send_attendance_report")] -EMAIL_BACKEND ='django.core.mail.backends.smtp.EmailBackend' -EMAIL_HOST = 'smtp.gmail.com' +EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" +EMAIL_HOST = "smtp.gmail.com" EMAIL_USE_TLS = True EMAIL_PORT = 587 # TODO: Setup the email and password -EMAIL_HOST_USER = '' -EMAIL_HOST_PASSWORD = '' +EMAIL_HOST_USER = "" +EMAIL_HOST_PASSWORD = "" diff --git a/server/server/urls.py b/server/server/urls.py index a38fc79..96c81df 100644 --- a/server/server/urls.py +++ b/server/server/urls.py @@ -21,10 +21,10 @@ ) urlpatterns = [ - path('admin/', admin.site.urls), - path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), - path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), - path('api/attendance/', include('attendance.urls')), - path('api/vendor/', include('vendors.urls')), - path('api/users/', include('users.urls')), + path("admin/", admin.site.urls), + path("api/token/", TokenObtainPairView.as_view(), name="token_obtain_pair"), + path("api/token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), + path("api/attendance/", include("attendance.urls")), + path("api/vendor/", include("vendors.urls")), + path("api/users/", include("users.urls")), ] diff --git a/server/server/wsgi.py b/server/server/wsgi.py index 3798fda..171e1c1 100644 --- a/server/server/wsgi.py +++ b/server/server/wsgi.py @@ -11,6 +11,6 @@ from django.core.wsgi import get_wsgi_application -os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'server.settings') +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "server.settings") application = get_wsgi_application() diff --git a/server/vendors/admin.py b/server/vendors/admin.py index a14131b..89cafed 100644 --- a/server/vendors/admin.py +++ b/server/vendors/admin.py @@ -18,19 +18,27 @@ class VendorAdmin(admin.ModelAdmin): class CustodianAdmin(admin.ModelAdmin): - list_display = ("id", "first_name", "last_name", "custodian_type", "email", "phone_number", "vendor") + list_display = ( + "id", + "first_name", + "last_name", + "custodian_type", + "email", + "phone_number", + "vendor", + ) list_display_links = ("id", "vendor", "custodian_type") search_fields = ("first_name", "last_name", "vendor", "custodian_type") list_per_page = 20 - class VehicleAdmin(admin.ModelAdmin): list_display = ("id", "model_name", "number_plate", "vendor") list_display_links = ("vendor",) search_fields = ("id", "model_name", "vendor", "number_plate") list_per_page = 20 + admin.site.register(Custodian, CustodianAdmin) admin.site.register(Vendor, VendorAdmin) admin.site.register(Vehicle, VehicleAdmin) diff --git a/server/vendors/apps.py b/server/vendors/apps.py index 1cc958b..5d12bd8 100644 --- a/server/vendors/apps.py +++ b/server/vendors/apps.py @@ -2,4 +2,4 @@ class VendorsConfig(AppConfig): - name = 'vendors' + name = "vendors" diff --git a/server/vendors/models.py b/server/vendors/models.py index e068710..7314315 100644 --- a/server/vendors/models.py +++ b/server/vendors/models.py @@ -20,27 +20,26 @@ def __str__(self): return f"{self.name} -> {self.email}" - class Custodian(models.Model): - CUSTODIAN_TYPE_CHOICES = [ - ('C', 'Custodian'), - ('G', 'Gunmen') - ] - custodian_type = models.CharField(max_length=1, default='C', choices=CUSTODIAN_TYPE_CHOICES) + CUSTODIAN_TYPE_CHOICES = [("C", "Custodian"), ("G", "Gunmen")] + custodian_type = models.CharField( + max_length=1, default="C", choices=CUSTODIAN_TYPE_CHOICES + ) first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) - + email = models.EmailField() phone_regex = RegexValidator( - regex=r'^\+?1?\d{9,15}$', - message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.") + regex=r"^\+?1?\d{9,15}$", + message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.", + ) phone_number = models.CharField(validators=[phone_regex], max_length=17, blank=True) - + vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: - return f'{self.custodian_type}: {self.first_name} {self.last_name}' + return f"{self.custodian_type}: {self.first_name} {self.last_name}" class Vehicle(models.Model): @@ -49,7 +48,7 @@ class Vehicle(models.Model): vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: - return f'{self.model_name} -> {self.number_plate}' + return f"{self.model_name} -> {self.number_plate}" class Gunmen(models.Model): @@ -59,5 +58,4 @@ class Gunmen(models.Model): vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: - return f'{self.first_name} {self.last_name}' - + return f"{self.first_name} {self.last_name}" From ae54c4e2c8f770efc8ebab672228dc275e8681b1 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 22:17:57 +0530 Subject: [PATCH 86/98] update requirements.txt --- server/requirements.txt | Bin 542 -> 722 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/requirements.txt b/server/requirements.txt index db441620d6210d042846242dadaa4335d413499a..f9b46d15dbe100392d37774806ce4c899232cd19 100644 GIT binary patch delta 159 zcmbQoa*1`qI_YGFB8Gg1Jcbg6M1~{=TOc%G&|@$MV#A5EpBm>elrrQp6fjhRr3`_> zMhqa*kb#$h3n-ol)S3b$i{bLdlgk-BRWrbb>VoA;7*c_zlrUs6Xp#rYgkiiTnZZP>Gqb~scq8>#6 delta 21 dcmcb_I*(<-x`}r#O@77bFgc1zVsa0Y8vt-#2_pai From 05d72be20428384a018e0c65d5f82dd5f58e07e9 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 22:20:05 +0530 Subject: [PATCH 87/98] remove .vscode and update gitignore --- .gitignore | 3 ++- .vscode/settings.json | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index fea2160..f87a8ca 100644 --- a/.gitignore +++ b/.gitignore @@ -195,4 +195,5 @@ npm-debug.log* yarn-debug.log* yarn-error.log* /requests.txt -/requests.http \ No newline at end of file +/requests.http +/.vscode \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index de288e1..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "python.formatting.provider": "black" -} \ No newline at end of file From a6c740e1211a7b723d99b51b1c6531d3cdb3b6ac Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 22:23:39 +0530 Subject: [PATCH 88/98] Create LICENSE --- LICENSE | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From ca2a9ef4f144ddddc98db42b1b4df86aa942fc58 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Wed, 21 Jul 2021 22:36:47 +0530 Subject: [PATCH 89/98] vehicle csv --- server/attendance/cron.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/server/attendance/cron.py b/server/attendance/cron.py index 708b5e7..67439f6 100644 --- a/server/attendance/cron.py +++ b/server/attendance/cron.py @@ -1,4 +1,4 @@ -from attendance.models import Attendance +from attendance.models import Attendance, AttendanceVehicle from attendance.utils import qs_to_local_csv from django.conf import settings import os @@ -8,9 +8,10 @@ def send_attendance_report(): - qs = Attendance.objects.all() + qs1 = Attendance.objects.all() + qs2 = AttendanceVehicle.objects.all() qs_to_local_csv( - qs, + qs1, fields=[ "id", "custodian__first_name", @@ -19,3 +20,13 @@ def send_attendance_report(): "exit_time", ], ) + qs_to_local_csv( + qs2, + fields=[ + "id", + "vehicle__model_name", + "custodian__number_plate", + "entry_time", + "exit_time", + ], + ) From e65a27ddcebbd051c986b19cb251379c328c30e8 Mon Sep 17 00:00:00 2001 From: vedantkokate07 Date: Thu, 22 Jul 2021 22:12:03 +0530 Subject: [PATCH 90/98] req --- server/requirements.txt | Bin 904 -> 946 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/requirements.txt b/server/requirements.txt index dc1e2ae8804c5930f3a4d277d6487aa95dde66c2..0fd4c60fcadcfa47eb2b9ca0e7d9b5e933345dea 100644 GIT binary patch delta 54 zcmeBR-^9K_j!83xA&ViAA&()QA)i5)A(^2FNarz>0L79RY=O{#L65;4hz&Q(GG#LY E06=^ScK`qY delta 12 TcmdnQ-od^>j%l+8Qx+ot8W;nC From afebe9b33da574dd65b2a6b6dc2d07c821457444 Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Thu, 22 Jul 2021 22:27:43 +0530 Subject: [PATCH 91/98] update requirements.txt --- server/requirements.txt | Bin 946 -> 722 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/requirements.txt b/server/requirements.txt index 0fd4c60fcadcfa47eb2b9ca0e7d9b5e933345dea..f9b46d15dbe100392d37774806ce4c899232cd19 100644 GIT binary patch delta 135 zcmdnQeu;I$y2(0B3KJJRFwSErWyobHV5nrU1wumxJq9B%X~@9Kzy%afWXNMk0g}aV zdE?3DjGn3)4EaDAU9emULn_de5{68M9Iz@QpeYt0lO}IvR2I%;sDSG=WH1AY8%(~) G=nDYC#Tv^1 literal 946 zcmb7CyH3ME5S$u`e~3gK%Qg=~K}SVJfkf>P8=QyZ*dQzUcwlBPcQ_;zk#$P!otd54 zz3;Ca9o|r(MS&9cd@d2$NpOxcyz+aC4;%)jF)%wP6-bxiE~|g-7%@6~9|$*G7Jkhe@@ymZ+N89Fw4_UAe9o7}@mJ z?5w2nqqKMYK74em9JXeL868Sh40&|7Z-^iM_uR>DZWTMWygy?5dn=WcZ=UBlN~>M8 z?CSCInA$!Xy3ib4a{2pvXAjxxn1nvApYJxO-jZ|r482^sY!5HA_c^lL_1~MX{s0d4 Bfa(AM From 13fc238df40647337065b9b0f6fbed39277fe5a7 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Thu, 22 Jul 2021 23:56:39 +0530 Subject: [PATCH 92/98] automated mails for report --- server/attendance/cron.py | 87 +++++++++++++++++++++++++++---------- server/attendance/utils.py | 2 + server/attendance/views.py | 1 - server/server/settings.py | 13 +++--- server/users/serializers.py | 21 --------- 5 files changed, 72 insertions(+), 52 deletions(-) diff --git a/server/attendance/cron.py b/server/attendance/cron.py index 67439f6..d646371 100644 --- a/server/attendance/cron.py +++ b/server/attendance/cron.py @@ -1,32 +1,73 @@ from attendance.models import Attendance, AttendanceVehicle +from vendors.models import Vendor from attendance.utils import qs_to_local_csv from django.conf import settings -import os from datetime import datetime +from django.core.mail import EmailMessage + BASE_DIR = settings.BASE_DIR def send_attendance_report(): - qs1 = Attendance.objects.all() - qs2 = AttendanceVehicle.objects.all() - qs_to_local_csv( - qs1, - fields=[ - "id", - "custodian__first_name", - "custodian__last_name", - "entry_time", - "exit_time", - ], - ) - qs_to_local_csv( - qs2, - fields=[ - "id", - "vehicle__model_name", - "custodian__number_plate", - "entry_time", - "exit_time", - ], - ) + today = datetime.today() + + for vendor in Vendor.objects.all(): + attendance_custodian = Attendance.objects.filter( + custodian__vendor = vendor, + entry_time__month = today.month, + entry_time__year = today.year, + ).order_by('entry_time').all() + + if attendance_custodian: + attendance_custodian_path = qs_to_local_csv( + attendance_custodian, + fields=[ + "id", + "custodian__first_name", + "custodian__last_name", + "entry_time", + "exit_time", + ], + ) + + mail = EmailMessage( + subject= f"Monthly Custodian Attendance Report: {today.strftime('%B %Y')}", + body= f"PFA the attendance reports for the custodians for {today.strftime('%B %Y')}", + from_email= settings.EMAIL_HOST_USER, + to=[vendor.email] + ) + + attendance_file = open(attendance_custodian_path) + mail.attach(f"attendance_report_{ today.strftime('%B_%Y') }.csv", attendance_file.read()) + mail.send() + + + attendance_vehicle = AttendanceVehicle.objects.filter( + custodian__vendor = vendor, + entry_time__month = today.month, + entry_time__year = today.year, + ).order_by('entry_time').all() + + if attendance_vehicle: + attendance_vehicle_path = qs_to_local_csv( + attendance_vehicle, + fields=[ + "id", + "vehicle__model_name", + "custodian__number_plate", + "entry_time", + "exit_time", + ], + ) + + mail = EmailMessage( + subject= f"Monthly Vehicle Attendance Report: {today.strftime('%B %Y')}", + body= f"PFA the attendance reports for the vehicles for {today.strftime('%B %Y')}", + from_email= settings.EMAIL_HOST_USER, + to=[vendor.email] + ) + + attendance_file = open(attendance_vehicle_path) + mail.attach(attendance_file.name, attendance_file.read()) + mail.send() diff --git a/server/attendance/utils.py b/server/attendance/utils.py index 930c64a..1ac08ab 100644 --- a/server/attendance/utils.py +++ b/server/attendance/utils.py @@ -104,3 +104,5 @@ def qs_to_local_csv(qs, fields=None, path=None): for data_item in dataset: writer.writerow(data_item) rows_done += 1 + + return filepath diff --git a/server/attendance/views.py b/server/attendance/views.py index 206637d..f4e8353 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -224,7 +224,6 @@ class AttendanceList( ordering_fields = "__all__" def get(self, request, *args, **kwargs): - params = request.query_params start_date = params.get("start_date", datetime.min) end_date = params.get("end_date", datetime.max) diff --git a/server/server/settings.py b/server/server/settings.py index ae4c23a..ae1d7e8 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -36,7 +36,6 @@ INSTALLED_APPS = [ "django_crontab", "jazzmin", - 'django_crontab', "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", @@ -167,13 +166,13 @@ # Run once a month at midnight of the first day of the month # 0 0 20 * * -# for now once every 5 minutes +# for now once every 10 minutes CRONJOBS = [("*/10 * * * *", "attendance.cron.send_attendance_report")] -EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" -EMAIL_HOST = "smtp.gmail.com" +EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' +EMAIL_HOST = 'smtp.gmail.com' EMAIL_USE_TLS = True EMAIL_PORT = 587 -# TODO: Setup the email and password -EMAIL_HOST_USER = "" -EMAIL_HOST_PASSWORD = "" +EMAIL_HOST_USER = '' +EMAIL_HOST_PASSWORD = '' + diff --git a/server/users/serializers.py b/server/users/serializers.py index f42f7e6..e632c64 100644 --- a/server/users/serializers.py +++ b/server/users/serializers.py @@ -1,5 +1,4 @@ from secrets import token_hex -from django.core.mail import send_mail from rest_framework import serializers from django.contrib.auth.models import User from django.contrib.auth.hashers import make_password @@ -114,23 +113,3 @@ class BranchSerializer(serializers.ModelSerializer): class Meta: model = Branch fields = ["id", "name", "address", "branch_manager", "region"] - - -def mail(subject, message, to_mail): - send_mail( - subject, - message, - from_email=None, - recipient_list=[to_mail], - fail_silently=False, - ) - - -def mail_attendance(subject, message, to_mail): - send_mail( - subject, - message, - from_email=None, - recipient_list=[to_mail], - fail_silently=False, - ) \ No newline at end of file From 98834bd98e8574e28327a5ba9f918fe33757cdcf Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Fri, 23 Jul 2021 20:07:16 +0530 Subject: [PATCH 93/98] current user route --- server/db.sqlite3 | Bin 299008 -> 299008 bytes server/users/urls.py | 1 + server/users/views.py | 13 ++++++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index c92e69a656fdc187f4937db2c8d729778393372c..c6c9a08a253d5d54dfc761b34005613cd8108264 100644 GIT binary patch delta 1112 zcmaKrTSyd97{|}qbH;U2=0D>lwQX^-dXQ3Qc6Ha5C?zU|E)teegh{*Eb+=q1B1)sD z9=ahkk10L$5VFaF)8)Z>2!e`=r06b);T1Ee9x~`mOHyEa9=`MNJKy#EzmBe)j;@?b z9vZ#8a1D+2?(QxwLKD%Hy%`u)W^f+~?89QLN3}ART%h+Uly^QaFDz|Ry=*Bx7LT;W zo7*C-`(sf#kFhcuKF|_vjWxG~5ATmQABwfAojDcj^3M>B{Cx_*{M6D8(cI3CigGHQ zO;p&43cB^k5*6J9KkyY(7)3vZ@E))52oG=@N%Y`4o})Xdb(}!9#3a(V=x^m~s7$BIzcYMJlMubK_;57!s zhu?uU&`+0NX<*#uU9OqpzGp6OT<0}Ry~YO(MZ(Bmj>6$3Bu5;QHMyA;{2$v6R_Ef} zaqpb?SSa8QB1(B6Bzhb>#IM!C>ya{vpUC3OD(jB~{HA^UB0H~UbBw2In#Q=Tb+JKE zZcQgxt{@Z6DtyBPrfu~mdzUI!(Ei_aj9@IaDx#A&4kVP@Q%_mG6V**{3kOgNx2+Dc z?@EczHBvxGet|4gnaE-tGaI+mHyCx1wn*bXVO)0U6npEm`N^qh9G^t)&$d#-Uod-^ fahjbPmOTz$WQY`#v%|F28vY)?r)cvAKC}84vXDlA delta 502 zcmZ8dJ!n%=7`^v>HwJCE=Ot;;swJ<8Lk1g*U^_{$pg1{6$5_%BTWX&4Q8F5Fawu)h za7Qa5ox+O-dzB8ULnj5v60l@QUqCxFg15%W4?gb4x#yhkr?eU?t;Uwm@$Aa^ z37&m@_eEk*{$NpgPhekm@c};W;{tAC9Fw)P&bs7OZj78sK4$&wzvw5r#HVMc3VAm( zHT__wkePGyvK&j@7#O09Cl|cjyqB5J10NJNSZ+*us0%P(h;>Ej@**_bnCpel6O+(s-Za%X596qXo=T=;cs?|-bZ(1U)McR~a4utbckbRtM2C?4?>f+h1 zhzJy!8D$G=C>o/", views.BranchDetail.as_view()), path("region/", views.RegionList.as_view()), path("region//", views.RegionDetail.as_view()), + path("current/", views.get_current_user), ] urlpatterns = format_suffix_patterns(urlpatterns) diff --git a/server/users/views.py b/server/users/views.py index 3feca77..344d501 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -8,10 +8,12 @@ from rest_framework.pagination import PageNumberPagination from rest_framework.response import Response from rest_framework import status +from rest_framework.decorators import api_view +from django.shortcuts import get_object_or_404 class CustomPagination(PageNumberPagination): - page_size = 10 + page_size = 100 page_size_query_param = "page_size" max_page_size = 1000 @@ -148,3 +150,12 @@ def put(self, request, *args, **kwargs): def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) + + + +@api_view(['GET']) +def get_current_user(request): + print(request.user.id) + user = get_object_or_404(User, pk=request.user.id) + serializer = UserSerializer(user) + return Response(serializer.data) \ No newline at end of file From 4472fe826067051276155d7855dff815ec704212 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Fri, 23 Jul 2021 20:17:59 +0530 Subject: [PATCH 94/98] current user route --- server/db.sqlite3 | Bin 299008 -> 299008 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index c6c9a08a253d5d54dfc761b34005613cd8108264..547c38caf06000925e4cfd56f3787091c10310d8 100644 GIT binary patch delta 291 zcmZozAk?rxXo56j{zMsP#{7*51$vCE%@_6BFX}OFzo^G#d~rF81GB(lmInqPhQf9r z@kf4J12c;PA1nVe2L3<%-}#^Mf8>9?S+L;>KPw9}CnM|h*Xx-jMZnU(`M>eM0ZKn( zFk@g~Fx@OzAi_UgXFu~UHdbavMkdzjZ}u}w08M(z!2gQ>DgST&ul(`Ee*tm&C;qoUrtNl#3(V)3H#;bJ TaZlIrXW0Ys$M(1WEW!=|h-Fsy delta 260 zcmZozAk?rxXo56j-b5K^#=MOQ1$vAu%@_6BFX}OFzo^G#e36HR|1AUmAO7$BpZMQy z7Hqi7zx^#gvv>eDaeroEfo%=UED9Vf{I9{9w(~7uzQI2+fPMPw^~{nYEc|a6_P From 2c1f9d50d53a16d4cb9d6576e6e4eda68f4b75b3 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Fri, 23 Jul 2021 22:37:02 +0530 Subject: [PATCH 95/98] updates --- server/attendance/views.py | 3 +++ server/server/settings.py | 1 + server/users/views.py | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index f4e8353..4e4e1ea 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -7,6 +7,7 @@ from rest_framework import generics from rest_framework import filters +from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination from django_filters.rest_framework import DjangoFilterBackend @@ -52,6 +53,7 @@ def get_paginated_response(self, data): class TripList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): + permission_classes = [IsAuthenticated] queryset = Trip.objects.all() serializer_class = TripSerializer pagination_class = CustomPagination @@ -80,6 +82,7 @@ class TripList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericA ordering_fields = "__all__" def get(self, request, *args, **kwargs): + print(request.user) return self.list(request, *args, **kwargs) def post(self, request, *args, **kwargs): diff --git a/server/server/settings.py b/server/server/settings.py index ae1d7e8..d2d302a 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -34,6 +34,7 @@ # Application definition INSTALLED_APPS = [ + "rest_framework", "django_crontab", "jazzmin", "django.contrib.admin", diff --git a/server/users/views.py b/server/users/views.py index 344d501..067bb1c 100644 --- a/server/users/views.py +++ b/server/users/views.py @@ -152,7 +152,6 @@ def delete(self, request, *args, **kwargs): return self.destroy(request, *args, **kwargs) - @api_view(['GET']) def get_current_user(request): print(request.user.id) From b775e11c9db0917d9fefe5be1c230cea4b7d534d Mon Sep 17 00:00:00 2001 From: RUiNtheExtinct Date: Fri, 23 Jul 2021 23:18:24 +0530 Subject: [PATCH 96/98] update settings.py --- server/attendance/views.py | 12 ++++++++++++ server/db.sqlite3 | Bin 299008 -> 323584 bytes server/server/settings.py | 16 ++++++++++------ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index 4e4e1ea..aa10a70 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -8,6 +8,11 @@ from rest_framework import filters from rest_framework.permissions import IsAuthenticated +from rest_framework.authentication import ( + BasicAuthentication, + SessionAuthentication, + TokenAuthentication, +) from rest_framework.response import Response from rest_framework.pagination import PageNumberPagination from django_filters.rest_framework import DjangoFilterBackend @@ -52,7 +57,14 @@ def get_paginated_response(self, data): ) +# @csrf_exempt class TripList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): + + # authentication_classes = [ + # TokenAuthentication, + # SessionAuthentication, + # BasicAuthentication, + # ] permission_classes = [IsAuthenticated] queryset = Trip.objects.all() serializer_class = TripSerializer diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 547c38caf06000925e4cfd56f3787091c10310d8..3527f83fb62ca3a65c65a23d5a95e1aa1dc9a067 100644 GIT binary patch delta 2555 zcmb7GUu;uV7(eHpb9Z+;c22u?>p-MkN8L)~`caDA*e2bO_ncEiOm^Ip% zDb^J-Yv+%}1nri*JiuSzkH!7kN`6eX^T1?p^bZg94)yN~^+}TC@+F@R4D=rwaY{}{ zl_Xa=U1o>8&LypL)K<$*sn#t&w}u6-eJCfr{t)UoX$F*L#}1m90U%B%i*cD zF@gf?B17zy$xxIzQJuTqEqmg1C6~k%ML`%5nmyBNL48|mBF+`i|QEk*ksHa(8rHH8-~b0 zw#S5xR!sWI_PE3R45>02Fff(nU@6kG0pp_s@$rrbL|!o(6TDHard*>HABeZapT!H} zX)($OZ|08`V`ztlSNDbvW)#e8#IOb$f}#DPp-_guGv)8@_4n<`^miCAv_XSE7|Z~- zYcVW?`bFxtA`GoipUK)XrG8$>1l zc7D6?1>c2_qABh&#}~XuXJ~lYg!+p%mIw?yYkbMA%pd1U$NJblQV+1yIhfiFK1VKZ z2a7u{80~gAt{?IT_J^{fvR+#@ZEb4oYBF~1lPnTCsa(+s2JK3yan$S@v;f9 zM$x^EjK0WdWJF-OjHGgj^r=rvUG@@lScT4YnUzBV;ZU- zFcVBe2=+EaUQ5S4QTxt@$l)}4@k(9Tvsv1Ad?MjjKD=&@dIeGaB2trWVTb$QH1_Wa z0iOr-JbODsx4r=J?nW^vNwuC(U2UKz=&6^wWjWL%c|zSTht%WtctZ7VPr&I9x}8~H wHg)Tqa&;YZx@7f}0@5phUSYi7(G7OAd&#V+*!%1X0v(K|oiW^^7$H&o4^raE*DrIAWadr>N)m$o44Eo@8> z!Glc~oP$cDP%Tsx-RkP0pl21ey@-df=43rcDMBt4oS+9Eymxr-@&D&LLAz5k7vjd8 zBuS%!|A6`{16g@aIykcY?A%SZ`OrkD(L!Ix#dnP4= zo)582y2IYGr|bf=*a#b@KbYxtC7Kkvq0jA1_aNIHPVdF6=;qV?F;k3c7yKVF3l1S( zxq&;}C+S=~84;mL%M$xZU(@fjOgHEfd&j=AHLrW{Fm>nkj8{JDATVjkRgU+0#{4Ap zN+*g4>`2yC#w+5=J7F(7_4zW`^pvZ7YB_5f-};D2DPQ;Vb+mFH>zIceY(ZSQ#0MOF zlFwA(o?meA4Dt)t@O3SOSVLkB&v3plzfr}#`Xdq`-50XM9t4T!Z;1Ya!0%fYo0cdv zLB2w&(9~A6t8I<8$IS&tkEb9GxCQ&!~(Qii*D YT|^mC|Au_Ims||{+9E8HhlAwI9~cmh$p8QV diff --git a/server/server/settings.py b/server/server/settings.py index d2d302a..8d6f3cc 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -45,6 +45,7 @@ "django.contrib.staticfiles", "django_filters", "corsheaders", + "rest_framework.authtoken", "users.apps.UsersConfig", "vendors.apps.VendorsConfig", "attendance.apps.AttendanceConfig", @@ -147,7 +148,7 @@ "ALGORITHM": "HS256", "SIGNING_KEY": SECRET_KEY, "VERIFYING_KEY": None, - "AUTH_HEADER_TYPES": ("JWT",), + "AUTH_HEADER_TYPES": ("JWT", "Bearer"), "USER_ID_FIELD": "id", "USER_ID_CLAIM": "user_id", "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), @@ -158,9 +159,13 @@ "DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.coreapi.AutoSchema", "DEFAULT_PERMISSION_CLASSES": [ "rest_framework.permissions.AllowAny", + "rest_framework.authentication.BasicAuthentication", + "rest_framework.authentication.SessionAuthentication", + "rest_framework.authentication.TokenAuthentication", ], "DEFAULT_AUTHENTICATION_CLASSES": [ "rest_framework_simplejwt.authentication.JWTAuthentication", + "rest_framework.permissions.IsAuthenticated", ], } @@ -170,10 +175,9 @@ # for now once every 10 minutes CRONJOBS = [("*/10 * * * *", "attendance.cron.send_attendance_report")] -EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -EMAIL_HOST = 'smtp.gmail.com' +EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" +EMAIL_HOST = "smtp.gmail.com" EMAIL_USE_TLS = True EMAIL_PORT = 587 -EMAIL_HOST_USER = '' -EMAIL_HOST_PASSWORD = '' - +EMAIL_HOST_USER = "" +EMAIL_HOST_PASSWORD = "" From 3898ea5dc7ad4f2ca2dbff9f9da73a17125ec8a7 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Fri, 23 Jul 2021 23:40:38 +0530 Subject: [PATCH 97/98] auth and current user details view --- server/db.sqlite3 | Bin 299008 -> 299008 bytes server/server/settings.py | 3 ++- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index 547c38caf06000925e4cfd56f3787091c10310d8..bbf98eeb92f53d56a089b92f7b311f2588315fa9 100644 GIT binary patch delta 577 zcmZozAk?rxXo56j@kAMC#^Q|$i{wSz83g&#SomM^{oy~z-^icAugo90Sxmu@UyXk~ zgAfA>;1y$*XG|VA$ivLb(5T74p~$Pw!Rg3b zkd&R0W)xqXk!WOUrebJe00b&tuDRhJX@yCKnJ&I6E(TtPzQKO(`l;#KmWleVK0dj@ z1%6%z=2c!H+5YB!`q}3C-a$Fxl_`$4C8@~nK^pN`ME|0Muxfu=DJ44 z^$LdORwjm41_pW-W+s+qMs-XO=g9N&;&e`xNtH)LR9L8CS)!pzVoFM3ZmMH`UX+`M zuZLxrWwyJUi<4VHN_JUkj%j8}l5eiNOI4n}XN3vEIdBIE8iO2QY-wd`p=V)aVQFGH zIePv|E@u8)4E*2uU-IADEZA^{UzU$qkrCk+W?o>dz`0D#-`8*dzMheH!EzP_CV}NF z2}}hXO#H7H_`mYM0&2gD+B*;{;xoFFZsDy WnHd?GnOK+^Ihoo%FfIGQyZ`_z_?Alm delta 208 zcmZozAk?rxXo56j{zMsP#{7*5i{wSZ83g&#*!W-a{oy~zzn(vXUzy*1vzUS*zZ#Di zvpi>FX-P(WX>n>10|S2}gCGMk5a(w$W}GgV!ze5%1QZuWmIJaSm6^>Mr%&u)5*20@ zU}sk602xypUr>~vmYI{f`JldY0vjWLGy{M1X2F6${>jnvR|5Ip8Th|%7HoLS-~4_3 m_V4Q%c^52ZX%JY>lE753ndQMB`Ar8{1X@{`x3aMO=?4IV{5Dzu diff --git a/server/server/settings.py b/server/server/settings.py index d2d302a..390ef35 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -147,7 +147,7 @@ "ALGORITHM": "HS256", "SIGNING_KEY": SECRET_KEY, "VERIFYING_KEY": None, - "AUTH_HEADER_TYPES": ("JWT",), + "AUTH_HEADER_TYPES": ("JWT", "Bearer"), "USER_ID_FIELD": "id", "USER_ID_CLAIM": "user_id", "AUTH_TOKEN_CLASSES": ("rest_framework_simplejwt.tokens.AccessToken",), @@ -158,6 +158,7 @@ "DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.coreapi.AutoSchema", "DEFAULT_PERMISSION_CLASSES": [ "rest_framework.permissions.AllowAny", + ], "DEFAULT_AUTHENTICATION_CLASSES": [ "rest_framework_simplejwt.authentication.JWTAuthentication", From 8e179aea22255beb67934cd4380c8bec37ab0df3 Mon Sep 17 00:00:00 2001 From: Phoenix009 Date: Sat, 23 Oct 2021 15:21:59 +0530 Subject: [PATCH 98/98] Use Generic Class Based views --- server/attendance/views.py | 102 +++++------------------------------ server/db.sqlite3 | Bin 299008 -> 323584 bytes server/users/views.py | 80 +++------------------------- server/vendors/models.py | 12 +++-- server/vendors/views.py | 105 +++---------------------------------- 5 files changed, 36 insertions(+), 263 deletions(-) diff --git a/server/attendance/views.py b/server/attendance/views.py index aa10a70..0aec2a1 100644 --- a/server/attendance/views.py +++ b/server/attendance/views.py @@ -58,7 +58,7 @@ def get_paginated_response(self, data): # @csrf_exempt -class TripList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView): +class TripList(generics.ListCreateAPIView): # authentication_classes = [ # TokenAuthentication, @@ -93,10 +93,6 @@ class TripList(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericA } ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - print(request.user) - return self.list(request, *args, **kwargs) - def post(self, request, *args, **kwargs): validated_data = request.data @@ -125,18 +121,10 @@ def post(self, request, *args, **kwargs): return self.create(request, *args, **kwargs) -class TripDetail( - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView, -): +class TripDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Trip.objects.all() serializer_class = TripSerializer - def get(self, request, *args, **kwargs): - return self.retrieve(request, *args, **kwargs) - def put(self, request, *args, **kwargs): validated_data = request.data @@ -163,16 +151,8 @@ def put(self, request, *args, **kwargs): request.data["custodian_3"] = request.data["custodian_1"] return self.update(request, *args, **kwargs) - def delete(self, request, *args, **kwargs): - return self.destroy(request, *args, **kwargs) - -class AttendanceVehicleList( - mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView, - # filters.FilterSet, -): +class AttendanceVehicleList(generics.ListCreateAPIView): queryset = AttendanceVehicle.objects.all() serializer_class = AttendanceVehicleSerializer pagination_class = CustomPagination @@ -190,37 +170,13 @@ class AttendanceVehicleList( ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - return self.list(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) - -class AttendanceVehicleDetail( - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView, -): +class AttendanceVehicleDetail(generics.RetrieveUpdateDestroyAPIView): queryset = AttendanceVehicle.objects.all() serializer_class = AttendanceVehicleSerializer - def get(self, request, *args, **kwargs): - return self.retrieve(request, *args, **kwargs) - - def put(self, request, *args, **kwargs): - return self.update(request, *args, **kwargs) - - def delete(self, request, *args, **kwargs): - return self.destroy(request, *args, **kwargs) - -class AttendanceList( - mixins.ListModelMixin, - mixins.CreateModelMixin, - generics.GenericAPIView, -): +class AttendanceList(generics.ListCreateAPIView): queryset = Attendance.objects.all() serializer_class = AttendanceSerializer pagination_class = CustomPagination @@ -244,7 +200,8 @@ def get(self, request, *args, **kwargs): end_date = params.get("end_date", datetime.max) queryset = self.filter_queryset(self.get_queryset()) - queryset = queryset.filter(entry_time__date__range=[start_date, end_date]) + queryset = queryset.filter(entry_time__date__range=[ + start_date, end_date]) page = self.paginate_queryset(queryset) if page is not None: @@ -291,7 +248,8 @@ def post(self, request, *args, **kwargs): attendance.save() result.append(AttendanceSerializer(attendance).data) else: - custodian_ = get_object_or_404(Custodian, pk=data.pop("custodian")) + custodian_ = get_object_or_404( + Custodian, pk=data.pop("custodian")) added_by_ = get_object_or_404(User, pk=data.pop("added_by")) branch_ = get_object_or_404(Branch, pk=data.pop("branch")) attendance_sheet_ = get_object_or_404( @@ -309,54 +267,18 @@ def post(self, request, *args, **kwargs): return Response(data=result) -class AttendanceDetail( - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView, -): +class AttendanceDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Attendance.objects.all() serializer_class = AttendanceSerializer - def get(self, request, *args, **kwargs): - return self.retrieve(request, *args, **kwargs) - def put(self, request, *args, **kwargs): - return self.update(request, *args, **kwargs) - - def delete(self, request, *args, **kwargs): - return self.destroy(request, *args, **kwargs) - - -class IssueList( - mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView -): +class IssueList(generics.ListCreateAPIView): queryset = Issue.objects.all() serializer_class = IssueSerializer pagination_class = CustomPagination ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - return self.list(request, *args, **kwargs) - - def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) - -class IssueDetail( - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView, -): +class IssueDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Issue.objects.all() serializer_class = IssueSerializer - - def get(self, request, *args, **kwargs): - return self.retrieve(request, *args, **kwargs) - - def put(self, request, *args, **kwargs): - return self.update(request, *args, **kwargs) - - def delete(self, request, *args, **kwargs): - return self.destroy(request, *args, **kwargs) diff --git a/server/db.sqlite3 b/server/db.sqlite3 index bbf98eeb92f53d56a089b92f7b311f2588315fa9..33b7a048b1f62cc88440805f7a2d7973bfd065c9 100644 GIT binary patch delta 2067 zcmah~ZERCj7`~_X+;w+b@9EZ#4m7m;D6Eui_uh7GH=Iz|fUUc2H@c10k6N~F?beTN z6!sy|c1(=?ky+#A2LTKk`A19*#UBR5e`unB(PS7hH71Z4B*e%cjh?oobQNQo^XA;= zea_SOz4t!vji0ZIuPRPGS9ydW2nSxhc##AFxaF+|aOC6H-bOW}7}6yqII46wR9DJy z)Ke#tQh8rV2|-<@PNcl@Mk;33Q-oS?^&X1)qmfBpm}OamC%c=PiOkLOEYCG@Y!h$L zux;%IQ@hd9Y%m%vtY!Nad~n;EgS-dJL_9ppnOL4Tc{sDt{44?9$hPrDqYevj+BFKC zClC%q1K!}Xj2c(i2OiFiXAroN+ zQ=DcK)1*>DLS6d|l_~{JsMaP@$L$F~I_c%4)VVA#t1pw&f6>3v-_uv=kLYDAc)v7O z4S^mg4+ng+1^3^nf}jN`M}0wG)K`Eza`=ef8y+vj?MeuAK>xMn#g*Az-8sSuq2XD#t9#b& z>ND6E`X}6-ldRok#fR+y`;gl&xU9Sb|3P<{?Z~}QToY@`zR2eG*4AdOjWe71#ceQK zdU86ZNwJgPLWV+n3G@Tni_$2B-bqzXnUJ=D6u|#AN2NkBQCm@Q`WOe7M; zOB>xW9`Xi)%_EUek+IC}My}apX*C$wRPWg7NqmYS;-fXmGV^21A zA0N1z9=HoGy)UUE#FDtAo*W>KiCg26{`9$bNg#PMwkS!*7Rf~!jg8GnWCYqTGN;IO zkh&+4r5jF>w@EQx0=wR8hGpsI@5l>4>}i3QMf1<(SK`AuC>78ANS3FMisT)s_&7;k zynLR7PSQzU6QvKyWjVYK&%y=hhGxi+zmV7PRIDLm^-hWadR?&_cX`8_jEgkcnX%b{ zNi9wPHfM&G^VSohJx46`R(85(h&eDvtQ9a(w^

TP{z-NRG3y7jtTL1#Zq)<;o23 zIvdVwo7R}Spr9P5C&wu)sGt^CT}J5nZcI{dero>=BU46JBE9-MS*zEThw($9h_YK{ zFVJG?qf$Zo3FU%I&)g6-aJTCbud7~ij%|^ ze7VV)2q)&HD!m>YS46!Bg1-C^%?-1nOJP@km(|s!aanivc4_L0vUQrqI&se#vXL5@ z@p+@7`W#s!uAG#-OyLirSP{e-?iAD}nT7@j09RKJn5g8!aIR3@F=8r+b+upPeQ#1{Mwr8MzXl$?@V W=*$P*hF4Dx|NAN>Pr=nc)&BrxiekM0 delta 532 zcmXX@O=uHA6rR~Po89bYXErHXYow$`ZK8oR1d3v5?L|^ZBo%{V5tN?9wnTz@OE<|D zk2YO!5B?;g1wo<86t^CF(W465dWsTaPxc~Ggm`oUK6u~Z`@Z)*c+cweS=%7Ye^Q%n(^d9?wb&*f963duqM73MxP>7^YmRc}C?6_b zq`Y>nf+3@&9VK5ETORm%`tlb!Ky($+cZMA}tE+$$SYgYEWTT=N?y4NH6zMq5QQ$tw@CxK z#tY+4U?=cW-_zIiL+U4WK*{+U-jQY42KQ0}p7+MF str: return f"{self.custodian_type}: {self.first_name} {self.last_name}" @@ -45,7 +47,8 @@ def __str__(self) -> str: class Vehicle(models.Model): model_name = models.CharField(max_length=200) number_plate = models.CharField(max_length=200) - vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + vendor = models.ForeignKey( + Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: return f"{self.model_name} -> {self.number_plate}" @@ -55,7 +58,8 @@ class Gunmen(models.Model): first_name = models.CharField(max_length=200) last_name = models.CharField(max_length=200) email = models.EmailField() - vendor = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True, blank=True) + vendor = models.ForeignKey( + Vendor, on_delete=models.SET_NULL, null=True, blank=True) def __str__(self) -> str: return f"{self.first_name} {self.last_name}" diff --git a/server/vendors/views.py b/server/vendors/views.py index b342d04..7fe6a2d 100644 --- a/server/vendors/views.py +++ b/server/vendors/views.py @@ -1,4 +1,3 @@ -from rest_framework import mixins from rest_framework import generics from rest_framework import filters from django_filters.rest_framework import DjangoFilterBackend @@ -33,9 +32,7 @@ def get_paginated_response(self, data): ) -class CustodianList( - mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView -): +class CustodianList(generics.ListCreateAPIView): queryset = Custodian.objects.all() serializer_class = CustodianSerializer pagination_class = CustomPagination @@ -57,36 +54,14 @@ class CustodianList( ] ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - return self.list(request, *args, **kwargs) - def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) - - -class CustodianDetail( - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView, -): +class CustodianDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Custodian.objects.all() serializer_class = CustodianSerializer ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - return self.retrieve(request, *args, **kwargs) - - def put(self, request, *args, **kwargs): - return self.update(request, *args, **kwargs) - - def delete(self, request, *args, **kwargs): - return self.destroy(request, *args, **kwargs) - -class VendorList( - mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView -): +class VendorList(generics.ListCreateAPIView): queryset = Vendor.objects.all() serializer_class = VendorSerializer pagination_class = CustomPagination @@ -103,36 +78,14 @@ class VendorList( ] ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - return self.list(request, *args, **kwargs) - def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) - - -class VendorDetail( - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView, -): +class VendorDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Vendor.objects.all() serializer_class = VendorSerializer ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - return self.retrieve(request, *args, **kwargs) - - def put(self, request, *args, **kwargs): - return self.update(request, *args, **kwargs) - - def delete(self, request, *args, **kwargs): - return self.destroy(request, *args, **kwargs) - -class GunmenList( - mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView -): +class GunmenList(generics.ListCreateAPIView): queryset = Gunmen.objects.all() serializer_class = GunmenSerializer pagination_class = CustomPagination @@ -141,35 +94,13 @@ class GunmenList( filterset_fields = ["first_name", "last_name", "vendor"] ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - return self.list(request, *args, **kwargs) - def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) - - -class GunmenDetail( - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView, -): +class GunmenDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Gunmen.objects.all() serializer_class = GunmenSerializer - def get(self, request, *args, **kwargs): - return self.retrieve(request, *args, **kwargs) - - def put(self, request, *args, **kwargs): - return self.update(request, *args, **kwargs) - - def delete(self, request, *args, **kwargs): - return self.destroy(request, *args, **kwargs) - -class VehicleList( - mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView -): +class VehicleList(generics.ListCreateAPIView): queryset = Vehicle.objects.all() serializer_class = VehicleSerializer pagination_class = CustomPagination @@ -178,27 +109,7 @@ class VehicleList( filterset_fields = ["model_name", "vendor", "number_plate"] ordering_fields = "__all__" - def get(self, request, *args, **kwargs): - return self.list(request, *args, **kwargs) - def post(self, request, *args, **kwargs): - return self.create(request, *args, **kwargs) - - -class VehicleDetail( - mixins.RetrieveModelMixin, - mixins.UpdateModelMixin, - mixins.DestroyModelMixin, - generics.GenericAPIView, -): +class VehicleDetail(generics.RetrieveUpdateDestroyAPIView): queryset = Vehicle.objects.all() serializer_class = VehicleSerializer - - def get(self, request, *args, **kwargs): - return self.retrieve(request, *args, **kwargs) - - def put(self, request, *args, **kwargs): - return self.update(request, *args, **kwargs) - - def delete(self, request, *args, **kwargs): - return self.destroy(request, *args, **kwargs)