mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-08-24 01:06:17 +00:00
Updates
[ci skip]
This commit is contained in:
@@ -23,6 +23,7 @@ from documents.models import CustomFieldInstance
|
|||||||
from documents.models import Document
|
from documents.models import Document
|
||||||
from documents.models import DocumentType
|
from documents.models import DocumentType
|
||||||
from documents.models import StoragePath
|
from documents.models import StoragePath
|
||||||
|
from documents.models import Tag
|
||||||
from documents.permissions import set_permissions_for_object
|
from documents.permissions import set_permissions_for_object
|
||||||
from documents.plugins.helpers import DocumentsStatusManager
|
from documents.plugins.helpers import DocumentsStatusManager
|
||||||
from documents.tasks import bulk_update_documents
|
from documents.tasks import bulk_update_documents
|
||||||
@@ -91,31 +92,46 @@ def set_document_type(doc_ids: list[int], document_type: DocumentType) -> Litera
|
|||||||
|
|
||||||
|
|
||||||
def add_tag(doc_ids: list[int], tag: int) -> Literal["OK"]:
|
def add_tag(doc_ids: list[int], tag: int) -> Literal["OK"]:
|
||||||
qs = Document.objects.filter(Q(id__in=doc_ids) & ~Q(tags__id=tag)).only("pk")
|
tag_obj = Tag.objects.get(pk=tag)
|
||||||
affected_docs = list(qs.values_list("pk", flat=True))
|
tags_to_add = [tag_obj, *tag_obj.get_all_ancestors()]
|
||||||
|
|
||||||
DocumentTagRelationship = Document.tags.through
|
DocumentTagRelationship = Document.tags.through
|
||||||
|
to_create = []
|
||||||
|
affected_docs: set[int] = set()
|
||||||
|
|
||||||
DocumentTagRelationship.objects.bulk_create(
|
for t in tags_to_add:
|
||||||
[DocumentTagRelationship(document_id=doc, tag_id=tag) for doc in affected_docs],
|
qs = Document.objects.filter(Q(id__in=doc_ids) & ~Q(tags__id=t.id)).only("pk")
|
||||||
)
|
doc_ids_missing_tag = list(qs.values_list("pk", flat=True))
|
||||||
|
affected_docs.update(doc_ids_missing_tag)
|
||||||
|
to_create.extend(
|
||||||
|
DocumentTagRelationship(document_id=doc, tag_id=t.id)
|
||||||
|
for doc in doc_ids_missing_tag
|
||||||
|
)
|
||||||
|
|
||||||
bulk_update_documents.delay(document_ids=affected_docs)
|
if to_create:
|
||||||
|
DocumentTagRelationship.objects.bulk_create(to_create)
|
||||||
|
|
||||||
|
if affected_docs:
|
||||||
|
bulk_update_documents.delay(document_ids=list(affected_docs))
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|
||||||
|
|
||||||
def remove_tag(doc_ids: list[int], tag: int) -> Literal["OK"]:
|
def remove_tag(doc_ids: list[int], tag: int) -> Literal["OK"]:
|
||||||
qs = Document.objects.filter(Q(id__in=doc_ids) & Q(tags__id=tag)).only("pk")
|
tag_obj = Tag.objects.get(pk=tag)
|
||||||
affected_docs = list(qs.values_list("pk", flat=True))
|
tags_to_remove = [tag_obj, *tag_obj.get_all_descendants()]
|
||||||
|
tag_ids = [t.id for t in tags_to_remove]
|
||||||
|
|
||||||
DocumentTagRelationship = Document.tags.through
|
DocumentTagRelationship = Document.tags.through
|
||||||
|
qs = DocumentTagRelationship.objects.filter(
|
||||||
|
document_id__in=doc_ids,
|
||||||
|
tag_id__in=tag_ids,
|
||||||
|
)
|
||||||
|
affected_docs = list(qs.values_list("document_id", flat=True).distinct())
|
||||||
|
qs.delete()
|
||||||
|
|
||||||
DocumentTagRelationship.objects.filter(
|
if affected_docs:
|
||||||
Q(document_id__in=affected_docs) & Q(tag_id=tag),
|
bulk_update_documents.delay(document_ids=affected_docs)
|
||||||
).delete()
|
|
||||||
|
|
||||||
bulk_update_documents.delay(document_ids=affected_docs)
|
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|
||||||
@@ -127,23 +143,35 @@ def modify_tags(
|
|||||||
) -> Literal["OK"]:
|
) -> Literal["OK"]:
|
||||||
qs = Document.objects.filter(id__in=doc_ids).only("pk")
|
qs = Document.objects.filter(id__in=doc_ids).only("pk")
|
||||||
affected_docs = list(qs.values_list("pk", flat=True))
|
affected_docs = list(qs.values_list("pk", flat=True))
|
||||||
|
|
||||||
DocumentTagRelationship = Document.tags.through
|
DocumentTagRelationship = Document.tags.through
|
||||||
|
|
||||||
DocumentTagRelationship.objects.filter(
|
# add with all ancestors
|
||||||
document_id__in=affected_docs,
|
expanded_add_tags: set[int] = set()
|
||||||
tag_id__in=remove_tags,
|
for tag_id in add_tags:
|
||||||
).delete()
|
t = Tag.objects.get(pk=tag_id)
|
||||||
|
expanded_add_tags.update([t.id for t in [t, *t.get_all_ancestors()]])
|
||||||
|
|
||||||
DocumentTagRelationship.objects.bulk_create(
|
# remove with all descendants
|
||||||
[
|
expanded_remove_tags: set[int] = set()
|
||||||
DocumentTagRelationship(document_id=doc, tag_id=tag)
|
for tag_id in remove_tags:
|
||||||
for (doc, tag) in itertools.product(affected_docs, add_tags)
|
t = Tag.objects.get(pk=tag_id)
|
||||||
],
|
expanded_remove_tags.update([t.id for t in [t, *t.get_all_descendants()]])
|
||||||
ignore_conflicts=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
bulk_update_documents.delay(document_ids=affected_docs)
|
if expanded_remove_tags:
|
||||||
|
DocumentTagRelationship.objects.filter(
|
||||||
|
document_id__in=affected_docs,
|
||||||
|
tag_id__in=expanded_remove_tags,
|
||||||
|
).delete()
|
||||||
|
|
||||||
|
to_create = [
|
||||||
|
DocumentTagRelationship(document_id=doc, tag_id=tag)
|
||||||
|
for (doc, tag) in itertools.product(affected_docs, expanded_add_tags)
|
||||||
|
]
|
||||||
|
if to_create:
|
||||||
|
DocumentTagRelationship.objects.bulk_create(to_create, ignore_conflicts=True)
|
||||||
|
|
||||||
|
if affected_docs:
|
||||||
|
bulk_update_documents.delay(document_ids=affected_docs)
|
||||||
|
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|
||||||
|
@@ -627,14 +627,17 @@ def run_workflows(
|
|||||||
|
|
||||||
def assignment_action():
|
def assignment_action():
|
||||||
if action.assign_tags.exists():
|
if action.assign_tags.exists():
|
||||||
|
tag_ids_to_add: set[int] = set()
|
||||||
|
for tag in action.assign_tags.all():
|
||||||
|
tag_ids_to_add.add(tag.pk)
|
||||||
|
tag_ids_to_add.update(t.pk for t in tag.get_all_ancestors())
|
||||||
|
|
||||||
if not use_overrides:
|
if not use_overrides:
|
||||||
doc_tag_ids.extend(action.assign_tags.values_list("pk", flat=True))
|
doc_tag_ids[:] = list(set(doc_tag_ids) | tag_ids_to_add)
|
||||||
else:
|
else:
|
||||||
if overrides.tag_ids is None:
|
if overrides.tag_ids is None:
|
||||||
overrides.tag_ids = []
|
overrides.tag_ids = []
|
||||||
overrides.tag_ids.extend(
|
overrides.tag_ids = list(set(overrides.tag_ids) | tag_ids_to_add)
|
||||||
action.assign_tags.values_list("pk", flat=True),
|
|
||||||
)
|
|
||||||
|
|
||||||
if action.assign_correspondent:
|
if action.assign_correspondent:
|
||||||
if not use_overrides:
|
if not use_overrides:
|
||||||
@@ -760,14 +763,17 @@ def run_workflows(
|
|||||||
else:
|
else:
|
||||||
overrides.tag_ids = None
|
overrides.tag_ids = None
|
||||||
else:
|
else:
|
||||||
|
tag_ids_to_remove: set[int] = set()
|
||||||
|
for tag in action.remove_tags.all():
|
||||||
|
tag_ids_to_remove.add(tag.pk)
|
||||||
|
tag_ids_to_remove.update(t.pk for t in tag.get_all_descendants())
|
||||||
|
|
||||||
if not use_overrides:
|
if not use_overrides:
|
||||||
for tag in action.remove_tags.filter(
|
doc_tag_ids[:] = [t for t in doc_tag_ids if t not in tag_ids_to_remove]
|
||||||
pk__in=document.tags.values_list("pk", flat=True),
|
|
||||||
):
|
|
||||||
doc_tag_ids.remove(tag.pk)
|
|
||||||
elif overrides.tag_ids:
|
elif overrides.tag_ids:
|
||||||
for tag in action.remove_tags.filter(pk__in=overrides.tag_ids):
|
overrides.tag_ids = [
|
||||||
overrides.tag_ids.remove(tag.pk)
|
t for t in overrides.tag_ids if t not in tag_ids_to_remove
|
||||||
|
]
|
||||||
|
|
||||||
if not use_overrides and (
|
if not use_overrides and (
|
||||||
action.remove_all_correspondents
|
action.remove_all_correspondents
|
||||||
|
Reference in New Issue
Block a user