From 760915276720336dcf7aaa32fed7698bb901ed61 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Sun, 12 Nov 2023 21:45:39 +0800 Subject: [PATCH] Added all required functionality for equipments and equipment handling --- Pipfile | 1 + Pipfile.lock | 10 +- equipment_tracker/api/urls.py | 3 +- equipment_tracker/config/settings.py | 4 +- equipment_tracker/db.sqlite3 | Bin 131072 -> 184320 bytes equipment_tracker/equipments/__init__.py | 0 equipment_tracker/equipments/admin.py | 5 + equipment_tracker/equipments/apps.py | 6 + .../equipments/migrations/0001_initial.py | 66 ++++++++ ...move_equipment_last_changed_by_and_more.py | 25 +++ .../migrations/0003_historicalequipment.py | 40 +++++ .../equipments/migrations/__init__.py | 0 equipment_tracker/equipments/models.py | 50 ++++++ equipment_tracker/equipments/serializers.py | 157 ++++++++++++++++++ equipment_tracker/equipments/tests.py | 3 + equipment_tracker/equipments/urls.py | 29 ++++ equipment_tracker/equipments/views.py | 89 ++++++++++ 17 files changed, 485 insertions(+), 3 deletions(-) create mode 100644 equipment_tracker/equipments/__init__.py create mode 100644 equipment_tracker/equipments/admin.py create mode 100644 equipment_tracker/equipments/apps.py create mode 100644 equipment_tracker/equipments/migrations/0001_initial.py create mode 100644 equipment_tracker/equipments/migrations/0002_remove_equipment_last_changed_by_and_more.py create mode 100644 equipment_tracker/equipments/migrations/0003_historicalequipment.py create mode 100644 equipment_tracker/equipments/migrations/__init__.py create mode 100644 equipment_tracker/equipments/models.py create mode 100644 equipment_tracker/equipments/serializers.py create mode 100644 equipment_tracker/equipments/tests.py create mode 100644 equipment_tracker/equipments/urls.py create mode 100644 equipment_tracker/equipments/views.py diff --git a/Pipfile b/Pipfile index 627e336..bf53dd8 100644 --- a/Pipfile +++ b/Pipfile @@ -14,6 +14,7 @@ drf-spectacular = {version = "*", extras = ["sidecar"]} django-extra-fields = "*" pillow = "*" psycopg2 = "*" +django-simple-history = "*" [dev-packages] diff --git a/Pipfile.lock b/Pipfile.lock index f1f704a..8120404 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "7ca25164f3d5c5501004130b514ab73101cc9d6937aa0af8356bf65a3cb354fe" + "sha256": "ebe508cba3dbd2fa271c39d69ab71cb95f5630e21875aea04ad9f6893ced1877" }, "pipfile-spec": 6, "requires": { @@ -254,6 +254,14 @@ "index": "pypi", "version": "==3.0.2" }, + "django-simple-history": { + "hashes": [ + "sha256:19bd1a87e1e2eba34dfd43eab1fcf2da5752221f343232f2372b2121c7e3b97d", + "sha256:992dcca3cddc0b67b470fc91f77292e2d2a6010d37c9eac3536e9d80e8754032" + ], + "index": "pypi", + "version": "==3.4.0" + }, "django-templated-mail": { "hashes": [ "sha256:8db807effebb42a532622e2d142dfd453dafcd0d7794c4c3332acb90656315f9", diff --git a/equipment_tracker/api/urls.py b/equipment_tracker/api/urls.py index 14fb12e..03edd51 100644 --- a/equipment_tracker/api/urls.py +++ b/equipment_tracker/api/urls.py @@ -1,5 +1,6 @@ from django.urls import path, include urlpatterns = [ - path('accounts/', include('accounts.urls')) + path('accounts/', include('accounts.urls')), + path('equipments/', include('equipments.urls')) ] diff --git a/equipment_tracker/config/settings.py b/equipment_tracker/config/settings.py index 86a6e26..cc422ea 100644 --- a/equipment_tracker/config/settings.py +++ b/equipment_tracker/config/settings.py @@ -64,11 +64,13 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'rest_framework', 'rest_framework_simplejwt', + 'simple_history', 'djoser', 'corsheaders', 'drf_spectacular', 'drf_spectacular_sidecar', - 'accounts' + 'accounts', + 'equipments', ] MIDDLEWARE = [ diff --git a/equipment_tracker/db.sqlite3 b/equipment_tracker/db.sqlite3 index 151391c1e3878bf8ec113c43d881832c7b9b3572..87da6db199c737d132b64699dfe3dde8dc390bf9 100644 GIT binary patch literal 184320 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 delta 1281 zcmb`FO>7%Q6vuaVV>`*(8JjdXV*Rn9Ax&j!&+hE5cU>a7`KULk6FW`XwDb_wm?)NL z?8vx|_>vtsAfeDkQ)#IqfBx+;-Lt@yPb^zcsDTg!E>81B+lg* zMM@5Z19a}^1>y^i0Kpj&Z}+mepUgZm^bj&cNy;c{2FXbSV-;(pAQ)~eD=JpWTY}`q z62&t4SrA=VHw+bH5{w)U9n7ukDw4=##GP8#bc9rLC4$^JGzrn@?<3faRg92K9*(Bn zSWytdWI3w2G1d@L$WHXQ8_Tq$PX3Cz-RLsvluXBDceJ#h/logs/', + views.EquipmentLogViewSet.as_view({'get': 'list'})), + # Last changed equipment + path('equipments/latest', views.LastUpdatedEquipmentViewSet.as_view()), + # Logs for all equipment instances + path('equipment_instances/logs', views.EquipmentInstancesLogsViewSet.as_view()), + # Logs for each equipment instance + path('equipment_instances//logs/', + views.EquipmentInstanceLogViewSet.as_view({'get': 'list'})), + # Last changed equipment instance + path('equipment_instances/latest', + views.LastUpdatedEquipmentInstanceViewSet.as_view()) +] diff --git a/equipment_tracker/equipments/views.py b/equipment_tracker/equipments/views.py new file mode 100644 index 0000000..b97306d --- /dev/null +++ b/equipment_tracker/equipments/views.py @@ -0,0 +1,89 @@ +from rest_framework.permissions import IsAuthenticated +from rest_framework import viewsets, generics +from .models import Equipment, EquipmentInstance +from . import serializers +from config.settings import DEBUG + +# -- Equipment Viewsets + + +class EquipmentViewSet(viewsets.ModelViewSet): + if (not DEBUG): + permission_classes = [IsAuthenticated] + serializer_class = serializers.EquipmentSerializer + queryset = Equipment.objects.all().order_by('-date_added') + +# For viewing all logs for all equipments + + +class EquipmentsLogsViewSet(generics.ListAPIView): + if (not DEBUG): + permission_classes = [IsAuthenticated] + serializer_class = serializers.EquipmentLogsSerializer + queryset = Equipment.history.all().order_by('-history_date') + +# For viewing logs per individual equipment + + +class EquipmentLogViewSet(viewsets.ReadOnlyModelViewSet): + if (not DEBUG): + permission_classes = [IsAuthenticated] + serializer_class = serializers.EquipmentLogSerializer + + def get_queryset(self): + equipment_id = self.kwargs['equipment_id'] + return Equipment.objects.filter(id=equipment_id) + +# Last changed equipment + + +class LastUpdatedEquipmentViewSet(generics.ListAPIView): + if (not DEBUG): + permission_classes = [IsAuthenticated] + serializer_class = serializers.EquipmentSerializer + queryset = Equipment.objects.all().order_by('-date_added') + + def get_queryset(self): + return super().get_queryset()[:1] + +# -- Equipment Instance Viewsets + + +class EquipmentInstanceViewSet(viewsets.ModelViewSet): + if (not DEBUG): + permission_classes = [IsAuthenticated] + serializer_class = serializers.EquipmentInstanceSerializer + queryset = EquipmentInstance.objects.all().order_by('-date_added') + +# For viewing all equipment instance logs + + +class EquipmentInstancesLogsViewSet(generics.ListAPIView): + if (not DEBUG): + permission_classes = [IsAuthenticated] + serializer_class = serializers.EquipmentInstanceLogsSerializer + queryset = EquipmentInstance.history.all().order_by('-history_date') + +# For viewing logs per individual equipment instance + + +class EquipmentInstanceLogViewSet(viewsets.ReadOnlyModelViewSet): + if (not DEBUG): + permission_classes = [IsAuthenticated] + serializer_class = serializers.EquipmentInstanceLogSerializer + + def get_queryset(self): + equipment_id = self.kwargs['equipment_id'] + return EquipmentInstance.objects.filter(id=equipment_id) + +# Last changed equipment instance + + +class LastUpdatedEquipmentInstanceViewSet(generics.ListAPIView): + if (not DEBUG): + permission_classes = [IsAuthenticated] + serializer_class = serializers.EquipmentInstanceSerializer + queryset = EquipmentInstance.objects.all().order_by('-date_added') + + def get_queryset(self): + return super().get_queryset()[:1]