mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-01-26 22:49:01 -06:00
Merge branch 'dev' into feature-6978-sharelink-bundle
This commit is contained in:
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py management_command "$@"
|
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
|
||||||
python3 manage.py management_command "$@"
|
python3 manage.py management_command "$@"
|
||||||
else
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
echo "Unknown user."
|
s6-setuidgid paperless python3 manage.py management_command "$@"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py convert_mariadb_uuid "$@"
|
python3 manage.py convert_mariadb_uuid "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py convert_mariadb_uuid "$@"
|
s6-setuidgid paperless python3 manage.py convert_mariadb_uuid "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py createsuperuser "$@"
|
python3 manage.py createsuperuser "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py createsuperuser "$@"
|
s6-setuidgid paperless python3 manage.py createsuperuser "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_archiver "$@"
|
python3 manage.py document_archiver "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_archiver "$@"
|
s6-setuidgid paperless python3 manage.py document_archiver "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_create_classifier "$@"
|
python3 manage.py document_create_classifier "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_create_classifier "$@"
|
s6-setuidgid paperless python3 manage.py document_create_classifier "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_exporter "$@"
|
python3 manage.py document_exporter "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_exporter "$@"
|
s6-setuidgid paperless python3 manage.py document_exporter "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_fuzzy_match "$@"
|
python3 manage.py document_fuzzy_match "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_fuzzy_match "$@"
|
s6-setuidgid paperless python3 manage.py document_fuzzy_match "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_importer "$@"
|
python3 manage.py document_importer "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_importer "$@"
|
s6-setuidgid paperless python3 manage.py document_importer "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_index "$@"
|
python3 manage.py document_index "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_index "$@"
|
s6-setuidgid paperless python3 manage.py document_index "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_renamer "$@"
|
python3 manage.py document_renamer "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_renamer "$@"
|
s6-setuidgid paperless python3 manage.py document_renamer "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_retagger "$@"
|
python3 manage.py document_retagger "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_retagger "$@"
|
s6-setuidgid paperless python3 manage.py document_retagger "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_sanity_checker "$@"
|
python3 manage.py document_sanity_checker "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_sanity_checker "$@"
|
s6-setuidgid paperless python3 manage.py document_sanity_checker "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py document_thumbnails "$@"
|
python3 manage.py document_thumbnails "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py document_thumbnails "$@"
|
s6-setuidgid paperless python3 manage.py document_thumbnails "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py mail_fetcher "$@"
|
python3 manage.py mail_fetcher "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py mail_fetcher "$@"
|
s6-setuidgid paperless python3 manage.py mail_fetcher "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py manage_superuser "$@"
|
python3 manage.py manage_superuser "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py manage_superuser "$@"
|
s6-setuidgid paperless python3 manage.py manage_superuser "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ set -e
|
|||||||
|
|
||||||
cd "${PAPERLESS_SRC_DIR}"
|
cd "${PAPERLESS_SRC_DIR}"
|
||||||
|
|
||||||
if [[ $(id -u) == 0 ]]; then
|
if [[ -n "${USER_IS_NON_ROOT}" ]]; then
|
||||||
s6-setuidgid paperless python3 manage.py prune_audit_logs "$@"
|
python3 manage.py prune_audit_logs "$@"
|
||||||
elif [[ $(id -un) == "paperless" ]]; then
|
elif [[ $(id -un) == "paperless" ]]; then
|
||||||
python3 manage.py prune_audit_logs "$@"
|
s6-setuidgid paperless python3 manage.py prune_audit_logs "$@"
|
||||||
else
|
|
||||||
echo "Unknown user."
|
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ lint.isort.force-single-line = true
|
|||||||
|
|
||||||
[tool.codespell]
|
[tool.codespell]
|
||||||
write-changes = true
|
write-changes = true
|
||||||
ignore-words-list = "criterias,afterall,valeu,ureue,equest,ure,assertIn,Oktober"
|
ignore-words-list = "criterias,afterall,valeu,ureue,equest,ure,assertIn,Oktober,commitish"
|
||||||
skip = "src-ui/src/locale/*,src-ui/pnpm-lock.yaml,src-ui/e2e/*,src/paperless_mail/tests/samples/*,src/documents/tests/samples/*,*.po,*.json"
|
skip = "src-ui/src/locale/*,src-ui/pnpm-lock.yaml,src-ui/e2e/*,src/paperless_mail/tests/samples/*,src/documents/tests/samples/*,*.po,*.json"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
|
|||||||
@@ -5257,84 +5257,105 @@
|
|||||||
<source>Has any of these tags</source>
|
<source>Has any of these tags</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">203</context>
|
<context context-type="linenumber">209</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4166903555074156852" datatype="html">
|
<trans-unit id="4166903555074156852" datatype="html">
|
||||||
<source>Has all of these tags</source>
|
<source>Has all of these tags</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">210</context>
|
<context context-type="linenumber">216</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6624363795312783141" datatype="html">
|
<trans-unit id="6624363795312783141" datatype="html">
|
||||||
<source>Does not have these tags</source>
|
<source>Does not have these tags</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">217</context>
|
<context context-type="linenumber">223</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="7168528512669831184" datatype="html">
|
||||||
|
<source>Has any of these correspondents</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
|
<context context-type="linenumber">230</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5281365940563983618" datatype="html">
|
<trans-unit id="5281365940563983618" datatype="html">
|
||||||
<source>Has correspondent</source>
|
<source>Has correspondent</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">224</context>
|
<context context-type="linenumber">238</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6884498632428600393" datatype="html">
|
<trans-unit id="6884498632428600393" datatype="html">
|
||||||
<source>Does not have correspondents</source>
|
<source>Does not have correspondents</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">232</context>
|
<context context-type="linenumber">246</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4806713133917046341" datatype="html">
|
<trans-unit id="4806713133917046341" datatype="html">
|
||||||
<source>Has document type</source>
|
<source>Has document type</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">240</context>
|
<context context-type="linenumber">254</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="8801397520369995032" datatype="html">
|
||||||
|
<source>Has any of these document types</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
|
<context context-type="linenumber">262</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="1507843981661822403" datatype="html">
|
<trans-unit id="1507843981661822403" datatype="html">
|
||||||
<source>Does not have document types</source>
|
<source>Does not have document types</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">248</context>
|
<context context-type="linenumber">270</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="4277260190522078330" datatype="html">
|
<trans-unit id="4277260190522078330" datatype="html">
|
||||||
<source>Has storage path</source>
|
<source>Has storage path</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">256</context>
|
<context context-type="linenumber">278</context>
|
||||||
|
</context-group>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="8858580062214623097" datatype="html">
|
||||||
|
<source>Has any of these storage paths</source>
|
||||||
|
<context-group purpose="location">
|
||||||
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
|
<context context-type="linenumber">286</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6070943364927280151" datatype="html">
|
<trans-unit id="6070943364927280151" datatype="html">
|
||||||
<source>Does not have storage paths</source>
|
<source>Does not have storage paths</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">264</context>
|
<context context-type="linenumber">294</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="6250799006816371860" datatype="html">
|
<trans-unit id="6250799006816371860" datatype="html">
|
||||||
<source>Matches custom field query</source>
|
<source>Matches custom field query</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">272</context>
|
<context context-type="linenumber">302</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="3138206142174978019" datatype="html">
|
<trans-unit id="3138206142174978019" datatype="html">
|
||||||
<source>Create new workflow</source>
|
<source>Create new workflow</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">474</context>
|
<context context-type="linenumber">531</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5996779210524133604" datatype="html">
|
<trans-unit id="5996779210524133604" datatype="html">
|
||||||
<source>Edit workflow</source>
|
<source>Edit workflow</source>
|
||||||
<context-group purpose="location">
|
<context-group purpose="location">
|
||||||
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.ts</context>
|
||||||
<context context-type="linenumber">478</context>
|
<context context-type="linenumber">535</context>
|
||||||
</context-group>
|
</context-group>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="5457837313196342910" datatype="html">
|
<trans-unit id="5457837313196342910" datatype="html">
|
||||||
|
|||||||
@@ -412,6 +412,9 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
return newFilter
|
return newFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const correspondentAny = addFilterOfType(TriggerFilterType.CorrespondentAny)
|
||||||
|
correspondentAny.get('values').setValue([11])
|
||||||
|
|
||||||
const correspondentIs = addFilterOfType(TriggerFilterType.CorrespondentIs)
|
const correspondentIs = addFilterOfType(TriggerFilterType.CorrespondentIs)
|
||||||
correspondentIs.get('values').setValue(1)
|
correspondentIs.get('values').setValue(1)
|
||||||
|
|
||||||
@@ -421,12 +424,18 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
const documentTypeIs = addFilterOfType(TriggerFilterType.DocumentTypeIs)
|
const documentTypeIs = addFilterOfType(TriggerFilterType.DocumentTypeIs)
|
||||||
documentTypeIs.get('values').setValue(1)
|
documentTypeIs.get('values').setValue(1)
|
||||||
|
|
||||||
|
const documentTypeAny = addFilterOfType(TriggerFilterType.DocumentTypeAny)
|
||||||
|
documentTypeAny.get('values').setValue([12])
|
||||||
|
|
||||||
const documentTypeNot = addFilterOfType(TriggerFilterType.DocumentTypeNot)
|
const documentTypeNot = addFilterOfType(TriggerFilterType.DocumentTypeNot)
|
||||||
documentTypeNot.get('values').setValue([1])
|
documentTypeNot.get('values').setValue([1])
|
||||||
|
|
||||||
const storagePathIs = addFilterOfType(TriggerFilterType.StoragePathIs)
|
const storagePathIs = addFilterOfType(TriggerFilterType.StoragePathIs)
|
||||||
storagePathIs.get('values').setValue(1)
|
storagePathIs.get('values').setValue(1)
|
||||||
|
|
||||||
|
const storagePathAny = addFilterOfType(TriggerFilterType.StoragePathAny)
|
||||||
|
storagePathAny.get('values').setValue([13])
|
||||||
|
|
||||||
const storagePathNot = addFilterOfType(TriggerFilterType.StoragePathNot)
|
const storagePathNot = addFilterOfType(TriggerFilterType.StoragePathNot)
|
||||||
storagePathNot.get('values').setValue([1])
|
storagePathNot.get('values').setValue([1])
|
||||||
|
|
||||||
@@ -441,10 +450,13 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
expect(formValues.triggers[0].filter_has_tags).toEqual([1])
|
expect(formValues.triggers[0].filter_has_tags).toEqual([1])
|
||||||
expect(formValues.triggers[0].filter_has_all_tags).toEqual([2, 3])
|
expect(formValues.triggers[0].filter_has_all_tags).toEqual([2, 3])
|
||||||
expect(formValues.triggers[0].filter_has_not_tags).toEqual([4])
|
expect(formValues.triggers[0].filter_has_not_tags).toEqual([4])
|
||||||
|
expect(formValues.triggers[0].filter_has_any_correspondents).toEqual([11])
|
||||||
expect(formValues.triggers[0].filter_has_correspondent).toEqual(1)
|
expect(formValues.triggers[0].filter_has_correspondent).toEqual(1)
|
||||||
expect(formValues.triggers[0].filter_has_not_correspondents).toEqual([1])
|
expect(formValues.triggers[0].filter_has_not_correspondents).toEqual([1])
|
||||||
|
expect(formValues.triggers[0].filter_has_any_document_types).toEqual([12])
|
||||||
expect(formValues.triggers[0].filter_has_document_type).toEqual(1)
|
expect(formValues.triggers[0].filter_has_document_type).toEqual(1)
|
||||||
expect(formValues.triggers[0].filter_has_not_document_types).toEqual([1])
|
expect(formValues.triggers[0].filter_has_not_document_types).toEqual([1])
|
||||||
|
expect(formValues.triggers[0].filter_has_any_storage_paths).toEqual([13])
|
||||||
expect(formValues.triggers[0].filter_has_storage_path).toEqual(1)
|
expect(formValues.triggers[0].filter_has_storage_path).toEqual(1)
|
||||||
expect(formValues.triggers[0].filter_has_not_storage_paths).toEqual([1])
|
expect(formValues.triggers[0].filter_has_not_storage_paths).toEqual([1])
|
||||||
expect(formValues.triggers[0].filter_custom_field_query).toEqual(
|
expect(formValues.triggers[0].filter_custom_field_query).toEqual(
|
||||||
@@ -507,16 +519,22 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
|
|
||||||
setFilter(TriggerFilterType.TagsAll, 11)
|
setFilter(TriggerFilterType.TagsAll, 11)
|
||||||
setFilter(TriggerFilterType.TagsNone, 12)
|
setFilter(TriggerFilterType.TagsNone, 12)
|
||||||
|
setFilter(TriggerFilterType.CorrespondentAny, 16)
|
||||||
setFilter(TriggerFilterType.CorrespondentNot, 13)
|
setFilter(TriggerFilterType.CorrespondentNot, 13)
|
||||||
|
setFilter(TriggerFilterType.DocumentTypeAny, 17)
|
||||||
setFilter(TriggerFilterType.DocumentTypeNot, 14)
|
setFilter(TriggerFilterType.DocumentTypeNot, 14)
|
||||||
|
setFilter(TriggerFilterType.StoragePathAny, 18)
|
||||||
setFilter(TriggerFilterType.StoragePathNot, 15)
|
setFilter(TriggerFilterType.StoragePathNot, 15)
|
||||||
|
|
||||||
const formValues = component['getFormValues']()
|
const formValues = component['getFormValues']()
|
||||||
|
|
||||||
expect(formValues.triggers[0].filter_has_all_tags).toEqual([11])
|
expect(formValues.triggers[0].filter_has_all_tags).toEqual([11])
|
||||||
expect(formValues.triggers[0].filter_has_not_tags).toEqual([12])
|
expect(formValues.triggers[0].filter_has_not_tags).toEqual([12])
|
||||||
|
expect(formValues.triggers[0].filter_has_any_correspondents).toEqual([16])
|
||||||
expect(formValues.triggers[0].filter_has_not_correspondents).toEqual([13])
|
expect(formValues.triggers[0].filter_has_not_correspondents).toEqual([13])
|
||||||
|
expect(formValues.triggers[0].filter_has_any_document_types).toEqual([17])
|
||||||
expect(formValues.triggers[0].filter_has_not_document_types).toEqual([14])
|
expect(formValues.triggers[0].filter_has_not_document_types).toEqual([14])
|
||||||
|
expect(formValues.triggers[0].filter_has_any_storage_paths).toEqual([18])
|
||||||
expect(formValues.triggers[0].filter_has_not_storage_paths).toEqual([15])
|
expect(formValues.triggers[0].filter_has_not_storage_paths).toEqual([15])
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -640,8 +658,11 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
filter_has_tags: [],
|
filter_has_tags: [],
|
||||||
filter_has_all_tags: [],
|
filter_has_all_tags: [],
|
||||||
filter_has_not_tags: [],
|
filter_has_not_tags: [],
|
||||||
|
filter_has_any_correspondents: [],
|
||||||
filter_has_not_correspondents: [],
|
filter_has_not_correspondents: [],
|
||||||
|
filter_has_any_document_types: [],
|
||||||
filter_has_not_document_types: [],
|
filter_has_not_document_types: [],
|
||||||
|
filter_has_any_storage_paths: [],
|
||||||
filter_has_not_storage_paths: [],
|
filter_has_not_storage_paths: [],
|
||||||
filter_has_correspondent: null,
|
filter_has_correspondent: null,
|
||||||
filter_has_document_type: null,
|
filter_has_document_type: null,
|
||||||
@@ -699,11 +720,14 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
trigger.filter_has_tags = [1]
|
trigger.filter_has_tags = [1]
|
||||||
trigger.filter_has_all_tags = [2, 3]
|
trigger.filter_has_all_tags = [2, 3]
|
||||||
trigger.filter_has_not_tags = [4]
|
trigger.filter_has_not_tags = [4]
|
||||||
|
trigger.filter_has_any_correspondents = [10] as any
|
||||||
trigger.filter_has_correspondent = 5 as any
|
trigger.filter_has_correspondent = 5 as any
|
||||||
trigger.filter_has_not_correspondents = [6] as any
|
trigger.filter_has_not_correspondents = [6] as any
|
||||||
trigger.filter_has_document_type = 7 as any
|
trigger.filter_has_document_type = 7 as any
|
||||||
|
trigger.filter_has_any_document_types = [11] as any
|
||||||
trigger.filter_has_not_document_types = [8] as any
|
trigger.filter_has_not_document_types = [8] as any
|
||||||
trigger.filter_has_storage_path = 9 as any
|
trigger.filter_has_storage_path = 9 as any
|
||||||
|
trigger.filter_has_any_storage_paths = [12] as any
|
||||||
trigger.filter_has_not_storage_paths = [10] as any
|
trigger.filter_has_not_storage_paths = [10] as any
|
||||||
trigger.filter_custom_field_query = JSON.stringify([
|
trigger.filter_custom_field_query = JSON.stringify([
|
||||||
'AND',
|
'AND',
|
||||||
@@ -714,8 +738,8 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
component.ngOnInit()
|
component.ngOnInit()
|
||||||
const triggerGroup = component.triggerFields.at(0) as FormGroup
|
const triggerGroup = component.triggerFields.at(0) as FormGroup
|
||||||
const filters = component.getFiltersFormArray(triggerGroup)
|
const filters = component.getFiltersFormArray(triggerGroup)
|
||||||
expect(filters.length).toBe(10)
|
expect(filters.length).toBe(13)
|
||||||
const customFieldFilter = filters.at(9) as FormGroup
|
const customFieldFilter = filters.at(12) as FormGroup
|
||||||
expect(customFieldFilter.get('type').value).toBe(
|
expect(customFieldFilter.get('type').value).toBe(
|
||||||
TriggerFilterType.CustomFieldQuery
|
TriggerFilterType.CustomFieldQuery
|
||||||
)
|
)
|
||||||
@@ -724,12 +748,27 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should expose select metadata helpers', () => {
|
it('should expose select metadata helpers', () => {
|
||||||
|
expect(component.isSelectMultiple(TriggerFilterType.CorrespondentAny)).toBe(
|
||||||
|
true
|
||||||
|
)
|
||||||
expect(component.isSelectMultiple(TriggerFilterType.CorrespondentNot)).toBe(
|
expect(component.isSelectMultiple(TriggerFilterType.CorrespondentNot)).toBe(
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
expect(component.isSelectMultiple(TriggerFilterType.CorrespondentIs)).toBe(
|
expect(component.isSelectMultiple(TriggerFilterType.CorrespondentIs)).toBe(
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
expect(component.isSelectMultiple(TriggerFilterType.DocumentTypeAny)).toBe(
|
||||||
|
true
|
||||||
|
)
|
||||||
|
expect(component.isSelectMultiple(TriggerFilterType.DocumentTypeIs)).toBe(
|
||||||
|
false
|
||||||
|
)
|
||||||
|
expect(component.isSelectMultiple(TriggerFilterType.StoragePathAny)).toBe(
|
||||||
|
true
|
||||||
|
)
|
||||||
|
expect(component.isSelectMultiple(TriggerFilterType.StoragePathIs)).toBe(
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
component.correspondents = [{ id: 1, name: 'C1' } as any]
|
component.correspondents = [{ id: 1, name: 'C1' } as any]
|
||||||
component.documentTypes = [{ id: 2, name: 'DT' } as any]
|
component.documentTypes = [{ id: 2, name: 'DT' } as any]
|
||||||
@@ -741,9 +780,15 @@ describe('WorkflowEditDialogComponent', () => {
|
|||||||
expect(
|
expect(
|
||||||
component.getFilterSelectItems(TriggerFilterType.DocumentTypeIs)
|
component.getFilterSelectItems(TriggerFilterType.DocumentTypeIs)
|
||||||
).toEqual(component.documentTypes)
|
).toEqual(component.documentTypes)
|
||||||
|
expect(
|
||||||
|
component.getFilterSelectItems(TriggerFilterType.DocumentTypeAny)
|
||||||
|
).toEqual(component.documentTypes)
|
||||||
expect(
|
expect(
|
||||||
component.getFilterSelectItems(TriggerFilterType.StoragePathIs)
|
component.getFilterSelectItems(TriggerFilterType.StoragePathIs)
|
||||||
).toEqual(component.storagePaths)
|
).toEqual(component.storagePaths)
|
||||||
|
expect(
|
||||||
|
component.getFilterSelectItems(TriggerFilterType.StoragePathAny)
|
||||||
|
).toEqual(component.storagePaths)
|
||||||
expect(component.getFilterSelectItems(TriggerFilterType.TagsAll)).toEqual(
|
expect(component.getFilterSelectItems(TriggerFilterType.TagsAll)).toEqual(
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -145,10 +145,13 @@ export enum TriggerFilterType {
|
|||||||
TagsAny = 'tags_any',
|
TagsAny = 'tags_any',
|
||||||
TagsAll = 'tags_all',
|
TagsAll = 'tags_all',
|
||||||
TagsNone = 'tags_none',
|
TagsNone = 'tags_none',
|
||||||
|
CorrespondentAny = 'correspondent_any',
|
||||||
CorrespondentIs = 'correspondent_is',
|
CorrespondentIs = 'correspondent_is',
|
||||||
CorrespondentNot = 'correspondent_not',
|
CorrespondentNot = 'correspondent_not',
|
||||||
|
DocumentTypeAny = 'document_type_any',
|
||||||
DocumentTypeIs = 'document_type_is',
|
DocumentTypeIs = 'document_type_is',
|
||||||
DocumentTypeNot = 'document_type_not',
|
DocumentTypeNot = 'document_type_not',
|
||||||
|
StoragePathAny = 'storage_path_any',
|
||||||
StoragePathIs = 'storage_path_is',
|
StoragePathIs = 'storage_path_is',
|
||||||
StoragePathNot = 'storage_path_not',
|
StoragePathNot = 'storage_path_not',
|
||||||
CustomFieldQuery = 'custom_field_query',
|
CustomFieldQuery = 'custom_field_query',
|
||||||
@@ -172,8 +175,11 @@ type TriggerFilterAggregate = {
|
|||||||
filter_has_tags: number[]
|
filter_has_tags: number[]
|
||||||
filter_has_all_tags: number[]
|
filter_has_all_tags: number[]
|
||||||
filter_has_not_tags: number[]
|
filter_has_not_tags: number[]
|
||||||
|
filter_has_any_correspondents: number[]
|
||||||
filter_has_not_correspondents: number[]
|
filter_has_not_correspondents: number[]
|
||||||
|
filter_has_any_document_types: number[]
|
||||||
filter_has_not_document_types: number[]
|
filter_has_not_document_types: number[]
|
||||||
|
filter_has_any_storage_paths: number[]
|
||||||
filter_has_not_storage_paths: number[]
|
filter_has_not_storage_paths: number[]
|
||||||
filter_has_correspondent: number | null
|
filter_has_correspondent: number | null
|
||||||
filter_has_document_type: number | null
|
filter_has_document_type: number | null
|
||||||
@@ -219,6 +225,14 @@ const TRIGGER_FILTER_DEFINITIONS: TriggerFilterDefinition[] = [
|
|||||||
allowMultipleEntries: false,
|
allowMultipleEntries: false,
|
||||||
allowMultipleValues: true,
|
allowMultipleValues: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: TriggerFilterType.CorrespondentAny,
|
||||||
|
name: $localize`Has any of these correspondents`,
|
||||||
|
inputType: 'select',
|
||||||
|
allowMultipleEntries: false,
|
||||||
|
allowMultipleValues: true,
|
||||||
|
selectItems: 'correspondents',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: TriggerFilterType.CorrespondentIs,
|
id: TriggerFilterType.CorrespondentIs,
|
||||||
name: $localize`Has correspondent`,
|
name: $localize`Has correspondent`,
|
||||||
@@ -243,6 +257,14 @@ const TRIGGER_FILTER_DEFINITIONS: TriggerFilterDefinition[] = [
|
|||||||
allowMultipleValues: false,
|
allowMultipleValues: false,
|
||||||
selectItems: 'documentTypes',
|
selectItems: 'documentTypes',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: TriggerFilterType.DocumentTypeAny,
|
||||||
|
name: $localize`Has any of these document types`,
|
||||||
|
inputType: 'select',
|
||||||
|
allowMultipleEntries: false,
|
||||||
|
allowMultipleValues: true,
|
||||||
|
selectItems: 'documentTypes',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: TriggerFilterType.DocumentTypeNot,
|
id: TriggerFilterType.DocumentTypeNot,
|
||||||
name: $localize`Does not have document types`,
|
name: $localize`Does not have document types`,
|
||||||
@@ -259,6 +281,14 @@ const TRIGGER_FILTER_DEFINITIONS: TriggerFilterDefinition[] = [
|
|||||||
allowMultipleValues: false,
|
allowMultipleValues: false,
|
||||||
selectItems: 'storagePaths',
|
selectItems: 'storagePaths',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: TriggerFilterType.StoragePathAny,
|
||||||
|
name: $localize`Has any of these storage paths`,
|
||||||
|
inputType: 'select',
|
||||||
|
allowMultipleEntries: false,
|
||||||
|
allowMultipleValues: true,
|
||||||
|
selectItems: 'storagePaths',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: TriggerFilterType.StoragePathNot,
|
id: TriggerFilterType.StoragePathNot,
|
||||||
name: $localize`Does not have storage paths`,
|
name: $localize`Does not have storage paths`,
|
||||||
@@ -306,6 +336,15 @@ const FILTER_HANDLERS: Record<TriggerFilterType, FilterHandler> = {
|
|||||||
extract: (trigger) => trigger.filter_has_not_tags,
|
extract: (trigger) => trigger.filter_has_not_tags,
|
||||||
hasValue: (value) => Array.isArray(value) && value.length > 0,
|
hasValue: (value) => Array.isArray(value) && value.length > 0,
|
||||||
},
|
},
|
||||||
|
[TriggerFilterType.CorrespondentAny]: {
|
||||||
|
apply: (aggregate, values) => {
|
||||||
|
aggregate.filter_has_any_correspondents = Array.isArray(values)
|
||||||
|
? [...values]
|
||||||
|
: [values]
|
||||||
|
},
|
||||||
|
extract: (trigger) => trigger.filter_has_any_correspondents,
|
||||||
|
hasValue: (value) => Array.isArray(value) && value.length > 0,
|
||||||
|
},
|
||||||
[TriggerFilterType.CorrespondentIs]: {
|
[TriggerFilterType.CorrespondentIs]: {
|
||||||
apply: (aggregate, values) => {
|
apply: (aggregate, values) => {
|
||||||
aggregate.filter_has_correspondent = Array.isArray(values)
|
aggregate.filter_has_correspondent = Array.isArray(values)
|
||||||
@@ -333,6 +372,15 @@ const FILTER_HANDLERS: Record<TriggerFilterType, FilterHandler> = {
|
|||||||
extract: (trigger) => trigger.filter_has_document_type,
|
extract: (trigger) => trigger.filter_has_document_type,
|
||||||
hasValue: (value) => value !== null && value !== undefined,
|
hasValue: (value) => value !== null && value !== undefined,
|
||||||
},
|
},
|
||||||
|
[TriggerFilterType.DocumentTypeAny]: {
|
||||||
|
apply: (aggregate, values) => {
|
||||||
|
aggregate.filter_has_any_document_types = Array.isArray(values)
|
||||||
|
? [...values]
|
||||||
|
: [values]
|
||||||
|
},
|
||||||
|
extract: (trigger) => trigger.filter_has_any_document_types,
|
||||||
|
hasValue: (value) => Array.isArray(value) && value.length > 0,
|
||||||
|
},
|
||||||
[TriggerFilterType.DocumentTypeNot]: {
|
[TriggerFilterType.DocumentTypeNot]: {
|
||||||
apply: (aggregate, values) => {
|
apply: (aggregate, values) => {
|
||||||
aggregate.filter_has_not_document_types = Array.isArray(values)
|
aggregate.filter_has_not_document_types = Array.isArray(values)
|
||||||
@@ -351,6 +399,15 @@ const FILTER_HANDLERS: Record<TriggerFilterType, FilterHandler> = {
|
|||||||
extract: (trigger) => trigger.filter_has_storage_path,
|
extract: (trigger) => trigger.filter_has_storage_path,
|
||||||
hasValue: (value) => value !== null && value !== undefined,
|
hasValue: (value) => value !== null && value !== undefined,
|
||||||
},
|
},
|
||||||
|
[TriggerFilterType.StoragePathAny]: {
|
||||||
|
apply: (aggregate, values) => {
|
||||||
|
aggregate.filter_has_any_storage_paths = Array.isArray(values)
|
||||||
|
? [...values]
|
||||||
|
: [values]
|
||||||
|
},
|
||||||
|
extract: (trigger) => trigger.filter_has_any_storage_paths,
|
||||||
|
hasValue: (value) => Array.isArray(value) && value.length > 0,
|
||||||
|
},
|
||||||
[TriggerFilterType.StoragePathNot]: {
|
[TriggerFilterType.StoragePathNot]: {
|
||||||
apply: (aggregate, values) => {
|
apply: (aggregate, values) => {
|
||||||
aggregate.filter_has_not_storage_paths = Array.isArray(values)
|
aggregate.filter_has_not_storage_paths = Array.isArray(values)
|
||||||
@@ -642,8 +699,11 @@ export class WorkflowEditDialogComponent
|
|||||||
filter_has_tags: [],
|
filter_has_tags: [],
|
||||||
filter_has_all_tags: [],
|
filter_has_all_tags: [],
|
||||||
filter_has_not_tags: [],
|
filter_has_not_tags: [],
|
||||||
|
filter_has_any_correspondents: [],
|
||||||
filter_has_not_correspondents: [],
|
filter_has_not_correspondents: [],
|
||||||
|
filter_has_any_document_types: [],
|
||||||
filter_has_not_document_types: [],
|
filter_has_not_document_types: [],
|
||||||
|
filter_has_any_storage_paths: [],
|
||||||
filter_has_not_storage_paths: [],
|
filter_has_not_storage_paths: [],
|
||||||
filter_has_correspondent: null,
|
filter_has_correspondent: null,
|
||||||
filter_has_document_type: null,
|
filter_has_document_type: null,
|
||||||
@@ -670,10 +730,16 @@ export class WorkflowEditDialogComponent
|
|||||||
trigger.filter_has_tags = aggregate.filter_has_tags
|
trigger.filter_has_tags = aggregate.filter_has_tags
|
||||||
trigger.filter_has_all_tags = aggregate.filter_has_all_tags
|
trigger.filter_has_all_tags = aggregate.filter_has_all_tags
|
||||||
trigger.filter_has_not_tags = aggregate.filter_has_not_tags
|
trigger.filter_has_not_tags = aggregate.filter_has_not_tags
|
||||||
|
trigger.filter_has_any_correspondents =
|
||||||
|
aggregate.filter_has_any_correspondents
|
||||||
trigger.filter_has_not_correspondents =
|
trigger.filter_has_not_correspondents =
|
||||||
aggregate.filter_has_not_correspondents
|
aggregate.filter_has_not_correspondents
|
||||||
|
trigger.filter_has_any_document_types =
|
||||||
|
aggregate.filter_has_any_document_types
|
||||||
trigger.filter_has_not_document_types =
|
trigger.filter_has_not_document_types =
|
||||||
aggregate.filter_has_not_document_types
|
aggregate.filter_has_not_document_types
|
||||||
|
trigger.filter_has_any_storage_paths =
|
||||||
|
aggregate.filter_has_any_storage_paths
|
||||||
trigger.filter_has_not_storage_paths =
|
trigger.filter_has_not_storage_paths =
|
||||||
aggregate.filter_has_not_storage_paths
|
aggregate.filter_has_not_storage_paths
|
||||||
trigger.filter_has_correspondent =
|
trigger.filter_has_correspondent =
|
||||||
@@ -856,8 +922,11 @@ export class WorkflowEditDialogComponent
|
|||||||
case TriggerFilterType.TagsAny:
|
case TriggerFilterType.TagsAny:
|
||||||
case TriggerFilterType.TagsAll:
|
case TriggerFilterType.TagsAll:
|
||||||
case TriggerFilterType.TagsNone:
|
case TriggerFilterType.TagsNone:
|
||||||
|
case TriggerFilterType.CorrespondentAny:
|
||||||
case TriggerFilterType.CorrespondentNot:
|
case TriggerFilterType.CorrespondentNot:
|
||||||
|
case TriggerFilterType.DocumentTypeAny:
|
||||||
case TriggerFilterType.DocumentTypeNot:
|
case TriggerFilterType.DocumentTypeNot:
|
||||||
|
case TriggerFilterType.StoragePathAny:
|
||||||
case TriggerFilterType.StoragePathNot:
|
case TriggerFilterType.StoragePathNot:
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
@@ -1179,8 +1248,11 @@ export class WorkflowEditDialogComponent
|
|||||||
filter_has_tags: [],
|
filter_has_tags: [],
|
||||||
filter_has_all_tags: [],
|
filter_has_all_tags: [],
|
||||||
filter_has_not_tags: [],
|
filter_has_not_tags: [],
|
||||||
|
filter_has_any_correspondents: [],
|
||||||
filter_has_not_correspondents: [],
|
filter_has_not_correspondents: [],
|
||||||
|
filter_has_any_document_types: [],
|
||||||
filter_has_not_document_types: [],
|
filter_has_not_document_types: [],
|
||||||
|
filter_has_any_storage_paths: [],
|
||||||
filter_has_not_storage_paths: [],
|
filter_has_not_storage_paths: [],
|
||||||
filter_custom_field_query: null,
|
filter_custom_field_query: null,
|
||||||
filter_has_correspondent: null,
|
filter_has_correspondent: null,
|
||||||
|
|||||||
@@ -44,10 +44,16 @@ export interface WorkflowTrigger extends ObjectWithId {
|
|||||||
|
|
||||||
filter_has_not_tags?: number[] // Tag.id[]
|
filter_has_not_tags?: number[] // Tag.id[]
|
||||||
|
|
||||||
|
filter_has_any_correspondents?: number[] // Correspondent.id[]
|
||||||
|
|
||||||
filter_has_not_correspondents?: number[] // Correspondent.id[]
|
filter_has_not_correspondents?: number[] // Correspondent.id[]
|
||||||
|
|
||||||
|
filter_has_any_document_types?: number[] // DocumentType.id[]
|
||||||
|
|
||||||
filter_has_not_document_types?: number[] // DocumentType.id[]
|
filter_has_not_document_types?: number[] // DocumentType.id[]
|
||||||
|
|
||||||
|
filter_has_any_storage_paths?: number[] // StoragePath.id[]
|
||||||
|
|
||||||
filter_has_not_storage_paths?: number[] // StoragePath.id[]
|
filter_has_not_storage_paths?: number[] // StoragePath.id[]
|
||||||
|
|
||||||
filter_custom_field_query?: string
|
filter_custom_field_query?: string
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ class DocumentMetadataOverrides:
|
|||||||
).values_list("id", flat=True),
|
).values_list("id", flat=True),
|
||||||
)
|
)
|
||||||
overrides.custom_fields = {
|
overrides.custom_fields = {
|
||||||
custom_field.id: custom_field.value
|
custom_field.field.id: custom_field.value
|
||||||
for custom_field in doc.custom_fields.all()
|
for custom_field in doc.custom_fields.all()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -403,6 +403,18 @@ def existing_document_matches_workflow(
|
|||||||
f"Document tags {list(document.tags.all())} include excluded tags {list(trigger_has_not_tags_qs)}",
|
f"Document tags {list(document.tags.all())} include excluded tags {list(trigger_has_not_tags_qs)}",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
allowed_correspondent_ids = set(
|
||||||
|
trigger.filter_has_any_correspondents.values_list("id", flat=True),
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
allowed_correspondent_ids
|
||||||
|
and document.correspondent_id not in allowed_correspondent_ids
|
||||||
|
):
|
||||||
|
return (
|
||||||
|
False,
|
||||||
|
f"Document correspondent {document.correspondent} is not one of {list(trigger.filter_has_any_correspondents.all())}",
|
||||||
|
)
|
||||||
|
|
||||||
# Document correspondent vs trigger has_correspondent
|
# Document correspondent vs trigger has_correspondent
|
||||||
if (
|
if (
|
||||||
trigger.filter_has_correspondent_id is not None
|
trigger.filter_has_correspondent_id is not None
|
||||||
@@ -424,6 +436,17 @@ def existing_document_matches_workflow(
|
|||||||
f"Document correspondent {document.correspondent} is excluded by {list(trigger.filter_has_not_correspondents.all())}",
|
f"Document correspondent {document.correspondent} is excluded by {list(trigger.filter_has_not_correspondents.all())}",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
allowed_document_type_ids = set(
|
||||||
|
trigger.filter_has_any_document_types.values_list("id", flat=True),
|
||||||
|
)
|
||||||
|
if allowed_document_type_ids and (
|
||||||
|
document.document_type_id not in allowed_document_type_ids
|
||||||
|
):
|
||||||
|
return (
|
||||||
|
False,
|
||||||
|
f"Document doc type {document.document_type} is not one of {list(trigger.filter_has_any_document_types.all())}",
|
||||||
|
)
|
||||||
|
|
||||||
# Document document_type vs trigger has_document_type
|
# Document document_type vs trigger has_document_type
|
||||||
if (
|
if (
|
||||||
trigger.filter_has_document_type_id is not None
|
trigger.filter_has_document_type_id is not None
|
||||||
@@ -445,6 +468,17 @@ def existing_document_matches_workflow(
|
|||||||
f"Document doc type {document.document_type} is excluded by {list(trigger.filter_has_not_document_types.all())}",
|
f"Document doc type {document.document_type} is excluded by {list(trigger.filter_has_not_document_types.all())}",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
allowed_storage_path_ids = set(
|
||||||
|
trigger.filter_has_any_storage_paths.values_list("id", flat=True),
|
||||||
|
)
|
||||||
|
if allowed_storage_path_ids and (
|
||||||
|
document.storage_path_id not in allowed_storage_path_ids
|
||||||
|
):
|
||||||
|
return (
|
||||||
|
False,
|
||||||
|
f"Document storage path {document.storage_path} is not one of {list(trigger.filter_has_any_storage_paths.all())}",
|
||||||
|
)
|
||||||
|
|
||||||
# Document storage_path vs trigger has_storage_path
|
# Document storage_path vs trigger has_storage_path
|
||||||
if (
|
if (
|
||||||
trigger.filter_has_storage_path_id is not None
|
trigger.filter_has_storage_path_id is not None
|
||||||
@@ -532,6 +566,10 @@ def prefilter_documents_by_workflowtrigger(
|
|||||||
|
|
||||||
# Correspondent, DocumentType, etc. filtering
|
# Correspondent, DocumentType, etc. filtering
|
||||||
|
|
||||||
|
if trigger.filter_has_any_correspondents.exists():
|
||||||
|
documents = documents.filter(
|
||||||
|
correspondent__in=trigger.filter_has_any_correspondents.all(),
|
||||||
|
)
|
||||||
if trigger.filter_has_correspondent is not None:
|
if trigger.filter_has_correspondent is not None:
|
||||||
documents = documents.filter(
|
documents = documents.filter(
|
||||||
correspondent=trigger.filter_has_correspondent,
|
correspondent=trigger.filter_has_correspondent,
|
||||||
@@ -541,6 +579,10 @@ def prefilter_documents_by_workflowtrigger(
|
|||||||
correspondent__in=trigger.filter_has_not_correspondents.all(),
|
correspondent__in=trigger.filter_has_not_correspondents.all(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if trigger.filter_has_any_document_types.exists():
|
||||||
|
documents = documents.filter(
|
||||||
|
document_type__in=trigger.filter_has_any_document_types.all(),
|
||||||
|
)
|
||||||
if trigger.filter_has_document_type is not None:
|
if trigger.filter_has_document_type is not None:
|
||||||
documents = documents.filter(
|
documents = documents.filter(
|
||||||
document_type=trigger.filter_has_document_type,
|
document_type=trigger.filter_has_document_type,
|
||||||
@@ -550,6 +592,10 @@ def prefilter_documents_by_workflowtrigger(
|
|||||||
document_type__in=trigger.filter_has_not_document_types.all(),
|
document_type__in=trigger.filter_has_not_document_types.all(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if trigger.filter_has_any_storage_paths.exists():
|
||||||
|
documents = documents.filter(
|
||||||
|
storage_path__in=trigger.filter_has_any_storage_paths.all(),
|
||||||
|
)
|
||||||
if trigger.filter_has_storage_path is not None:
|
if trigger.filter_has_storage_path is not None:
|
||||||
documents = documents.filter(
|
documents = documents.filter(
|
||||||
storage_path=trigger.filter_has_storage_path,
|
storage_path=trigger.filter_has_storage_path,
|
||||||
@@ -604,8 +650,11 @@ def document_matches_workflow(
|
|||||||
"filter_has_tags",
|
"filter_has_tags",
|
||||||
"filter_has_all_tags",
|
"filter_has_all_tags",
|
||||||
"filter_has_not_tags",
|
"filter_has_not_tags",
|
||||||
|
"filter_has_any_document_types",
|
||||||
"filter_has_not_document_types",
|
"filter_has_not_document_types",
|
||||||
|
"filter_has_any_correspondents",
|
||||||
"filter_has_not_correspondents",
|
"filter_has_not_correspondents",
|
||||||
|
"filter_has_any_storage_paths",
|
||||||
"filter_has_not_storage_paths",
|
"filter_has_not_storage_paths",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
# Generated by Django 5.2.7 on 2025-12-17 22:25
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("documents", "0004_remove_document_storage_type"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="workflowtrigger",
|
||||||
|
name="filter_has_any_correspondents",
|
||||||
|
field=models.ManyToManyField(
|
||||||
|
blank=True,
|
||||||
|
related_name="workflowtriggers_has_any_correspondent",
|
||||||
|
to="documents.correspondent",
|
||||||
|
verbose_name="has one of these correspondents",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="workflowtrigger",
|
||||||
|
name="filter_has_any_document_types",
|
||||||
|
field=models.ManyToManyField(
|
||||||
|
blank=True,
|
||||||
|
related_name="workflowtriggers_has_any_document_type",
|
||||||
|
to="documents.documenttype",
|
||||||
|
verbose_name="has one of these document types",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="workflowtrigger",
|
||||||
|
name="filter_has_any_storage_paths",
|
||||||
|
field=models.ManyToManyField(
|
||||||
|
blank=True,
|
||||||
|
related_name="workflowtriggers_has_any_storage_path",
|
||||||
|
to="documents.storagepath",
|
||||||
|
verbose_name="has one of these storage paths",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1180,6 +1180,13 @@ class WorkflowTrigger(models.Model):
|
|||||||
verbose_name=_("has this document type"),
|
verbose_name=_("has this document type"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
filter_has_any_document_types = models.ManyToManyField(
|
||||||
|
DocumentType,
|
||||||
|
blank=True,
|
||||||
|
related_name="workflowtriggers_has_any_document_type",
|
||||||
|
verbose_name=_("has one of these document types"),
|
||||||
|
)
|
||||||
|
|
||||||
filter_has_not_document_types = models.ManyToManyField(
|
filter_has_not_document_types = models.ManyToManyField(
|
||||||
DocumentType,
|
DocumentType,
|
||||||
blank=True,
|
blank=True,
|
||||||
@@ -1202,6 +1209,13 @@ class WorkflowTrigger(models.Model):
|
|||||||
verbose_name=_("does not have these correspondent(s)"),
|
verbose_name=_("does not have these correspondent(s)"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
filter_has_any_correspondents = models.ManyToManyField(
|
||||||
|
Correspondent,
|
||||||
|
blank=True,
|
||||||
|
related_name="workflowtriggers_has_any_correspondent",
|
||||||
|
verbose_name=_("has one of these correspondents"),
|
||||||
|
)
|
||||||
|
|
||||||
filter_has_storage_path = models.ForeignKey(
|
filter_has_storage_path = models.ForeignKey(
|
||||||
StoragePath,
|
StoragePath,
|
||||||
null=True,
|
null=True,
|
||||||
@@ -1210,6 +1224,13 @@ class WorkflowTrigger(models.Model):
|
|||||||
verbose_name=_("has this storage path"),
|
verbose_name=_("has this storage path"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
filter_has_any_storage_paths = models.ManyToManyField(
|
||||||
|
StoragePath,
|
||||||
|
blank=True,
|
||||||
|
related_name="workflowtriggers_has_any_storage_path",
|
||||||
|
verbose_name=_("has one of these storage paths"),
|
||||||
|
)
|
||||||
|
|
||||||
filter_has_not_storage_paths = models.ManyToManyField(
|
filter_has_not_storage_paths = models.ManyToManyField(
|
||||||
StoragePath,
|
StoragePath,
|
||||||
blank=True,
|
blank=True,
|
||||||
|
|||||||
@@ -2405,8 +2405,11 @@ class WorkflowTriggerSerializer(serializers.ModelSerializer):
|
|||||||
"filter_has_all_tags",
|
"filter_has_all_tags",
|
||||||
"filter_has_not_tags",
|
"filter_has_not_tags",
|
||||||
"filter_custom_field_query",
|
"filter_custom_field_query",
|
||||||
|
"filter_has_any_correspondents",
|
||||||
"filter_has_not_correspondents",
|
"filter_has_not_correspondents",
|
||||||
|
"filter_has_any_document_types",
|
||||||
"filter_has_not_document_types",
|
"filter_has_not_document_types",
|
||||||
|
"filter_has_any_storage_paths",
|
||||||
"filter_has_not_storage_paths",
|
"filter_has_not_storage_paths",
|
||||||
"filter_has_correspondent",
|
"filter_has_correspondent",
|
||||||
"filter_has_document_type",
|
"filter_has_document_type",
|
||||||
@@ -2644,14 +2647,26 @@ class WorkflowSerializer(serializers.ModelSerializer):
|
|||||||
filter_has_tags = trigger.pop("filter_has_tags", None)
|
filter_has_tags = trigger.pop("filter_has_tags", None)
|
||||||
filter_has_all_tags = trigger.pop("filter_has_all_tags", None)
|
filter_has_all_tags = trigger.pop("filter_has_all_tags", None)
|
||||||
filter_has_not_tags = trigger.pop("filter_has_not_tags", None)
|
filter_has_not_tags = trigger.pop("filter_has_not_tags", None)
|
||||||
|
filter_has_any_correspondents = trigger.pop(
|
||||||
|
"filter_has_any_correspondents",
|
||||||
|
None,
|
||||||
|
)
|
||||||
filter_has_not_correspondents = trigger.pop(
|
filter_has_not_correspondents = trigger.pop(
|
||||||
"filter_has_not_correspondents",
|
"filter_has_not_correspondents",
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
filter_has_any_document_types = trigger.pop(
|
||||||
|
"filter_has_any_document_types",
|
||||||
|
None,
|
||||||
|
)
|
||||||
filter_has_not_document_types = trigger.pop(
|
filter_has_not_document_types = trigger.pop(
|
||||||
"filter_has_not_document_types",
|
"filter_has_not_document_types",
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
filter_has_any_storage_paths = trigger.pop(
|
||||||
|
"filter_has_any_storage_paths",
|
||||||
|
None,
|
||||||
|
)
|
||||||
filter_has_not_storage_paths = trigger.pop(
|
filter_has_not_storage_paths = trigger.pop(
|
||||||
"filter_has_not_storage_paths",
|
"filter_has_not_storage_paths",
|
||||||
None,
|
None,
|
||||||
@@ -2668,14 +2683,26 @@ class WorkflowSerializer(serializers.ModelSerializer):
|
|||||||
trigger_instance.filter_has_all_tags.set(filter_has_all_tags)
|
trigger_instance.filter_has_all_tags.set(filter_has_all_tags)
|
||||||
if filter_has_not_tags is not None:
|
if filter_has_not_tags is not None:
|
||||||
trigger_instance.filter_has_not_tags.set(filter_has_not_tags)
|
trigger_instance.filter_has_not_tags.set(filter_has_not_tags)
|
||||||
|
if filter_has_any_correspondents is not None:
|
||||||
|
trigger_instance.filter_has_any_correspondents.set(
|
||||||
|
filter_has_any_correspondents,
|
||||||
|
)
|
||||||
if filter_has_not_correspondents is not None:
|
if filter_has_not_correspondents is not None:
|
||||||
trigger_instance.filter_has_not_correspondents.set(
|
trigger_instance.filter_has_not_correspondents.set(
|
||||||
filter_has_not_correspondents,
|
filter_has_not_correspondents,
|
||||||
)
|
)
|
||||||
|
if filter_has_any_document_types is not None:
|
||||||
|
trigger_instance.filter_has_any_document_types.set(
|
||||||
|
filter_has_any_document_types,
|
||||||
|
)
|
||||||
if filter_has_not_document_types is not None:
|
if filter_has_not_document_types is not None:
|
||||||
trigger_instance.filter_has_not_document_types.set(
|
trigger_instance.filter_has_not_document_types.set(
|
||||||
filter_has_not_document_types,
|
filter_has_not_document_types,
|
||||||
)
|
)
|
||||||
|
if filter_has_any_storage_paths is not None:
|
||||||
|
trigger_instance.filter_has_any_storage_paths.set(
|
||||||
|
filter_has_any_storage_paths,
|
||||||
|
)
|
||||||
if filter_has_not_storage_paths is not None:
|
if filter_has_not_storage_paths is not None:
|
||||||
trigger_instance.filter_has_not_storage_paths.set(
|
trigger_instance.filter_has_not_storage_paths.set(
|
||||||
filter_has_not_storage_paths,
|
filter_has_not_storage_paths,
|
||||||
|
|||||||
@@ -186,8 +186,11 @@ class TestApiWorkflows(DirectoriesMixin, APITestCase):
|
|||||||
"filter_has_tags": [self.t1.id],
|
"filter_has_tags": [self.t1.id],
|
||||||
"filter_has_all_tags": [self.t2.id],
|
"filter_has_all_tags": [self.t2.id],
|
||||||
"filter_has_not_tags": [self.t3.id],
|
"filter_has_not_tags": [self.t3.id],
|
||||||
|
"filter_has_any_correspondents": [self.c.id],
|
||||||
"filter_has_not_correspondents": [self.c2.id],
|
"filter_has_not_correspondents": [self.c2.id],
|
||||||
|
"filter_has_any_document_types": [self.dt.id],
|
||||||
"filter_has_not_document_types": [self.dt2.id],
|
"filter_has_not_document_types": [self.dt2.id],
|
||||||
|
"filter_has_any_storage_paths": [self.sp.id],
|
||||||
"filter_has_not_storage_paths": [self.sp2.id],
|
"filter_has_not_storage_paths": [self.sp2.id],
|
||||||
"filter_custom_field_query": json.dumps(
|
"filter_custom_field_query": json.dumps(
|
||||||
[
|
[
|
||||||
@@ -248,14 +251,26 @@ class TestApiWorkflows(DirectoriesMixin, APITestCase):
|
|||||||
set(trigger.filter_has_not_tags.values_list("id", flat=True)),
|
set(trigger.filter_has_not_tags.values_list("id", flat=True)),
|
||||||
{self.t3.id},
|
{self.t3.id},
|
||||||
)
|
)
|
||||||
|
self.assertSetEqual(
|
||||||
|
set(trigger.filter_has_any_correspondents.values_list("id", flat=True)),
|
||||||
|
{self.c.id},
|
||||||
|
)
|
||||||
self.assertSetEqual(
|
self.assertSetEqual(
|
||||||
set(trigger.filter_has_not_correspondents.values_list("id", flat=True)),
|
set(trigger.filter_has_not_correspondents.values_list("id", flat=True)),
|
||||||
{self.c2.id},
|
{self.c2.id},
|
||||||
)
|
)
|
||||||
|
self.assertSetEqual(
|
||||||
|
set(trigger.filter_has_any_document_types.values_list("id", flat=True)),
|
||||||
|
{self.dt.id},
|
||||||
|
)
|
||||||
self.assertSetEqual(
|
self.assertSetEqual(
|
||||||
set(trigger.filter_has_not_document_types.values_list("id", flat=True)),
|
set(trigger.filter_has_not_document_types.values_list("id", flat=True)),
|
||||||
{self.dt2.id},
|
{self.dt2.id},
|
||||||
)
|
)
|
||||||
|
self.assertSetEqual(
|
||||||
|
set(trigger.filter_has_any_storage_paths.values_list("id", flat=True)),
|
||||||
|
{self.sp.id},
|
||||||
|
)
|
||||||
self.assertSetEqual(
|
self.assertSetEqual(
|
||||||
set(trigger.filter_has_not_storage_paths.values_list("id", flat=True)),
|
set(trigger.filter_has_not_storage_paths.values_list("id", flat=True)),
|
||||||
{self.sp2.id},
|
{self.sp2.id},
|
||||||
@@ -419,8 +434,11 @@ class TestApiWorkflows(DirectoriesMixin, APITestCase):
|
|||||||
"filter_has_tags": [self.t1.id],
|
"filter_has_tags": [self.t1.id],
|
||||||
"filter_has_all_tags": [self.t2.id],
|
"filter_has_all_tags": [self.t2.id],
|
||||||
"filter_has_not_tags": [self.t3.id],
|
"filter_has_not_tags": [self.t3.id],
|
||||||
|
"filter_has_any_correspondents": [self.c.id],
|
||||||
"filter_has_not_correspondents": [self.c2.id],
|
"filter_has_not_correspondents": [self.c2.id],
|
||||||
|
"filter_has_any_document_types": [self.dt.id],
|
||||||
"filter_has_not_document_types": [self.dt2.id],
|
"filter_has_not_document_types": [self.dt2.id],
|
||||||
|
"filter_has_any_storage_paths": [self.sp.id],
|
||||||
"filter_has_not_storage_paths": [self.sp2.id],
|
"filter_has_not_storage_paths": [self.sp2.id],
|
||||||
"filter_custom_field_query": json.dumps(
|
"filter_custom_field_query": json.dumps(
|
||||||
["AND", [[self.cf1.id, "exact", "value"]]],
|
["AND", [[self.cf1.id, "exact", "value"]]],
|
||||||
@@ -450,14 +468,26 @@ class TestApiWorkflows(DirectoriesMixin, APITestCase):
|
|||||||
workflow.triggers.first().filter_has_not_tags.first(),
|
workflow.triggers.first().filter_has_not_tags.first(),
|
||||||
self.t3,
|
self.t3,
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
workflow.triggers.first().filter_has_any_correspondents.first(),
|
||||||
|
self.c,
|
||||||
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
workflow.triggers.first().filter_has_not_correspondents.first(),
|
workflow.triggers.first().filter_has_not_correspondents.first(),
|
||||||
self.c2,
|
self.c2,
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
workflow.triggers.first().filter_has_any_document_types.first(),
|
||||||
|
self.dt,
|
||||||
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
workflow.triggers.first().filter_has_not_document_types.first(),
|
workflow.triggers.first().filter_has_not_document_types.first(),
|
||||||
self.dt2,
|
self.dt2,
|
||||||
)
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
workflow.triggers.first().filter_has_any_storage_paths.first(),
|
||||||
|
self.sp,
|
||||||
|
)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
workflow.triggers.first().filter_has_not_storage_paths.first(),
|
workflow.triggers.first().filter_has_not_storage_paths.first(),
|
||||||
self.sp2,
|
self.sp2,
|
||||||
|
|||||||
@@ -1276,6 +1276,76 @@ class TestWorkflows(
|
|||||||
)
|
)
|
||||||
self.assertIn(expected_str, cm.output[1])
|
self.assertIn(expected_str, cm.output[1])
|
||||||
|
|
||||||
|
def test_document_added_any_filters(self):
|
||||||
|
trigger = WorkflowTrigger.objects.create(
|
||||||
|
type=WorkflowTrigger.WorkflowTriggerType.DOCUMENT_ADDED,
|
||||||
|
)
|
||||||
|
trigger.filter_has_any_correspondents.set([self.c])
|
||||||
|
trigger.filter_has_any_document_types.set([self.dt])
|
||||||
|
trigger.filter_has_any_storage_paths.set([self.sp])
|
||||||
|
|
||||||
|
matching_doc = Document.objects.create(
|
||||||
|
title="sample test",
|
||||||
|
correspondent=self.c,
|
||||||
|
document_type=self.dt,
|
||||||
|
storage_path=self.sp,
|
||||||
|
original_filename="sample.pdf",
|
||||||
|
checksum="checksum-any-match",
|
||||||
|
)
|
||||||
|
|
||||||
|
matched, reason = existing_document_matches_workflow(matching_doc, trigger)
|
||||||
|
self.assertTrue(matched)
|
||||||
|
self.assertIsNone(reason)
|
||||||
|
|
||||||
|
wrong_correspondent = Document.objects.create(
|
||||||
|
title="wrong correspondent",
|
||||||
|
correspondent=self.c2,
|
||||||
|
document_type=self.dt,
|
||||||
|
storage_path=self.sp,
|
||||||
|
original_filename="sample2.pdf",
|
||||||
|
)
|
||||||
|
matched, reason = existing_document_matches_workflow(
|
||||||
|
wrong_correspondent,
|
||||||
|
trigger,
|
||||||
|
)
|
||||||
|
self.assertFalse(matched)
|
||||||
|
self.assertIn("correspondent", reason)
|
||||||
|
|
||||||
|
other_document_type = DocumentType.objects.create(name="Other")
|
||||||
|
wrong_document_type = Document.objects.create(
|
||||||
|
title="wrong doc type",
|
||||||
|
correspondent=self.c,
|
||||||
|
document_type=other_document_type,
|
||||||
|
storage_path=self.sp,
|
||||||
|
original_filename="sample3.pdf",
|
||||||
|
checksum="checksum-wrong-doc-type",
|
||||||
|
)
|
||||||
|
matched, reason = existing_document_matches_workflow(
|
||||||
|
wrong_document_type,
|
||||||
|
trigger,
|
||||||
|
)
|
||||||
|
self.assertFalse(matched)
|
||||||
|
self.assertIn("doc type", reason)
|
||||||
|
|
||||||
|
other_storage_path = StoragePath.objects.create(
|
||||||
|
name="Other path",
|
||||||
|
path="/other/",
|
||||||
|
)
|
||||||
|
wrong_storage_path = Document.objects.create(
|
||||||
|
title="wrong storage",
|
||||||
|
correspondent=self.c,
|
||||||
|
document_type=self.dt,
|
||||||
|
storage_path=other_storage_path,
|
||||||
|
original_filename="sample4.pdf",
|
||||||
|
checksum="checksum-wrong-storage-path",
|
||||||
|
)
|
||||||
|
matched, reason = existing_document_matches_workflow(
|
||||||
|
wrong_storage_path,
|
||||||
|
trigger,
|
||||||
|
)
|
||||||
|
self.assertFalse(matched)
|
||||||
|
self.assertIn("storage path", reason)
|
||||||
|
|
||||||
def test_document_added_custom_field_query_no_match(self):
|
def test_document_added_custom_field_query_no_match(self):
|
||||||
trigger = WorkflowTrigger.objects.create(
|
trigger = WorkflowTrigger.objects.create(
|
||||||
type=WorkflowTrigger.WorkflowTriggerType.DOCUMENT_ADDED,
|
type=WorkflowTrigger.WorkflowTriggerType.DOCUMENT_ADDED,
|
||||||
@@ -1384,6 +1454,39 @@ class TestWorkflows(
|
|||||||
self.assertIn(doc1, filtered)
|
self.assertIn(doc1, filtered)
|
||||||
self.assertNotIn(doc2, filtered)
|
self.assertNotIn(doc2, filtered)
|
||||||
|
|
||||||
|
def test_prefilter_documents_any_filters(self):
|
||||||
|
trigger = WorkflowTrigger.objects.create(
|
||||||
|
type=WorkflowTrigger.WorkflowTriggerType.DOCUMENT_ADDED,
|
||||||
|
)
|
||||||
|
trigger.filter_has_any_correspondents.set([self.c])
|
||||||
|
trigger.filter_has_any_document_types.set([self.dt])
|
||||||
|
trigger.filter_has_any_storage_paths.set([self.sp])
|
||||||
|
|
||||||
|
allowed_document = Document.objects.create(
|
||||||
|
title="allowed",
|
||||||
|
correspondent=self.c,
|
||||||
|
document_type=self.dt,
|
||||||
|
storage_path=self.sp,
|
||||||
|
original_filename="doc-allowed.pdf",
|
||||||
|
checksum="checksum-any-allowed",
|
||||||
|
)
|
||||||
|
blocked_document = Document.objects.create(
|
||||||
|
title="blocked",
|
||||||
|
correspondent=self.c2,
|
||||||
|
document_type=self.dt,
|
||||||
|
storage_path=self.sp,
|
||||||
|
original_filename="doc-blocked.pdf",
|
||||||
|
checksum="checksum-any-blocked",
|
||||||
|
)
|
||||||
|
|
||||||
|
filtered = prefilter_documents_by_workflowtrigger(
|
||||||
|
Document.objects.all(),
|
||||||
|
trigger,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIn(allowed_document, filtered)
|
||||||
|
self.assertNotIn(blocked_document, filtered)
|
||||||
|
|
||||||
def test_consumption_trigger_requires_filter_configuration(self):
|
def test_consumption_trigger_requires_filter_configuration(self):
|
||||||
serializer = WorkflowTriggerSerializer(
|
serializer = WorkflowTriggerSerializer(
|
||||||
data={
|
data={
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: paperless-ngx\n"
|
"Project-Id-Version: paperless-ngx\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2026-01-25 03:30+0000\n"
|
"POT-Creation-Date: 2026-01-25 21:46+0000\n"
|
||||||
"PO-Revision-Date: 2022-02-17 04:17\n"
|
"PO-Revision-Date: 2022-02-17 04:17\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: English\n"
|
"Language-Team: English\n"
|
||||||
@@ -89,7 +89,7 @@ msgstr ""
|
|||||||
msgid "Automatic"
|
msgid "Automatic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:64 documents/models.py:434 documents/models.py:1507
|
#: documents/models.py:64 documents/models.py:434 documents/models.py:1528
|
||||||
#: paperless_mail/models.py:23 paperless_mail/models.py:143
|
#: paperless_mail/models.py:23 paperless_mail/models.py:143
|
||||||
msgid "name"
|
msgid "name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -252,7 +252,7 @@ msgid "The position of this document in your physical document archive."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:303 documents/models.py:678 documents/models.py:732
|
#: documents/models.py:303 documents/models.py:678 documents/models.py:732
|
||||||
#: documents/models.py:1550
|
#: documents/models.py:1571
|
||||||
msgid "document"
|
msgid "document"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -869,346 +869,358 @@ msgid "has this document type"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1073
|
#: documents/models.py:1073
|
||||||
|
msgid "has one of these document types"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: documents/models.py:1080
|
||||||
msgid "does not have these document type(s)"
|
msgid "does not have these document type(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1081
|
#: documents/models.py:1088
|
||||||
msgid "has this correspondent"
|
msgid "has this correspondent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1088
|
#: documents/models.py:1095
|
||||||
msgid "does not have these correspondent(s)"
|
msgid "does not have these correspondent(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1096
|
#: documents/models.py:1102
|
||||||
msgid "has this storage path"
|
msgid "has one of these correspondents"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: documents/models.py:1103
|
|
||||||
msgid "does not have these storage path(s)"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: documents/models.py:1107
|
|
||||||
msgid "filter custom field query"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1110
|
#: documents/models.py:1110
|
||||||
msgid "JSON-encoded custom field query expression."
|
msgid "has this storage path"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: documents/models.py:1114
|
|
||||||
msgid "schedule offset days"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1117
|
#: documents/models.py:1117
|
||||||
|
msgid "has one of these storage paths"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: documents/models.py:1124
|
||||||
|
msgid "does not have these storage path(s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: documents/models.py:1128
|
||||||
|
msgid "filter custom field query"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: documents/models.py:1131
|
||||||
|
msgid "JSON-encoded custom field query expression."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: documents/models.py:1135
|
||||||
|
msgid "schedule offset days"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: documents/models.py:1138
|
||||||
msgid "The number of days to offset the schedule trigger by."
|
msgid "The number of days to offset the schedule trigger by."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1122
|
#: documents/models.py:1143
|
||||||
msgid "schedule is recurring"
|
msgid "schedule is recurring"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1125
|
#: documents/models.py:1146
|
||||||
msgid "If the schedule should be recurring."
|
msgid "If the schedule should be recurring."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1130
|
#: documents/models.py:1151
|
||||||
msgid "schedule recurring delay in days"
|
msgid "schedule recurring delay in days"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1134
|
#: documents/models.py:1155
|
||||||
msgid "The number of days between recurring schedule triggers."
|
msgid "The number of days between recurring schedule triggers."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1139
|
#: documents/models.py:1160
|
||||||
msgid "schedule date field"
|
msgid "schedule date field"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1144
|
#: documents/models.py:1165
|
||||||
msgid "The field to check for a schedule trigger."
|
msgid "The field to check for a schedule trigger."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1153
|
#: documents/models.py:1174
|
||||||
msgid "schedule date custom field"
|
msgid "schedule date custom field"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1157
|
#: documents/models.py:1178
|
||||||
msgid "workflow trigger"
|
msgid "workflow trigger"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1158
|
#: documents/models.py:1179
|
||||||
msgid "workflow triggers"
|
msgid "workflow triggers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1166
|
#: documents/models.py:1187
|
||||||
msgid "email subject"
|
msgid "email subject"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1170
|
#: documents/models.py:1191
|
||||||
msgid ""
|
msgid ""
|
||||||
"The subject of the email, can include some placeholders, see documentation."
|
"The subject of the email, can include some placeholders, see documentation."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1176
|
#: documents/models.py:1197
|
||||||
msgid "email body"
|
msgid "email body"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1179
|
#: documents/models.py:1200
|
||||||
msgid ""
|
msgid ""
|
||||||
"The body (message) of the email, can include some placeholders, see "
|
"The body (message) of the email, can include some placeholders, see "
|
||||||
"documentation."
|
"documentation."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1185
|
#: documents/models.py:1206
|
||||||
msgid "emails to"
|
msgid "emails to"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1188
|
#: documents/models.py:1209
|
||||||
msgid "The destination email addresses, comma separated."
|
msgid "The destination email addresses, comma separated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1194
|
#: documents/models.py:1215
|
||||||
msgid "include document in email"
|
msgid "include document in email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1205
|
#: documents/models.py:1226
|
||||||
msgid "webhook url"
|
msgid "webhook url"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1208
|
#: documents/models.py:1229
|
||||||
msgid "The destination URL for the notification."
|
msgid "The destination URL for the notification."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1213
|
#: documents/models.py:1234
|
||||||
msgid "use parameters"
|
msgid "use parameters"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1218
|
#: documents/models.py:1239
|
||||||
msgid "send as JSON"
|
msgid "send as JSON"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1222
|
#: documents/models.py:1243
|
||||||
msgid "webhook parameters"
|
msgid "webhook parameters"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1225
|
#: documents/models.py:1246
|
||||||
msgid "The parameters to send with the webhook URL if body not used."
|
msgid "The parameters to send with the webhook URL if body not used."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1229
|
#: documents/models.py:1250
|
||||||
msgid "webhook body"
|
msgid "webhook body"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1232
|
#: documents/models.py:1253
|
||||||
msgid "The body to send with the webhook URL if parameters not used."
|
msgid "The body to send with the webhook URL if parameters not used."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1236
|
#: documents/models.py:1257
|
||||||
msgid "webhook headers"
|
msgid "webhook headers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1239
|
#: documents/models.py:1260
|
||||||
msgid "The headers to send with the webhook URL."
|
msgid "The headers to send with the webhook URL."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1244
|
#: documents/models.py:1265
|
||||||
msgid "include document in webhook"
|
msgid "include document in webhook"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1255
|
#: documents/models.py:1276
|
||||||
msgid "Assignment"
|
msgid "Assignment"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1259
|
#: documents/models.py:1280
|
||||||
msgid "Removal"
|
msgid "Removal"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1263 documents/templates/account/password_reset.html:15
|
#: documents/models.py:1284 documents/templates/account/password_reset.html:15
|
||||||
msgid "Email"
|
msgid "Email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1267
|
#: documents/models.py:1288
|
||||||
msgid "Webhook"
|
msgid "Webhook"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1271
|
#: documents/models.py:1292
|
||||||
msgid "Workflow Action Type"
|
msgid "Workflow Action Type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1276 documents/models.py:1509
|
#: documents/models.py:1297 documents/models.py:1530
|
||||||
#: paperless_mail/models.py:145
|
#: paperless_mail/models.py:145
|
||||||
msgid "order"
|
msgid "order"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1279
|
#: documents/models.py:1300
|
||||||
msgid "assign title"
|
msgid "assign title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1283
|
#: documents/models.py:1304
|
||||||
msgid "Assign a document title, must be a Jinja2 template, see documentation."
|
msgid "Assign a document title, must be a Jinja2 template, see documentation."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1291 paperless_mail/models.py:274
|
#: documents/models.py:1312 paperless_mail/models.py:274
|
||||||
msgid "assign this tag"
|
msgid "assign this tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1300 paperless_mail/models.py:282
|
#: documents/models.py:1321 paperless_mail/models.py:282
|
||||||
msgid "assign this document type"
|
msgid "assign this document type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1309 paperless_mail/models.py:296
|
#: documents/models.py:1330 paperless_mail/models.py:296
|
||||||
msgid "assign this correspondent"
|
msgid "assign this correspondent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1318
|
#: documents/models.py:1339
|
||||||
msgid "assign this storage path"
|
msgid "assign this storage path"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1327
|
#: documents/models.py:1348
|
||||||
msgid "assign this owner"
|
msgid "assign this owner"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1334
|
#: documents/models.py:1355
|
||||||
msgid "grant view permissions to these users"
|
msgid "grant view permissions to these users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1341
|
#: documents/models.py:1362
|
||||||
msgid "grant view permissions to these groups"
|
msgid "grant view permissions to these groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1348
|
#: documents/models.py:1369
|
||||||
msgid "grant change permissions to these users"
|
msgid "grant change permissions to these users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1355
|
#: documents/models.py:1376
|
||||||
msgid "grant change permissions to these groups"
|
msgid "grant change permissions to these groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1362
|
#: documents/models.py:1383
|
||||||
msgid "assign these custom fields"
|
msgid "assign these custom fields"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1366
|
#: documents/models.py:1387
|
||||||
msgid "custom field values"
|
msgid "custom field values"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1370
|
#: documents/models.py:1391
|
||||||
msgid "Optional values to assign to the custom fields."
|
msgid "Optional values to assign to the custom fields."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1379
|
#: documents/models.py:1400
|
||||||
msgid "remove these tag(s)"
|
msgid "remove these tag(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1384
|
#: documents/models.py:1405
|
||||||
msgid "remove all tags"
|
msgid "remove all tags"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1391
|
#: documents/models.py:1412
|
||||||
msgid "remove these document type(s)"
|
msgid "remove these document type(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1396
|
#: documents/models.py:1417
|
||||||
msgid "remove all document types"
|
msgid "remove all document types"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1403
|
#: documents/models.py:1424
|
||||||
msgid "remove these correspondent(s)"
|
msgid "remove these correspondent(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1408
|
#: documents/models.py:1429
|
||||||
msgid "remove all correspondents"
|
msgid "remove all correspondents"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1415
|
#: documents/models.py:1436
|
||||||
msgid "remove these storage path(s)"
|
msgid "remove these storage path(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1420
|
#: documents/models.py:1441
|
||||||
msgid "remove all storage paths"
|
msgid "remove all storage paths"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1427
|
#: documents/models.py:1448
|
||||||
msgid "remove these owner(s)"
|
msgid "remove these owner(s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1432
|
#: documents/models.py:1453
|
||||||
msgid "remove all owners"
|
msgid "remove all owners"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1439
|
#: documents/models.py:1460
|
||||||
msgid "remove view permissions for these users"
|
msgid "remove view permissions for these users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1446
|
#: documents/models.py:1467
|
||||||
msgid "remove view permissions for these groups"
|
msgid "remove view permissions for these groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1453
|
#: documents/models.py:1474
|
||||||
msgid "remove change permissions for these users"
|
msgid "remove change permissions for these users"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1460
|
#: documents/models.py:1481
|
||||||
msgid "remove change permissions for these groups"
|
msgid "remove change permissions for these groups"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1465
|
#: documents/models.py:1486
|
||||||
msgid "remove all permissions"
|
msgid "remove all permissions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1472
|
#: documents/models.py:1493
|
||||||
msgid "remove these custom fields"
|
msgid "remove these custom fields"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1477
|
#: documents/models.py:1498
|
||||||
msgid "remove all custom fields"
|
msgid "remove all custom fields"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1486
|
#: documents/models.py:1507
|
||||||
msgid "email"
|
msgid "email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1495
|
#: documents/models.py:1516
|
||||||
msgid "webhook"
|
msgid "webhook"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1499
|
#: documents/models.py:1520
|
||||||
msgid "workflow action"
|
msgid "workflow action"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1500
|
#: documents/models.py:1521
|
||||||
msgid "workflow actions"
|
msgid "workflow actions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1515
|
#: documents/models.py:1536
|
||||||
msgid "triggers"
|
msgid "triggers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1522
|
#: documents/models.py:1543
|
||||||
msgid "actions"
|
msgid "actions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1525 paperless_mail/models.py:154
|
#: documents/models.py:1546 paperless_mail/models.py:154
|
||||||
msgid "enabled"
|
msgid "enabled"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1536
|
#: documents/models.py:1557
|
||||||
msgid "workflow"
|
msgid "workflow"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1540
|
#: documents/models.py:1561
|
||||||
msgid "workflow trigger type"
|
msgid "workflow trigger type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1554
|
#: documents/models.py:1575
|
||||||
msgid "date run"
|
msgid "date run"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1560
|
#: documents/models.py:1581
|
||||||
msgid "workflow run"
|
msgid "workflow run"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: documents/models.py:1561
|
#: documents/models.py:1582
|
||||||
msgid "workflow runs"
|
msgid "workflow runs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user