Revision 958c1727
Von Bernd Bleßmann vor fast 4 Jahren hinzugefügt
SL/Controller/Helper/ReportGenerator.pm | ||
---|---|---|
|
||
use Carp;
|
||
use List::Util qw(max);
|
||
use Scalar::Util qw(blessed);
|
||
|
||
use SL::Common;
|
||
use SL::MoreCommon;
|
||
... | ... | |
my @columns = $params{report}->get_visible_columns('HTML');
|
||
|
||
for my $obj (@{ $params{objects} || [] }) {
|
||
my %data = map {
|
||
my $def = $column_defs->{$_};
|
||
my $tmp;
|
||
$tmp->{raw_data} = $def->{raw_data} ? $def->{raw_data}->($obj) : '';
|
||
$tmp->{data} = $def->{sub} ? $def->{sub}->($obj)
|
||
: $obj->can($_) ? $obj->$_
|
||
: $obj->{$_};
|
||
$tmp->{link} = $def->{obj_link} ? $def->{obj_link}->($obj) : '';
|
||
$_ => $tmp;
|
||
} @columns;
|
||
my %data;
|
||
|
||
if (blessed($obj) && $obj->isa('SL::Controller::Helper::ReportGenerator::ControlRow::Base')) {
|
||
$obj->set_data($params{report});
|
||
next;
|
||
|
||
} else {
|
||
%data = map {
|
||
my $def = $column_defs->{$_};
|
||
my $tmp;
|
||
$tmp->{raw_data} = $def->{raw_data} ? $def->{raw_data}->($obj) : '';
|
||
$tmp->{data} = $def->{sub} ? $def->{sub}->($obj)
|
||
: $obj->can($_) ? $obj->$_
|
||
: $obj->{$_};
|
||
$tmp->{link} = $def->{obj_link} ? $def->{obj_link}->($obj) : '';
|
||
$_ => $tmp;
|
||
} @columns;
|
||
}
|
||
|
||
$params{data_callback}->(\%data) if $params{data_callback};
|
||
|
||
... | ... | |
|
||
Mandatory. An array reference of RDBO models to output.
|
||
|
||
An element of the array can also be an instance of a control row, i.e.
|
||
an instance of a class derived from
|
||
C<SL::Controller::Helper::ReportGenerator::ControlRow::Base>.
|
||
See also:
|
||
|
||
L<SL::Controller::Helper::ReportGenerator::ControlRow>
|
||
L<SL::Controller::Helper::ReportGenerator::ControlRow::*>
|
||
|
||
=item C<data_callback>
|
||
|
||
Optional. A callback handler (code reference) that gets called for
|
SL/Controller/Helper/ReportGenerator/ControlRow.pm | ||
---|---|---|
package SL::Controller::Helper::ReportGenerator::ControlRow;
|
||
|
||
use strict;
|
||
use Carp;
|
||
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow::ALL;
|
||
|
||
use Exporter 'import';
|
||
our @EXPORT = qw(
|
||
make_control_row
|
||
);
|
||
|
||
|
||
sub make_control_row {
|
||
my ($type, %args) = @_;
|
||
|
||
my $class = $SL::Controller::Helper::ReportGenerator::ControlRow::ALL::type_to_class{$type} // croak "unknown type $type";
|
||
my $obj = $class->new(params => \%args);
|
||
my @errors = $obj->validate_params;
|
||
croak join("\n", @errors) if @errors;
|
||
|
||
return $obj;
|
||
}
|
||
|
||
|
||
1;
|
||
|
||
__END__
|
||
|
||
=encoding utf-8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Controller::Helper::ReportGenerator::ControlRow - an interface for
|
||
report generator control rows
|
||
|
||
=head1 DESCRIPTION
|
||
|
||
ControlRow is an interface that allows generic control rows to be added
|
||
to objects for the C<SL::Controller::Helper::ReportGenerator>.
|
||
|
||
Each control row implementation can access the report and add data for a row.
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
package SL::Controller::TimeRecording;
|
||
|
||
use SL::Controller::Helper::ReportGenerator;
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow qw(make_control_row);
|
||
|
||
sub action_list {
|
||
my ($self) = @_;
|
||
|
||
# Set up the report generator instance. In this example this is
|
||
# hidden in "prepare_report".
|
||
my $report = $self->prepare_report;
|
||
|
||
# Get objects from database.
|
||
my $objects = SL::DB::Manager::TimeRecording->get_all(...);
|
||
|
||
# Add a separator
|
||
push @$objects, make_control_row("separator");
|
||
|
||
# And a simple total
|
||
my $total = sum0 map { _round_total($_->duration_in_hours) } @$objects;
|
||
push @$objects, make_control_row("simple_data", data => {duration => $total});
|
||
|
||
# Let report generator create the output.
|
||
$self->report_generator_list_objects(
|
||
report => $report,
|
||
objects => $objects,
|
||
);
|
||
}
|
||
|
||
|
||
=head1 WRITING OWN CONTROL ROW CLASSES
|
||
|
||
See C<SL::Controller::Helper::ReportGenerator::ControlRow::Base>.
|
||
|
||
=head1 FUNCTIONS
|
||
|
||
=over 4
|
||
|
||
=item C<make_control_row TYPE %PARAMS>
|
||
|
||
Returns an instance of the control row class for the given type. This
|
||
object can be used as an element of objects to the report generator helper
|
||
(see C<SL::Controller::Helper::ReportGenerator>).
|
||
|
||
Available types are 'separator', 'data, 'simple_data' for now.
|
||
|
||
C<%PARAMS> depends on the type. See also:
|
||
|
||
L<SL::Controller::Helper::ReportGenerator::ControlRow::ALL>
|
||
L<SL::Controller::Helper::ReportGenerator::ControlRow::*>
|
||
|
||
=back
|
||
|
||
=head1 AUTHOR
|
||
|
||
Bernd Bleßmann E<lt>bernd@kivitendo-premium.deE<gt>
|
||
|
||
=cut
|
SL/Controller/Helper/ReportGenerator/ControlRow/ALL.pm | ||
---|---|---|
package SL::Controller::Helper::ReportGenerator::ControlRow::ALL;
|
||
|
||
use strict;
|
||
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow::Data;
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow::Separator;
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow::SimpleData;
|
||
|
||
our %type_to_class = (
|
||
data => 'SL::Controller::Helper::ReportGenerator::ControlRow::Data',
|
||
separator => 'SL::Controller::Helper::ReportGenerator::ControlRow::Separator',
|
||
simple_data => 'SL::Controller::Helper::ReportGenerator::ControlRow::SimpleData',
|
||
);
|
||
|
||
1;
|
SL/Controller/Helper/ReportGenerator/ControlRow/Base.pm | ||
---|---|---|
package SL::Controller::Helper::ReportGenerator::ControlRow::Base;
|
||
|
||
use strict;
|
||
|
||
use parent qw(SL::DB::Object);
|
||
|
||
use Rose::Object::MakeMethods::Generic (
|
||
scalar => [ qw(params) ],
|
||
);
|
||
|
||
|
||
sub validate_params { die 'name needs to be implemented' }
|
||
sub set_data { die 'name needs to be implemented' }
|
||
|
||
|
||
1;
|
||
|
||
|
||
__END__
|
||
|
||
=encoding utf-8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Controller::Helper::ReportGenerator::ControlRow::Base - a base class
|
||
for report generator control row classes
|
||
|
||
=head1 DESCRIPTION
|
||
|
||
ControlRow is an interface that allows generic control rows to be added
|
||
to objects for the C<SL::Controller::Helper::ReportGenerator>. This is a
|
||
base class from which all control row classes are derived.
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
Adding your own new control row of the type "only_dashes":
|
||
|
||
package SL::Controller::Helper::ReportGenerator::ControlRow::OnlyDashes;
|
||
|
||
use parent qw(SL::Controller::Helper::ReportGenerator::ControlRow::Base);
|
||
|
||
sub validate_params { return; } # no params
|
||
|
||
sub set_data {
|
||
my ($self, $report) = @_;
|
||
|
||
my %data = map { $_ => {data => '---'} } keys %{ $report->{columns} };
|
||
|
||
$report->add_data(\%data);
|
||
}
|
||
|
||
After that, you have to register your new class in
|
||
C<SL::Controller::Helper::ReportGenerator::ControlRow::ALL>:
|
||
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow::OnlyDashes;
|
||
|
||
our %type_to_class = (
|
||
...,
|
||
only_dashes => 'SL::Controller::Helper::ReportGenerator::ControlRow::OnlyDashes',
|
||
);
|
||
|
||
|
||
=head1 WRITING OWN CONTROL ROW CLASSES
|
||
|
||
You can use C<SL::Controller::Helper::ReportGenerator::ControlRow::Base>
|
||
as parent of your module. You have to provide two methods:
|
||
|
||
=over 4
|
||
|
||
=item C<validate_params>
|
||
|
||
This method is used to validate any params used for your module.
|
||
You can access the params through the method C<params> which contains all
|
||
remaining params after the type of the call to make_control_row (see
|
||
C<SL::Controller::Helper::ReportGenerator::ControlRow>).
|
||
|
||
The method should return an array of error messages if there are any
|
||
errors. Otherwise it should return C<undef>.
|
||
|
||
=item C<set_data REPORT>
|
||
|
||
This method sould set the data for the report generator, which is handeled
|
||
over as argument.
|
||
|
||
=back
|
||
|
||
=head1 REGISTERING OWN CONTROL ROW CLASSES
|
||
|
||
See C<SL::Controller::Helper::ReportGenerator::ControlRow::ALL>. Here your
|
||
class should be included with C<use> and entered in the map C<%type_to_class>
|
||
with an appropiate name for it's type.
|
||
|
||
|
||
=head1 AUTHOR
|
||
|
||
Bernd Bleßmann E<lt>bernd@kivitendo-premium.deE<gt>
|
||
|
||
=cut
|
SL/Controller/Helper/ReportGenerator/ControlRow/Data.pm | ||
---|---|---|
package SL::Controller::Helper::ReportGenerator::ControlRow::Data;
|
||
|
||
use strict;
|
||
|
||
use parent qw(SL::Controller::Helper::ReportGenerator::ControlRow::Base);
|
||
|
||
|
||
sub validate_params {
|
||
my ($self) = @_;
|
||
|
||
my @errors;
|
||
push @errors, 'type "data" needs a parameter "row" as hash ref' if !$self->params->{row} || ('HASH' ne ref $self->params->{row});
|
||
|
||
return @errors;;
|
||
}
|
||
|
||
sub set_data {
|
||
my ($self, $report) = @_;
|
||
|
||
my %data;
|
||
%data = map {
|
||
my $def = $self->params->{row}->{$_};
|
||
my $tmp;
|
||
|
||
foreach my $attr (qw(raw_data data link class align)) {
|
||
$tmp->{$attr} = $def->{$attr} if defined $def->{$attr};
|
||
}
|
||
$_ => $tmp;
|
||
} keys %{ $self->params->{row} };
|
||
|
||
$report->add_data(\%data);
|
||
}
|
||
|
||
|
||
1;
|
||
|
||
__END__
|
||
|
||
=encoding utf-8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Controller::Helper::ReportGenerator::ControlRow::Data - an
|
||
implementaion of a control row class to display data
|
||
|
||
=head1 DESCRIPTION
|
||
|
||
This class implements a control row for the report generator helper to display
|
||
data. You can configure the way the data is displayed.
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
use SL::Controller::Helper::ReportGenerator;
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow qw(make_control_row);
|
||
|
||
sub action_list {
|
||
my ($self) = @_;
|
||
|
||
# Set up the report generator instance. In this example this is
|
||
# hidden in "prepare_report".
|
||
my $report = $self->prepare_report;
|
||
|
||
# Get objects from database.
|
||
my $objects = SL::DB::Manager::TimeRecording->get_all(...);
|
||
|
||
# Add a simple data
|
||
my $total = $self->get_total($objects);
|
||
push @$objects, make_control_row(
|
||
"data",
|
||
row => { duration => { data => $total,
|
||
class => 'listtotal',
|
||
link => '#info_for_total' } }
|
||
);
|
||
|
||
# Let report generator create the output.
|
||
$self->report_generator_list_objects(
|
||
report => $report,
|
||
objects => $objects,
|
||
);
|
||
}
|
||
|
||
=head1 PARAMETERS
|
||
|
||
This control row gets the paramter C<row>, which must a hash ref.
|
||
The keys are the column names for the fields you want to show your
|
||
data. The values are hash refs itself and can contain the keys
|
||
C<raw_data>, C<data>, C<link>, C<class> and C<align> which are passed
|
||
in the data added to the report.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Bernd Bleßmann E<lt>bernd@kivitendo-premium.deE<gt>
|
||
|
||
=cut
|
SL/Controller/Helper/ReportGenerator/ControlRow/Separator.pm | ||
---|---|---|
package SL::Controller::Helper::ReportGenerator::ControlRow::Separator;
|
||
|
||
use strict;
|
||
|
||
use parent qw(SL::Controller::Helper::ReportGenerator::ControlRow::Base);
|
||
|
||
|
||
sub validate_params {
|
||
return;
|
||
}
|
||
|
||
sub set_data {
|
||
my ($self, $report) = @_;
|
||
|
||
$report->add_separator();
|
||
}
|
||
|
||
|
||
1;
|
||
|
||
|
||
__END__
|
||
|
||
=encoding utf-8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Controller::Helper::ReportGenerator::ControlRow::Separator - an
|
||
implementaion of a control row class to display a separator
|
||
|
||
=head1 DESCRIPTION
|
||
|
||
This class implements a control row for the report generator helper to display
|
||
a separator.
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
use SL::Controller::Helper::ReportGenerator;
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow qw(make_control_row);
|
||
|
||
sub action_list {
|
||
my ($self) = @_;
|
||
|
||
# Set up the report generator instance. In this example this is
|
||
# hidden in "prepare_report".
|
||
my $report = $self->prepare_report;
|
||
|
||
# Get objects from database.
|
||
my $objects = SL::DB::Manager::TimeRecording->get_all(...);
|
||
|
||
# Add a separator
|
||
push @$objects, make_control_row("separator");
|
||
|
||
# Let report generator create the output.
|
||
$self->report_generator_list_objects(
|
||
report => $report,
|
||
objects => $objects,
|
||
);
|
||
}
|
||
|
||
=head1 PARAMETERS
|
||
|
||
This control row does not use any parameters.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Bernd Bleßmann E<lt>bernd@kivitendo-premium.deE<gt>
|
||
|
||
=cut
|
SL/Controller/Helper/ReportGenerator/ControlRow/SimpleData.pm | ||
---|---|---|
package SL::Controller::Helper::ReportGenerator::ControlRow::SimpleData;
|
||
|
||
use strict;
|
||
|
||
use parent qw(SL::Controller::Helper::ReportGenerator::ControlRow::Base);
|
||
|
||
|
||
sub validate_params {
|
||
my ($self) = @_;
|
||
|
||
my @errors;
|
||
push @errors, 'type "simple_data" needs a parameter "data" as hash ref' if !$self->params->{data} || ('HASH' ne ref $self->params->{data});
|
||
|
||
return @errors;
|
||
}
|
||
|
||
sub set_data {
|
||
my ($self, $report) = @_;
|
||
|
||
my %data = map {
|
||
my $tmp;
|
||
$tmp->{data} = $self->params->{data}->{$_};
|
||
$_ => $tmp;
|
||
} keys %{ $self->params->{data} };
|
||
|
||
$report->add_data(\%data);
|
||
}
|
||
|
||
|
||
1;
|
||
|
||
|
||
__END__
|
||
|
||
=encoding utf-8
|
||
|
||
=head1 NAME
|
||
|
||
SL::Controller::Helper::ReportGenerator::ControlRow::SimpleData - an
|
||
implementaion of a control row class to display simple data
|
||
|
||
=head1 DESCRIPTION
|
||
|
||
This class implements a control row for the report generator helper to display
|
||
simple data. C<Simple> because you only have to provide the column and your data
|
||
as a string.
|
||
|
||
=head1 SYNOPSIS
|
||
|
||
use SL::Controller::Helper::ReportGenerator;
|
||
use SL::Controller::Helper::ReportGenerator::ControlRow qw(make_control_row);
|
||
|
||
sub action_list {
|
||
my ($self) = @_;
|
||
|
||
# Set up the report generator instance. In this example this is
|
||
# hidden in "prepare_report".
|
||
my $report = $self->prepare_report;
|
||
|
||
# Get objects from database.
|
||
my $objects = SL::DB::Manager::TimeRecording->get_all(...);
|
||
|
||
# Add a simple data
|
||
push @$objects, make_control_row(
|
||
"simple_data",
|
||
data => { duration => 'Total sum of duration is not implemeted yet' }
|
||
);
|
||
|
||
# Let report generator create the output.
|
||
$self->report_generator_list_objects(
|
||
report => $report,
|
||
objects => $objects,
|
||
);
|
||
}
|
||
|
||
=head1 PARAMETERS
|
||
|
||
This control row gets the paramter C<data>, which must a hash ref.
|
||
The keys are the column names for the fields you want to show your
|
||
data. The values are the data.
|
||
|
||
=head1 AUTHOR
|
||
|
||
Bernd Bleßmann E<lt>bernd@kivitendo-premium.deE<gt>
|
||
|
||
=cut
|
Auch abrufbar als: Unified diff
S:C:H:ReportGenerator: Interface und Impmentierung von Kontroll-Zeilen
Es wurde eine Schnittstelle geschaffen, um Kontroll-Zeilen an den
ReportGenerator-Helfer zu übergeben.
Umgesetzt sind Kontroll-Zeilen für einen Separator und für eigene Daten.