[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
SF.net SVN: ledger-smb:[5239] addons/1.3/report_framework/trunk
- Subject: SF.net SVN: ledger-smb:[5239] addons/1.3/report_framework/trunk
- From: ..hidden..
- Date: Thu, 22 Nov 2012 06:58:53 +0000
Revision: 5239
http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=5239&view=rev
Author: einhverfr
Date: 2012-11-22 06:58:53 +0000 (Thu, 22 Nov 2012)
Log Message:
-----------
New PNL framework added, backporting current reporting framework to 1.3
Added Paths:
-----------
addons/1.3/report_framework/trunk/LedgerSMB/Report/
addons/1.3/report_framework/trunk/LedgerSMB/Report.pm
addons/1.3/report_framework/trunk/UI/Reports/
addons/1.3/report_framework/trunk/patches/
addons/1.3/report_framework/trunk/patches/pnl_invoice.diff
addons/1.3/report_framework/trunk/patches/pnl_product.diff
Removed Paths:
-------------
addons/1.3/report_framework/trunk/LedgerSMB/DBObject/
addons/1.3/report_framework/trunk/UI/Reports/
Copied: addons/1.3/report_framework/trunk/LedgerSMB/Report.pm (from rev 5237, trunk/LedgerSMB/Report.pm)
===================================================================
--- addons/1.3/report_framework/trunk/LedgerSMB/Report.pm (rev 0)
+++ addons/1.3/report_framework/trunk/LedgerSMB/Report.pm 2012-11-22 06:58:53 UTC (rev 5239)
@@ -0,0 +1,350 @@
+=head1 NAME
+
+LedgerSMB::Report - Base Reporting Functionality for LedgerSMB
+
+=head1 SYNPOSIS
+
+This Perl module provides base utility functions for reporting in LedgerSMB.
+This is intended to be an abstract class, never having direct instances, but
+instead inherited out to other modules.
+
+=head1 DESCRIPTION
+
+LedgerSMB::DBObject::Report provides basic utility functions for reporting in
+LedgerSMB. It is an abstract class. Individual report types MUST inherit this
+out.
+
+Subclasses MUST define the following subroutines:
+
+=over
+
+=item get_columns
+
+This MUST return a list of hashrefs for the columns per the dynatable block.
+
+=back
+
+Additionally, subclasses MAY define any of the following:
+
+=over
+
+=item template
+
+Returns the name of the template to be used. Otherwise a generic
+UI/reports/display_report template will be used.
+
+=back
+
+=cut
+
+package LedgerSMB::Report;
+use Moose;
+with 'LedgerSMB::DBObject_Moose', 'LedgerSMB::I18N';
+use LedgerSMB::Template;
+use LedgerSMB::App_State;
+
+=head1 PROPERTIES
+
+=over
+
+=item cols
+
+This is an array of hashrefs. Properties for each hashref:
+
+=over
+
+=item col_id
+
+ID of column, alphanumeric, used in names of elements, classes, etc. Required
+for smooth operation.
+
+=item name
+
+Localized name of column for labelling purposes
+
+=item type
+
+Display type of info. May be text, href, input_text, checkbox, or radio. For a
+report, it will typically be text or href.
+
+=item href_base
+
+Base for href. Only meaningful if type is href
+
+=item class
+
+CSS class (additional) for the column.
+
+=back
+
+=cut
+
+has 'cols' => (is => 'rw', isa => 'ArrayRef[HashRef[Any]]');
+
+=item rows
+
+This is an arrayref of rows. Each row has fields with keys equal to the col_id
+fields of the columns above.
+
+=cut
+
+has 'rows' => (is => 'rw', isa => 'ArrayRef[HashRef[Any]]');
+
+=item format
+
+This is the format, and must be one used by LedgerSMB::Template. Options
+expected for 1.4 out of the box include csv, pdf, ps, xls, and ods. Other
+formats could be supported in the future. If undefined, defaults html.
+
+=cut
+
+has 'format' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item order_by
+
+The column to order on. used in providing subtotals also.
+
+=cut
+
+has order_by => (is => 'rw', isa => 'Maybe[Str]');
+
+=item old_order_by
+
+Previous order by. Used internally to determine order direction.
+
+=cut
+
+has old_order_by => (is => 'rw', isa => 'Maybe[Str]');
+
+=item order_dir
+
+either asc, desc, or undef. used to determine next ordering.
+
+=cut
+
+has order_dir => (is => 'rw', isa => 'Maybe[Str]');
+
+=item order_url
+
+Url for order redirection. Interal only.
+
+=cut
+
+has order_url => (is => 'rw', isa => 'Maybe[Str]');
+
+=item show_subtotals
+
+bool, determines whether to show subtotals.
+
+=cut
+
+has show_subtotals => (is => 'rw', isa => 'Bool');
+
+=item buttons
+
+Buttons to show at the bottom of the screen
+
+=cut
+
+has buttons => (is => 'rw', isa => 'ArrayRef[Any]',
+ lazy => 1, builder => 'set_buttons');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item set_buttons
+
+This returns an empty arrayref here but can be overridden by individual
+reports.
+
+=cut
+
+sub set_buttons {
+ return [];
+}
+
+=item render
+
+This takes no arguments and simply renders the report as is.
+
+=cut
+
+sub render {
+ my ($self, $request) = @_;
+ my $template;
+
+ my $testref = $self->rows;
+ $self->run_report if !defined $testref;
+ # This is a hook for other modules to use to override the default
+ # template --CT
+ eval {$template = $self->template};
+ $template ||= 'Reports/display_report';
+
+ # Sorting and Subtotal logic
+ my $url = LedgerSMB::App_State::get_url();
+ if ($self->order_by eq $self->old_order_by){
+ if (lc($self->order_dir) eq 'asc'){
+ $self->order_dir('desc');
+ } else {
+ $self->order_dir('asc');
+ }
+ }
+ $url =~ s/&?order_by=[^\&]*/$1/g;
+ $url =~ s/&?order_dir=[^\&]*/$1/g;
+ $self->order_url(
+ "$url&old_order_by=".$self->order_by."&order_dir=".$self->order_dir
+ );
+
+ my $rows = $self->rows;
+ @$rows = sort {$a->{$self->order_by} cmp $b->{$self->order_by}} @$rows
+ if $self->order_by;
+ if (lc($self->order_dir) eq 'desc' and $self->order_by) {
+ @$rows = reverse @$rows;
+ }
+ $self->rows($rows);
+ if ($self->show_subtotals){
+ my @newrows;
+ my $subtotals = {html_class => 'subtotal'};
+ for my $col ({eval $self->subtotal_on}){
+ $subtotals->{$col} = 0;
+ }
+ my $col_val = undef;
+ for my $r (@{$self->rows}){
+ if (defined $col_val and ($col_val ne $r->{$self->order_by})){
+ push @newrows, $subtotals;
+ $subtotals = {html_class => 'subtotal'};
+ for my $col ({eval $self->subtotal_on}){
+ $subtotals->{$col} = 0;
+ }
+ }
+ for my $col ({eval $self->subtotal_on}){
+ $subtotals->{$col} += $r->{$col};
+ }
+ push @newrows, $r;
+ }
+ }
+
+ # Rendering
+
+ if (!defined $self->format){
+ $self->format('html');
+ }
+ $template = LedgerSMB::Template->new(
+ user => $LedgerSMB::App_State::User,
+ locale => $LedgerSMB::App_State::Locale,
+ path => 'UI',
+ template => $template,
+ format => uc($request->{format} || 'HTML'),
+ );
+ $template->render({report => $self,
+ request => $request,
+ name => $self->name,
+ hlines => $self->header_lines,
+ columns => $self->show_cols($request),
+ order_url => $self->order_url,
+ buttons => $self->buttons,
+ rows => $self->rows});
+}
+
+=item show_cols
+
+Returns a list of columns based on selected ones from the report
+
+=cut
+
+sub show_cols {
+ my ($self, $request) = @_;
+ my @retval;
+ for my $ref (@{$self->columns}){
+ if ($request->{"col_$ref->{col_id}"}){
+ push @retval, $ref;
+ }
+ if ($ref->{col_id} =~ /bc_\d+/){
+ push @retval, $ref if $request->{"col_business_units"};
+ }
+ }
+ if (scalar @retval == 0){
+ @retval = @{$self->columns};
+ }
+ return ..hidden..;
+}
+
+=over
+
+=item none
+
+No start date, end date as first of the month
+
+=item month
+
+Valid for the month selected
+
+=item quarter
+
+Valid for the month selected and the two proceeding ones.
+
+=item year
+
+Valid for a year starting with the month selected.
+
+=back
+
+=cut
+
+sub prepare_input {
+ my ($self, $request) = @_;
+ if ($request->{from_month} and $request->{year}){
+ my $interval = $self->get_interval_dates(
+ $request->{year},
+ $request->{from_month},
+ $request->{interval}
+ );
+ $request->{from_date} = $interval->{start};
+ $request->{to_date} = $interval->{end};
+ } else {
+ $request->{from_date} = LedgerSMB::PGDate->from_input(
+ $request->{from_date}
+ );
+ $request->{date_to} = LedgerSMB::PGDate->from_input(
+ $request->{date_to}
+ );
+ }
+ $request->{from_amount} = LedgerSMB::PGNumber->from_input(
+ $request->{from_amount}
+ );
+ $request->{to_amount} = LedgerSMB::PGNumber->from_input(
+ $request->{to_amount}
+ );
+}
+
+=item process_bclasses($ref)
+
+This function processes a ref for a hashref key of business_units, which holds
+an array of arrays of (class_id, bu_id) and adds keys in the form of
+bc_$class_id holding the $bu_id fields.
+
+=cut
+
+sub process_bclasses {
+ my ($self, $ref) = @_;
+ for my $bu (@{$ref->{business_units}}){
+ push @{$ref->{$bu->[0]}}, $bu->[1]
+ unless grep(/$bu->[1]/, @{$ref->{$bu->[0]}});
+ }
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team. This file may be re-used under the
+terms of the LedgerSMB General Public License version 2 or at your option any
+later version. Please see enclosed LICENSE file for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;
Added: addons/1.3/report_framework/trunk/patches/pnl_invoice.diff
===================================================================
--- addons/1.3/report_framework/trunk/patches/pnl_invoice.diff (rev 0)
+++ addons/1.3/report_framework/trunk/patches/pnl_invoice.diff 2012-11-22 06:58:53 UTC (rev 5239)
@@ -0,0 +1,36 @@
+Index: bin/aa.pl
+===================================================================
+--- bin/aa.pl (revision 5220)
++++ bin/aa.pl (working copy)
+@@ -1059,6 +1059,7 @@
+ }
+ if ($form->{id}){
+ print qq|
++<a href="pnl.pl?action=generate_income_statement&pnl_type=invoice&id=$form->{id}">[| . $locale->text('Profit/Loss') . qq|]</a><br />
+ <table width="100%">
+ <tr class="listtop">
+ <th colspan="4">| . $locale->text('Attached and Linked Files') . qq|</th>
+Index: bin/ir.pl
+===================================================================
+--- bin/ir.pl (revision 5220)
++++ bin/ir.pl (working copy)
+@@ -954,6 +954,7 @@
+ if ($form->{id}){
+ IR->get_files($form, $locale);
+ print qq|
++<a href="pnl.pl?action=generate_income_statement&pnl_type=invoice&id=$form->{id}">[| . $locale->text('Profit/Loss') . qq|]</a><br />
+ <table width="100%">
+ <tr class="listtop">
+ <th colspan="4">| . $locale->text('Attached and Linked Files') . qq|</th>
+Index: bin/is.pl
+===================================================================
+--- bin/is.pl (revision 5220)
++++ bin/is.pl (working copy)
+@@ -1040,6 +1040,7 @@
+ if ($form->{id}){
+ IS->get_files($form, $locale);
+ print qq|
++<a href="pnl.pl?action=generate_income_statement&pnl_type=invoice&id=$form->{id}">[| . $locale->text('Profit/Loss') . qq|]</a><br />
+ <table width="100%">
+ <tr class="listtop">
+ <th colspan="4">| . $locale->text('Attached and Linked Files') . qq|</th>
Added: addons/1.3/report_framework/trunk/patches/pnl_product.diff
===================================================================
--- addons/1.3/report_framework/trunk/patches/pnl_product.diff (rev 0)
+++ addons/1.3/report_framework/trunk/patches/pnl_product.diff 2012-11-22 06:58:53 UTC (rev 5239)
@@ -0,0 +1,38 @@
+Index: bin/ic.pl
+===================================================================
+--- bin/ic.pl (revision 5234)
++++ bin/ic.pl (working copy)
+@@ -955,8 +955,31 @@
+ qw(login path sessionid callback previousform isassemblyitem));
+
+ print qq|
+-</form>
+-| . $form->close_status_div . qq|
++</form> |;
++ if ($form->{id}){
++ print qq|<form action="pnl.pl" method="GET">
++ <input type="hidden" name="id" value="$form->{id}">
++ <input type="hidden" name="pnl_type" value="product">
++ <table width="100%">
++ <col width="20em"><col>
++ <tr class="listtop"><th colspan=2>| . $locale->text('Profit/Loss') . qq|
++ </th>
++ </tr>
++ <tr><th>| . $locale->text('Date From') . qq|</th>
++ <td><input type="text" size="12" name="date_from" class="date"></td>
++ </tr><tr>
++ <th>| . $locale->text('Date To') . qq|</th>
++ <td><input type="text" size="12" name="date_to" class="date"></td>
++ </tr><tr>
++ <td><button type="submit" name="action"
++ value="generate_income_statement"
++ class="submit">| . $locale->text('Continue') .
++ qq|</button><td>
++ </tr>
++ </table>
++ </form>|;
++ }
++ print $form->close_status_div . qq|
+ </body>
+ </html>
+ |;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.