Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision d11ed75b

Von Cem Aydin vor fast 2 Jahren hinzugefügt

  • ID d11ed75bb2986dfc3d79ff1128c2a5986a069981
  • Vorgänger 272d7a97
  • Nachfolger 33801bdb

Neuer Presenter: SL::Presenter::DatePeriod

Liefert Element P.date_period.picker zum Auswählen eines Zeitraums
mit optionaler Vorauswahl

Enthält zwei Datumsfelder plus ein Button/PopUp-Dialog mit
Vorgewählten Zeiträumen.

Geplante Verwendung in neuer Ansicht Buchungsliste (ersetzt
ca/list).

Mögliche weitere Verwendungen u.a.:

- rp/erfolgsrechnung (swiss)
- rp/trial_balance
- Inventory/stock_usage

Siehe auch perldoc SL/Presenter/DatePeriod.pm

Unterschiede anzeigen:

SL/Presenter/ALL.pm
4 4

  
5 5
use SL::Presenter::Chart;
6 6
use SL::Presenter::CustomerVendor;
7
use SL::Presenter::DatePeriod;
7 8
use SL::Presenter::DeliveryOrder;
8 9
use SL::Presenter::Dunning;
9 10
use SL::Presenter::EscapedText;
......
28 29
our %presenters = (
29 30
  chart                       => 'SL::Presenter::Chart',
30 31
  customer_vendor             => 'SL::Presenter::CustomerVendor',
32
  date_period                 => 'SL::Presenter::DatePeriod',
31 33
  delivery_order              => 'SL::Presenter::DeliveryOrder',
32 34
  dunning                     => 'SL::Presenter::Dunning',
33 35
  escaped_text                => 'SL::Presenter::EscapedText',
SL/Presenter/DatePeriod.pm
1
package SL::Presenter::DatePeriod;
2

  
3
use strict;
4

  
5
use Exporter qw(import);
6
our @EXPORT_OK = qw(
7
  date_period_picker
8
  get_dialog_defaults_from_report_generator
9
  populate_hidden_variables
10
);
11

  
12
use SL::Presenter::Tag qw(name_to_id);
13

  
14
sub date_period_picker {
15
  my ($name, $value_from, $value_to, %params) = @_;
16

  
17
  my $id = name_to_id($name);
18
  my @classes = $params{class} ? ($params{class}) : ();
19
  push @classes, 'date_period_picker';
20

  
21
  my $dialog_defaults = {
22
    year => $params{dialog_defaults}->{year} // DateTime->today->year,
23
    type => $params{dialog_defaults}->{type} // 'yearly',
24
    quarter => $params{dialog_defaults}->{quarter} // 'A',
25
    month => $params{dialog_defaults}->{month} // '1',
26
  };
27

  
28
  my $html = SL::Presenter->get->render(
29
    'presenter/date_period/date_period_picker',
30
    id => $id,
31
    classes => \@classes,
32
    defaults => {
33
      report_period_from_date => $value_from || '',
34
      report_period_to_date => $value_to || '',
35
      dialog => $dialog_defaults
36
    },
37
    years_list => get_years(),
38
    months_list => get_months(),
39
  );
40
  $::request->layout->add_javascripts('kivi.Presenter.DatePeriodPicker.js');
41

  
42
  return $html;
43
}
44

  
45
### convenience functions
46

  
47
sub get_dialog_defaults_from_report_generator {
48
  my ($name) = @_;
49

  
50
  my $id = name_to_id($name);
51

  
52
  my %fallback_dateperiod_dialog = (
53
    year => DateTime->today->year,
54
    type => 'yearly',
55
    quarter => 'A',
56
    month => '1',
57
  );
58
  my %defaults_dialog;
59
  for (keys %fallback_dateperiod_dialog) {
60
    $defaults_dialog{$_} = $::form->{'report_generator_hidden_' . $id . '_selected_preset_' . $_} //
61
                            $fallback_dateperiod_dialog{$_};
62
  }
63
  return \%defaults_dialog;
64
}
65

  
66
sub populate_hidden_variables {
67
  my ($name, $hidden_variables_ref) = @_;
68

  
69
  my $id = name_to_id($name);
70

  
71
  my @vars = qw(
72
    _from_date
73
    _to_date
74
    _selected_preset_year
75
    _selected_preset_type
76
    _selected_preset_quarter
77
    _selected_preset_month
78
  );
79

  
80
  push @{ $hidden_variables_ref }, map { $id . $_ } @vars;
81
}
82

  
83
### helper
84

  
85
sub get_months {
86
  my $dt = DateTime->now;
87
  my $months = $dt->{locale}->{locale_data}->{month_format_wide};
88
  my $i = 0;
89
  [ map { $i++; [ $i, $::locale->text($_) ] } @{ $months } ];
90
}
91

  
92
sub get_years {
93
  my $current = DateTime->today->year;
94
  [ map { [ $current - $_, $current - $_, ] } (0..39) ];
95
}
96

  
97
sub picker { goto &date_period_picker }
98

  
99
1;
100

  
101
__END__
102

  
103
=encoding utf-8
104

  
105
=head1 NAME
106

  
107
SL::Presenter::DatePeriod - Date period stuff
108

  
109
=head1 SYNOPSIS
110

  
111
  # use in perl code
112
  use SL::Presenter::DatePeriod qw(date_period_picker);
113
  my $html   = date_period_picker('my-picker-id', '', '');
114
  my $html   = date_period_picker('my-other-picker-id', $from_date, $to_date);
115

  
116
  # use in template
117
  [% P.date_period.picker('my-picker-id', '', '') %]
118
  [% P.date_period.picker('my-other-picker-id',
119
                            defaults.from_date,
120
                            defaults.to_date,
121
                            dialog_defaults => defaults.dialog) %]
122

  
123
see also L<SL::Presenter>
124

  
125
=head1 DATE PERIOD PICKER UI DESCRIPTION
126

  
127
Two date input fields are shown: 'From' and 'To', to select a date period.
128

  
129
Additionally a button is shown: 'Select from preset'.
130

  
131
When clicked it shows a dialog that allows the selection of a date period
132
from sensible presets.
133

  
134
=over 2
135

  
136
=item Dialog:
137

  
138
The dialog shows a select 'Year', containing the current year plus years up
139
to forty years back.
140

  
141
A period is selected with a radio button, that is either 'yearly' (default),
142
'quarterly' or 'monthly'.
143

  
144
For quarterly and monthly there is a select shown containing the respective
145
values.
146

  
147
=back
148

  
149
=head1 FUNCTIONS
150

  
151
=over 2
152

  
153
=item C<date_period_picker $name, $value_from, $value_to, %params>
154

  
155
Renders a date period picker with preset dialog.
156

  
157
C<$name> should be a unique name. It is converted to an id for the main
158
element. This id is also used as a prefix for all sub-elements that need an id.
159

  
160
B<Important:> The selected dates are available from the form elements
161

  
162
C<id _ '_from_date'> and C<id _ '_to_date'>.
163

  
164
In above example this would be C<'my-picker-id_from_date'> and
165
C<'my-picker-id_to_date'>.
166

  
167
C<$value_from> and C<$value_to> are used as preset values for the respective
168
date fields. This may be useful to keep entered value between page switches.
169

  
170
C<$params> Classes in C<class> are forwarded to the main element.
171

  
172
If you want to keep the selection over multiple requests this has to be handled
173
in the controller.
174

  
175
C<$params> can therefor contain a hash called C<dialog_defaults> with the
176
key/values:
177

  
178
  year => DateTime->today->year,  # numeric year
179
  type => 'yearly',               # the radio button selection:
180
                                  # 'yearly', 'monthly', 'quarterly'
181
  quarter => 'A',                 # the quarter as a letter code:
182
                                  # 'A', 'B', 'C', 'D' A being 1st quarter etc.
183
  month => '1',                   # numeric month
184

  
185
The values will be used to pre-select the dialog fields.
186

  
187
These values are also set into some hidden fields with the id in the format
188
e.g.: C<id _ '_selected_preset_year'>.
189

  
190
Convenience functions to handle report generator hidden variables are provided.
191
E.g.:
192

  
193
  use SL::Presenter::DatePeriod qw(get_dialog_defaults_from_report_generator
194
                                    populate_hidden_variables);
195

  
196
  # use values from form, then report generator form, then fallback
197
  my %fallback = (
198
    dateperiod_from_date => '',
199
    dateperiod_to_date => '',
200
    # other fields e.g.:
201
    # chart_id      => '',
202
  );
203
  my %defaults;
204
  for (keys %fallback) {
205
    $defaults{$_} = $::form->{$_} // $::form->{'report_generator_hidden_' . $_} // $fallback{$_};
206
  }
207

  
208
  # set dialog defaults
209
  $defaults{dialog} = get_dialog_defaults_from_report_generator('dateperiod');
210

  
211
  # set hidden fields for the report generator
212
  my @hidden_variables = qw(chart_id);    # e.g.
213
  populate_hidden_variables('dateperiod', \@hidden_variables);
214

  
215

  
216
=item C<get_dialog_defaults_from_report_generator $name>
217

  
218
Convenience function to get the dialog defaults from hidden report generator
219
fields. (Use in controller.)
220

  
221
C<$name> name of the date picker.
222

  
223
=item C<populate_hidden_variables $name $hidden_variables_ref>
224

  
225
Convenience function Add hidden variables to report a generator.
226
(Use in controller.)
227

  
228
C<$name> name of the date picker.
229

  
230
C<$hidden_variables_ref> reference to the hidden variable array.
231

  
232
=back
233

  
234
=head1 USE / MOTIVATION / GOAL
235

  
236
Use date_period_picker when you want to select a date period with preset
237
dialog.
238

  
239
Planned use: ListTransactions report settings view (new, replacement for
240
ca/list).
241

  
242
Possible uses in report settings views for:
243

  
244
  - rp/erfolgsrechnung (swiss)
245
  - rp/trial_balance
246
  - Inventory/stock_usage
247

  
248
And possibly more.
249

  
250
Current implementations for report periods repeat a lot of template and
251
perl code in different places. Hopefully this can be reduced.
252

  
253
While this UI may require slightly more clicks than previous / current
254
implementations, the interface is much more concise. It is easier on the eyes
255
and fits better into the new design 4.0.
256

  
257
=head1 LIMITATIONS
258

  
259
If multiple date_period_picker elements were to be used on the same page the
260
handling of hidden variables becomes ugly.
261

  
262
  my @hidden_variables = qw(
263
    dateperiod_from_date
264
    dateperiod_to_date
265
    dateperiod_selected_preset_year
266
    dateperiod_selected_preset_type
267
    # ... etc.
268
  );
269

  
270
Convenience functions are provided to help handle this. Currently i don't see
271
another way of handling this.
272

  
273
=head1 BUGS
274

  
275
None atm :)
276

  
277
=head1 AUTHOR
278

  
279
Cem Aydin E<lt>cem.aydin@revamp-it.chE<gt>
280

  
281
=cut
js/kivi.Presenter.DatePeriodPicker.js
1
namespace('kivi.ReportPeriod', function(ns) {
2

  
3
  ns.open_dialog = function(el) {
4

  
5
    ns.current_id = el.parentNode.id;
6

  
7
    ns.current_dialog = $(`#${ ns.current_id }_preset_dialog`).dialog({
8
      title: kivi.t8('Select from preset'),
9
      width:  340,
10
      height: 330,
11
      modal: true,
12
    });
13
  }
14

  
15
  ns.apply_preset = function() {
16

  
17
    const year = $(`#${ ns.current_id }_preset_dialog_year`).val();
18
    const type = $(`input[name="${ ns.current_id }_preset_dialog_type"]:checked`).val();
19
    const quarter = $(`#${ ns.current_id }_preset_dialog_quarter`).val();
20
    const month = $(`#${ ns.current_id }_preset_dialog_month`).val();
21

  
22
    let duetyp = 13; // (yearly)
23
    if (type === 'quarterly') {
24
      duetyp = quarter;
25
    } else if (type === 'monthly') {
26
      duetyp = month;
27
    }
28
    ns.set_from_to(duetyp, year);
29

  
30
    $(`#${ ns.current_id }_selected_preset_year`).val(year);
31
    $(`#${ ns.current_id }_selected_preset_type`).val(type);
32
    $(`#${ ns.current_id }_selected_preset_quarter`).val(quarter);
33
    $(`#${ ns.current_id }_selected_preset_month`).val(month);
34

  
35
    ns.current_dialog.dialog('close');
36
    $(`#${ ns.current_id }_preset_dialog_button`)
37
  }
38

  
39
  ns.set_from_to = function (duetyp, year) {
40
    const date = {
41
      1:  [ 1,  1, 1,  31 ],
42
      2:  [ 2,  1, 2,  new Date(year, 1, 29).getMonth() == 1 ? 29 : 28 ],
43
      3:  [ 3,  1, 3,  31 ],
44
      4:  [ 4,  1, 4,  30 ],
45
      5:  [ 5,  1, 5,  31 ],
46
      6:  [ 6,  1, 6,  30 ],
47
      7:  [ 7,  1, 7,  31 ],
48
      8:  [ 8,  1, 8,  31 ],
49
      9:  [ 9,  1, 9,  30 ],
50
      10: [ 10, 1, 10, 31 ],
51
      11: [ 11, 1, 11, 30 ],
52
      12: [ 12, 1, 12, 31 ],
53
      13: [  1, 1, 12, 31 ],
54
      'A': [ 1,  1, 3,  31 ],
55
      'B': [ 4,  1, 6,  30 ],
56
      'C': [ 7,  1, 9,  30 ],
57
      'D': [ 10, 1, 12, 31 ]
58
    }[duetyp];
59

  
60
    $(`#${ ns.current_id }_from_date`).val(kivi.format_date(new Date(year, date[0]-1, date[1])));
61
    $(`#${ ns.current_id }_to_date`).val(kivi.format_date(new Date(year, date[2]-1, date[3])));
62
  }
63
});
js/locale/de.js
146 146
"Save":"Speichern",
147 147
"Save and keep open":"Speichern und geöffnet lassen",
148 148
"Section/Function block actions":"Abschnitts-/Funktionsblockaktionen",
149
"Select from preset":"Aus Voreinstellung wählen",
149 150
"Select template to paste":"Einzufügende Vorlage auswählen",
150 151
"Send email":"E-Mail verschicken",
151 152
"Sep":"Sep",
js/locale/en.js
146 146
"Save":"",
147 147
"Save and keep open":"",
148 148
"Section/Function block actions":"",
149
"Select from preset":"",
149 150
"Select template to paste":"",
150 151
"Send email":"",
151 152
"Sep":"",
locale/de/all
3283 3283
  'Select federal state...'     => 'Bundesland auswählen...',
3284 3284
  'Select file to upload'       => 'Datei zum Hochladen auswählen',
3285 3285
  'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
3286
  'Select from preset'          => 'Aus Voreinstellung wählen',
3286 3287
  'Select postscript or PDF!'   => 'Postscript oder PDF auswählen!',
3287 3288
  'Select tax office...'        => 'Finanzamt auswählen...',
3288 3289
  'Select template to paste'    => 'Einzufügende Vorlage auswählen',
locale/en/all
3282 3282
  'Select federal state...'     => '',
3283 3283
  'Select file to upload'       => '',
3284 3284
  'Select from one of the items below' => '',
3285
  'Select from preset'          => '',
3285 3286
  'Select postscript or PDF!'   => '',
3286 3287
  'Select tax office...'        => '',
3287 3288
  'Select template to paste'    => '',
templates/design40_webpages/presenter/date_period/date_period_picker.html
1
[% USE HTML %]
2
[% USE LxERP %]
3
[% USE L %]
4
[% USE P %]
5
[% USE T8 %]
6

  
7
<div id="[% id %]" class="[% classes.join(' ') %]">
8
  [% 'From' | $T8 %] [% L.date_tag(id _ '_from_date',
9
                                    defaults.report_period_from_date) %]
10

  
11
  [% 'To' | $T8 %] [% L.date_tag(id _ '_to_date',
12
                                  defaults.report_period_to_date) %]
13

  
14
  [% P.button_tag('kivi.ReportPeriod.open_dialog(event.target)',
15
                  LxERP.t8('Select from preset'),
16
                  id => id _ '_preset_dialog_button',
17
                  class => 'neutral') %]
18

  
19
  <div id="[% id _ '_preset_dialog' %]" style="display: none;">
20
    <h3>[% 'Year' | $T8 %]</h3>
21
    <p>[% L.select_tag(id _ '_preset_dialog_year', years_list, default = defaults.dialog.year) %]</p>
22
    <h3>[% 'Period' | $T8 %]</h3>
23
    <table class="tbl-horizontal">
24
      <colgroup>
25
        <col class="wi-mediumsmall">
26
        <col class="wi-mediumsmall">
27
      </colgroup>
28
      <tbody>
29
        <tr>
30
          <th>[% L.radio_button_tag(id _ '_preset_dialog_type',
31
                                    value => 'yearly',
32
                                    checked => defaults.dialog.type == 'yearly' ? 1 : 0,
33
                                    label => LxERP.t8('Yearly')) %]</th>
34
          <td></td>
35
        </tr>
36
        <tr>
37
          <th>[% L.radio_button_tag(id _ '_preset_dialog_type',
38
                                    value => 'quarterly',
39
                                    checked => defaults.dialog.type == 'quarterly' ? 1 : 0,
40
                                    label => LxERP.t8('Quarterly')) %]</th>
41
          <td>[% L.select_tag(id _ '_preset_dialog_quarter',
42
                              [
43
                                [ 'A', LxERP.t8('1. Quarter') ],
44
                                [ 'B', LxERP.t8('2. Quarter') ],
45
                                [ 'C', LxERP.t8('3. Quarter') ],
46
                                [ 'D', LxERP.t8('4. Quarter') ],
47
                              ],  default => defaults.dialog.quarter) %]</td>
48
        </tr>
49
        <tr>
50
          <th>[% L.radio_button_tag(id _ '_preset_dialog_type',
51
                                    value => 'monthly',
52
                                    checked => defaults.dialog.type == 'monthly' ? 1 : 0,
53
                                    label => LxERP.t8('Monthly')) %]</th>
54
          <td>[% L.select_tag(id _ '_preset_dialog_month', months_list,
55
                              default => defaults.dialog.month) %]</td>
56
        </tr>
57
      </tbody>
58
    </table>
59
    <p>[% P.button_tag('kivi.ReportPeriod.apply_preset()',
60
                        LxERP.t8('Apply')) %]</p>
61
  </div>
62
  [% L.hidden_tag(id _ '_selected_preset_year', defaults.dialog.year) %]
63
  [% L.hidden_tag(id _ '_selected_preset_type', defaults.dialog.type) %]
64
  [% L.hidden_tag(id _ '_selected_preset_quarter', defaults.dialog.quarter) %]
65
  [% L.hidden_tag(id _ '_selected_preset_month', defaults.dialog.month) %]
66
</div>
templates/webpages/presenter/date_period/date_period_picker.html
1
[% USE HTML %]
2
[% USE LxERP %]
3
[% USE L %]
4
[% USE P %]
5
[% USE T8 %]
6

  
7
<div id="[% id %]" class="[% classes.join(' ') %]">
8
  [% 'From' | $T8 %] [% L.date_tag(id _ '_from_date',
9
                                    defaults.report_period_from_date) %]
10

  
11
  [% 'To' | $T8 %] [% L.date_tag(id _ '_to_date',
12
                                  defaults.report_period_to_date) %]
13

  
14
  [% P.button_tag('kivi.ReportPeriod.open_dialog(event.target)',
15
                  LxERP.t8('Select from preset'),
16
                  id => id _ '_preset_dialog_button',
17
                  class => 'neutral') %]
18

  
19
  <div id="[% id _ '_preset_dialog' %]" style="display: none;">
20
    <h4>[% 'Year' | $T8 %]</h4>
21
    <p>[% L.select_tag(id _ '_preset_dialog_year', years_list, default = defaults.dialog.year) %]</p>
22
    <h4>[% 'Period' | $T8 %]</h4>
23
    <table class="tbl-horizontal">
24
      <tbody>
25
        <tr>
26
          <th align="left">[% L.radio_button_tag(id _ '_preset_dialog_type',
27
                                    value => 'yearly',
28
                                    checked => defaults.dialog.type == 'yearly' ? 1 : 0,
29
                                    label => LxERP.t8('Yearly')) %]</th>
30
          <td></td>
31
        </tr>
32
        <tr>
33
          <th align="left">[% L.radio_button_tag(id _ '_preset_dialog_type',
34
                                    value => 'quarterly',
35
                                    checked => defaults.dialog.type == 'quarterly' ? 1 : 0,
36
                                    label => LxERP.t8('Quarterly')) %]</th>
37
          <td>[% L.select_tag(id _ '_preset_dialog_quarter',
38
                              [
39
                                [ 'A', LxERP.t8('1. Quarter') ],
40
                                [ 'B', LxERP.t8('2. Quarter') ],
41
                                [ 'C', LxERP.t8('3. Quarter') ],
42
                                [ 'D', LxERP.t8('4. Quarter') ],
43
                              ],  default => defaults.dialog.quarter) %]</td>
44
        </tr>
45
        <tr>
46
          <th align="left">[% L.radio_button_tag(id _ '_preset_dialog_type',
47
                                    value => 'monthly',
48
                                    checked => defaults.dialog.type == 'monthly' ? 1 : 0,
49
                                    label => LxERP.t8('Monthly')) %]</th>
50
          <td>[% L.select_tag(id _ '_preset_dialog_month', months_list,
51
                              default => defaults.dialog.month) %]</td>
52
        </tr>
53
      </tbody>
54
    </table>
55
    <p>[% P.button_tag('kivi.ReportPeriod.apply_preset()',
56
                        LxERP.t8('Apply')) %]</p>
57
  </div>
58
  [% L.hidden_tag(id _ '_selected_preset_year', defaults.dialog.year) %]
59
  [% L.hidden_tag(id _ '_selected_preset_type', defaults.dialog.type) %]
60
  [% L.hidden_tag(id _ '_selected_preset_quarter', defaults.dialog.quarter) %]
61
  [% L.hidden_tag(id _ '_selected_preset_month', defaults.dialog.month) %]
62
</div>

Auch abrufbar als: Unified diff