]> git.ipfire.org Git - thirdparty/paperless-ngx.git/commitdiff
Allow setting the ASN on document upload
authorTrenton Holmes <797416+stumpylog@users.noreply.github.com>
Mon, 20 Feb 2023 00:38:34 +0000 (16:38 -0800)
committerTrenton H <797416+stumpylog@users.noreply.github.com>
Mon, 20 Feb 2023 15:56:37 +0000 (07:56 -0800)
docs/api.md
src/documents/serialisers.py
src/documents/tasks.py
src/documents/tests/test_api.py
src/documents/views.py

index 2ed1cbce8355e7d4a4e3861498d232bad1169db7..f4a16b2643de3249efbc902c28e0e9470ed0e63f 100644 (file)
@@ -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.
-
-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.
+- `archive_serial_number`: An optional archive serial number to set.
+
+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
 
index a4199dd3dbc697130fa749e015019faac18b4070..d7feec7efe81b1f55857ec7df15efa7dc19fdb26 100644 (file)
@@ -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)
index c3064cc10fbce547a0cecfecd67176592312277d..403025d0866f504730ea9b5f764350acf45d3e38 100644 (file)
@@ -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,
     )
 
index 3d3ab9bbc8cefeb0ecdfdc5f995bf15414b5e637..1b6e5c157c2c5d5b9fa824bd071aebc4183862af 100644 (file)
@@ -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):
index 89a30636e400e7355122ee5e4776aead53e6bc62..7305073f57c4fc078ec9b0b4e580035853749410 100644 (file)
@@ -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)