diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index 87c6657da..3a7f505db 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -646,10 +646,26 @@ class CustomFieldInstanceSerializer(serializers.ModelSerializer): custom_field.data_type, ) + api_version = int( + self.context.get("request").version + if self.context.get("request") + else settings.REST_FRAMEWORK["ALLOWED_VERSIONS"][-1], + ) + if custom_field.data_type == CustomField.FieldDataType.DOCUMENTLINK: # prior to update so we can look for any docs that are going to be removed self.reflect_doclinks(document, custom_field, validated_data["value"]) + if ( + custom_field.data_type == CustomField.FieldDataType.SELECT + and api_version < 7 + ): + # Convert the index of the option in the field.extra_data["select_options"] list + # to the actual value + validated_data["value"] = custom_field.extra_data["select_options"][ + validated_data["value"] + ]["id"] + # Actually update or create the instance, providing the value # to fill in the correct attribute based on the type instance, _ = CustomFieldInstance.objects.update_or_create( @@ -660,6 +676,21 @@ class CustomFieldInstanceSerializer(serializers.ModelSerializer): return instance def get_value(self, obj: CustomFieldInstance): + api_version = int( + self.context.get("request").version + if self.context.get("request") + else settings.REST_FRAMEWORK["ALLOWED_VERSIONS"][-1], + ) + if api_version < 7 and obj.field.data_type == CustomField.FieldDataType.SELECT: + # return the index of the option in the field.extra_data["select_options"] list + return next( + ( + idx + for idx, option in enumerate(obj.field.extra_data["select_options"]) + if option["id"] == obj.value + ), + None, + ) return obj.value def validate(self, data): @@ -958,6 +989,12 @@ class DocumentSerializer( ): kwargs["full_perms"] = True + self.api_version = int( + context.get("request").version + if context.get("request") + else settings.REST_FRAMEWORK["ALLOWED_VERSIONS"][-1], + ) + super().__init__(*args, **kwargs) class Meta: diff --git a/src/documents/tests/test_api_custom_fields.py b/src/documents/tests/test_api_custom_fields.py index cd15de006..e4a261ff7 100644 --- a/src/documents/tests/test_api_custom_fields.py +++ b/src/documents/tests/test_api_custom_fields.py @@ -328,6 +328,60 @@ class TestCustomFieldsAPI(DirectoriesMixin, APITestCase): ], ) + def test_custom_field_select_value_old_version(self): + """ + GIVEN: + - Existing document with custom field select + WHEN: + - API post request is made to add the field for document with api version header < 7 + - API get request is made for document with api version header < 7 + THEN: + - The select value is returned in the old format, the index of the option + """ + custom_field_select = CustomField.objects.create( + name="Select Field", + data_type=CustomField.FieldDataType.SELECT, + extra_data={ + "select_options": [ + {"label": "Option 1", "id": "abc-123"}, + {"label": "Option 2", "id": "def-456"}, + ], + }, + ) + + doc = Document.objects.create( + title="WOW", + content="the content", + checksum="123", + mime_type="application/pdf", + ) + CustomFieldInstance.objects.create( + document=doc, + field=custom_field_select, + value_select="abc-123", + ) + + resp = self.client.patch( + f"/api/documents/{doc.id}/", + headers={"Accept": "application/json; version=6"}, + data={ + "custom_fields": [ + {"field": custom_field_select.id, "value": 0}, + ], + }, + ) + self.assertEqual(resp.status_code, status.HTTP_200_OK) + self.assertEqual(doc.custom_fields.first().value, "abc-123") + + resp = self.client.get( + f"/api/documents/{doc.id}/", + headers={"Accept": "application/json; version=6"}, + ) + self.assertEqual(resp.status_code, status.HTTP_200_OK) + + data = resp.json() + self.assertEqual(data["custom_fields"][0]["value"], 0) + def test_create_custom_field_monetary_validation(self): """ GIVEN: