Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 958c1727

Von Bernd Bleßmann vor fast 4 Jahren hinzugefügt

  • ID 958c1727a1453b28feaf8c4bfa40ef25f8bcc3ea
  • Vorgänger 20615592
  • Nachfolger f9c38bb5

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.

Unterschiede anzeigen:

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