mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-28 03:46:06 -05:00 
			
		
		
		
	Allow setting the ASN on document upload
This commit is contained in:
		 Trenton Holmes
					Trenton Holmes
				
			
				
					committed by
					
						 Trenton H
						Trenton H
					
				
			
			
				
	
			
			
			 Trenton H
						Trenton H
					
				
			
						parent
						
							d0773874e5
						
					
				
				
					commit
					96e5e9b67c
				
			
							
								
								
									
										11
									
								
								docs/api.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								docs/api.md
									
									
									
									
									
								
							| @@ -257,11 +257,14 @@ The endpoint supports the following optional form fields: | |||||||
| - `tags`: Similar to correspondent. Specify this multiple times to | - `tags`: Similar to correspondent. Specify this multiple times to | ||||||
|   have multiple tags added to the document. |   have multiple tags added to the document. | ||||||
| - `owner`: An optional user ID to set as the owner. | - `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 | The endpoint will immediately return HTTP 200 if the document consumption | ||||||
| process was started successfully. No additional status information about | process was started successfully, with the UUID of the consumption task | ||||||
| the consumption process itself is available, since that happens in a | as the data. No additional status information about | ||||||
| different process. | 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 | ## API Versioning | ||||||
|  |  | ||||||
|   | |||||||
| @@ -691,6 +691,14 @@ class PostDocumentSerializer(serializers.Serializer): | |||||||
|         required=False, |         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): |     def validate_document(self, document): | ||||||
|         document_data = document.file.read() |         document_data = document.file.read() | ||||||
|         mime_type = magic.from_buffer(document_data, mime=True) |         mime_type = magic.from_buffer(document_data, mime=True) | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ import os | |||||||
| import shutil | import shutil | ||||||
| import uuid | import uuid | ||||||
| from pathlib import Path | from pathlib import Path | ||||||
|  | from typing import Optional | ||||||
| from typing import Type | from typing import Type | ||||||
|  |  | ||||||
| import dateutil.parser | import dateutil.parser | ||||||
| @@ -97,6 +98,7 @@ def consume_file( | |||||||
|     task_id=None, |     task_id=None, | ||||||
|     override_created=None, |     override_created=None, | ||||||
|     override_owner_id=None, |     override_owner_id=None, | ||||||
|  |     override_archive_serial_num: Optional[int] = None, | ||||||
| ): | ): | ||||||
|  |  | ||||||
|     path = Path(path).resolve() |     path = Path(path).resolve() | ||||||
| @@ -207,7 +209,7 @@ def consume_file( | |||||||
|         override_tag_ids=override_tag_ids, |         override_tag_ids=override_tag_ids, | ||||||
|         task_id=task_id, |         task_id=task_id, | ||||||
|         override_created=override_created, |         override_created=override_created, | ||||||
|         override_asn=asn, |         override_asn=override_archive_serial_num or asn, | ||||||
|         override_owner_id=override_owner_id, |         override_owner_id=override_owner_id, | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1318,6 +1318,34 @@ class TestDocumentApi(DirectoriesMixin, APITestCase): | |||||||
|  |  | ||||||
|         self.assertEqual(kwargs["override_created"], created) |         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): |     def test_get_metadata(self): | ||||||
|         doc = Document.objects.create( |         doc = Document.objects.create( | ||||||
|             title="test", |             title="test", | ||||||
| @@ -3580,7 +3608,7 @@ class TestTasks(DirectoriesMixin, APITestCase): | |||||||
|         self.assertEqual(returned_data["task_file_name"], "anothertest.pdf") |         self.assertEqual(returned_data["task_file_name"], "anothertest.pdf") | ||||||
|  |  | ||||||
|  |  | ||||||
| class TestApiUser(APITestCase): | class TestApiUser(DirectoriesMixin, APITestCase): | ||||||
|     ENDPOINT = "/api/users/" |     ENDPOINT = "/api/users/" | ||||||
|  |  | ||||||
|     def setUp(self): |     def setUp(self): | ||||||
| @@ -3720,7 +3748,7 @@ class TestApiUser(APITestCase): | |||||||
|         self.assertNotEqual(returned_user2.password, initial_password) |         self.assertNotEqual(returned_user2.password, initial_password) | ||||||
|  |  | ||||||
|  |  | ||||||
| class TestApiGroup(APITestCase): | class TestApiGroup(DirectoriesMixin, APITestCase): | ||||||
|     ENDPOINT = "/api/groups/" |     ENDPOINT = "/api/groups/" | ||||||
|  |  | ||||||
|     def setUp(self): |     def setUp(self): | ||||||
|   | |||||||
| @@ -667,6 +667,7 @@ class PostDocumentView(GenericAPIView): | |||||||
|         title = serializer.validated_data.get("title") |         title = serializer.validated_data.get("title") | ||||||
|         created = serializer.validated_data.get("created") |         created = serializer.validated_data.get("created") | ||||||
|         owner_id = serializer.validated_data.get("owner") |         owner_id = serializer.validated_data.get("owner") | ||||||
|  |         archive_serial_number = serializer.validated_data.get("archive_serial_number") | ||||||
|  |  | ||||||
|         t = int(mktime(datetime.now().timetuple())) |         t = int(mktime(datetime.now().timetuple())) | ||||||
|  |  | ||||||
| @@ -692,6 +693,7 @@ class PostDocumentView(GenericAPIView): | |||||||
|             task_id=task_id, |             task_id=task_id, | ||||||
|             override_created=created, |             override_created=created, | ||||||
|             override_owner_id=owner_id, |             override_owner_id=owner_id, | ||||||
|  |             override_archive_serial_num=archive_serial_number, | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|         return Response(async_task.id) |         return Response(async_task.id) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user