diff --git a/apiserver/apiserver/api/models.py b/apiserver/apiserver/api/models.py index 66fee6a..bd43ce0 100644 --- a/apiserver/apiserver/api/models.py +++ b/apiserver/apiserver/api/models.py @@ -250,6 +250,24 @@ class PinballScore(models.Model): def __str__(self): return str(self.started_at) +class StorageSpace(models.Model): + user = models.ForeignKey(User, related_name='storage', blank=True, null=True, on_delete=models.SET_NULL) + + shelf_id = models.TextField(unique=True) + location = models.TextField(choices=[ + ('member_shelves', 'Member Shelves'), + ('lockers', 'Lockers'), + ('large_project_storage', 'Large Project Storage'), + ]) + memo = models.TextField(blank=True) + + history = HistoricalRecords() + + MY_FIELDS = ['shelf_id', 'location', 'user', 'id'] + def __str__(self): + return self.shelf_id + + class HistoryIndex(models.Model): content_type = models.ForeignKey(ContentType, null=True, on_delete=models.SET_NULL) object_id = models.PositiveIntegerField() diff --git a/apiserver/apiserver/api/serializers.py b/apiserver/apiserver/api/serializers.py index e576bb4..a4742e8 100644 --- a/apiserver/apiserver/api/serializers.py +++ b/apiserver/apiserver/api/serializers.py @@ -185,6 +185,7 @@ class TransactionSerializer(serializers.ModelSerializer): class OtherMemberSerializer(serializers.ModelSerializer): pinball_score = serializers.IntegerField(required=False) last_name = serializers.SerializerMethodField() + storage = serializers.SerializerMethodField() class Meta: model = models.Member @@ -198,6 +199,7 @@ class OtherMemberSerializer(serializers.ModelSerializer): 'photo_small', 'public_bio', 'pinball_score', + 'storage', ] def get_last_name(self, obj): @@ -206,9 +208,15 @@ class OtherMemberSerializer(serializers.ModelSerializer): else: return '' + def get_storage(self, obj): + serializer = SimpleStorageSpaceSerializer(data=obj.user.storage, many=True) + serializer.is_valid() + return serializer.data + # vetted member viewing other members class VettedOtherMemberSerializer(serializers.ModelSerializer): pinball_score = serializers.IntegerField(required=False) + storage = serializers.SerializerMethodField() class Meta: model = models.Member @@ -223,8 +231,14 @@ class VettedOtherMemberSerializer(serializers.ModelSerializer): 'photo_large', 'public_bio', 'pinball_score', + 'storage', ] + def get_storage(self, obj): + serializer = StorageSpaceSerializer(data=obj.user.storage, many=True) + serializer.is_valid() + return serializer.data + # member viewing his own details class MemberSerializer(serializers.ModelSerializer): @@ -501,6 +515,43 @@ class CardSerializer(serializers.ModelSerializer): return obj.user.member.id +class SimpleStorageSpaceSerializer(serializers.ModelSerializer): + class Meta: + model = models.StorageSpace + fields = '__all__' + + +class StorageSpaceSerializer(serializers.ModelSerializer): + member = serializers.SerializerMethodField() + member_id = serializers.IntegerField(write_only=True, required=False) + + class Meta: + model = models.StorageSpace + fields = '__all__' + read_only_fields = [ + 'id', + 'shelf_id', + 'location', + ] + + def update(self, instance, validated_data): + member_id = self.initial_data.get('member_id', None) + if member_id: + member = get_object_or_404(models.Member, id=self.initial_data['member_id']) + validated_data['user'] = member.user + else: + validated_data['user'] = None + + return super().update(instance, validated_data) + + def get_member(self, obj): + if obj.user: + serializer = OtherMemberSerializer(obj.user.member) + return serializer.data + else: + return None + + class TrainingSerializer(serializers.ModelSerializer): attendance_status = serializers.ChoiceField([ 'Waiting for payment', diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index f24ffe7..e46c133 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -1050,6 +1050,7 @@ class UsageViewSet(Base): return response + class InterestViewSet(Base, Retrieve, Create): permission_classes = [AllowMetadata | IsAuthenticated] queryset = models.Interest.objects.all() @@ -1302,6 +1303,13 @@ class PinballViewSet(Base): return Response(200) + +class StorageSpaceViewSet(Base, List, Retrieve, Update): + permission_classes = [AllowMetadata | IsAdmin] + queryset = models.StorageSpace.objects.all() + serializer_class = serializers.StorageSpaceSerializer + + class RegistrationView(RegisterView): serializer_class = serializers.MyRegisterSerializer diff --git a/apiserver/apiserver/urls.py b/apiserver/apiserver/urls.py index fc13f9b..2ee92ae 100644 --- a/apiserver/apiserver/urls.py +++ b/apiserver/apiserver/urls.py @@ -20,6 +20,7 @@ router.register(r'courses', views.CourseViewSet, basename='course') router.register(r'history', views.HistoryViewSet, basename='history') router.register(r'vetting', views.VettingViewSet, basename='vetting') router.register(r'pinball', views.PinballViewSet, basename='pinball') +router.register(r'storage', views.StorageSpaceViewSet, basename='storage') router.register(r'sessions', views.SessionViewSet, basename='session') router.register(r'training', views.TrainingViewSet, basename='training') router.register(r'interest', views.InterestViewSet, basename='interest') diff --git a/apiserver/generate_storage_spaces.py b/apiserver/generate_storage_spaces.py new file mode 100755 index 0000000..fe58cf8 --- /dev/null +++ b/apiserver/generate_storage_spaces.py @@ -0,0 +1,249 @@ +import django, sys, os +os.environ['DJANGO_SETTINGS_MODULE'] = 'apiserver.settings' +django.setup() + +from apiserver.api import models + +SHELVES = [ + ('A1A', 0), + ('A1B', 0), + ('A1C', 0), + ('A1D', 0), + ('A1E', 0), + ('A2A', 0), + ('A2B', 0), + ('A2C', 0), + ('A2D', 0), + ('A2E', 0), + ('A3A', 0), + ('A3B', 0), + ('A3C', 0), + ('A3D', 0), + ('A3E', 0), + ('A4A', 0), + ('A4B', 0), + ('A4C', 0), + ('A4D', 0), + ('A4E', 0), + ('A5A', 0), + ('A5B', 0), + ('A5C', 0), + ('A5D', 0), + ('A5E', 0), + ('A6A', 0), + ('A6B', 0), + ('A6C', 0), + ('A6D', 0), + ('A6E', 0), + ('A7A', 0), + ('A7B', 0), + ('A7C', 0), + ('A7D', 0), + ('A7E', 0), + ('B1A', 0), + ('B1B', 0), + ('B1C', 0), + ('B1D', 0), + ('B1E', 0), + ('B2A', 0), + ('B2B', 0), + ('B2C', 0), + ('B2D', 0), + ('B2E', 0), + ('B3A', 0), + ('B3B', 0), + ('B3C', 0), + ('B3D', 0), + ('B3E', 0), + ('B4A', 0), + ('B4B', 0), + ('B4C', 0), + ('B4D', 0), + ('B4E', 0), + ('B5A', 0), + ('B5B', 0), + ('B5C', 0), + ('B5D', 0), + ('B5E', 0), + ('B6A', 0), + ('B6B', 0), + ('B6C', 0), + ('B6D', 0), + ('B6E', 0), + ('C1A', 0), + ('C1B', 0), + ('C1C', 0), + ('C1D', 0), + ('C1E', 0), + ('C2A', 0), + ('C2B', 0), + ('C2C', 0), + ('C2D', 0), + ('C2E', 0), + ('C3A', 0), + ('C3B', 0), + ('C3C', 0), + ('C3D', 0), + ('C3E', 0), + ('C4A', 0), + ('C4B', 0), + ('C4C', 0), + ('C4D', 0), + ('C4E', 0), + ('C5A', 0), + ('C5B', 0), + ('C5C', 0), + ('C5D', 0), + ('C5E', 0), + ('C6A', 0), + ('C6B', 0), + ('C6C', 0), + ('C6D', 0), + ('C6E', 0), + ('C6F', 6), + ('C6G', 7), + ('D1A', 0), + ('D1B', 0), + ('D1C', 0), + ('D1D', 0), + ('D1E', 0), + ('D2A', 0), + ('D2B', 0), + ('D2C', 0), + ('D2D', 0), + ('D2E', 0), + ('D3A', 0), + ('D3B', 0), + ('D3C', 0), + ('D3D', 0), + ('D3E', 0), + ('D4A', 0), + ('D4B', 0), + ('D4C', 0), + ('D4D', 0), + ('D4E', 0), + ('D5A', 0), + ('D5B', 0), + ('D5C', 0), + ('D5D', 0), + ('D5E', 0), + ('D6A', 0), + ('D6B', 0), + ('D6C', 0), + ('D6D', 0), + ('D6E', 0), + ('D7A', 33), + ('D7B', 34), + ('D7C', 35), + ('D7D', 36), + ('E1A', 0), + ('E1B', 0), + ('E1C', 0), + ('E1D', 0), + ('E1E', 0), + ('E2A', 0), + ('E2B', 0), + ('E2C', 0), + ('E2D', 0), + ('E2E', 0), + ('E3A', 0), + ('E3B', 0), + ('E3C', 0), + ('E3D', 0), + ('E3E', 0), + ('E4A', 0), + ('E4B', 0), + ('E4C', 0), + ('E4D', 0), + ('E4E', 0), + ('E5A', 0), + ('E5B', 0), + ('E5C', 0), + ('E5D', 0), + ('E5E', 0), + ('E6A', 0), + ('E6B', 0), + ('E6C', 0), + ('E6D', 0), + ('E6E', 0), + ('E6F', 69), + ('E6G', 70), + ('E6H', 71), + ('E6I', 72), + ('E6J', 291), + ('E6K', 292), + ('E6L', 293), + ('E6M', 294), + ('E6N', 331), + ('E6O', 332), + ('E6P', 333), + ('E6Q', 334), + ('F1A', 0), + ('F1B', 0), + ('F1C', 0), + ('F2A', 0), + ('F2B', 0), + ('F2C', 0), + ('F3A', 0), + ('F3B', 0), + ('F3C', 0), + ('F4A', 0), + ('F4B', 0), + ('F4C', 0), + ('F5A', 0), + ('F5B', 0), + ('F5C', 0), + ('F6A', 0), + ('F6B', 0), + ('F6C', 0), + ('F6D', 0), + ('F6E', 0), + ('G1A', 0), + ('G1B', 0), + ('G1C', 0), + ('G2A', 0), + ('G2B', 0), + ('G2C', 0), + ('G3A', 0), + ('G3B', 0), + ('G3C', 0), + ('G4A', 0), + ('G4B', 0), + ('G4C', 0), + ('G5A', 0), + ('G5B', 0), + ('G5C', 0), + ('G6A', 0), + ('G6B', 0), + ('G6C', 0), + ('G6D', 0), + ('G6E', 0), + ('H1A', 1), + ('H2A', 0), + ('H2B', 0), + ('H2C', 0), + ('H2D', 0), + ('H3A', 0), + ('H3B', 0), + ('H3C', 0), + ('H3D', 0), + ('H4A', 0), + ('H4B', 0), + ('H4C', 0), + ('H4D', 0), + ('H5A', 0), + ('H5B', 0), + ('H5C', 0), + ('H5D', 0), + ('H6A', 0), + ('H6B', 0), + ('H6C', 0), + ('H6D', 0), +] + +for shelf in SHELVES: + models.StorageSpace.objects.create( + shelf_id=shelf[0], + location='lockers' if shelf[1] else 'member_shelves', + ) +