Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision e6af833d

Von Tamino Steinert vor 12 Tagen hinzugefügt

  • ID e6af833dc4ff65761a67a176c6ebfc04132bdaa6
  • Vorgänger efc07572

EmailJournal: Komplexer Bericht mit komplexen Filter

Unterschiede anzeigen:

SL/Controller/EmailJournal.pm
4 4

  
5 5
use parent qw(SL::Controller::Base);
6 6

  
7
use SL::ReportGenerator;
8
use SL::Controller::Helper::ReportGenerator;
7 9
use SL::ZUGFeRD;
8 10
use SL::Controller::ZUGFeRD;
9 11
use SL::Controller::Helper::GetModels;
......
11 13
use SL::DB::EmailJournal;
12 14
use SL::DB::EmailJournalAttachment;
13 15
use SL::Presenter::EmailJournal;
16
use SL::Presenter::Filter::EmailJournal;
14 17
use SL::Presenter::Record qw(grouped_record_list);
15 18
use SL::Presenter::Tag qw(html_tag div_tag button_tag);
16 19
use SL::Helper::Flash;
......
222 225
  my ($self) = @_;
223 226

  
224 227
  $::auth->assert('email_journal');
225
  # default filter
226
  $::form->{filter} ||= {"obsolete:eq_ignore_empty" => 0};
227 228

  
228 229
  if ( $::instance_conf->get_email_journal == 0 ) {
229
    flash('info',  $::locale->text('Storing the emails in the journal is currently disabled in the client configuration.'));
230
    flash('info',  t8('Storing the emails in the journal is currently disabled in the client configuration.'));
230 231
  }
232

  
233
  $::form->{filter} ||= {
234
    'obsolete:eq_ignore_empty' => 0,
235
  };
236

  
231 237
  $self->setup_list_action_bar;
232
  my @record_types_with_info = $self->get_record_types_with_info();
233
  my %record_types_to_text   = $self->get_record_types_to_text();
234
  $self->render('email_journal/list',
235
                title   => $::locale->text('Email journal'),
236
                ENTRIES => $self->models->get,
237
                MODELS  => $self->models,
238
                RECORD_TYPES_WITH_INFO => \@record_types_with_info,
239
                RECORD_TYPES_TO_TEXT   => \%record_types_to_text,
240
              );
238
  my $report = $self->prepare_report;
239
  $self->report_generator_list_objects(
240
    report => $report,
241
    objects => $self->models->get,
242
  );
241 243
}
242 244

  
243 245
sub action_show {
......
778 780
  return $customer_vendor;
779 781
}
780 782

  
783
sub prepare_report {
784
  my ($self) = @_;
785

  
786
  my %record_types_to_text   = $self->get_record_types_to_text();
787
  my @record_types_with_info = $self->get_record_types_with_info();
788

  
789
  my $report = SL::ReportGenerator->new(\%::myconfig, $::form);
790

  
791
  my $callback    = $self->models->get_callback;
792

  
793
  my @columns_order = qw(
794
    id
795
    sender
796
    from
797
    recipients
798
    subject
799
    sent_on
800
    attachment_names
801
    has_unprocessed_attachments
802
    unprocessed_attachment_names
803
    status
804
    extended_status
805
    record_type
806
    linked_to
807
    obsolete
808
  );
809

  
810
  my @default_columns = qw(
811
    from
812
    recipients
813
    subject
814
    sent_on
815
  );
816

  
817
  my %column_defs = (
818
    id => {
819
      obj_link => sub {$self->url_for(
820
          action => 'show', id => $_[0]->id, callback => $callback
821
        )},
822
      sub => sub { $_[0]->id },
823
    },
824
    sender => {
825
      sub => sub { $_[0]->sender ? $_[0]->sender->name : '' },
826
    },
827
    from => {
828
      obj_link => sub {$self->url_for(
829
          action => 'show', id => $_[0]->id, callback => $callback
830
        )},
831
      sub => sub { $_[0]->from },
832
    },
833
    recipients => {
834
      obj_link => sub {$self->url_for(
835
          action => 'show', id => $_[0]->id, callback => $callback
836
        )},
837
      sub => sub { $_[0]->recipients },
838
    },
839
    subject => {
840
      obj_link => sub {$self->url_for(
841
          action => 'show', id => $_[0]->id, callback => $callback
842
        )},
843
      sub => sub { $_[0]->subject },
844
    },
845
    sent_on => {
846
      obj_link => sub {$self->url_for(
847
          action => 'show', id => $_[0]->id, callback => $callback
848
        )},
849
      sub => sub { $_[0]->sent_on->to_kivitendo(precision => 'minute') },
850
    },
851
    attachment_names => {
852
      sub => sub {join(', ',
853
          map {$_->name}
854
          sort {$a->position <=> $b->position}
855
          @{$_[0]->attachments}
856
        )},
857
    },
858
    has_unprocessed_attachments => {
859
      sub => sub { $_[0]->has_unprocessed_attachments }
860
    },
861
    unprocessed_attachment_names => {
862
      sub => sub {join(', ',
863
          map {$_->name}
864
          sort {$a->position <=> $b->position}
865
          grep {$_->processed == 0}
866
          @{$_[0]->attachments}
867
        )},
868
    },
869
    status => {
870
      sub => sub { SL::Presenter::EmailJournal::entry_status($_[0]) },
871
    },
872
    extended_status => {
873
      sub => sub { $_[0]->extended_status },
874
    },
875
    record_type => {
876
      sub => sub { $record_types_to_text{$_[0]->record_type} },
877
    },
878
    linked_to => {
879
      raw_data => sub {
880
        SL::Presenter::Record::simple_grouped_record_list($_[0]->linked_records)
881
      }
882
    },
883
    obsolete => {
884
      sub => sub { $_[0]->obsolete_as_bool_yn }
885
    },
886
  );
887
  $column_defs{$_}->{text} ||=
888
    t8( $self->models->get_sort_spec->{$_}->{title} || $_ )
889
    for keys %column_defs;
890

  
891
  # make all sortable
892
  my @sortable = keys %column_defs;
893

  
894
  unless ($::form->{active_in_report}) {
895
    $::form->{active_in_report}->{$_} = 1 foreach @default_columns;
896
  }
897

  
898
  $column_defs{$_}->{visible} = $::form->{active_in_report}->{"$_"} || 0
899
    foreach keys %column_defs;
900

  
901
  my $filter_html = SL::Presenter::Filter::EmailJournal::filter(
902
    $::form->{filter},
903
    active_in_report => $::form->{active_in_report},
904
    record_types_with_info => \@record_types_with_info,
905
  );
906

  
907
  $self->models->disable_plugin('paginated')
908
    if $report->{options}{output_format} =~ /^(pdf|csv)$/i;
909
  $self->models->add_additional_url_params(
910
    active_in_report => $::form->{active_in_report}
911
  );
912
  $self->models->finalize; # for filter laundering
913

  
914
  $report->set_options(
915
    std_column_visibility => 1,
916
    controller_class      => 'EmailJournal',
917
    output_format         => 'HTML',
918
    raw_top_info_text     => $self->render(
919
     'email_journal/_report_top',
920
     { output => 0 },
921
     FILTER_HTML => $filter_html,
922
    ),
923
    raw_bottom_info_text  => $self->render(
924
     'email_journal/_report_bottom',
925
     { output => 0 },
926
     models => $self->models
927
    ),
928
    title                 => t8('Email journal'),
929
    allow_pdf_export      => 1,
930
    allow_csv_export      => 1,
931
  );
932
  $report->set_columns(%column_defs);
933
  $report->set_column_order(@columns_order);
934
  $report->set_export_options('list', qw(filter active_in_report));
935
  $report->set_options_from_form;
936

  
937
  $self->models->set_report_generator_sort_options(
938
    report => $report,
939
    sortable_columns => \@sortable
940
  );
941

  
942
  return $report;
943
}
944

  
781 945
sub add_js {
782 946
  $::request->{layout}->use_javascript("${_}.js") for qw(
783 947
    kivi.EmailJournal
......
797 961
    query             => \@where,
798 962
    with_objects      => [ 'sender' ],
799 963
    sorted            => {
964
      _default => {
965
        by => 'sent_on',
966
        dir => 0,
967
      },
800 968
      sender          => t8('Sender'),
801 969
      from            => t8('From'),
802 970
      recipients      => t8('Recipients'),
803 971
      subject         => t8('Subject'),
804
      attachments     => t8('Attachments'),
972
      attachment_names => t8('Attachments'),
973
      has_unprocessed_attachments => t8('Has unprocessed attachments'),
974
      unprocessed_attachment_names => t8('Unprocessed Attachments'),
805 975
      sent_on         => t8('Sent on'),
806 976
      status          => t8('Status'),
807 977
      extended_status => t8('Extended status'),
808 978
      record_type     => t8('Record Type'),
809 979
      obsolete        => t8('Obsolete'),
810 980
      linked_to       => t8('Linked to'),
811
      has_unprocessed_attachments => t8('Has unprocessed attachments'),
812 981
    },
813 982
  );
814 983
}
SL/DB/Manager/EmailJournal.pm
33 33
          )
34 34
        )} => \'TRUE';
35 35
  },
36
  unprocessed_attachment_names => sub {
37
    my ($key, $value, $prefix) = @_;
38
    return (
39
        and => [
40
        'attachments.name' => $value,
41
        'attachments.processed' => 0,
42
      ],
43
      'attachments'
44
    )
45
  },
36 46
  has_unprocessed_attachments => sub {
37 47
    my ($key, $value, $prefix) = @_;
38 48

  
......
68 78
            AND record_links.to_id = email_journal.id
69 79
          )
70 80
      )},
71
      attachment => qq{(
81
      attachment_names => qq{(
82
        SELECT STRING_AGG(
83
          email_journal_attachments.name,
84
          ', '
85
          ORDER BY email_journal_attachments.position ASC
86
       )
87
        FROM email_journal_attachments
88
        WHERE
89
          email_journal_attachments.email_journal_id = email_journal.id
90
      )},
91
      unprocessed_attachment_names => qq{(
72 92
        SELECT STRING_AGG(
73 93
          email_journal_attachments.name,
74 94
          ', '
......
77 97
        FROM email_journal_attachments
78 98
        WHERE
79 99
          email_journal_attachments.email_journal_id = email_journal.id
100
            AND email_journal_attachments.processed = FALSE
80 101
      )},
81 102
      has_unprocessed_attachments => qq{(
82 103
        SELECT count(*)
SL/Presenter/Filter/EmailJournal.pm
1
package SL::Presenter::Filter::EmailJournal;
2

  
3
use parent SL::Presenter::Filter;
4

  
5
use strict;
6

  
7
use SL::Locale::String qw(t8);
8

  
9
use Params::Validate qw(:all);
10

  
11
sub get_default_filter_elements {
12
  my ($filter) = shift @_;
13
  my %params = validate_with(
14
    params => \@_,
15
    spec   => {
16
    record_types_with_info => {
17
      type => ARRAYREF
18
    },
19
    },
20
  );
21

  
22
  my %default_filter_elements = ( # {{{
23
    id => {
24
      'position' => 1,
25
      'text' => t8("ID"),
26
      'input_type' => 'input_tag',
27
      'input_name' => 'filter.id:number',
28
      'input_default' => $filter->{'id:number'},
29
      'report_id' => 'id',
30
      'active' => 0,
31
    },
32
    sender => {
33
      'position' => 2,
34
      'text' => t8("Sender"),
35
      'input_type' => 'input_tag',
36
      'input_name' => 'filter.sender.name:substr::ilike',
37
      'input_default' => $filter->{sender}->{'name:substr::ilike'},
38
      'report_id' => 'sender',
39
      'active' => $::auth->assert('email_employee_readall', 1),
40
    },
41
    from => {
42
      'position' => 3,
43
      'text' => t8("From"),
44
      'input_type' => 'input_tag',
45
      'input_name' => 'filter.from:substr::ilike',
46
      'input_default' => $filter->{'from:substr::ilike'},
47
      'report_id' => 'from',
48
      'active' => 1,
49
    },
50
    recipients => {
51
      'position' => 4,
52
      'text' => t8("Recipients"),
53
      'input_type' => 'input_tag',
54
      'input_name' => 'filter.recipients:substr::ilike',
55
      'input_default' => $filter->{'recipients:substr::ilike'},
56
      'report_id' => 'recipients',
57
      'active' => 1,
58
    },
59
    subject => {
60
      'position' => 5,
61
      'text' => t8("Subject"),
62
      'input_type' => 'input_tag',
63
      'input_name' => 'filter.subject:substr::ilike',
64
      'input_default' => $filter->{'subject:substr::ilike'},
65
      'report_id' => 'subject',
66
      'active' => 1,
67
    },
68
    sent_on => {
69
      'position' => 6,
70
      'text' => t8("Sent on"),
71
      'input_type' => 'date_tag',
72
      'input_name' => 'sent_on',
73
      'input_default_ge' => $filter->{'sent_on' . ':date::ge'},
74
      'input_default_le' => $filter->{'sent_on' . ':date::le'},
75
      'report_id' => 'sent_on',
76
      'active' => 1,
77
    },
78
    attachment_names => {
79
      'position' => 7,
80
      'text' => t8("Attachments"),
81
      'input_type' => 'input_tag',
82
      'input_name' => 'filter.attachments.name:substr::ilike',
83
      'input_default' => $filter->{attachments}->{'name:substr::ilike'},
84
      'report_id' => 'attachment_names',
85
      'active' => 1,
86
    },
87
    'has_unprocessed_attachments' => {
88
      'position' => 8,
89
      'text' => t8("Has unprocessed attachments"),
90
      'input_type' => 'yes_no_tag',
91
      'input_name' => 'filter.has_unprocessed_attachments:eq_ignore_empty',
92
      'input_default' => $filter->{'has_unprocessed_attachments:eq_ignore_empty'},
93
      'report_id' => 'has_unprocessed_attachments',
94
      'active' => 1,
95
    },
96
    unprocessed_attachment_names => {
97
      'position' => 9,
98
      'text' => t8("Unprocessed Attachments"),
99
      'input_type' => 'input_tag',
100
      'input_name' => 'filter.unprocessed_attachment_names:substr::ilike',
101
      'input_default' => $filter->{'unprocessed_attachment_names:substr::ilike'},
102
      'report_id' => 'unprocessed_attachment_names',
103
      'active' => 1,
104
    },
105
    status => {
106
      'position' => 10,
107
      'text' => t8("Status"),
108
      'input_type' => 'select_tag',
109
      'input_values' => [
110
        [ "", "" ],
111
        [ "send_failed", t8("send failed") ],
112
        [ "sent", t8("sent") ],
113
        [ "imported", t8("imported") ]
114
      ],
115
      'input_name' => 'filter.status',
116
      'input_default' => $filter->{'status'},
117
      'report_id' => 'status',
118
      'active' => 1,
119
    },
120
    extended_status => {
121
      'position' => 11,
122
      'text' => t8("Extended status"),
123
      'input_type' => 'input_tag',
124
      'input_name' => 'filter.extended_status:substr::ilike',
125
      'input_default' => $filter->{'extended_status:substr::ilike'},
126
      'report_id' => 'extended_status',
127
      'active' => 1,
128
    },
129
    record_type => {
130
      'position' => 12,
131
      'text' => t8("Record Type"),
132
      'input_type' => 'select_tag',
133
      'input_values' => [
134
        map {[
135
           $_->{record_type} => $_->{text},
136
        ]}
137
        grep {!$_->{is_template}}
138
        {},
139
        {text=> t8("Catch-all"), record_type => 'catch_all'},
140
        @{$params{record_types_with_info}}
141
      ],
142
      'input_name' => 'filter.record_type:eq_ignore_empty',
143
      'input_default' => $filter->{'record_type:eq_ignore_empty'},
144
      'report_id' => 'record_type',
145
      'active' => 1,
146
    },
147
    'linked' => {
148
      'position' => 13,
149
      'text' => t8("Linked"),
150
      'input_type' => 'yes_no_tag',
151
      'input_name' => 'filter.linked_to:eq_ignore_empty',
152
      'input_default' => $filter->{'linked_to:eq_ignore_empty'},
153
      'report_id' => 'linked_to',
154
      'active' => 1,
155
    },
156
    'obsolete' => {
157
      'position' => 14,
158
      'text' => t8("Obsolete"),
159
      'input_type' => 'yes_no_tag',
160
      'input_name' => 'filter.obsolete:eq_ignore_empty',
161
      'input_default' => $filter->{'obsolete:eq_ignore_empty'},
162
      'report_id' => 'obsolete',
163
      'active' => 1,
164
    },
165
  ); # }}}
166
  return \%default_filter_elements;
167
}
168

  
169
sub filter {
170
  my $filter = shift @_ || {};
171
  die "filter has to be a hash ref" if ref $filter ne 'HASH';
172
  my %params = validate_with(
173
    params => \@_,
174
    spec   => {
175
      record_types_with_info => {
176
        type => ARRAYREF
177
      },
178
    },
179
    allow_extra => 1,
180
  );
181

  
182
  my $filter_elements = get_default_filter_elements($filter,
183
    record_types_with_info => delete $params{record_types_with_info},
184
  );
185

  
186
  return SL::Presenter::Filter::create_filter($filter_elements, %params);
187
}
188

  
189
1;
190

  
191
__END__
192

  
193
=pod
194

  
195
=encoding utf8
196

  
197
=head1 NAME
198

  
199
SL::Presenter::Filter::EmailJournal - Presenter module for a generic filter on
200
EmailJournal.
201

  
202
=head1 SYNOPSIS
203

  
204
  # in EmailJournal Controller
205
  my $filter_html = SL::Presenter::Filter::EmailJournal::filter(
206
    $::form->{filter},
207
    active_in_report => $::form->{active_in_report}
208
    record_types_with_info => \@record_types_with_info,
209
  );
210

  
211

  
212
=head1 FUNCTIONS
213

  
214
=over 4
215

  
216
=item C<filter $filter, %params>
217

  
218
Returns a rendered version (actually an instance of
219
L<SL::Presenter::EscapedText>) of a filter form for email journal.
220

  
221
C<$filter> should be the C<filter> value of the last C<$::form>. This is used to
222
get the previous values of the input fields.
223

  
224
C<%params> can include:
225

  
226
=over 2
227

  
228

  
229
= item * record_types_with_info
230

  
231
Is used to set the drop down for record type.
232

  
233
=back
234

  
235
Other C<%params> fields get forwarded to
236
C<SL::Presenter::Filter::create_filter>.
237

  
238
=back
239

  
240
=head1 BUGS
241

  
242
Nothing here yet.
243

  
244
=head1 AUTHOR
245

  
246
Tamino Steinert E<lt>tamino.steinert@tamino.stE<gt>
247

  
248
=cut
locale/de/all
4378 4378
  'There are mulitple vendors selected' => 'Es sind mehrere Lieferanten ausgewählt',
4379 4379
  'There are no documents in the WebDAV directory at the moment.' => 'Es befinden sich im WebDAV-Verzeichnis momentan keine Dokumente.',
4380 4380
  'There are no entries in the background job history.' => 'Es gibt keine Einträge im Hintergrund-Job-Verlauf.',
4381
  'There are no entries that match the filter.' => 'Es gibt keine Einträge, auf die der Filter zutrifft.',
4382 4381
  'There are no items in stock.' => 'Dieser Artikel ist nicht eingelagert.',
4383 4382
  'There are no items on your TODO list at the moment.' => 'Ihre Aufgabenliste enthält momentan keine Einträge.',
4384 4383
  'There are no items selected' => 'Es wurden keine Positionen ausgewählt',
......
4669 4668
  'Unlink bank transactions'    => 'Bankverbuchung(en) rückgängig machen',
4670 4669
  'Unlock System'               => 'System entsperren',
4671 4670
  'Unprocessed'                 => 'Nicht verarbeitet',
4671
  'Unprocessed Attachments'     => 'Nicht verarbeitete Anhänge',
4672 4672
  'Unsuccessfully executed:\n'  => 'Erfolglos ausgeführt:',
4673 4673
  'Unsupported image type (supported types: #1)' => 'Nicht unterstützter Bildtyp (unterstützte Typen: #1)',
4674 4674
  'Until'                       => 'Bis',
locale/en/all
4376 4376
  'There are mulitple vendors selected' => '',
4377 4377
  'There are no documents in the WebDAV directory at the moment.' => '',
4378 4378
  'There are no entries in the background job history.' => '',
4379
  'There are no entries that match the filter.' => '',
4380 4379
  'There are no items in stock.' => '',
4381 4380
  'There are no items on your TODO list at the moment.' => '',
4382 4381
  'There are no items selected' => '',
......
4667 4666
  'Unlink bank transactions'    => '',
4668 4667
  'Unlock System'               => '',
4669 4668
  'Unprocessed'                 => '',
4669
  'Unprocessed Attachments'     => '',
4670 4670
  'Unsuccessfully executed:\n'  => '',
4671 4671
  'Unsupported image type (supported types: #1)' => '',
4672 4672
  'Until'                       => '',
templates/design40_webpages/email_journal/_filter.html
1
[% USE L %]
2
[% USE LxERP %]
3
[% USE HTML %]
4

  
5
[% BLOCK filter_toggle_panel %]
6
  <table id="filter_table" class="tbl-horizontal">
7
    <tbody>
8
    <tr>
9
      <th>[% LxERP.t8("From") %]</th>
10
      <td>[% L.input_tag("filter.from:substr::ilike", filter.from_substr__ilike, size = 20) %]
11
      </td>
12
    </tr>
13
    <tr>
14
      <th>[% LxERP.t8("Recipients") %]</th>
15
      <td>[% L.input_tag("filter.recipients:substr::ilike", filter.recipients_substr__ilike, size = 20) %]
16
      </td>
17
    </tr>
18
    <tr>
19
      <th>[% LxERP.t8("Sent on") %]</th>
20
      <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) %]
21
      </td>
22
    </tr>
23
    <tr>
24
      <th>[% LxERP.t8("Status") %]</th>
25
      <td>[% L.select_tag("filter.status:eq_ignore_empty", [
26
                 [ "", "" ],
27
                 [ "send_failed", LxERP.t8("send failed") ],
28
                 [ "sent", LxERP.t8("sent") ],
29
                 [ "imported", LxERP.t8("imported") ]
30
               ], default=filter.status_eq_ignore_empty) %]
31
      </td>
32
    </tr>
33
    <tr>
34
      <th>[% LxERP.t8("Record Type") %]</th>
35
      <td>
36
        [%
37
          SET record_type_options = [];
38
          record_type_options.push({text=LxERP.t8("Catch-all"), record_type='catch_all'});
39
          FOREACH record_info = RECORD_TYPES_WITH_INFO;
40
            IF (!record_info.is_template);
41
              record_type_options.push(record_info);
42
            END;
43
          END;
44
        %]
45
        [% L.select_tag("filter.record_type:eq_ignore_empty",
46
             record_type_options,
47
             title_key = 'text', value_key = 'record_type',
48
             with_empty=1, default=filter.record_type_eq_ignore_empty) %]
49
      </td>
50
    </tr>
51
    <tr>
52
      <th>[% LxERP.t8("Obsolete") %]</th>
53
      <td>[% L.yes_no_tag("filter.obsolete:eq_ignore_empty",
54
            filter.obsolete, with_empty=1,
55
            default=filter.obsolete_eq_ignore_empty
56
            ) %]
57
      </td>
58
    </tr>
59
    <tr>
60
      <th>[% LxERP.t8("Linked") %]</th>
61
      <td>[% L.yes_no_tag("filter.linked_to:eq_ignore_empty",
62
            filter.linked_to, with_empty=1,
63
            default=filter.linked_to_eq_ignore_empty
64
            ) %]
65
      </td>
66
    </tr>
67
    <tr>
68
      <th>[% LxERP.t8("Has unprocessed attachments") %]</th>
69
      <td>[% L.yes_no_tag("filter.has_unprocessed_attachments:eq_ignore_empty",
70
            filter.has_unprocessed_attachments, with_empty=1,
71
            default=filter.has_unprocessed_attachments_eq_ignore_empty
72
            ) %]
73
      </td>
74
    </tr>
75
    </tbody>
76
  </table>
77
  [% L.hidden_tag("sort_by", FORM.sort_by) %]
78
  [% L.hidden_tag("sort_dir", FORM.sort_dir) %]
79
  [% L.hidden_tag("page", FORM.page) %]
80
  <div class="buttons">[% L.button_tag('$("#filter_form").resetForm()', LxERP.t8('Reset')) %]</div>
81
[% END %]
82

  
83
<div class="wrapper">
84
<form action="controller.pl" method="post" id="filter_form">
85

  
86
[% INCLUDE common/toggle_panel.html %]
87

  
88

  
89

  
90
</div>
91

  
92
</form>
93
</div>
templates/design40_webpages/email_journal/_report_bottom.html
1
[% USE L %]
2
[%- L.paginate_controls(models=models) %]
templates/design40_webpages/email_journal/_report_top.html
1
[% USE L %]
2

  
3
[% BLOCK filter_toggle_panel %]
4
[%- FILTER_HTML %]
5
[% END %]
6

  
7
<div class="wrapper">
8
  [% SET display_status = 'open' %]
9
  [% INCLUDE 'common/toggle_panel.html' %]
10
</div><!-- /.wrapper -->
templates/design40_webpages/email_journal/list.html
1
[% USE HTML %]
2
[% USE L %]
3
[% USE P %]
4
[% USE LxERP %]
5

  
6
<h1>[% FORM.title %]</h1>
7

  
8
[% INCLUDE 'common/flash.html' %]
9
[% PROCESS 'email_journal/_filter.html' filter=SELF.models.filtered.laundered %]
10

  
11
[% IF !ENTRIES.size %]
12
  <p>[% LxERP.t8('There are no entries that match the filter.') %]</p>
13

  
14
[% ELSE %]
15

  
16
<table id="email_journal_list" class="tbl-list wi-moderate">
17
  <thead>
18
    <tr>
19
      [% IF SELF.can_view_all %]
20
        <th>[% L.sortable_table_header("sender") %]</th>
21
      [% END %]
22
      <th>[% L.sortable_table_header("from") %]</th>
23
      <th>[% L.sortable_table_header("recipients") %]</th>
24
      <th>[% L.sortable_table_header("subject") %]</th>
25
      <th>[% L.sortable_table_header("sent_on") %]</th>
26
      <th>[% L.sortable_table_header("attachments") %]</th>
27
      <th>[% L.sortable_table_header("status") %]</th>
28
      <th>[% L.sortable_table_header("extended_status") %]</th>
29
      <th>[% L.sortable_table_header("record_type") %]</th>
30
      <th>[% L.sortable_table_header("obsolete") %]</th>
31
      <th>[% L.sortable_table_header("linked_to") %]</th>
32
      <th>[% L.sortable_table_header("has_unprocessed_attachments") %]</th>
33
    </tr>
34
  </thead>
35
  <tbody>
36
    [% FOREACH entry = ENTRIES %]
37
    <tr id="email_journal_id_[% entry.id %]" [% IF entry.status == 'send_failed' %] class="listrow_error" [% END %]>
38
      [% IF SELF.can_view_all %]
39
        <td>[% IF entry.sender %] [% HTML.escape(entry.sender.name) %] [% ELSE %] [% LxERP.t8("kivitendo") %] [% END %]</td>
40
      [% END %]
41
      [% action_show_link = SELF.url_for(
42
           action => 'show', id => entry.id,
43
           back_to => SELF.models.get_callback(),
44
      ) %]
45
      <td><a href="[% action_show_link %]"> [% HTML.escape(entry.from) %] </a></td>
46
      <td>[% HTML.escape(entry.recipients) %]</td>
47
      <td><a href="[% action_show_link %]"> [% HTML.escape(entry.subject) %] </a></td>
48
      <td>[% HTML.escape(entry.sent_on.to_lxoffice('precision' => 'second')) %]</td>
49
      <td>
50
        [% FOREACH attachment = entry.attachments %]
51
          <span>[% HTML.escape(attachment.name) %]</span>
52
        [% END %]
53
      </td>
54
      <td> [% P.email_journal.entry_status(entry) %] </td>
55
      <td>[% HTML.escape(entry.extended_status) %]</td>
56
      <td>[% HTML.escape(RECORD_TYPES_TO_TEXT.${entry.record_type}) %]</td>
57
      <td>[% HTML.escape(entry.obsolete_as_bool_yn) %]</td>
58
      <td>
59
        [% P.record.simple_grouped_record_list(entry.linked_records) %]
60
      </td>
61
      <td>[% HTML.escape(entry.has_unprocessed_attachments) %]</td>
62
    </tr>
63
    [% END %]
64
  </tbody>
65
</table>
66

  
67
[% END %]
68

  
69
[% L.paginate_controls %]
templates/webpages/email_journal/_filter.html
1
[%- USE L %][%- USE LxERP %][%- USE HTML %]
2
<form action="controller.pl" method="post" id="filter_form">
3
 <div class="filter_toggle">
4
  <a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8('Show Filter') %]</a>
5
  [% IF SELF.filter_summary %]([% LxERP.t8("Current filter") %]: [% SELF.filter_summary %])[% END %]
6
 </div>
7

  
8
 <div class="filter_toggle" style="display:none">
9
  <a href="#" onClick="javascript:$('.filter_toggle').toggle()">[% LxERP.t8('Hide Filter') %]</a>
10
  <table id="filter_table">
11
   <tr>
12
    <th align="right">[% LxERP.t8("From") %]</th>
13
    <td>[% L.input_tag("filter.from:substr::ilike", filter.from_substr__ilike, size = 20) %]</td>
14
   </tr>
15
   <tr>
16
    <th align="right">[% LxERP.t8("Recipients") %]</th>
17
    <td>[% L.input_tag("filter.recipients:substr::ilike", filter.recipients_substr__ilike, size = 20) %]</td>
18
   </tr>
19
   <tr>
20
    <th align="right">[% LxERP.t8("Sent on") %]</th>
21
    <td>
22
     [% L.date_tag("filter.sent_on:date::ge", filter.sent_on_date__ge) %]
23
     [% LxERP.t8("To Date") %]
24
     [% L.date_tag("filter.sent_on:date::le", filter.sent_on_date__le) %]
25
    </td>
26
   </tr>
27
   <tr>
28
    <th align="right">[% LxERP.t8("Status") %]</th>
29
    <td>[% L.select_tag("filter.status:eq_ignore_empty", [
30
               [ "", "" ],
31
               [ "send_failed", LxERP.t8("send failed") ],
32
               [ "sent", LxERP.t8("sent") ],
33
               [ "imported", LxERP.t8("imported") ]
34
             ], default=filter.status_eq_ignore_empty) %]</td>
35
   </tr>
36
    <tr>
37
      <th align="right">[% LxERP.t8("Record Type") %]</th>
38
      <td>
39
        [%
40
          SET record_type_options = [];
41
          record_type_options.push({text=LxERP.t8("Catch-all"), record_type='catch_all'});
42
          FOREACH record_info = RECORD_TYPES_WITH_INFO;
43
            IF (!record_info.is_template);
44
              record_type_options.push(record_info);
45
            END;
46
          END;
47
        %]
48
        [% L.select_tag("filter.record_type:eq_ignore_empty",
49
             record_type_options,
50
             title_key = 'text', value_key = 'record_type',
51
             with_empty=1, default=filter.record_type_eq_ignore_empty) %]
52
      </td>
53
    </tr>
54
    <tr>
55
      <th align="right">[% LxERP.t8("Obsolete") %]</th>
56
      <td>[% L.yes_no_tag("filter.obsolete:eq_ignore_empty",
57
            filter.obsolete, with_empty=1,
58
            default=filter.obsolete_eq_ignore_empty
59
            ) %]
60
      </td>
61
    <tr>
62
      <th align="right">[% LxERP.t8("Linked") %]</th>
63
      <td>[% L.yes_no_tag("filter.linked_to:eq_ignore_empty",
64
            filter.linked_to, with_empty=1,
65
            default=filter.linked_to_eq_ignore_empty
66
            ) %]
67
      </td>
68
    </tr>
69
    <tr>
70
      <th>[% LxERP.t8("Has unprocessed attachments") %]</th>
71
      <td>[% L.yes_no_tag("filter.has_unprocessed_attachments:eq_ignore_empty",
72
            filter.has_unprocessed_attachments, with_empty=1,
73
            default=filter.has_unprocessed_attachments_eq_ignore_empty
74
            ) %]
75
      </td>
76
    </tr>
77
  </table>
78

  
79
  [% L.hidden_tag("sort_by", FORM.sort_by) %]
80
  [% L.hidden_tag("sort_dir", FORM.sort_dir) %]
81
  [% L.hidden_tag("page", FORM.page) %]
82

  
83
  [% L.button_tag('$("#filter_form").resetForm()', LxERP.t8('Reset')) %]
84

  
85
 </div>
86

  
87
</form>
templates/webpages/email_journal/_report_bottom.html
1
[% USE L %]
2
[%- L.paginate_controls(models=models) %]
templates/webpages/email_journal/_report_top.html
1
[% USE L %]
2

  
3
[% FILTER_HTML %]
templates/webpages/email_journal/list.html
1
[% USE HTML %][% USE L %][% USE P %][% USE LxERP %]
2

  
3
<h1>[% FORM.title %]</h1>
4

  
5
[%- INCLUDE 'common/flash.html' %]
6

  
7
[%- PROCESS 'email_journal/_filter.html' filter=SELF.models.filtered.laundered %]
8

  
9
[% IF !ENTRIES.size %]
10
 <p>
11
  [%- LxERP.t8('There are no entries that match the filter.') %]
12
 </p>
13

  
14
[%- ELSE %]
15
 <table id="email_journal_list" width="100%">
16
  <thead>
17
   <tr class="listheading">
18
    [% IF SELF.can_view_all %]
19
     <th>[% L.sortable_table_header("sender") %]</th>
20
    [% END %]
21
    <th>[% L.sortable_table_header("from") %]</th>
22
    <th>[% L.sortable_table_header("recipients") %]</th>
23
    <th>[% L.sortable_table_header("subject") %]</th>
24
    <th>[% L.sortable_table_header("sent_on") %]</th>
25
    <th>[% L.sortable_table_header("attachments") %]</th>
26
    <th>[% L.sortable_table_header("status") %]</th>
27
    <th>[% L.sortable_table_header("extended_status") %]</th>
28
    <th>[% L.sortable_table_header("record_type") %]</th>
29
    <th>[% L.sortable_table_header("obsolete") %]</th>
30
    <th>[% L.sortable_table_header("linked_to") %]</th>
31
    <th>[% L.sortable_table_header("has_unprocessed_attachments") %]</th>
32
   </tr>
33
  </thead>
34

  
35
  <tbody>
36
  [%- FOREACH entry = ENTRIES %]
37
  <tr class="listrow[% IF entry.status == 'send_failed' %]_error[% END %]" id="email_journal_id_[% entry.id %]">
38
   [% IF SELF.can_view_all %]
39
    <td>
40
     [% IF entry.sender %]
41
      [% HTML.escape(entry.sender.name) %]
42
     [% ELSE %]
43
      [% LxERP.t8("kivitendo") %]
44
     [% END %]
45
    </td>
46
   [% END %]
47
   [% action_show_link = SELF.url_for(
48
        action => 'show', id => entry.id,
49
        back_to => SELF.models.get_callback(),
50
   ) %]
51
   <td><a href="[% action_show_link %]">[%- HTML.escape(entry.from) %]</a></td>
52
   <td>[%- HTML.escape(entry.recipients) %]</td>
53
   <td><a href="[% action_show_link %]">[%- HTML.escape(entry.subject) %]</a></td>
54
   <td>[%- HTML.escape(entry.sent_on.to_lxoffice('precision' => 'second')) %]</td>
55
   <td>
56
    [% FOREACH attachment = entry.attachments %]
57
     <span>[% HTML.escape(attachment.name) %]</span>
58
    [% END %]
59
   </td>
60
   <td> [% P.email_journal.entry_status(entry) %] </td>
61
   <td>[%- HTML.escape(entry.extended_status) %]</td>
62
   <td>[% HTML.escape(RECORD_TYPES_TO_TEXT.${entry.record_type}) %]</td>
63
   <td>[% HTML.escape(entry.obsolete_as_bool_yn) %]</td>
64
   <td>
65
     [% P.record.simple_grouped_record_list(entry.linked_records) %]
66
   </td>
67
    <td>[% HTML.escape(entry.has_unprocessed_attachments) %]</td>
68
  </tr>
69
  [%- END %]
70
  </tbody>
71
 </table>
72
[%- END %]
73

  
74
[% L.paginate_controls %]

Auch abrufbar als: Unified diff