Repository: paperless-ngx/paperless-ngx

Issue:
[BUG] PDF rotate leads to bulk_update_documents() error
### Description

I tried the new Actions->Rotate feature in 2.7.0. The UI shows the "Rotate confirm" window, I choose the proper rotation, and click on Proceed. It says "Rotation will begin in the background. Close and re-open the document after the operation has completed to see the changes."

The operation doesn't complete. I wait, reopen the document, and it still shows the wrong rotation.

(probably not related: this document is likely not to have any content that can be OCRed - it contains hand-written notes by a child)

The log files show the following error:
```
""bulk_update_documents() got multiple values for argument 'document_ids'")
webserver-1  | Traceback (most recent call last):"
```

I can confirm though that the original document was modified, at least, its timestamp was updated. When I manually view the document in a PDF viewer, it still shows the wrong rotation.

### Steps to reproduce

1. Actions->Rotate
2. Proceed
3. Re-open document

### Webserver logs

```bash
webserver-1  | [2024-04-06 11:33:38,998] [INFO] [paperless.bulk_edit] Attempting to rotate 1 documents by 270 degrees.
webserver-1  | [2024-04-06 11:33:39,027] [INFO] [paperless.bulk_edit] Rotated document 5021 by 270 degrees
webserver-1  | [2024-04-06 11:33:39,040] [INFO] [celery.worker.strategy] Task documents.tasks.update_document_archive_file[9a078839-4229-43bf-95dd-7bc76680efc4] received
webserver-1  | [2024-04-06 11:33:39,084] [INFO] [paperless.parsing.tesseract] pdftotext exited 0
webserver-1  | [2024-04-06 11:33:39,269] [INFO] [ocrmypdf._pipelines.ocr] Start processing 2 pages concurrently
webserver-1  | [2024-04-06 11:33:40,298] [INFO] [ocrmypdf._pipeline] with existing rotation ⇨, page is facing ⇩, confidence 1.38 - confidence too low to rotate
webserver-1  | [2024-04-06 11:33:40,341] [INFO] [ocrmypdf._pipeline] with existing rotation ⇨, page is facing ⇧, confidence 0.43 - no change
webserver-1  | [2024-04-06 11:33:46,640] [INFO] [ocrmypdf._pipelines.ocr] Postprocessing...
webserver-1  | [2024-04-06 11:33:47,628] [INFO] [ocrmypdf._pipeline] Image optimization ratio: 1.39 savings: 28.0%
webserver-1  | [2024-04-06 11:33:47,628] [INFO] [ocrmypdf._pipeline] Total file size ratio: 0.93 savings: -7.4%
webserver-1  | [2024-04-06 11:33:47,630] [INFO] [ocrmypdf._pipelines._common] Output file is a PDF/A-2B (as expected)
webserver-1  | [2024-04-06 11:33:48,058] [WARNING] [paperless.parsing.tesseract] Encountered an error while running OCR: No text was found in the original document. Attempting force OCR to get the text.
webserver-1  | [2024-04-06 11:33:48,136] [INFO] [ocrmypdf._pipelines.ocr] Start processing 2 pages concurrently
webserver-1  | [2024-04-06 11:33:49,156] [INFO] [ocrmypdf._pipeline] with existing rotation ⇨, page is facing ⇩, confidence 1.38 - confidence too low to rotate
webserver-1  | [2024-04-06 11:33:49,206] [INFO] [ocrmypdf._pipeline] with existing rotation ⇨, page is facing ⇧, confidence 0.43 - no change
webserver-1  | [2024-04-06 11:33:55,548] [INFO] [ocrmypdf._pipelines.ocr] Postprocessing...
webserver-1  | [2024-04-06 11:33:56,532] [INFO] [ocrmypdf._pipeline] Image optimization ratio: 1.39 savings: 28.0%
webserver-1  | [2024-04-06 11:33:56,532] [INFO] [ocrmypdf._pipeline] Total file size ratio: 0.93 savings: -7.4%
webserver-1  | [2024-04-06 11:33:56,533] [INFO] [ocrmypdf._pipelines._common] Output file is a PDF/A-2B (as expected)
webserver-1  | [2024-04-06 11:33:56,957] [WARNING] [paperless.parsing.tesseract] No text was found in /usr/src/paperless/media/documents/originals/2022/School/20220525_102026_scan_006629.pdf, the content will be empty.
webserver-1  | [2024-04-06 11:33:57,827] [INFO] [paperless.parsing] convert exited 0
webserver-1  | [2024-04-06 11:33:57,925] [ERROR] [django_celery_results.backends.database] Chord '5e848aea-d35a-4ce2-8ca0-5b56ac3c78ee' raised: TypeError("bulk_update_documents() got multiple values for argument 'document_ids'")
webserver-1  | Traceback (most recent call last):
webserver-1  |   File "/usr/local/lib/python3.11/site-packages/django_celery_results/backends/database.py", line 303, in trigger_callback
webserver-1  |     callback.delay(ret)
webserver-1  |   File "/usr/local/lib/python3.11/site-packages/celery/canvas.py", line 353, in delay
webserver-1  |     return self.apply_async(partial_args, partial_kwargs)
webserver-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
webserver-1  |   File "/usr/local/lib/python3.11/site-packages/celery/canvas.py", line 400, in apply_async
webserver-1  |     return _apply(args, kwargs, **options)
webserver-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
webserver-1  |   File "/usr/local/lib/python3.11/site-packages/celery/app/task.py", line 559, in apply_async
webserver-1  |     check_arguments(*(args or ()), **(kwargs or {}))
webserver-1  | TypeError: bulk_update_documents() got multiple values for argument 'document_ids'
webserver-1  | [2024-04-06 11:33:57,931] [INFO] [celery.app.trace] Task documents.tasks.update_document_archive_file[9a078839-4229-43bf-95dd-7bc76680efc4] succeeded in 18.889272468863055s: None
```


### Browser logs

_No response_

### Paperless-ngx version

2.7.0

### Host OS

Debian Bookworm / amd64

### Installation method

Docker - official image

### Browser

Chrome

### Configuration changes

_No response_

### Other

_No response_

### Please confirm the following

- [X] I believe this issue is a bug that affects all users of Paperless-ngx, not something specific to my installation.
- [X] I have already searched for relevant existing issues and discussions before opening this report.
- [X] I have updated the title field above with a concise description.


Discussion:
~It would be useful if you could reproduce the error while _not_ also consuming a document~

Nevermind, that's just the re-creation of the archive file

Resolving patch:
diff --git a/src/documents/bulk_edit.py b/src/documents/bulk_edit.py
--- a/src/documents/bulk_edit.py
+++ b/src/documents/bulk_edit.py
@@ -195,7 +195,7 @@ def rotate(doc_ids: list[int], degrees: int):
             logger.exception(f"Error rotating document {doc.id}: {e}")
 
     if len(affected_docs) > 0:
-        bulk_update_task = bulk_update_documents.s(document_ids=affected_docs)
+        bulk_update_task = bulk_update_documents.si(document_ids=affected_docs)
         chord(header=rotate_tasks, body=bulk_update_task).delay()
 
     return "OK"


Test patch:
diff --git a/src/documents/tests/test_bulk_edit.py b/src/documents/tests/test_bulk_edit.py
--- a/src/documents/tests/test_bulk_edit.py
+++ b/src/documents/tests/test_bulk_edit.py
@@ -463,7 +463,7 @@ def test_split_with_errors(self, mock_save_pdf, mock_consume_file):
 
         mock_consume_file.assert_not_called()
 
-    @mock.patch("documents.tasks.bulk_update_documents.s")
+    @mock.patch("documents.tasks.bulk_update_documents.si")
     @mock.patch("documents.tasks.update_document_archive_file.s")
     @mock.patch("celery.chord.delay")
     def test_rotate(self, mock_chord, mock_update_document, mock_update_documents):
@@ -482,7 +482,7 @@ def test_rotate(self, mock_chord, mock_update_document, mock_update_documents):
         mock_chord.assert_called_once()
         self.assertEqual(result, "OK")
 
-    @mock.patch("documents.tasks.bulk_update_documents.s")
+    @mock.patch("documents.tasks.bulk_update_documents.si")
     @mock.patch("documents.tasks.update_document_archive_file.s")
     @mock.patch("pikepdf.Pdf.save")
     def test_rotate_with_error(
@@ -510,7 +510,7 @@ def test_rotate_with_error(
             self.assertIn(expected_str, error_str)
             mock_update_archive_file.assert_not_called()
 
-    @mock.patch("documents.tasks.bulk_update_documents.s")
+    @mock.patch("documents.tasks.bulk_update_documents.si")
     @mock.patch("documents.tasks.update_document_archive_file.s")
     @mock.patch("celery.chord.delay")
     def test_rotate_non_pdf(