mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-04-02 13:45:10 -05:00
Fix: Document history could include extra fields (#6989)
* Fixes creation of a custom field being included in a document's history even if not attached * Show custom field creation in UI --------- Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
This commit is contained in:
parent
fa7a5451db
commit
61485b0f1d
@ -27,31 +27,33 @@
|
||||
}
|
||||
<span class="badge bg-secondary ms-auto" [class.bg-primary]="entry.action === AuditLogAction.Create">{{ entry.action | titlecase }}</span>
|
||||
</div>
|
||||
@if (entry.action === AuditLogAction.Update) {
|
||||
<ul class="mt-2">
|
||||
@for (change of entry.changes | keyvalue; track change.key) {
|
||||
@if (change.value["type"] === 'm2m') {
|
||||
<li>
|
||||
<span class="fst-italic">{{ change.value["operation"] | titlecase }}</span>
|
||||
<span>{{ change.key | titlecase }}</span>:
|
||||
<code class="text-primary">{{ change.value["objects"].join(', ') }}</code>
|
||||
</li>
|
||||
}
|
||||
@else if (change.value["type"] === 'custom_field') {
|
||||
<li>
|
||||
<span>{{ change.value["field"] }}</span>:
|
||||
<code class="text-primary">{{ change.value["value"] }}</code>
|
||||
</li>
|
||||
}
|
||||
@else {
|
||||
<li>
|
||||
<span>{{ change.key | titlecase }}</span>:
|
||||
<code class="text-primary">{{ change.value[1] }}</code>
|
||||
</li>
|
||||
}
|
||||
<ul class="mt-2">
|
||||
@for (change of entry.changes | keyvalue; track change.key) {
|
||||
@if (change.value["type"] === 'm2m') {
|
||||
<li>
|
||||
<span class="fst-italic">{{ change.value["operation"] | titlecase }}</span>
|
||||
<span>{{ change.key | titlecase }}</span>:
|
||||
<code class="text-primary">{{ change.value["objects"].join(', ') }}</code>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
@else if (change.value["type"] === 'custom_field') {
|
||||
<li>
|
||||
<span>{{ change.value["field"] }}</span>:
|
||||
<code class="text-primary">{{ change.value["value"] }}</code>
|
||||
</li>
|
||||
}
|
||||
@else {
|
||||
<li>
|
||||
<span>{{ change.key | titlecase }}</span>:
|
||||
@if (change.key === 'content') {
|
||||
<code class="text-primary">{{ change.value[1]?.substring(0,100) }}...</code>
|
||||
} @else {
|
||||
<code class="text-primary">{{ change.value[1] }}</code>
|
||||
}
|
||||
</li>
|
||||
}
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
}
|
||||
}
|
||||
|
@ -366,6 +366,16 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
|
||||
data_type=CustomField.FieldDataType.STRING,
|
||||
)
|
||||
self.client.force_login(user=self.user)
|
||||
|
||||
# Initial response should include only document's creation
|
||||
response = self.client.get(f"/api/documents/{doc.pk}/history/")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(len(response.data), 1)
|
||||
|
||||
self.assertIsNone(response.data[0]["actor"])
|
||||
self.assertEqual(response.data[0]["action"], "create")
|
||||
|
||||
self.client.patch(
|
||||
f"/api/documents/{doc.pk}/",
|
||||
data={
|
||||
@ -379,12 +389,15 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
|
||||
format="json",
|
||||
)
|
||||
|
||||
# Second response should include custom field addition
|
||||
response = self.client.get(f"/api/documents/{doc.pk}/history/")
|
||||
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(response.data[1]["actor"]["id"], self.user.id)
|
||||
self.assertEqual(response.data[1]["action"], "create")
|
||||
self.assertEqual(len(response.data), 2)
|
||||
self.assertEqual(response.data[0]["actor"]["id"], self.user.id)
|
||||
self.assertEqual(response.data[0]["action"], "create")
|
||||
self.assertEqual(
|
||||
response.data[1]["changes"],
|
||||
response.data[0]["changes"],
|
||||
{
|
||||
"custom_fields": {
|
||||
"type": "custom_field",
|
||||
@ -393,6 +406,8 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
|
||||
},
|
||||
},
|
||||
)
|
||||
self.assertIsNone(response.data[1]["actor"])
|
||||
self.assertEqual(response.data[1]["action"], "create")
|
||||
|
||||
@override_settings(AUDIT_LOG_ENABLED=False)
|
||||
def test_document_history_action_disabled(self):
|
||||
|
@ -19,7 +19,6 @@ from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Group
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.db import connections
|
||||
from django.db.migrations.loader import MigrationLoader
|
||||
from django.db.migrations.recorder import MigrationRecorder
|
||||
@ -106,7 +105,6 @@ from documents.matching import match_storage_paths
|
||||
from documents.matching import match_tags
|
||||
from documents.models import Correspondent
|
||||
from documents.models import CustomField
|
||||
from documents.models import CustomFieldInstance
|
||||
from documents.models import Document
|
||||
from documents.models import DocumentType
|
||||
from documents.models import Note
|
||||
@ -799,15 +797,14 @@ class DocumentViewSet(
|
||||
else None
|
||||
),
|
||||
}
|
||||
for entry in LogEntry.objects.filter(object_pk=doc.pk).select_related(
|
||||
for entry in LogEntry.objects.get_for_object(doc).select_related(
|
||||
"actor",
|
||||
)
|
||||
]
|
||||
|
||||
# custom fields
|
||||
for entry in LogEntry.objects.filter(
|
||||
object_pk__in=list(doc.custom_fields.values_list("id", flat=True)),
|
||||
content_type=ContentType.objects.get_for_model(CustomFieldInstance),
|
||||
for entry in LogEntry.objects.get_for_objects(
|
||||
doc.custom_fields.all(),
|
||||
).select_related("actor"):
|
||||
entries.append(
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user