Refactoring, filters to and, show sources on list
Show sources on template list, update some translation strings Make filters and minor testing
This commit is contained in:
parent
1aa0792b88
commit
ba6302fa42
@ -8,11 +8,11 @@
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<pngx-input-text i18n-title title="Name" formControlName="name" [error]="error?.name"></pngx-input-text>
|
||||
<pngx-input-number i18n-title title="Rule order" formControlName="order" [showAdd]="false" [error]="error?.order"></pngx-input-number>
|
||||
<p class="small" i18n>Paperless-ngx will process mails that match <em>any</em> of the filters specified below.</p>
|
||||
<pngx-input-number i18n-title title="Sort order" formControlName="order" [showAdd]="false" [error]="error?.order"></pngx-input-number>
|
||||
<p class="small" i18n>Paperless-ngx will process mails that match <em>all</em> of the filters specified below.</p>
|
||||
<pngx-input-select i18n-title title="Filter sources" [items]="sourceOptions" [multiple]="true" formControlName="sources" [error]="error?.filter_filename"></pngx-input-select>
|
||||
<pngx-input-text i18n-title title="Filter filename" formControlName="filter_filename" i18n-hint hint="Apply template to documents that match this filename. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." [error]="error?.filter_filename"></pngx-input-text>
|
||||
<pngx-input-text i18n-title title="Filter path" formControlName="filter_path" i18n-hint hint="Apply template to documents that match this path. Wildcards specified as * are allowed. Case insensitive." [error]="error?.filter_path"></pngx-input-text>
|
||||
<pngx-input-text i18n-title title="Filter filename" formControlName="filter_filename" i18n-hint hint="Apply to documents that match this filename. Wildcards such as *.pdf or *invoice* are allowed. Case insensitive." [error]="error?.filter_filename"></pngx-input-text>
|
||||
<pngx-input-text i18n-title title="Filter path" formControlName="filter_path" i18n-hint hint="Apply to documents that match this path. Wildcards specified as * are allowed. Case insensitive. Also see PAPERLESS_CONSUMER_RECURSIVE" [error]="error?.filter_path"></pngx-input-text>
|
||||
</div>
|
||||
<div class="col">
|
||||
<pngx-input-text i18n-title title="Assign title" formControlName="assign_title" i18n-hint hint="Assign a document title, can include some placeholders, see documentation." [error]="error?.assign_title"></pngx-input-text>
|
||||
|
@ -17,18 +17,18 @@ import { UserService } from 'src/app/services/rest/user.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
import { EditDialogComponent } from '../edit-dialog.component'
|
||||
|
||||
const SOURCE_OPTIONS = [
|
||||
export const DOCUMENT_SOURCE_OPTIONS = [
|
||||
{
|
||||
id: DocumentSource.ConsumeFolder,
|
||||
name: $localize`Documents uploaded via consume folder`,
|
||||
name: $localize`Consume Folder`,
|
||||
},
|
||||
{
|
||||
id: DocumentSource.ApiUpload,
|
||||
name: $localize`Documents uploaded via api upload`,
|
||||
name: $localize`API Upload`,
|
||||
},
|
||||
{
|
||||
id: DocumentSource.MailFetch,
|
||||
name: $localize`Documents uploaded via mail fetch`,
|
||||
name: $localize`Mail Fetch`,
|
||||
},
|
||||
]
|
||||
|
||||
@ -100,6 +100,6 @@ export class ConsumptionTemplateEditDialogComponent extends EditDialogComponent<
|
||||
}
|
||||
|
||||
get sourceOptions() {
|
||||
return SOURCE_OPTIONS
|
||||
return DOCUMENT_SOURCE_OPTIONS
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
<div class="col">
|
||||
<pngx-input-select i18n-title title="Action" [items]="actionOptions" formControlName="action" i18n-hint hint="Action is only performed when documents are consumed from the mail. Mails without attachments remain entirely untouched."></pngx-input-select>
|
||||
<pngx-input-text i18n-title title="Action parameter" *ngIf="showActionParamField" formControlName="action_parameter" [error]="error?.action_parameter"></pngx-input-text>
|
||||
<p class="small fst-italic mt-5" i18n>Assignments specified here will supersede any consumption templates.</p>
|
||||
<pngx-input-select i18n-title title="Assign title from" [items]="metadataTitleOptions" formControlName="assign_title_from"></pngx-input-select>
|
||||
<pngx-input-tags [allowCreate]="false" formControlName="assign_tags"></pngx-input-tags>
|
||||
<pngx-input-select i18n-title title="Assign document type" [items]="documentTypes" [allowNull]="true" formControlName="assign_document_type"></pngx-input-select>
|
||||
|
@ -11,6 +11,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" i18n>Name</th>
|
||||
<th scope="col" i18n>Document Sources</th>
|
||||
<th scope="col" i18n>File name filter</th>
|
||||
<th scope="col" i18n>Path filter</th>
|
||||
<th scope="col" i18n>Actions</th>
|
||||
@ -19,6 +20,7 @@
|
||||
<tbody>
|
||||
<tr *ngFor="let template of templates">
|
||||
<td scope="row"><button class="btn btn-link p-0" type="button" (click)="editTemplate(template)" [disabled]="!permissionsService.currentUserCan(PermissionAction.Change, PermissionType.ConsumptionTemplate)">{{template.name}}</button></td>
|
||||
<td scope="row">{{getSourceList(template)}}</td>
|
||||
<td scope="row"><code>{{template.filter_filename}}</code></td>
|
||||
<td scope="row"><code>{{template.filter_path}}</code></td>
|
||||
<td scope="row">
|
||||
|
@ -2,11 +2,17 @@ import { Component, OnInit } from '@angular/core'
|
||||
import { ConsumptionTemplateService } from 'src/app/services/rest/consumption-template.service'
|
||||
import { ComponentWithPermissions } from '../../with-permissions/with-permissions.component'
|
||||
import { Subject, takeUntil } from 'rxjs'
|
||||
import { PaperlessConsumptionTemplate } from 'src/app/data/paperless-consumption-template'
|
||||
import {
|
||||
DocumentSource,
|
||||
PaperlessConsumptionTemplate,
|
||||
} from 'src/app/data/paperless-consumption-template'
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { PermissionsService } from 'src/app/services/permissions.service'
|
||||
import { ConsumptionTemplateEditDialogComponent } from '../../common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component'
|
||||
import {
|
||||
ConsumptionTemplateEditDialogComponent,
|
||||
DOCUMENT_SOURCE_OPTIONS,
|
||||
} from '../../common/edit-dialog/consumption-template-edit-dialog/consumption-template-edit-dialog.component'
|
||||
import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dialog.component'
|
||||
import { EditDialogMode } from '../../common/edit-dialog/edit-dialog.component'
|
||||
|
||||
@ -45,6 +51,12 @@ export class ConsmptionTemplatesListComponent
|
||||
})
|
||||
}
|
||||
|
||||
getSourceList(template: PaperlessConsumptionTemplate): string {
|
||||
return template.sources
|
||||
.map((id) => DOCUMENT_SOURCE_OPTIONS.find((s) => s.id === id).name)
|
||||
.join(', ')
|
||||
}
|
||||
|
||||
editTemplate(rule: PaperlessConsumptionTemplate) {
|
||||
const modal = this.modalService.open(
|
||||
ConsumptionTemplateEditDialogComponent,
|
||||
|
@ -604,15 +604,15 @@ class Consumer(LoggingMixin):
|
||||
|
||||
if int(input_doc.source) in [int(x) for x in list(template.sources)] and (
|
||||
(
|
||||
template.filter_filename is not None
|
||||
and fnmatch(
|
||||
len(template.filter_filename) == 0
|
||||
or fnmatch(
|
||||
input_doc.original_file.name.lower(),
|
||||
template.filter_filename.lower(),
|
||||
)
|
||||
)
|
||||
or (
|
||||
template.filter_path is not None
|
||||
and input_doc.original_file.match(template.filter_path)
|
||||
and (
|
||||
len(template.filter_path) == 0
|
||||
or input_doc.original_file.match(template.filter_path)
|
||||
)
|
||||
):
|
||||
self.log.info(f"Document matched consumption template {template.name}")
|
||||
@ -720,8 +720,6 @@ class Consumer(LoggingMixin):
|
||||
|
||||
storage_type = Document.STORAGE_TYPE_UNENCRYPTED
|
||||
|
||||
print("override_title", self.override_title)
|
||||
|
||||
with open(self.path, "rb") as f:
|
||||
document = Document.objects.create(
|
||||
title=(
|
||||
|
@ -22,6 +22,7 @@ from documents.models import Correspondent
|
||||
from documents.models import Document
|
||||
from documents.models import DocumentType
|
||||
from documents.models import FileInfo
|
||||
from documents.models import StoragePath
|
||||
from documents.models import Tag
|
||||
from documents.parsers import DocumentParser
|
||||
from documents.parsers import ParseError
|
||||
@ -431,6 +432,16 @@ class TestConsumer(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
self.assertEqual(document.document_type.id, dt.id)
|
||||
self._assert_first_last_send_progress()
|
||||
|
||||
def testOverrideStoragePath(self):
|
||||
sp = StoragePath.objects.create(name="test")
|
||||
|
||||
document = self.consumer.try_consume_file(
|
||||
self.get_test_file(),
|
||||
override_storage_path_id=sp.pk,
|
||||
)
|
||||
self.assertEqual(document.storage_path.id, sp.id)
|
||||
self._assert_first_last_send_progress()
|
||||
|
||||
def testOverrideTags(self):
|
||||
t1 = Tag.objects.create(name="t1")
|
||||
t2 = Tag.objects.create(name="t2")
|
||||
@ -445,6 +456,20 @@ class TestConsumer(DirectoriesMixin, FileSystemAssertsMixin, TestCase):
|
||||
self.assertIn(t3, document.tags.all())
|
||||
self._assert_first_last_send_progress()
|
||||
|
||||
def testOverrideTitlePlaceholders(self):
|
||||
c = Correspondent.objects.create(name="Correspondent Name")
|
||||
dt = DocumentType.objects.create(name="DocType Name")
|
||||
|
||||
document = self.consumer.try_consume_file(
|
||||
self.get_test_file(),
|
||||
override_correspondent_id=c.pk,
|
||||
override_document_type_id=dt.pk,
|
||||
override_title="{correspondent}{document_type} {added_month}-{added_year_short}",
|
||||
)
|
||||
now = timezone.now()
|
||||
self.assertEqual(document.title, f"{c.name}{dt.name} {now.strftime('%m-%y')}")
|
||||
self._assert_first_last_send_progress()
|
||||
|
||||
def testNotAFile(self):
|
||||
self.assertRaisesMessage(
|
||||
ConsumerError,
|
||||
|
Loading…
x
Reference in New Issue
Block a user