Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision d11ed75b

Von Cem Aydin vor etwa 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
use SL::Presenter::Chart;
use SL::Presenter::CustomerVendor;
use SL::Presenter::DatePeriod;
use SL::Presenter::DeliveryOrder;
use SL::Presenter::Dunning;
use SL::Presenter::EscapedText;
......
our %presenters = (
chart => 'SL::Presenter::Chart',
customer_vendor => 'SL::Presenter::CustomerVendor',
date_period => 'SL::Presenter::DatePeriod',
delivery_order => 'SL::Presenter::DeliveryOrder',
dunning => 'SL::Presenter::Dunning',
escaped_text => 'SL::Presenter::EscapedText',
SL/Presenter/DatePeriod.pm
package SL::Presenter::DatePeriod;
use strict;
use Exporter qw(import);
our @EXPORT_OK = qw(
date_period_picker
get_dialog_defaults_from_report_generator
populate_hidden_variables
);
use SL::Presenter::Tag qw(name_to_id);
sub date_period_picker {
my ($name, $value_from, $value_to, %params) = @_;
my $id = name_to_id($name);
my @classes = $params{class} ? ($params{class}) : ();
push @classes, 'date_period_picker';
my $dialog_defaults = {
year => $params{dialog_defaults}->{year} // DateTime->today->year,
type => $params{dialog_defaults}->{type} // 'yearly',
quarter => $params{dialog_defaults}->{quarter} // 'A',
month => $params{dialog_defaults}->{month} // '1',
};
my $html = SL::Presenter->get->render(
'presenter/date_period/date_period_picker',
id => $id,
classes => \@classes,
defaults => {
report_period_from_date => $value_from || '',
report_period_to_date => $value_to || '',
dialog => $dialog_defaults
},
years_list => get_years(),
months_list => get_months(),
);
$::request->layout->add_javascripts('kivi.Presenter.DatePeriodPicker.js');
return $html;
}
### convenience functions
sub get_dialog_defaults_from_report_generator {
my ($name) = @_;
my $id = name_to_id($name);
my %fallback_dateperiod_dialog = (
year => DateTime->today->year,
type => 'yearly',
quarter => 'A',
month => '1',
);
my %defaults_dialog;
for (keys %fallback_dateperiod_dialog) {
$defaults_dialog{$_} = $::form->{'report_generator_hidden_' . $id . '_selected_preset_' . $_} //
$fallback_dateperiod_dialog{$_};
}
return \%defaults_dialog;
}
sub populate_hidden_variables {
my ($name, $hidden_variables_ref) = @_;
my $id = name_to_id($name);
my @vars = qw(
_from_date
_to_date
_selected_preset_year
_selected_preset_type
_selected_preset_quarter
_selected_preset_month
);
push @{ $hidden_variables_ref }, map { $id . $_ } @vars;
}
### helper
sub get_months {
my $dt = DateTime->now;
my $months = $dt->{locale}->{locale_data}->{month_format_wide};
my $i = 0;
[ map { $i++; [ $i, $::locale->text($_) ] } @{ $months } ];
}
sub get_years {
my $current = DateTime->today->year;
[ map { [ $current - $_, $current - $_, ] } (0..39) ];
}
sub picker { goto &date_period_picker }
1;
__END__
=encoding utf-8
=head1 NAME
SL::Presenter::DatePeriod - Date period stuff
=head1 SYNOPSIS
# use in perl code
use SL::Presenter::DatePeriod qw(date_period_picker);
my $html = date_period_picker('my-picker-id', '', '');
my $html = date_period_picker('my-other-picker-id', $from_date, $to_date);
# use in template
[% P.date_period.picker('my-picker-id', '', '') %]
[% P.date_period.picker('my-other-picker-id',
defaults.from_date,
defaults.to_date,
dialog_defaults => defaults.dialog) %]
see also L<SL::Presenter>
=head1 DATE PERIOD PICKER UI DESCRIPTION
Two date input fields are shown: 'From' and 'To', to select a date period.
Additionally a button is shown: 'Select from preset'.
When clicked it shows a dialog that allows the selection of a date period
from sensible presets.
=over 2
=item Dialog:
The dialog shows a select 'Year', containing the current year plus years up
to forty years back.
A period is selected with a radio button, that is either 'yearly' (default),
'quarterly' or 'monthly'.
For quarterly and monthly there is a select shown containing the respective
values.
=back
=head1 FUNCTIONS
=over 2
=item C<date_period_picker $name, $value_from, $value_to, %params>
Renders a date period picker with preset dialog.
C<$name> should be a unique name. It is converted to an id for the main
element. This id is also used as a prefix for all sub-elements that need an id.
B<Important:> The selected dates are available from the form elements
C<id _ '_from_date'> and C<id _ '_to_date'>.
In above example this would be C<'my-picker-id_from_date'> and
C<'my-picker-id_to_date'>.
C<$value_from> and C<$value_to> are used as preset values for the respective
date fields. This may be useful to keep entered value between page switches.
C<$params> Classes in C<class> are forwarded to the main element.
If you want to keep the selection over multiple requests this has to be handled
in the controller.
C<$params> can therefor contain a hash called C<dialog_defaults> with the
key/values:
year => DateTime->today->year, # numeric year
type => 'yearly', # the radio button selection:
# 'yearly', 'monthly', 'quarterly'
quarter => 'A', # the quarter as a letter code:
# 'A', 'B', 'C', 'D' A being 1st quarter etc.
month => '1', # numeric month
The values will be used to pre-select the dialog fields.
These values are also set into some hidden fields with the id in the format
e.g.: C<id _ '_selected_preset_year'>.
Convenience functions to handle report generator hidden variables are provided.
E.g.:
use SL::Presenter::DatePeriod qw(get_dialog_defaults_from_report_generator
populate_hidden_variables);
# use values from form, then report generator form, then fallback
my %fallback = (
dateperiod_from_date => '',
dateperiod_to_date => '',
# other fields e.g.:
# chart_id => '',
);
my %defaults;
for (keys %fallback) {
$defaults{$_} = $::form->{$_} // $::form->{'report_generator_hidden_' . $_} // $fallback{$_};
}
# set dialog defaults
$defaults{dialog} = get_dialog_defaults_from_report_generator('dateperiod');
# set hidden fields for the report generator
my @hidden_variables = qw(chart_id); # e.g.
populate_hidden_variables('dateperiod', \@hidden_variables);
=item C<get_dialog_defaults_from_report_generator $name>
Convenience function to get the dialog defaults from hidden report generator
fields. (Use in controller.)
C<$name> name of the date picker.
=item C<populate_hidden_variables $name $hidden_variables_ref>
Convenience function Add hidden variables to report a generator.
(Use in controller.)
C<$name> name of the date picker.
C<$hidden_variables_ref> reference to the hidden variable array.
=back
=head1 USE / MOTIVATION / GOAL
Use date_period_picker when you want to select a date period with preset
dialog.
Planned use: ListTransactions report settings view (new, replacement for
ca/list).
Possible uses in report settings views for:
- rp/erfolgsrechnung (swiss)
- rp/trial_balance
- Inventory/stock_usage
And possibly more.
Current implementations for report periods repeat a lot of template and
perl code in different places. Hopefully this can be reduced.
While this UI may require slightly more clicks than previous / current
implementations, the interface is much more concise. It is easier on the eyes
and fits better into the new design 4.0.
=head1 LIMITATIONS
If multiple date_period_picker elements were to be used on the same page the
handling of hidden variables becomes ugly.
my @hidden_variables = qw(
dateperiod_from_date
dateperiod_to_date
dateperiod_selected_preset_year
dateperiod_selected_preset_type
# ... etc.
);
Convenience functions are provided to help handle this. Currently i don't see
another way of handling this.
=head1 BUGS
None atm :)
=head1 AUTHOR
Cem Aydin E<lt>cem.aydin@revamp-it.chE<gt>
=cut
js/kivi.Presenter.DatePeriodPicker.js
namespace('kivi.ReportPeriod', function(ns) {
ns.open_dialog = function(el) {
ns.current_id = el.parentNode.id;
ns.current_dialog = $(`#${ ns.current_id }_preset_dialog`).dialog({
title: kivi.t8('Select from preset'),
width: 340,
height: 330,
modal: true,
});
}
ns.apply_preset = function() {
const year = $(`#${ ns.current_id }_preset_dialog_year`).val();
const type = $(`input[name="${ ns.current_id }_preset_dialog_type"]:checked`).val();
const quarter = $(`#${ ns.current_id }_preset_dialog_quarter`).val();
const month = $(`#${ ns.current_id }_preset_dialog_month`).val();
let duetyp = 13; // (yearly)
if (type === 'quarterly') {
duetyp = quarter;
} else if (type === 'monthly') {
duetyp = month;
}
ns.set_from_to(duetyp, year);
$(`#${ ns.current_id }_selected_preset_year`).val(year);
$(`#${ ns.current_id }_selected_preset_type`).val(type);
$(`#${ ns.current_id }_selected_preset_quarter`).val(quarter);
$(`#${ ns.current_id }_selected_preset_month`).val(month);
ns.current_dialog.dialog('close');
$(`#${ ns.current_id }_preset_dialog_button`)
}
ns.set_from_to = function (duetyp, year) {
const date = {
1: [ 1, 1, 1, 31 ],
2: [ 2, 1, 2, new Date(year, 1, 29).getMonth() == 1 ? 29 : 28 ],
3: [ 3, 1, 3, 31 ],
4: [ 4, 1, 4, 30 ],
5: [ 5, 1, 5, 31 ],
6: [ 6, 1, 6, 30 ],
7: [ 7, 1, 7, 31 ],
8: [ 8, 1, 8, 31 ],
9: [ 9, 1, 9, 30 ],
10: [ 10, 1, 10, 31 ],
11: [ 11, 1, 11, 30 ],
12: [ 12, 1, 12, 31 ],
13: [ 1, 1, 12, 31 ],
'A': [ 1, 1, 3, 31 ],
'B': [ 4, 1, 6, 30 ],
'C': [ 7, 1, 9, 30 ],
'D': [ 10, 1, 12, 31 ]
}[duetyp];
$(`#${ ns.current_id }_from_date`).val(kivi.format_date(new Date(year, date[0]-1, date[1])));
$(`#${ ns.current_id }_to_date`).val(kivi.format_date(new Date(year, date[2]-1, date[3])));
}
});
js/locale/de.js
"Save":"Speichern",
"Save and keep open":"Speichern und geöffnet lassen",
"Section/Function block actions":"Abschnitts-/Funktionsblockaktionen",
"Select from preset":"Aus Voreinstellung wählen",
"Select template to paste":"Einzufügende Vorlage auswählen",
"Send email":"E-Mail verschicken",
"Sep":"Sep",
js/locale/en.js
"Save":"",
"Save and keep open":"",
"Section/Function block actions":"",
"Select from preset":"",
"Select template to paste":"",
"Send email":"",
"Sep":"",
locale/de/all
'Select federal state...' => 'Bundesland auswählen...',
'Select file to upload' => 'Datei zum Hochladen auswählen',
'Select from one of the items below' => 'Wählen Sie einen der untenstehenden Einträge',
'Select from preset' => 'Aus Voreinstellung wählen',
'Select postscript or PDF!' => 'Postscript oder PDF auswählen!',
'Select tax office...' => 'Finanzamt auswählen...',
'Select template to paste' => 'Einzufügende Vorlage auswählen',
locale/en/all
'Select federal state...' => '',
'Select file to upload' => '',
'Select from one of the items below' => '',
'Select from preset' => '',
'Select postscript or PDF!' => '',
'Select tax office...' => '',
'Select template to paste' => '',
templates/design40_webpages/presenter/date_period/date_period_picker.html
[% USE HTML %]
[% USE LxERP %]
[% USE L %]
[% USE P %]
[% USE T8 %]
<div id="[% id %]" class="[% classes.join(' ') %]">
[% 'From' | $T8 %] [% L.date_tag(id _ '_from_date',
defaults.report_period_from_date) %]
[% 'To' | $T8 %] [% L.date_tag(id _ '_to_date',
defaults.report_period_to_date) %]
[% P.button_tag('kivi.ReportPeriod.open_dialog(event.target)',
LxERP.t8('Select from preset'),
id => id _ '_preset_dialog_button',
class => 'neutral') %]
<div id="[% id _ '_preset_dialog' %]" style="display: none;">
<h3>[% 'Year' | $T8 %]</h3>
<p>[% L.select_tag(id _ '_preset_dialog_year', years_list, default = defaults.dialog.year) %]</p>
<h3>[% 'Period' | $T8 %]</h3>
<table class="tbl-horizontal">
<colgroup>
<col class="wi-mediumsmall">
<col class="wi-mediumsmall">
</colgroup>
<tbody>
<tr>
<th>[% L.radio_button_tag(id _ '_preset_dialog_type',
value => 'yearly',
checked => defaults.dialog.type == 'yearly' ? 1 : 0,
label => LxERP.t8('Yearly')) %]</th>
<td></td>
</tr>
<tr>
<th>[% L.radio_button_tag(id _ '_preset_dialog_type',
value => 'quarterly',
checked => defaults.dialog.type == 'quarterly' ? 1 : 0,
label => LxERP.t8('Quarterly')) %]</th>
<td>[% L.select_tag(id _ '_preset_dialog_quarter',
[
[ 'A', LxERP.t8('1. Quarter') ],
[ 'B', LxERP.t8('2. Quarter') ],
[ 'C', LxERP.t8('3. Quarter') ],
[ 'D', LxERP.t8('4. Quarter') ],
], default => defaults.dialog.quarter) %]</td>
</tr>
<tr>
<th>[% L.radio_button_tag(id _ '_preset_dialog_type',
value => 'monthly',
checked => defaults.dialog.type == 'monthly' ? 1 : 0,
label => LxERP.t8('Monthly')) %]</th>
<td>[% L.select_tag(id _ '_preset_dialog_month', months_list,
default => defaults.dialog.month) %]</td>
</tr>
</tbody>
</table>
<p>[% P.button_tag('kivi.ReportPeriod.apply_preset()',
LxERP.t8('Apply')) %]</p>
</div>
[% L.hidden_tag(id _ '_selected_preset_year', defaults.dialog.year) %]
[% L.hidden_tag(id _ '_selected_preset_type', defaults.dialog.type) %]
[% L.hidden_tag(id _ '_selected_preset_quarter', defaults.dialog.quarter) %]
[% L.hidden_tag(id _ '_selected_preset_month', defaults.dialog.month) %]
</div>
templates/webpages/presenter/date_period/date_period_picker.html
[% USE HTML %]
[% USE LxERP %]
[% USE L %]
[% USE P %]
[% USE T8 %]
<div id="[% id %]" class="[% classes.join(' ') %]">
[% 'From' | $T8 %] [% L.date_tag(id _ '_from_date',
defaults.report_period_from_date) %]
[% 'To' | $T8 %] [% L.date_tag(id _ '_to_date',
defaults.report_period_to_date) %]
[% P.button_tag('kivi.ReportPeriod.open_dialog(event.target)',
LxERP.t8('Select from preset'),
id => id _ '_preset_dialog_button',
class => 'neutral') %]
<div id="[% id _ '_preset_dialog' %]" style="display: none;">
<h4>[% 'Year' | $T8 %]</h4>
<p>[% L.select_tag(id _ '_preset_dialog_year', years_list, default = defaults.dialog.year) %]</p>
<h4>[% 'Period' | $T8 %]</h4>
<table class="tbl-horizontal">
<tbody>
<tr>
<th align="left">[% L.radio_button_tag(id _ '_preset_dialog_type',
value => 'yearly',
checked => defaults.dialog.type == 'yearly' ? 1 : 0,
label => LxERP.t8('Yearly')) %]</th>
<td></td>
</tr>
<tr>
<th align="left">[% L.radio_button_tag(id _ '_preset_dialog_type',
value => 'quarterly',
checked => defaults.dialog.type == 'quarterly' ? 1 : 0,
label => LxERP.t8('Quarterly')) %]</th>
<td>[% L.select_tag(id _ '_preset_dialog_quarter',
[
[ 'A', LxERP.t8('1. Quarter') ],
[ 'B', LxERP.t8('2. Quarter') ],
[ 'C', LxERP.t8('3. Quarter') ],
[ 'D', LxERP.t8('4. Quarter') ],
], default => defaults.dialog.quarter) %]</td>
</tr>
<tr>
<th align="left">[% L.radio_button_tag(id _ '_preset_dialog_type',
value => 'monthly',
checked => defaults.dialog.type == 'monthly' ? 1 : 0,
label => LxERP.t8('Monthly')) %]</th>
<td>[% L.select_tag(id _ '_preset_dialog_month', months_list,
default => defaults.dialog.month) %]</td>
</tr>
</tbody>
</table>
<p>[% P.button_tag('kivi.ReportPeriod.apply_preset()',
LxERP.t8('Apply')) %]</p>
</div>
[% L.hidden_tag(id _ '_selected_preset_year', defaults.dialog.year) %]
[% L.hidden_tag(id _ '_selected_preset_type', defaults.dialog.type) %]
[% L.hidden_tag(id _ '_selected_preset_quarter', defaults.dialog.quarter) %]
[% L.hidden_tag(id _ '_selected_preset_month', defaults.dialog.month) %]
</div>

Auch abrufbar als: Unified diff