mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-02-09 23:49:29 -06:00
Enhancement: option to stop processing further mail rules
This commit is contained in:
@@ -9,19 +9,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-6">
|
||||||
<pngx-input-text [horizontal]="true" i18n-title title="Name" formControlName="name" [error]="error?.name" autocomplete="off"></pngx-input-text>
|
<pngx-input-text [horizontal]="true" i18n-title title="Name" formControlName="name" [error]="error?.name" autocomplete="off"></pngx-input-text>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-4">
|
||||||
<pngx-input-select [horizontal]="true" i18n-title title="Account" [items]="accounts" formControlName="account"></pngx-input-select>
|
<pngx-input-select [horizontal]="true" i18n-title title="Account" [items]="accounts" formControlName="account"></pngx-input-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
|
||||||
<pngx-input-number [horizontal]="true" i18n-title title="Order" formControlName="order" [showAdd]="false" [error]="error?.order"></pngx-input-number>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-2 pt-2">
|
<div class="col-md-2 pt-2">
|
||||||
<pngx-input-switch [horizontal]="true" i18n-title title="Enabled" formControlName="enabled"></pngx-input-switch>
|
<pngx-input-switch [horizontal]="true" i18n-title title="Enabled" formControlName="enabled"></pngx-input-switch>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<pngx-input-number [horizontal]="true" i18n-title title="Order" formControlName="order" [showAdd]="false" [error]="error?.order"></pngx-input-number>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<pngx-input-switch [horizontal]="true" i18n-title title="Stop further processing" formControlName="stop_processing" i18n-hint hint="Stop processing further rules if this rule queues any document(s)."></pngx-input-switch>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<hr class="mt-0"/>
|
<hr class="mt-0"/>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<p class="small" i18n>Paperless will only process mails that match <em>all</em> of the criteria specified below.</p>
|
<p class="small" i18n>Paperless will only process mails that match <em>all</em> of the criteria specified below.</p>
|
||||||
|
|||||||
@@ -222,6 +222,7 @@ export class MailRuleEditDialogComponent extends EditDialogComponent<MailRule> {
|
|||||||
),
|
),
|
||||||
assign_correspondent: new FormControl(null),
|
assign_correspondent: new FormControl(null),
|
||||||
assign_owner_from_rule: new FormControl(true),
|
assign_owner_from_rule: new FormControl(true),
|
||||||
|
stop_processing: new FormControl(false),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,4 +84,6 @@ export interface MailRule extends ObjectWithPermissions {
|
|||||||
assign_correspondent?: number // PaperlessCorrespondent.id
|
assign_correspondent?: number // PaperlessCorrespondent.id
|
||||||
|
|
||||||
assign_owner_from_rule: boolean
|
assign_owner_from_rule: boolean
|
||||||
|
|
||||||
|
stop_processing: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const mail_rules = [
|
|||||||
action: MailAction.MarkRead,
|
action: MailAction.MarkRead,
|
||||||
assign_title_from: MailMetadataTitleOption.FromSubject,
|
assign_title_from: MailMetadataTitleOption.FromSubject,
|
||||||
assign_owner_from_rule: true,
|
assign_owner_from_rule: true,
|
||||||
|
stop_processing: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Mail Rule 2',
|
name: 'Mail Rule 2',
|
||||||
@@ -52,6 +53,7 @@ const mail_rules = [
|
|||||||
action: MailAction.Delete,
|
action: MailAction.Delete,
|
||||||
assign_title_from: MailMetadataTitleOption.FromSubject,
|
assign_title_from: MailMetadataTitleOption.FromSubject,
|
||||||
assign_owner_from_rule: true,
|
assign_owner_from_rule: true,
|
||||||
|
stop_processing: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Mail Rule 3',
|
name: 'Mail Rule 3',
|
||||||
@@ -71,6 +73,7 @@ const mail_rules = [
|
|||||||
action: MailAction.Flag,
|
action: MailAction.Flag,
|
||||||
assign_title_from: MailMetadataTitleOption.FromSubject,
|
assign_title_from: MailMetadataTitleOption.FromSubject,
|
||||||
assign_owner_from_rule: false,
|
assign_owner_from_rule: false,
|
||||||
|
stop_processing: false,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -575,6 +575,11 @@ class MailAccountHandler(LoggingMixin):
|
|||||||
rule,
|
rule,
|
||||||
supports_gmail_labels=supports_gmail_labels,
|
supports_gmail_labels=supports_gmail_labels,
|
||||||
)
|
)
|
||||||
|
if total_processed_files > 0 and rule.stop_processing:
|
||||||
|
self.log.debug(
|
||||||
|
f"Rule {rule}: Stopping processing rules due to stop_processing flag",
|
||||||
|
)
|
||||||
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.log.exception(
|
self.log.exception(
|
||||||
f"Rule {rule}: Error while processing rule: {e}",
|
f"Rule {rule}: Error while processing rule: {e}",
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
# Generated by Django 5.1.6 on 2025-02-24 16:07
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("paperless_mail", "0029_mailrule_pdf_layout"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="mailrule",
|
||||||
|
name="stop_processing",
|
||||||
|
field=models.BooleanField(
|
||||||
|
default=False,
|
||||||
|
help_text="If True, no further rules will be processed after this one if any document is consumed.",
|
||||||
|
verbose_name="Stop processing further rules",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -301,6 +301,14 @@ class MailRule(document_models.ModelWithOwner):
|
|||||||
default=True,
|
default=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
stop_processing = models.BooleanField(
|
||||||
|
_("Stop processing further rules"),
|
||||||
|
default=False,
|
||||||
|
help_text=_(
|
||||||
|
"If True, no further rules will be processed after this one if any document is queued.",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.account.name}.{self.name}"
|
return f"{self.account.name}.{self.name}"
|
||||||
|
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ class MailRuleSerializer(OwnedObjectSerializer):
|
|||||||
"user_can_change",
|
"user_can_change",
|
||||||
"permissions",
|
"permissions",
|
||||||
"set_permissions",
|
"set_permissions",
|
||||||
|
"stop_processing",
|
||||||
]
|
]
|
||||||
|
|
||||||
def update(self, instance, validated_data):
|
def update(self, instance, validated_data):
|
||||||
|
|||||||
@@ -1692,6 +1692,39 @@ class TestTasks(TestCase):
|
|||||||
result = tasks.process_mail_accounts(account_ids=[account_b.id])
|
result = tasks.process_mail_accounts(account_ids=[account_b.id])
|
||||||
self.assertIn("No new", result)
|
self.assertIn("No new", result)
|
||||||
|
|
||||||
|
@mock.patch("paperless_mail.tasks.MailAccountHandler.handle_mail_account")
|
||||||
|
def test_rule_with_stop_processing(self, m):
|
||||||
|
"""
|
||||||
|
GIVEN:
|
||||||
|
- Mail account with a rule with stop_processing=True
|
||||||
|
WHEN:
|
||||||
|
- Mail account is processed
|
||||||
|
THEN:
|
||||||
|
- Should only process the first rule
|
||||||
|
"""
|
||||||
|
m.side_effect = lambda account: 6
|
||||||
|
|
||||||
|
account = MailAccount.objects.create(
|
||||||
|
name="A",
|
||||||
|
imap_server="A",
|
||||||
|
username="A",
|
||||||
|
password="A",
|
||||||
|
)
|
||||||
|
MailRule.objects.create(
|
||||||
|
name="A",
|
||||||
|
account=account,
|
||||||
|
stop_processing=True,
|
||||||
|
)
|
||||||
|
MailRule.objects.create(
|
||||||
|
name="B",
|
||||||
|
account=account,
|
||||||
|
)
|
||||||
|
|
||||||
|
result = tasks.process_mail_accounts()
|
||||||
|
|
||||||
|
self.assertEqual(m.call_count, 1)
|
||||||
|
self.assertIn("Added 6", result)
|
||||||
|
|
||||||
|
|
||||||
class TestMailAccountTestView(APITestCase):
|
class TestMailAccountTestView(APITestCase):
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user