Enhancement: support negative offset in scheduled workflows (#9746)

This commit is contained in:
shamoon 2025-05-11 13:04:46 -07:00 committed by GitHub
parent 73f0f1212d
commit 344cc70cd5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 227 additions and 97 deletions

View File

@ -406,7 +406,8 @@ Currently, there are three events that correspond to workflow trigger 'types':
3. **Document Updated**: when a document is updated. Similar to 'added' events, triggers can include filtering by content matching, 3. **Document Updated**: when a document is updated. Similar to 'added' events, triggers can include filtering by content matching,
tags, doc type, or correspondent. tags, doc type, or correspondent.
4. **Scheduled**: a scheduled trigger that can be used to run workflows at a specific time. The date used can be either the document 4. **Scheduled**: a scheduled trigger that can be used to run workflows at a specific time. The date used can be either the document
added, created, updated date or you can specify a (date) custom field. You can also specify a day offset from the date. added, created, updated date or you can specify a (date) custom field. You can also specify a day offset from the date (positive
offsets will trigger before the date, negative offsets will trigger after).
The following flow diagram illustrates the three document trigger types: The following flow diagram illustrates the three document trigger types:

View File

@ -1284,19 +1284,19 @@
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">201</context> <context context-type="linenumber">209</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">220</context> <context context-type="linenumber">228</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">287</context> <context context-type="linenumber">295</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">306</context> <context context-type="linenumber">314</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/permissions/permissions-form/permissions-form.component.html</context> <context context-type="sourcefile">src/app/components/common/input/permissions/permissions-form/permissions-form.component.html</context>
@ -1319,19 +1319,19 @@
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">209</context> <context context-type="linenumber">217</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">228</context> <context context-type="linenumber">236</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">295</context> <context context-type="linenumber">303</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">314</context> <context context-type="linenumber">322</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/permissions/permissions-form/permissions-form.component.html</context> <context context-type="sourcefile">src/app/components/common/input/permissions/permissions-form/permissions-form.component.html</context>
@ -1357,11 +1357,11 @@
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">234</context> <context context-type="linenumber">242</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">320</context> <context context-type="linenumber">328</context>
</context-group> </context-group>
<context-group purpose="location"> <context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/input/permissions/permissions-form/permissions-form.component.html</context> <context context-type="sourcefile">src/app/components/common/input/permissions/permissions-form/permissions-form.component.html</context>
@ -3691,7 +3691,7 @@
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">163</context> <context context-type="linenumber">171</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6457471243969293847" datatype="html"> <trans-unit id="6457471243969293847" datatype="html">
@ -4115,7 +4115,7 @@
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">188</context> <context context-type="linenumber">196</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4754802869258527587" datatype="html"> <trans-unit id="4754802869258527587" datatype="html">
@ -4133,7 +4133,7 @@
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">189</context> <context context-type="linenumber">197</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1519954996184640001" datatype="html"> <trans-unit id="1519954996184640001" datatype="html">
@ -4645,381 +4645,388 @@
<source>Offset days</source> <source>Offset days</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">126</context> <context context-type="linenumber">128</context>
</context-group>
</trans-unit>
<trans-unit id="1488741788768120127" datatype="html">
<source>Positive values will trigger the workflow before the date, negative values after.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">132</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3726450101884717309" datatype="html"> <trans-unit id="3726450101884717309" datatype="html">
<source>Relative to</source> <source>Relative to</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">129</context> <context context-type="linenumber">137</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3878884308536053934" datatype="html"> <trans-unit id="3878884308536053934" datatype="html">
<source>Custom field</source> <source>Custom field</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">133</context> <context context-type="linenumber">141</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1088170562604583291" datatype="html"> <trans-unit id="1088170562604583291" datatype="html">
<source>Custom field to use for date.</source> <source>Custom field to use for date.</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">133</context> <context context-type="linenumber">141</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1011433830042635014" datatype="html"> <trans-unit id="1011433830042635014" datatype="html">
<source>Recurring</source> <source>Recurring</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">139</context> <context context-type="linenumber">147</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1421663004162437543" datatype="html"> <trans-unit id="1421663004162437543" datatype="html">
<source>Trigger is recurring.</source> <source>Trigger is recurring.</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">139</context> <context context-type="linenumber">147</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5937989815294159481" datatype="html"> <trans-unit id="5937989815294159481" datatype="html">
<source>Recurring interval days</source> <source>Recurring interval days</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">143</context> <context context-type="linenumber">151</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="722765958672682251" datatype="html"> <trans-unit id="722765958672682251" datatype="html">
<source>Repeat the trigger every n days.</source> <source>Repeat the trigger every n days.</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">143</context> <context context-type="linenumber">151</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8727727835543352574" datatype="html"> <trans-unit id="8727727835543352574" datatype="html">
<source>Trigger for documents that match <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>all<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> filters specified below.</source> <source>Trigger for documents that match <x id="START_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;em&gt;"/>all<x id="CLOSE_EMPHASISED_TEXT" ctype="x-em" equiv-text="&lt;/em&gt;"/> filters specified below.</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">148</context> <context context-type="linenumber">156</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7467799586957602479" datatype="html"> <trans-unit id="7467799586957602479" datatype="html">
<source>Filter filename</source> <source>Filter filename</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">151</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3694878959415278689" datatype="html"> <trans-unit id="3694878959415278689" datatype="html">
<source>Apply to documents that match this filename. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive.</source> <source>Apply to documents that match this filename. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive.</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">151</context> <context context-type="linenumber">159</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1473412958770421458" datatype="html"> <trans-unit id="1473412958770421458" datatype="html">
<source>Filter sources</source> <source>Filter sources</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">153</context> <context context-type="linenumber">161</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6540860478788535250" datatype="html"> <trans-unit id="6540860478788535250" datatype="html">
<source>Filter path</source> <source>Filter 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">162</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5491897741674893121" datatype="html"> <trans-unit id="5491897741674893121" datatype="html">
<source>Apply to documents that match this path. Wildcards specified as * are allowed. Case-normalized.&lt;/a&gt;</source> <source>Apply to documents that match this path. Wildcards specified as * are allowed. Case-normalized.&lt;/a&gt;</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">154</context> <context context-type="linenumber">162</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7468453896129193641" datatype="html"> <trans-unit id="7468453896129193641" datatype="html">
<source>Filter mail rule</source> <source>Filter mail rule</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">155</context> <context context-type="linenumber">163</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8663702115863339485" datatype="html"> <trans-unit id="8663702115863339485" datatype="html">
<source>Apply to documents consumed via this mail rule.</source> <source>Apply to documents consumed via this mail rule.</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">155</context> <context context-type="linenumber">163</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6840369584127435743" datatype="html"> <trans-unit id="6840369584127435743" datatype="html">
<source>Content matching algorithm</source> <source>Content matching algorithm</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">158</context> <context context-type="linenumber">166</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="510635115034690805" datatype="html"> <trans-unit id="510635115034690805" datatype="html">
<source>Content matching pattern</source> <source>Content matching pattern</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">160</context> <context context-type="linenumber">168</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3484236514968690689" datatype="html"> <trans-unit id="3484236514968690689" datatype="html">
<source>Has any of tags</source> <source>Has any of 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">169</context> <context context-type="linenumber">177</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">170</context> <context context-type="linenumber">178</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">171</context> <context context-type="linenumber">179</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6417103744331194518" datatype="html"> <trans-unit id="6417103744331194518" datatype="html">
<source>Action type</source> <source>Action 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">181</context> <context context-type="linenumber">189</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6019822389883736115" datatype="html"> <trans-unit id="6019822389883736115" datatype="html">
<source>Assign title</source> <source>Assign title</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">186</context> <context context-type="linenumber">194</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1098196422099517191" datatype="html"> <trans-unit id="1098196422099517191" datatype="html">
<source>Can include some placeholders, see &lt;a target=&apos;_blank&apos; href=&apos;https://docs.paperless-ngx.com/usage/#workflows&apos;&gt;documentation&lt;/a&gt;.</source> <source>Can include some placeholders, see &lt;a target=&apos;_blank&apos; href=&apos;https://docs.paperless-ngx.com/usage/#workflows&apos;&gt;documentation&lt;/a&gt;.</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">186</context> <context context-type="linenumber">194</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6528897010417701530" datatype="html"> <trans-unit id="6528897010417701530" datatype="html">
<source>Assign tags</source> <source>Assign 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">187</context> <context context-type="linenumber">195</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7198346314713788799" datatype="html"> <trans-unit id="7198346314713788799" datatype="html">
<source>Assign storage path</source> <source>Assign 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">190</context> <context context-type="linenumber">198</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="475685412372379925" datatype="html"> <trans-unit id="475685412372379925" datatype="html">
<source>Assign custom fields</source> <source>Assign custom fields</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">191</context> <context context-type="linenumber">199</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5057200219587080996" datatype="html"> <trans-unit id="5057200219587080996" datatype="html">
<source>Assign owner</source> <source>Assign owner</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">195</context> <context context-type="linenumber">203</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1749184201773078639" datatype="html"> <trans-unit id="1749184201773078639" datatype="html">
<source>Assign view permissions</source> <source>Assign view permissions</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">197</context> <context context-type="linenumber">205</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1744964187586405039" datatype="html"> <trans-unit id="1744964187586405039" datatype="html">
<source>Assign edit permissions</source> <source>Assign edit permissions</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">216</context> <context context-type="linenumber">224</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6236311670364192011" datatype="html"> <trans-unit id="6236311670364192011" datatype="html">
<source>Remove tags</source> <source>Remove 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">243</context> <context context-type="linenumber">251</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7890599006071681081" datatype="html"> <trans-unit id="7890599006071681081" datatype="html">
<source>Remove all</source> <source>Remove all</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">244</context> <context context-type="linenumber">252</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">250</context> <context context-type="linenumber">258</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">256</context> <context context-type="linenumber">264</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">262</context> <context context-type="linenumber">270</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">268</context> <context context-type="linenumber">276</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">275</context> <context context-type="linenumber">283</context>
</context-group> </context-group>
<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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">281</context> <context context-type="linenumber">289</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8636414563726517994" datatype="html"> <trans-unit id="8636414563726517994" datatype="html">
<source>Remove correspondents</source> <source>Remove 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">249</context> <context context-type="linenumber">257</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5305293055593064952" datatype="html"> <trans-unit id="5305293055593064952" datatype="html">
<source>Remove document types</source> <source>Remove 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">255</context> <context context-type="linenumber">263</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2400388879708187" datatype="html"> <trans-unit id="2400388879708187" datatype="html">
<source>Remove storage paths</source> <source>Remove 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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">261</context> <context context-type="linenumber">269</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4324304327041955720" datatype="html"> <trans-unit id="4324304327041955720" datatype="html">
<source>Remove custom fields</source> <source>Remove custom fields</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">267</context> <context context-type="linenumber">275</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8367536502602515064" datatype="html"> <trans-unit id="8367536502602515064" datatype="html">
<source>Remove owners</source> <source>Remove owners</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">274</context> <context context-type="linenumber">282</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3393772184866313281" datatype="html"> <trans-unit id="3393772184866313281" datatype="html">
<source>Remove permissions</source> <source>Remove permissions</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">280</context> <context context-type="linenumber">288</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3145629643370481114" datatype="html"> <trans-unit id="3145629643370481114" datatype="html">
<source>View permissions</source> <source>View permissions</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">283</context> <context context-type="linenumber">291</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1946660694635960249" datatype="html"> <trans-unit id="1946660694635960249" datatype="html">
<source>Edit permissions</source> <source>Edit permissions</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">302</context> <context context-type="linenumber">310</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8987736563240025468" datatype="html"> <trans-unit id="8987736563240025468" datatype="html">
<source>Email subject</source> <source>Email subject</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">330</context> <context context-type="linenumber">338</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="8239445959209739142" datatype="html"> <trans-unit id="8239445959209739142" datatype="html">
<source>Email body</source> <source>Email body</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">331</context> <context context-type="linenumber">339</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="1222152280703048012" datatype="html"> <trans-unit id="1222152280703048012" datatype="html">
<source>Email recipients</source> <source>Email recipients</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">332</context> <context context-type="linenumber">340</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7916910101279824329" datatype="html"> <trans-unit id="7916910101279824329" datatype="html">
<source>Attach document</source> <source>Attach document</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">333</context> <context context-type="linenumber">341</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="5028001922785731600" datatype="html"> <trans-unit id="5028001922785731600" datatype="html">
<source>Webhook url</source> <source>Webhook url</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">341</context> <context context-type="linenumber">349</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7491983459027245019" datatype="html"> <trans-unit id="7491983459027245019" datatype="html">
<source>Use parameters for webhook body</source> <source>Use parameters for webhook body</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">343</context> <context context-type="linenumber">351</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4078214298308732810" datatype="html"> <trans-unit id="4078214298308732810" datatype="html">
<source>Send webhook payload as JSON</source> <source>Send webhook payload as JSON</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">344</context> <context context-type="linenumber">352</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="6806149889743731985" datatype="html"> <trans-unit id="6806149889743731985" datatype="html">
<source>Webhook params</source> <source>Webhook params</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">347</context> <context context-type="linenumber">355</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="7089924379374330" datatype="html"> <trans-unit id="7089924379374330" datatype="html">
<source>Webhook body</source> <source>Webhook body</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">349</context> <context context-type="linenumber">357</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="3829826512656746316" datatype="html"> <trans-unit id="3829826512656746316" datatype="html">
<source>Webhook headers</source> <source>Webhook headers</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">351</context> <context context-type="linenumber">359</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="2114525789021600887" datatype="html"> <trans-unit id="2114525789021600887" datatype="html">
<source>Include document</source> <source>Include document</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.html</context> <context context-type="sourcefile">src/app/components/common/edit-dialog/workflow-edit-dialog/workflow-edit-dialog.component.html</context>
<context context-type="linenumber">352</context> <context context-type="linenumber">360</context>
</context-group> </context-group>
</trans-unit> </trans-unit>
<trans-unit id="4626030417479279989" datatype="html"> <trans-unit id="4626030417479279989" datatype="html">

View File

@ -123,7 +123,15 @@
<p class="small" i18n>Set scheduled trigger offset and which date field to use.</p> <p class="small" i18n>Set scheduled trigger offset and which date field to use.</p>
<div class="row"> <div class="row">
<div class="col-4"> <div class="col-4">
<pngx-input-number i18n-title title="Offset days" formControlName="schedule_offset_days" [showAdd]="false" [error]="error?.schedule_offset_days"></pngx-input-number> <pngx-input-number
i18n-title
title="Offset days"
formControlName="schedule_offset_days"
[showAdd]="false"
[error]="error?.schedule_offset_days"
hint="Positive values will trigger the workflow before the date, negative values after."
i18n-hint
></pngx-input-number>
</div> </div>
<div class="col-4"> <div class="col-4">
<pngx-input-select i18n-title title="Relative to" formControlName="schedule_date_field" [items]="scheduleDateFieldOptions" [error]="error?.schedule_date_field"></pngx-input-select> <pngx-input-select i18n-title title="Relative to" formControlName="schedule_date_field" [items]="scheduleDateFieldOptions" [error]="error?.schedule_date_field"></pngx-input-select>

View File

@ -0,0 +1,22 @@
# Generated by Django 5.1.7 on 2025-04-15 19:18
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("documents", "1065_workflowaction_assign_custom_fields_values"),
]
operations = [
migrations.AlterField(
model_name="workflowtrigger",
name="schedule_offset_days",
field=models.IntegerField(
default=0,
help_text="The number of days to offset the schedule trigger by.",
verbose_name="schedule offset days",
),
),
]

View File

@ -1019,7 +1019,7 @@ class WorkflowTrigger(models.Model):
verbose_name=_("has this correspondent"), verbose_name=_("has this correspondent"),
) )
schedule_offset_days = models.PositiveIntegerField( schedule_offset_days = models.IntegerField(
_("schedule offset days"), _("schedule offset days"),
default=0, default=0,
help_text=_( help_text=_(

View File

@ -1,8 +1,8 @@
import datetime
import hashlib import hashlib
import logging import logging
import shutil import shutil
import uuid import uuid
from datetime import timedelta
from pathlib import Path from pathlib import Path
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
@ -357,7 +357,7 @@ def empty_trash(doc_ids=None):
if doc_ids is not None if doc_ids is not None
else Document.deleted_objects.filter( else Document.deleted_objects.filter(
deleted_at__lt=timezone.localtime(timezone.now()) deleted_at__lt=timezone.localtime(timezone.now())
- timedelta( - datetime.timedelta(
days=settings.EMPTY_TRASH_DELAY, days=settings.EMPTY_TRASH_DELAY,
), ),
) )
@ -397,6 +397,7 @@ def check_scheduled_workflows():
) )
if scheduled_workflows.count() > 0: if scheduled_workflows.count() > 0:
logger.debug(f"Checking {len(scheduled_workflows)} scheduled workflows") logger.debug(f"Checking {len(scheduled_workflows)} scheduled workflows")
now = timezone.now()
for workflow in scheduled_workflows: for workflow in scheduled_workflows:
schedule_triggers = workflow.triggers.filter( schedule_triggers = workflow.triggers.filter(
type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED, type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED,
@ -404,31 +405,60 @@ def check_scheduled_workflows():
trigger: WorkflowTrigger trigger: WorkflowTrigger
for trigger in schedule_triggers: for trigger in schedule_triggers:
documents = Document.objects.none() documents = Document.objects.none()
offset_td = timedelta(days=trigger.schedule_offset_days) offset_td = datetime.timedelta(days=-trigger.schedule_offset_days)
threshold = now - offset_td
logger.debug( logger.debug(
f"Checking trigger {trigger} with offset {offset_td} against field: {trigger.schedule_date_field}", f"Trigger {trigger.id}: checking if (date + {offset_td}) <= now ({now})",
) )
match trigger.schedule_date_field: match trigger.schedule_date_field:
case WorkflowTrigger.ScheduleDateField.ADDED: case WorkflowTrigger.ScheduleDateField.ADDED:
documents = Document.objects.filter( documents = Document.objects.filter(added__lte=threshold)
added__lt=timezone.now() - offset_td,
)
case WorkflowTrigger.ScheduleDateField.CREATED: case WorkflowTrigger.ScheduleDateField.CREATED:
documents = Document.objects.filter( documents = Document.objects.filter(created__lte=threshold)
created__lt=timezone.now() - offset_td,
)
case WorkflowTrigger.ScheduleDateField.MODIFIED: case WorkflowTrigger.ScheduleDateField.MODIFIED:
documents = Document.objects.filter( documents = Document.objects.filter(modified__lte=threshold)
modified__lt=timezone.now() - offset_td,
)
case WorkflowTrigger.ScheduleDateField.CUSTOM_FIELD: case WorkflowTrigger.ScheduleDateField.CUSTOM_FIELD:
cf_instances = CustomFieldInstance.objects.filter( # cap earliest date to avoid massive scans
field=trigger.schedule_date_custom_field, earliest_date = now - datetime.timedelta(days=365)
value_date__lt=timezone.now() - offset_td, if offset_td.days < -365:
logger.warning(
f"Trigger {trigger.id} has large negative offset ({offset_td.days}), "
f"limiting earliest scan date to {earliest_date}",
) )
documents = Document.objects.filter(
id__in=cf_instances.values_list("document", flat=True), cf_filter_kwargs = {
"field": trigger.schedule_date_custom_field,
"value_date__isnull": False,
"value_date__lte": threshold,
"value_date__gte": earliest_date,
}
recent_cf_instances = CustomFieldInstance.objects.filter(
**cf_filter_kwargs,
) )
matched_ids = [
cfi.document_id
for cfi in recent_cf_instances
if cfi.value_date
and (
timezone.make_aware(
datetime.datetime.combine(
cfi.value_date,
datetime.time.min,
),
)
+ offset_td
<= now
)
]
documents = Document.objects.filter(id__in=matched_ids)
if documents.count() > 0: if documents.count() > 0:
logger.debug( logger.debug(
f"Found {documents.count()} documents for trigger {trigger}", f"Found {documents.count()} documents for trigger {trigger}",
@ -440,18 +470,18 @@ def check_scheduled_workflows():
workflow=workflow, workflow=workflow,
).order_by("-run_at") ).order_by("-run_at")
if not trigger.schedule_is_recurring and workflow_runs.exists(): if not trigger.schedule_is_recurring and workflow_runs.exists():
# schedule is non-recurring and the workflow has already been run
logger.debug( logger.debug(
f"Skipping document {document} for non-recurring workflow {workflow} as it has already been run", f"Skipping document {document} for non-recurring workflow {workflow} as it has already been run",
) )
continue continue
elif (
if (
trigger.schedule_is_recurring trigger.schedule_is_recurring
and workflow_runs.exists() and workflow_runs.exists()
and ( and (
workflow_runs.last().run_at workflow_runs.last().run_at
> timezone.now() > now
- timedelta( - datetime.timedelta(
days=trigger.schedule_recurring_interval_days, days=trigger.schedule_recurring_interval_days,
) )
) )

View File

@ -1336,6 +1336,8 @@ class TestWorkflows(
GIVEN: GIVEN:
- Existing workflow with SCHEDULED trigger against the created field and action that assigns owner - Existing workflow with SCHEDULED trigger against the created field and action that assigns owner
- Existing doc that matches the trigger - Existing doc that matches the trigger
- Workflow set to trigger at (now - offset) = now - 1 day
- Document created date is 2 days ago trigger condition met
WHEN: WHEN:
- Scheduled workflows are checked - Scheduled workflows are checked
THEN: THEN:
@ -1359,7 +1361,7 @@ class TestWorkflows(
w.save() w.save()
now = timezone.localtime(timezone.now()) now = timezone.localtime(timezone.now())
created = now - timedelta(weeks=520) created = now - timedelta(days=2)
doc = Document.objects.create( doc = Document.objects.create(
title="sample test", title="sample test",
correspondent=self.c, correspondent=self.c,
@ -1377,6 +1379,8 @@ class TestWorkflows(
GIVEN: GIVEN:
- Existing workflow with SCHEDULED trigger against the added field and action that assigns owner - Existing workflow with SCHEDULED trigger against the added field and action that assigns owner
- Existing doc that matches the trigger - Existing doc that matches the trigger
- Workflow set to trigger at (now - offset) = now - 1 day
- Document added date is 365 days ago
WHEN: WHEN:
- Scheduled workflows are checked - Scheduled workflows are checked
THEN: THEN:
@ -1418,6 +1422,8 @@ class TestWorkflows(
GIVEN: GIVEN:
- Existing workflow with SCHEDULED trigger against the modified field and action that assigns owner - Existing workflow with SCHEDULED trigger against the modified field and action that assigns owner
- Existing doc that matches the trigger - Existing doc that matches the trigger
- Workflow set to trigger at (now - offset) = now - 1 day
- Document modified date is mocked as sufficiently in the past
WHEN: WHEN:
- Scheduled workflows are checked - Scheduled workflows are checked
THEN: THEN:
@ -1458,6 +1464,8 @@ class TestWorkflows(
GIVEN: GIVEN:
- Existing workflow with SCHEDULED trigger against a custom field and action that assigns owner - Existing workflow with SCHEDULED trigger against a custom field and action that assigns owner
- Existing doc that matches the trigger - Existing doc that matches the trigger
- Workflow set to trigger at (now - offset) = now - 1 day
- Custom field date is 2 days ago
WHEN: WHEN:
- Scheduled workflows are checked - Scheduled workflows are checked
THEN: THEN:
@ -1502,6 +1510,7 @@ class TestWorkflows(
GIVEN: GIVEN:
- Existing workflow with SCHEDULED trigger - Existing workflow with SCHEDULED trigger
- Existing doc that has already had the workflow run - Existing doc that has already had the workflow run
- Document created 2 days ago, workflow offset = 1 day trigger time = yesterday
WHEN: WHEN:
- Scheduled workflows are checked - Scheduled workflows are checked
THEN: THEN:
@ -1552,6 +1561,7 @@ class TestWorkflows(
GIVEN: GIVEN:
- Existing workflow with SCHEDULED trigger and recurring interval of 7 days - Existing workflow with SCHEDULED trigger and recurring interval of 7 days
- Workflow run date is 6 days ago - Workflow run date is 6 days ago
- Document created 40 days ago, offset = 30 trigger time = 10 days ago
WHEN: WHEN:
- Scheduled workflows are checked - Scheduled workflows are checked
THEN: THEN:
@ -1600,6 +1610,58 @@ class TestWorkflows(
doc.refresh_from_db() doc.refresh_from_db()
self.assertIsNone(doc.owner) self.assertIsNone(doc.owner)
def test_workflow_scheduled_trigger_negative_offset(self):
"""
GIVEN:
- Existing workflow with SCHEDULED trigger and negative offset of -7 days (so 7 days after date)
- Custom field date initially set to 5 days ago trigger time = 2 days in future
- Then updated to 8 days ago trigger time = 1 day ago
WHEN:
- Scheduled workflows are checked for document with custom field date 8 days in the past
THEN:
- Workflow runs and document owner is updated
"""
trigger = WorkflowTrigger.objects.create(
type=WorkflowTrigger.WorkflowTriggerType.SCHEDULED,
schedule_offset_days=-7,
schedule_date_field=WorkflowTrigger.ScheduleDateField.CUSTOM_FIELD,
schedule_date_custom_field=self.cf1,
)
action = WorkflowAction.objects.create(
assign_title="Doc assign owner",
assign_owner=self.user2,
)
w = Workflow.objects.create(
name="Workflow 1",
order=0,
)
w.triggers.add(trigger)
w.actions.add(action)
w.save()
doc = Document.objects.create(
title="sample test",
correspondent=self.c,
original_filename="sample.pdf",
)
cfi = CustomFieldInstance.objects.create(
document=doc,
field=self.cf1,
value_date=timezone.now() - timedelta(days=5),
)
tasks.check_scheduled_workflows()
doc.refresh_from_db()
self.assertIsNone(doc.owner) # has not triggered yet
cfi.value_date = timezone.now() - timedelta(days=8)
cfi.save()
tasks.check_scheduled_workflows()
doc.refresh_from_db()
self.assertEqual(doc.owner, self.user2)
def test_workflow_enabled_disabled(self): def test_workflow_enabled_disabled(self):
trigger = WorkflowTrigger.objects.create( trigger = WorkflowTrigger.objects.create(
type=WorkflowTrigger.WorkflowTriggerType.DOCUMENT_ADDED, type=WorkflowTrigger.WorkflowTriggerType.DOCUMENT_ADDED,