diff --git a/docs/api.md b/docs/api.md index 2ed1cbce8..f4a16b264 100644 --- a/docs/api.md +++ b/docs/api.md @@ -257,11 +257,14 @@ The endpoint supports the following optional form fields: - `tags`: Similar to correspondent. Specify this multiple times to have multiple tags added to the document. - `owner`: An optional user ID to set as the owner. +- `archive_serial_number`: An optional archive serial number to set. -The endpoint will immediately return "OK" if the document consumption -process was started successfully. No additional status information about -the consumption process itself is available, since that happens in a -different process. +The endpoint will immediately return HTTP 200 if the document consumption +process was started successfully, with the UUID of the consumption task +as the data. No additional status information about +the consumption process itself is available immediately, since that happens in a +different process. Querying the tasks endpoint with the returned UUID will +provide information on the state of the consumption. ## API Versioning diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index a4199dd3d..d7feec7ef 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -691,6 +691,14 @@ class PostDocumentSerializer(serializers.Serializer): required=False, ) + archive_serial_number = serializers.IntegerField( + label="ASN", + write_only=True, + required=False, + min_value=Document.ARCHIVE_SERIAL_NUMBER_MIN, + max_value=Document.ARCHIVE_SERIAL_NUMBER_MAX, + ) + def validate_document(self, document): document_data = document.file.read() mime_type = magic.from_buffer(document_data, mime=True) diff --git a/src/documents/tasks.py b/src/documents/tasks.py index c3064cc10..403025d08 100644 --- a/src/documents/tasks.py +++ b/src/documents/tasks.py @@ -4,6 +4,7 @@ import os import shutil import uuid from pathlib import Path +from typing import Optional from typing import Type import dateutil.parser @@ -97,6 +98,7 @@ def consume_file( task_id=None, override_created=None, override_owner_id=None, + override_archive_serial_num: Optional[int] = None, ): path = Path(path).resolve() @@ -207,7 +209,7 @@ def consume_file( override_tag_ids=override_tag_ids, task_id=task_id, override_created=override_created, - override_asn=asn, + override_asn=override_archive_serial_num or asn, override_owner_id=override_owner_id, ) diff --git a/src/documents/tests/test_api.py b/src/documents/tests/test_api.py index 3d3ab9bbc..1b6e5c157 100644 --- a/src/documents/tests/test_api.py +++ b/src/documents/tests/test_api.py @@ -1318,6 +1318,34 @@ class TestDocumentApi(DirectoriesMixin, APITestCase): self.assertEqual(kwargs["override_created"], created) + @mock.patch("documents.views.consume_file.delay") + def test_upload_with_asn(self, m): + + m.return_value = celery.result.AsyncResult(id=str(uuid.uuid4())) + + with open( + os.path.join(os.path.dirname(__file__), "samples", "simple.pdf"), + "rb", + ) as f: + response = self.client.post( + "/api/documents/post_document/", + {"document": f, "archive_serial_number": 500}, + ) + + self.assertEqual(response.status_code, 200) + + m.assert_called_once() + + args, kwargs = m.call_args + file_path = Path(args[0]) + self.assertEqual(file_path.name, "simple.pdf") + self.assertIn(Path(settings.SCRATCH_DIR), file_path.parents) + self.assertIsNone(kwargs["override_title"]) + self.assertIsNone(kwargs["override_correspondent_id"]) + self.assertIsNone(kwargs["override_document_type_id"]) + self.assertIsNone(kwargs["override_tag_ids"]) + self.assertEqual(500, kwargs["override_archive_serial_num"]) + def test_get_metadata(self): doc = Document.objects.create( title="test", @@ -3580,7 +3608,7 @@ class TestTasks(DirectoriesMixin, APITestCase): self.assertEqual(returned_data["task_file_name"], "anothertest.pdf") -class TestApiUser(APITestCase): +class TestApiUser(DirectoriesMixin, APITestCase): ENDPOINT = "/api/users/" def setUp(self): @@ -3720,7 +3748,7 @@ class TestApiUser(APITestCase): self.assertNotEqual(returned_user2.password, initial_password) -class TestApiGroup(APITestCase): +class TestApiGroup(DirectoriesMixin, APITestCase): ENDPOINT = "/api/groups/" def setUp(self): diff --git a/src/documents/views.py b/src/documents/views.py index 89a30636e..7305073f5 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -667,6 +667,7 @@ class PostDocumentView(GenericAPIView): title = serializer.validated_data.get("title") created = serializer.validated_data.get("created") owner_id = serializer.validated_data.get("owner") + archive_serial_number = serializer.validated_data.get("archive_serial_number") t = int(mktime(datetime.now().timetuple())) @@ -692,6 +693,7 @@ class PostDocumentView(GenericAPIView): task_id=task_id, override_created=created, override_owner_id=owner_id, + override_archive_serial_num=archive_serial_number, ) return Response(async_task.id)