Revision dfdfb88c
Von Tamino Steinert vor 6 Monaten hinzugefügt
- ID dfdfb88c555d5b4f0be25b551e4bc2aa709b111b
- Vorgänger 6aa91d87
SL/Controller/EmailJournal.pm | ||
---|---|---|
|
||
use parent qw(SL::Controller::Base);
|
||
|
||
use SL::ReportGenerator;
|
||
use SL::Controller::Helper::ReportGenerator;
|
||
use SL::ZUGFeRD;
|
||
use SL::Controller::ZUGFeRD;
|
||
use SL::Controller::Helper::GetModels;
|
||
... | ... | |
use SL::DB::EmailJournal;
|
||
use SL::DB::EmailJournalAttachment;
|
||
use SL::Presenter::EmailJournal;
|
||
use SL::Presenter::Filter::EmailJournal;
|
||
use SL::Presenter::Record qw(grouped_record_list);
|
||
use SL::Presenter::Tag qw(html_tag div_tag button_tag);
|
||
use SL::Helper::Flash;
|
||
... | ... | |
my ($self) = @_;
|
||
|
||
$::auth->assert('email_journal');
|
||
# default filter
|
||
$::form->{filter} ||= {"obsolete:eq_ignore_empty" => 0};
|
||
|
||
if ( $::instance_conf->get_email_journal == 0 ) {
|
||
flash('info', $::locale->text('Storing the emails in the journal is currently disabled in the client configuration.'));
|
||
flash('info', t8('Storing the emails in the journal is currently disabled in the client configuration.'));
|
||
}
|
||
|
||
$::form->{filter} ||= {
|
||
'obsolete:eq_ignore_empty' => 0,
|
||
};
|
||
|
||
$self->setup_list_action_bar;
|
||
my @record_types_with_info = $self->get_record_types_with_info();
|
||
my %record_types_to_text = $self->get_record_types_to_text();
|
||
$self->render('email_journal/list',
|
||
title => $::locale->text('Email journal'),
|
||
ENTRIES => $self->models->get,
|
||
MODELS => $self->models,
|
||
RECORD_TYPES_WITH_INFO => \@record_types_with_info,
|
||
RECORD_TYPES_TO_TEXT => \%record_types_to_text,
|
||
);
|
||
my $report = $self->prepare_report;
|
||
$self->report_generator_list_objects(
|
||
report => $report,
|
||
objects => $self->models->get,
|
||
);
|
||
}
|
||
|
||
sub action_show {
|
||
... | ... | |
return $customer_vendor;
|
||
}
|
||
|
||
sub prepare_report {
|
||
my ($self) = @_;
|
||
|
||
my %record_types_to_text = $self->get_record_types_to_text();
|
||
my @record_types_with_info = $self->get_record_types_with_info();
|
||
|
||
my $report = SL::ReportGenerator->new(\%::myconfig, $::form);
|
||
|
||
my $callback = $self->models->get_callback;
|
||
|
||
my @columns_order = qw(
|
||
id
|
||
sender
|
||
from
|
||
recipients
|
||
subject
|
||
sent_on
|
||
attachment_names
|
||
has_unprocessed_attachments
|
||
unprocessed_attachment_names
|
||
status
|
||
extended_status
|
||
record_type
|
||
linked_to
|
||
obsolete
|
||
);
|
||
|
||
my @default_columns = qw(
|
||
from
|
||
recipients
|
||
subject
|
||
sent_on
|
||
);
|
||
|
||
my %column_defs = (
|
||
id => {
|
||
obj_link => sub {$self->url_for(
|
||
action => 'show', id => $_[0]->id, callback => $callback
|
||
)},
|
||
sub => sub { $_[0]->id },
|
||
},
|
||
sender => {
|
||
sub => sub { $_[0]->sender ? $_[0]->sender->name : '' },
|
||
},
|
||
from => {
|
||
obj_link => sub {$self->url_for(
|
||
action => 'show', id => $_[0]->id, callback => $callback
|
||
)},
|
||
sub => sub { $_[0]->from },
|
||
},
|
||
recipients => {
|
||
obj_link => sub {$self->url_for(
|
||
action => 'show', id => $_[0]->id, callback => $callback
|
||
)},
|
||
sub => sub { $_[0]->recipients },
|
||
},
|
||
subject => {
|
||
obj_link => sub {$self->url_for(
|
||
action => 'show', id => $_[0]->id, callback => $callback
|
||
)},
|
||
sub => sub { $_[0]->subject },
|
||
},
|
||
sent_on => {
|
||
obj_link => sub {$self->url_for(
|
||
action => 'show', id => $_[0]->id, callback => $callback
|
||
)},
|
||
sub => sub { $_[0]->sent_on->to_kivitendo(precision => 'minute') },
|
||
},
|
||
attachment_names => {
|
||
sub => sub {join(', ',
|
||
map {$_->name}
|
||
sort {$a->position <=> $b->position}
|
||
@{$_[0]->attachments}
|
||
)},
|
||
},
|
||
has_unprocessed_attachments => {
|
||
sub => sub { $_[0]->has_unprocessed_attachments }
|
||
},
|
||
unprocessed_attachment_names => {
|
||
sub => sub {join(', ',
|
||
map {$_->name}
|
||
sort {$a->position <=> $b->position}
|
||
grep {$_->processed == 0}
|
||
@{$_[0]->attachments}
|
||
)},
|
||
},
|
||
status => {
|
||
sub => sub { SL::Presenter::EmailJournal::entry_status($_[0]) },
|
||
},
|
||
extended_status => {
|
||
sub => sub { $_[0]->extended_status },
|
||
},
|
||
record_type => {
|
||
sub => sub { $record_types_to_text{$_[0]->record_type} },
|
||
},
|
||
linked_to => {
|
||
raw_data => sub {
|
||
SL::Presenter::Record::simple_grouped_record_list($_[0]->linked_records)
|
||
}
|
||
},
|
||
obsolete => {
|
||
sub => sub { $_[0]->obsolete_as_bool_yn }
|
||
},
|
||
);
|
||
$column_defs{$_}->{text} ||=
|
||
t8( $self->models->get_sort_spec->{$_}->{title} || $_ )
|
||
for keys %column_defs;
|
||
|
||
# make all sortable
|
||
my @sortable = keys %column_defs;
|
||
|
||
unless ($::form->{active_in_report}) {
|
||
$::form->{active_in_report}->{$_} = 1 foreach @default_columns;
|
||
}
|
||
|
||
$column_defs{$_}->{visible} = $::form->{active_in_report}->{"$_"} || 0
|
||
foreach keys %column_defs;
|
||
|
||
my $filter_html = SL::Presenter::Filter::EmailJournal::filter(
|
||
$::form->{filter},
|
||
active_in_report => $::form->{active_in_report},
|
||
record_types_with_info => \@record_types_with_info,
|
||
);
|
||
|
||
$self->models->disable_plugin('paginated')
|
||
if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
|
||
$self->models->add_additional_url_params(
|
||
active_in_report => $::form->{active_in_report}
|
||
);
|
||
$self->models->finalize; # for filter laundering
|
||
|
||
$report->set_options(
|
||
std_column_visibility => 1,
|
||
controller_class => 'EmailJournal',
|
||
output_format => 'HTML',
|
||
raw_top_info_text => $self->render(
|
||
'email_journal/_report_top',
|
||
{ output => 0 },
|
||
FILTER_HTML => $filter_html,
|
||
),
|
||
raw_bottom_info_text => $self->render(
|
||
'email_journal/_report_bottom',
|
||
{ output => 0 },
|
||
models => $self->models
|
||
),
|
||
title => t8('Email journal'),
|
||
allow_pdf_export => 1,
|
||
allow_csv_export => 1,
|
||
);
|
||
$report->set_columns(%column_defs);
|
||
$report->set_column_order(@columns_order);
|
||
$report->set_export_options('list', qw(filter active_in_report));
|
||
$report->set_options_from_form;
|
||
|
||
$self->models->set_report_generator_sort_options(
|
||
report => $report,
|
||
sortable_columns => \@sortable
|
||
);
|
||
|
||
return $report;
|
||
}
|
||
|
||
sub add_js {
|
||
$::request->{layout}->use_javascript("${_}.js") for qw(
|
||
kivi.EmailJournal
|
||
... | ... | |
query => \@where,
|
||
with_objects => [ 'sender' ],
|
||
sorted => {
|
||
_default => {
|
||
by => 'sent_on',
|
||
dir => 0,
|
||
},
|
||
sender => t8('Sender'),
|
||
from => t8('From'),
|
||
recipients => t8('Recipients'),
|
||
subject => t8('Subject'),
|
||
attachments => t8('Attachments'),
|
||
attachment_names => t8('Attachments'),
|
||
has_unprocessed_attachments => t8('Has unprocessed attachments'),
|
||
unprocessed_attachment_names => t8('Unprocessed Attachments'),
|
||
sent_on => t8('Sent on'),
|
||
status => t8('Status'),
|
||
extended_status => t8('Extended status'),
|
||
record_type => t8('Record Type'),
|
||
obsolete => t8('Obsolete'),
|
||
linked_to => t8('Linked to'),
|
||
has_unprocessed_attachments => t8('Has unprocessed attachments'),
|
||
},
|
||
);
|
||
}
|
SL/DB/Manager/EmailJournal.pm | ||
---|---|---|
)
|
||
)} => \'TRUE';
|
||
},
|
||
unprocessed_attachment_names => sub {
|
||
my ($key, $value, $prefix) = @_;
|
||
return (
|
||
and => [
|
||
'attachments.name' => $value,
|
||
'attachments.processed' => 0,
|
||
],
|
||
'attachments'
|
||
)
|
||
},
|
||
has_unprocessed_attachments => sub {
|
||
my ($key, $value, $prefix) = @_;
|
||
|
||
... | ... | |
AND record_links.to_id = email_journal.id
|
||
)
|
||
)},
|
||
attachment => qq{(
|
||
attachment_names => qq{(
|
||
SELECT STRING_AGG(
|
||
email_journal_attachments.name,
|
||
', '
|
||
ORDER BY email_journal_attachments.position ASC
|
||
)
|
||
FROM email_journal_attachments
|
||
WHERE
|
||
email_journal_attachments.email_journal_id = email_journal.id
|
||
)},
|
||
unprocessed_attachment_names => qq{(
|
||
SELECT STRING_AGG(
|
||
email_journal_attachments.name,
|
||
', '
|
||
... | ... | |
FROM email_journal_attachments
|
||
WHERE
|
||
email_journal_attachments.email_journal_id = email_journal.id
|
||
AND email_journal_attachments.processed = FALSE
|
||
)},
|
||
has_unprocessed_attachments => qq{(
|
||
SELECT count(*)
|
SL/Presenter/Filter/EmailJournal.pm | ||
---|---|---|
package SL::Presenter::Filter::EmailJournal;
|
||
|
||
use parent SL::Presenter::Filter;
|
||
|
||
use strict;
|
||
|
||
use SL::Locale::String qw(t8);
|
||
|
||
use Params::Validate qw(:all);
|
||
|
||
sub get_default_filter_elements {
|
||
my $filter = shift @_;
|
||
my %params = validate_with(
|
||
params => \@_,
|
||
spec => {
|
||
record_types_with_info => {
|
||
type => ARRAYREF
|
||
},
|
||
},
|
||
);
|
||
|
||
my %default_filter_elements = ( # {{{
|
||
id => {
|
||
'position' => 1,
|
||
'text' => t8("ID"),
|
||
'input_type' => 'input_tag',
|
||
'input_name' => 'filter.id:number',
|
||
'input_default' => $filter->{'id:number'},
|
||
'report_id' => 'id',
|
||
'active' => 0,
|
||
},
|
||
sender => {
|
||
'position' => 2,
|
||
'text' => t8("Sender"),
|
||
'input_type' => 'input_tag',
|
||
'input_name' => 'filter.sender.name:substr::ilike',
|
||
'input_default' => $filter->{sender}->{'name:substr::ilike'},
|
||
'report_id' => 'sender',
|
||
'active' => $::auth->assert('email_employee_readall', 1),
|
||
},
|
||
from => {
|
||
'position' => 3,
|
||
'text' => t8("From"),
|
||
'input_type' => 'input_tag',
|
||
'input_name' => 'filter.from:substr::ilike',
|
||
'input_default' => $filter->{'from:substr::ilike'},
|
||
'report_id' => 'from',
|
||
'active' => 1,
|
||
},
|
||
recipients => {
|
||
'position' => 4,
|
||
'text' => t8("Recipients"),
|
||
'input_type' => 'input_tag',
|
||
'input_name' => 'filter.recipients:substr::ilike',
|
||
'input_default' => $filter->{'recipients:substr::ilike'},
|
||
'report_id' => 'recipients',
|
||
'active' => 1,
|
||
},
|
||
subject => {
|
||
'position' => 5,
|
||
'text' => t8("Subject"),
|
||
'input_type' => 'input_tag',
|
||
'input_name' => 'filter.subject:substr::ilike',
|
||
'input_default' => $filter->{'subject:substr::ilike'},
|
||
'report_id' => 'subject',
|
||
'active' => 1,
|
||
},
|
||
sent_on => {
|
||
'position' => 6,
|
||
'text' => t8("Sent on"),
|
||
'input_type' => 'date_tag',
|
||
'input_name' => 'sent_on',
|
||
'input_default_ge' => $filter->{'sent_on' . ':date::ge'},
|
||
'input_default_le' => $filter->{'sent_on' . ':date::le'},
|
||
'report_id' => 'sent_on',
|
||
'active' => 1,
|
||
},
|
||
attachment_names => {
|
||
'position' => 7,
|
||
'text' => t8("Attachments"),
|
||
'input_type' => 'input_tag',
|
||
'input_name' => 'filter.attachments.name:substr::ilike',
|
||
'input_default' => $filter->{attachments}->{'name:substr::ilike'},
|
||
'report_id' => 'attachment_names',
|
||
'active' => 1,
|
||
},
|
||
'has_unprocessed_attachments' => {
|
||
'position' => 8,
|
||
'text' => t8("Has unprocessed attachments"),
|
||
'input_type' => 'yes_no_tag',
|
||
'input_name' => 'filter.has_unprocessed_attachments:eq_ignore_empty',
|
||
'input_default' => $filter->{'has_unprocessed_attachments:eq_ignore_empty'},
|
||
'report_id' => 'has_unprocessed_attachments',
|
||
'active' => 1,
|
||
},
|
||
unprocessed_attachment_names => {
|
||
'position' => 9,
|
||
'text' => t8("Unprocessed Attachments"),
|
||
'input_type' => 'input_tag',
|
||
'input_name' => 'filter.unprocessed_attachment_names:substr::ilike',
|
||
'input_default' => $filter->{'unprocessed_attachment_names:substr::ilike'},
|
||
'report_id' => 'unprocessed_attachment_names',
|
||
'active' => 1,
|
||
},
|
||
status => {
|
||
'position' => 10,
|
||
'text' => t8("Status"),
|
||
'input_type' => 'select_tag',
|
||
'input_values' => [
|
||
[ "", "" ],
|
||
[ "send_failed", t8("send failed") ],
|
||
[ "sent", t8("sent") ],
|
||
[ "imported", t8("imported") ]
|
||
],
|
||
'input_name' => 'filter.status',
|
||
'input_default' => $filter->{'status'},
|
||
'report_id' => 'status',
|
||
'active' => 1,
|
||
},
|
||
extended_status => {
|
||
'position' => 11,
|
||
'text' => t8("Extended status"),
|
||
'input_type' => 'input_tag',
|
||
'input_name' => 'filter.extended_status:substr::ilike',
|
||
'input_default' => $filter->{'extended_status:substr::ilike'},
|
||
'report_id' => 'extended_status',
|
||
'active' => 1,
|
||
},
|
||
record_type => {
|
||
'position' => 12,
|
||
'text' => t8("Record Type"),
|
||
'input_type' => 'select_tag',
|
||
'input_values' => [
|
||
map {[
|
||
$_->{record_type} => $_->{text},
|
||
]}
|
||
grep {!$_->{is_template}}
|
||
{},
|
||
{text=> t8("Catch-all"), record_type => 'catch_all'},
|
||
@{$params{record_types_with_info}}
|
||
],
|
||
'input_name' => 'filter.record_type:eq_ignore_empty',
|
||
'input_default' => $filter->{'record_type:eq_ignore_empty'},
|
||
'report_id' => 'record_type',
|
||
'active' => 1,
|
||
},
|
||
'linked' => {
|
||
'position' => 13,
|
||
'text' => t8("Linked"),
|
||
'input_type' => 'yes_no_tag',
|
||
'input_name' => 'filter.linked_to:eq_ignore_empty',
|
||
'input_default' => $filter->{'linked_to:eq_ignore_empty'},
|
||
'report_id' => 'linked_to',
|
||
'active' => 1,
|
||
},
|
||
'obsolete' => {
|
||
'position' => 14,
|
||
'text' => t8("Obsolete"),
|
||
'input_type' => 'yes_no_tag',
|
||
'input_name' => 'filter.obsolete:eq_ignore_empty',
|
||
'input_default' => $filter->{'obsolete:eq_ignore_empty'},
|
||
'report_id' => 'obsolete',
|
||
'active' => 1,
|
||
},
|
||
); # }}}
|
||
return \%default_filter_elements;
|
||
}
|
||
|
||
sub filter {
|
||
my $filter = shift @_;
|
||
die "filter has to be a hash ref" if ref $filter ne 'HASH';
|
||
my %params = validate_with(
|
||
params => \@_,
|
||
spec => {
|
||
record_types_with_info => {
|
||
type => ARRAYREF
|
||
},
|
||
},
|
||
allow_extra => 1,
|
||
);
|
||
|
||
my $filter_elements = get_default_filter_elements($filter,
|
||
record_types_with_info => delete $params{record_types_with_info},
|
||
);
|
||
|
||
return SL::Presenter::Filter::create_filter($filter_elements, %params);
|
||
}
|
||
|
||
1;
|
||
|
||
__END__
|
||
|
||
=pod
|
||
|
||
=encoding utf8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Presenter::Filter::EmailJournal - Presenter module for a generic filter on
|
||
EmailJournal.
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
# in EmailJournal Controller
|
||
my $filter_html = SL::Presenter::Filter::EmailJournal::filter(
|
||
$::form->{filter},
|
||
active_in_report => $::form->{active_in_report}
|
||
record_types_with_info => \@record_types_with_info,
|
||
);
|
||
|
||
|
||
=head1 FUNCTIONS
|
||
|
||
=over 4
|
||
|
||
=item C<filter $filter, %params>
|
||
|
||
Returns a rendered version (actually an instance of
|
||
L<SL::Presenter::EscapedText>) of a filter form for email journal.
|
||
|
||
C<$filter> should be the C<filter> value of the last C<$::form>. This is used to
|
||
get the previous values of the input fields.
|
||
|
||
C<%params> can include:
|
||
|
||
=over 2
|
||
|
||
|
||
= item * record_types_with_info
|
||
|
||
Is used to set the drop down for record type.
|
||
|
||
=back
|
||
|
||
Other C<%params> fields get forwarded to
|
||
C<SL::Presenter::Filter::create_filter>.
|
||
|
||
=back
|
||
|
||
=head1 BUGS
|
||
|
||
Nothing here yet.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Tamino Steinert E<lt>tamino.steinert@tamino.stE<gt>
|
||
|
||
=cut
|
locale/de/all | ||
---|---|---|
'There are mulitple vendors selected' => 'Es sind mehrere Lieferanten ausgewählt',
|
||
'There are no documents in the WebDAV directory at the moment.' => 'Es befinden sich im WebDAV-Verzeichnis momentan keine Dokumente.',
|
||
'There are no entries in the background job history.' => 'Es gibt keine Einträge im Hintergrund-Job-Verlauf.',
|
||
'There are no entries that match the filter.' => 'Es gibt keine Einträge, auf die der Filter zutrifft.',
|
||
'There are no items in stock.' => 'Dieser Artikel ist nicht eingelagert.',
|
||
'There are no items on your TODO list at the moment.' => 'Ihre Aufgabenliste enthält momentan keine Einträge.',
|
||
'There are no items selected' => 'Es wurden keine Positionen ausgewählt',
|
||
... | ... | |
'Unlink bank transactions' => 'Bankverbuchung(en) rückgängig machen',
|
||
'Unlock System' => 'System entsperren',
|
||
'Unprocessed' => 'Nicht verarbeitet',
|
||
'Unprocessed Attachments' => 'Nicht verarbeitete Anhänge',
|
||
'Unsuccessfully executed:\n' => 'Erfolglos ausgeführt:',
|
||
'Unsupported image type (supported types: #1)' => 'Nicht unterstützter Bildtyp (unterstützte Typen: #1)',
|
||
'Until' => 'Bis',
|
locale/en/all | ||
---|---|---|
'There are mulitple vendors selected' => '',
|
||
'There are no documents in the WebDAV directory at the moment.' => '',
|
||
'There are no entries in the background job history.' => '',
|
||
'There are no entries that match the filter.' => '',
|
||
'There are no items in stock.' => '',
|
||
'There are no items on your TODO list at the moment.' => '',
|
||
'There are no items selected' => '',
|
||
... | ... | |
'Unlink bank transactions' => '',
|
||
'Unlock System' => '',
|
||
'Unprocessed' => '',
|
||
'Unprocessed Attachments' => '',
|
||
'Unsuccessfully executed:\n' => '',
|
||
'Unsupported image type (supported types: #1)' => '',
|
||
'Until' => '',
|
templates/design40_webpages/email_journal/_filter.html | ||
---|---|---|
[% USE L %]
|
||
[% USE LxERP %]
|
||
[% USE HTML %]
|
||
|
||
[% BLOCK filter_toggle_panel %]
|
||
<table id="filter_table" class="tbl-horizontal">
|
||
<tbody>
|
||
<tr>
|
||
<th>[% LxERP.t8("From") %]</th>
|
||
<td>[% L.input_tag("filter.from:substr::ilike", filter.from_substr__ilike, size = 20) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8("Recipients") %]</th>
|
||
<td>[% L.input_tag("filter.recipients:substr::ilike", filter.recipients_substr__ilike, size = 20) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8("Sent on") %]</th>
|
||
<td>[% L.date_tag("filter.sent_on:date::ge", filter.sent_on_date__ge) %] [% LxERP.t8("To Date") %] [% L.date_tag("filter.sent_on:date::le", filter.sent_on_date__le) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8("Status") %]</th>
|
||
<td>[% L.select_tag("filter.status:eq_ignore_empty", [
|
||
[ "", "" ],
|
||
[ "send_failed", LxERP.t8("send failed") ],
|
||
[ "sent", LxERP.t8("sent") ],
|
||
[ "imported", LxERP.t8("imported") ]
|
||
], default=filter.status_eq_ignore_empty) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8("Record Type") %]</th>
|
||
<td>
|
||
[%
|
||
SET record_type_options = [];
|
||
record_type_options.push({text=LxERP.t8("Catch-all"), record_type='catch_all'});
|
||
FOREACH record_info = RECORD_TYPES_WITH_INFO;
|
||
IF (!record_info.is_template);
|
||
record_type_options.push(record_info);
|
||
END;
|
||
END;
|
||
%]
|
||
[% L.select_tag("filter.record_type:eq_ignore_empty",
|
||
record_type_options,
|
||
title_key = 'text', value_key = 'record_type',
|
||
with_empty=1, default=filter.record_type_eq_ignore_empty) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8("Obsolete") %]</th>
|
||
<td>[% L.yes_no_tag("filter.obsolete:eq_ignore_empty",
|
||
filter.obsolete, with_empty=1,
|
||
default=filter.obsolete_eq_ignore_empty
|
||
) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8("Linked") %]</th>
|
||
<td>[% L.yes_no_tag("filter.linked_to:eq_ignore_empty",
|
||
filter.linked_to, with_empty=1,
|
||
default=filter.linked_to_eq_ignore_empty
|
||
) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8("Has unprocessed attachments") %]</th>
|
||
<td>[% L.yes_no_tag("filter.has_unprocessed_attachments:eq_ignore_empty",
|
||
filter.has_unprocessed_attachments, with_empty=1,
|
||
default=filter.has_unprocessed_attachments_eq_ignore_empty
|
||
) %]
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
[% L.hidden_tag("sort_by", FORM.sort_by) %]
|
||
[% L.hidden_tag("sort_dir", FORM.sort_dir) %]
|
||
[% L.hidden_tag("page", FORM.page) %]
|
||
<div class="buttons">[% L.button_tag('$("#filter_form").resetForm()', LxERP.t8('Reset')) %]</div>
|
||
[% END %]
|
||
|
||
<div class="wrapper">
|
||
<form action="controller.pl" method="post" id="filter_form">
|
||
|
||
[% INCLUDE common/toggle_panel.html %]
|
||
|
||
|
||
|
||
</div>
|
||
|
||
</form>
|
||
</div>
|
templates/design40_webpages/email_journal/_report_bottom.html | ||
---|---|---|
[% USE L %]
|
||
[%- L.paginate_controls(models=models) %]
|
templates/design40_webpages/email_journal/_report_top.html | ||
---|---|---|
[% USE L %]
|
||
|
||
[% BLOCK filter_toggle_panel %]
|
||
[%- FILTER_HTML %]
|
||
[% END %]
|
||
|
||
<div class="wrapper">
|
||
[% SET display_status = 'open' %]
|
||
[% INCLUDE 'common/toggle_panel.html' %]
|
||
</div><!-- /.wrapper -->
|
templates/design40_webpages/email_journal/list.html | ||
---|---|---|
[% USE HTML %]
|
||
[% USE L %]
|
||
[% USE P %]
|
||
[% USE LxERP %]
|
||
|
||
<h1>[% FORM.title %]</h1>
|
||
|
||
[% INCLUDE 'common/flash.html' %]
|
||
[% PROCESS 'email_journal/_filter.html' filter=SELF.models.filtered.laundered %]
|
||
|
||
[% IF !ENTRIES.size %]
|
||
<p>[% LxERP.t8('There are no entries that match the filter.') %]</p>
|
||
|
||
[% ELSE %]
|
||
|
||
<table id="email_journal_list" class="tbl-list wi-moderate">
|
||
<thead>
|
||
<tr>
|
||
[% IF SELF.can_view_all %]
|
||
<th>[% L.sortable_table_header("sender") %]</th>
|
||
[% END %]
|
||
<th>[% L.sortable_table_header("from") %]</th>
|
||
<th>[% L.sortable_table_header("recipients") %]</th>
|
||
<th>[% L.sortable_table_header("subject") %]</th>
|
||
<th>[% L.sortable_table_header("sent_on") %]</th>
|
||
<th>[% L.sortable_table_header("attachments") %]</th>
|
||
<th>[% L.sortable_table_header("status") %]</th>
|
||
<th>[% L.sortable_table_header("extended_status") %]</th>
|
||
<th>[% L.sortable_table_header("record_type") %]</th>
|
||
<th>[% L.sortable_table_header("obsolete") %]</th>
|
||
<th>[% L.sortable_table_header("linked_to") %]</th>
|
||
<th>[% L.sortable_table_header("has_unprocessed_attachments") %]</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
[% FOREACH entry = ENTRIES %]
|
||
<tr id="email_journal_id_[% entry.id %]" [% IF entry.status == 'send_failed' %] class="listrow_error" [% END %]>
|
||
[% IF SELF.can_view_all %]
|
||
<td>[% IF entry.sender %] [% HTML.escape(entry.sender.name) %] [% ELSE %] [% LxERP.t8("kivitendo") %] [% END %]</td>
|
||
[% END %]
|
||
[% action_show_link = SELF.url_for(
|
||
action => 'show', id => entry.id,
|
||
back_to => SELF.models.get_callback(),
|
||
) %]
|
||
<td><a href="[% action_show_link %]"> [% HTML.escape(entry.from) %] </a></td>
|
||
<td>[% HTML.escape(entry.recipients) %]</td>
|
||
<td><a href="[% action_show_link %]"> [% HTML.escape(entry.subject) %] </a></td>
|
||
<td>[% HTML.escape(entry.sent_on.to_lxoffice('precision' => 'second')) %]</td>
|
||
<td>
|
||
[% FOREACH attachment = entry.attachments %]
|
||
<span>[% HTML.escape(attachment.name) %]</span>
|
||
[% END %]
|
||
</td>
|
||
<td> [% P.email_journal.entry_status(entry) %] </td>
|
||
<td>[% HTML.escape(entry.extended_status) %]</td>
|
||
<td>[% HTML.escape(RECORD_TYPES_TO_TEXT.${entry.record_type}) %]</td>
|
||
<td>[% HTML.escape(entry.obsolete_as_bool_yn) %]</td>
|
||
<td>
|
||
[% P.record.simple_grouped_record_list(entry.linked_records) %]
|
||
</td>
|
||
<td>[% HTML.escape(entry.has_unprocessed_attachments) %]</td>
|
||
</tr>
|
||
[% END %]
|
||
</tbody>
|
||
</table>
|
||
|
||
[% END %]
|
||
|
||
[% L.paginate_controls %]
|
templates/webpages/email_journal/_filter.html | ||
---|---|---|
[%- USE L %][%- USE LxERP %][%- USE HTML %]
|
||
<form action="controller.pl" method="post" id="filter_form">
|
||
<div class="filter_toggle">
|
||
<a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8('Show Filter') %]</a>
|
||
[% IF SELF.filter_summary %]([% LxERP.t8("Current filter") %]: [% SELF.filter_summary %])[% END %]
|
||
</div>
|
||
|
||
<div class="filter_toggle" style="display:none">
|
||
<a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8('Hide Filter') %]</a>
|
||
<table id="filter_table">
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("From") %]</th>
|
||
<td>[% L.input_tag("filter.from:substr::ilike", filter.from_substr__ilike, size = 20) %]</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Recipients") %]</th>
|
||
<td>[% L.input_tag("filter.recipients:substr::ilike", filter.recipients_substr__ilike, size = 20) %]</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Sent on") %]</th>
|
||
<td>
|
||
[% L.date_tag("filter.sent_on:date::ge", filter.sent_on_date__ge) %]
|
||
[% LxERP.t8("To Date") %]
|
||
[% L.date_tag("filter.sent_on:date::le", filter.sent_on_date__le) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Status") %]</th>
|
||
<td>[% L.select_tag("filter.status:eq_ignore_empty", [
|
||
[ "", "" ],
|
||
[ "send_failed", LxERP.t8("send failed") ],
|
||
[ "sent", LxERP.t8("sent") ],
|
||
[ "imported", LxERP.t8("imported") ]
|
||
], default=filter.status_eq_ignore_empty) %]</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Record Type") %]</th>
|
||
<td>
|
||
[%
|
||
SET record_type_options = [];
|
||
record_type_options.push({text=LxERP.t8("Catch-all"), record_type='catch_all'});
|
||
FOREACH record_info = RECORD_TYPES_WITH_INFO;
|
||
IF (!record_info.is_template);
|
||
record_type_options.push(record_info);
|
||
END;
|
||
END;
|
||
%]
|
||
[% L.select_tag("filter.record_type:eq_ignore_empty",
|
||
record_type_options,
|
||
title_key = 'text', value_key = 'record_type',
|
||
with_empty=1, default=filter.record_type_eq_ignore_empty) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Obsolete") %]</th>
|
||
<td>[% L.yes_no_tag("filter.obsolete:eq_ignore_empty",
|
||
filter.obsolete, with_empty=1,
|
||
default=filter.obsolete_eq_ignore_empty
|
||
) %]
|
||
</td>
|
||
<tr>
|
||
<th align="right">[% LxERP.t8("Linked") %]</th>
|
||
<td>[% L.yes_no_tag("filter.linked_to:eq_ignore_empty",
|
||
filter.linked_to, with_empty=1,
|
||
default=filter.linked_to_eq_ignore_empty
|
||
) %]
|
||
</td>
|
||
</tr>
|
||
<tr>
|
||
<th>[% LxERP.t8("Has unprocessed attachments") %]</th>
|
||
<td>[% L.yes_no_tag("filter.has_unprocessed_attachments:eq_ignore_empty",
|
||
filter.has_unprocessed_attachments, with_empty=1,
|
||
default=filter.has_unprocessed_attachments_eq_ignore_empty
|
||
) %]
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
[% L.hidden_tag("sort_by", FORM.sort_by) %]
|
||
[% L.hidden_tag("sort_dir", FORM.sort_dir) %]
|
||
[% L.hidden_tag("page", FORM.page) %]
|
||
|
||
[% L.button_tag('$("#filter_form").resetForm()', LxERP.t8('Reset')) %]
|
||
|
||
</div>
|
||
|
||
</form>
|
templates/webpages/email_journal/_report_bottom.html | ||
---|---|---|
[% USE L %]
|
||
[%- L.paginate_controls(models=models) %]
|
templates/webpages/email_journal/_report_top.html | ||
---|---|---|
[% USE L %]
|
||
|
||
[% FILTER_HTML %]
|
templates/webpages/email_journal/list.html | ||
---|---|---|
[% USE HTML %][% USE L %][% USE P %][% USE LxERP %]
|
||
|
||
<h1>[% FORM.title %]</h1>
|
||
|
||
[%- INCLUDE 'common/flash.html' %]
|
||
|
||
[%- PROCESS 'email_journal/_filter.html' filter=SELF.models.filtered.laundered %]
|
||
|
||
[% IF !ENTRIES.size %]
|
||
<p>
|
||
[%- LxERP.t8('There are no entries that match the filter.') %]
|
||
</p>
|
||
|
||
[%- ELSE %]
|
||
<table id="email_journal_list" width="100%">
|
||
<thead>
|
||
<tr class="listheading">
|
||
[% IF SELF.can_view_all %]
|
||
<th>[% L.sortable_table_header("sender") %]</th>
|
||
[% END %]
|
||
<th>[% L.sortable_table_header("from") %]</th>
|
||
<th>[% L.sortable_table_header("recipients") %]</th>
|
||
<th>[% L.sortable_table_header("subject") %]</th>
|
||
<th>[% L.sortable_table_header("sent_on") %]</th>
|
||
<th>[% L.sortable_table_header("attachments") %]</th>
|
||
<th>[% L.sortable_table_header("status") %]</th>
|
||
<th>[% L.sortable_table_header("extended_status") %]</th>
|
||
<th>[% L.sortable_table_header("record_type") %]</th>
|
||
<th>[% L.sortable_table_header("obsolete") %]</th>
|
||
<th>[% L.sortable_table_header("linked_to") %]</th>
|
||
<th>[% L.sortable_table_header("has_unprocessed_attachments") %]</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tbody>
|
||
[%- FOREACH entry = ENTRIES %]
|
||
<tr class="listrow[% IF entry.status == 'send_failed' %]_error[% END %]" id="email_journal_id_[% entry.id %]">
|
||
[% IF SELF.can_view_all %]
|
||
<td>
|
||
[% IF entry.sender %]
|
||
[% HTML.escape(entry.sender.name) %]
|
||
[% ELSE %]
|
||
[% LxERP.t8("kivitendo") %]
|
||
[% END %]
|
||
</td>
|
||
[% END %]
|
||
[% action_show_link = SELF.url_for(
|
||
action => 'show', id => entry.id,
|
||
back_to => SELF.models.get_callback(),
|
||
) %]
|
||
<td><a href="[% action_show_link %]">[%- HTML.escape(entry.from) %]</a></td>
|
||
<td>[%- HTML.escape(entry.recipients) %]</td>
|
||
<td><a href="[% action_show_link %]">[%- HTML.escape(entry.subject) %]</a></td>
|
||
<td>[%- HTML.escape(entry.sent_on.to_lxoffice('precision' => 'second')) %]</td>
|
||
<td>
|
||
[% FOREACH attachment = entry.attachments %]
|
||
<span>[% HTML.escape(attachment.name) %]</span>
|
||
[% END %]
|
||
</td>
|
||
<td> [% P.email_journal.entry_status(entry) %] </td>
|
||
<td>[%- HTML.escape(entry.extended_status) %]</td>
|
||
<td>[% HTML.escape(RECORD_TYPES_TO_TEXT.${entry.record_type}) %]</td>
|
||
<td>[% HTML.escape(entry.obsolete_as_bool_yn) %]</td>
|
||
<td>
|
||
[% P.record.simple_grouped_record_list(entry.linked_records) %]
|
||
</td>
|
||
<td>[% HTML.escape(entry.has_unprocessed_attachments) %]</td>
|
||
</tr>
|
||
[%- END %]
|
||
</tbody>
|
||
</table>
|
||
[%- END %]
|
||
|
||
[% L.paginate_controls %]
|
Auch abrufbar als: Unified diff
EmailJournal: Komplexer Bericht mit komplexen Filter