[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SF.net SVN: ledger-smb:[5016] trunk/LedgerSMB



Revision: 5016
          http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=5016&view=rev
Author:   einhverfr
Date:     2012-07-19 12:37:47 +0000 (Thu, 19 Jul 2012)
Log Message:
-----------
Moving LedgerSMB::DBObject::Reports to LedgerSMB::Reports

Modified Paths:
--------------
    trunk/LedgerSMB/Scripts/budget_reports.pm
    trunk/LedgerSMB/Scripts/contact_reports.pm
    trunk/LedgerSMB/Scripts/drafts.pm
    trunk/LedgerSMB/Scripts/inv_reports.pm
    trunk/LedgerSMB/Scripts/journal.pm
    trunk/LedgerSMB/Scripts/lreports_co.pm
    trunk/LedgerSMB/Scripts/report_aging.pm
    trunk/LedgerSMB/Scripts/trial_balance.pm
    trunk/LedgerSMB/Scripts/vouchers.pm

Added Paths:
-----------
    trunk/LedgerSMB/Report/
    trunk/LedgerSMB/Report/Aging.pm
    trunk/LedgerSMB/Report/Budget/
    trunk/LedgerSMB/Report/Budget/Search.pm
    trunk/LedgerSMB/Report/Budget/Variance.pm
    trunk/LedgerSMB/Report/COA.pm
    trunk/LedgerSMB/Report/Contact/
    trunk/LedgerSMB/Report/Contact/History.pm
    trunk/LedgerSMB/Report/Contact/Purchase.pm
    trunk/LedgerSMB/Report/Contact/Search.pm
    trunk/LedgerSMB/Report/GL.pm
    trunk/LedgerSMB/Report/Inventory/
    trunk/LedgerSMB/Report/Inventory/Adj_Details.pm
    trunk/LedgerSMB/Report/Inventory/Search_Adj.pm
    trunk/LedgerSMB/Report/Margin/
    trunk/LedgerSMB/Report/Margin/ECA.pm
    trunk/LedgerSMB/Report/Margin/Invoice.pm
    trunk/LedgerSMB/Report/Trial_Balance.pm
    trunk/LedgerSMB/Report/Unapproved/
    trunk/LedgerSMB/Report/Unapproved/Batch_Detail.pm
    trunk/LedgerSMB/Report/Unapproved/Batch_Overview.pm
    trunk/LedgerSMB/Report/Unapproved/Drafts.pm
    trunk/LedgerSMB/Report/co/
    trunk/LedgerSMB/Report/co/Balance_y_Mayor.pm
    trunk/LedgerSMB/Report/co/Caja_Diaria.pm
    trunk/LedgerSMB/Report.pm

Removed Paths:
-------------
    trunk/LedgerSMB/DBObject/Report/
    trunk/LedgerSMB/DBObject/Report.pm

Deleted: trunk/LedgerSMB/DBObject/Report.pm
===================================================================
--- trunk/LedgerSMB/DBObject/Report.pm	2012-07-19 12:00:57 UTC (rev 5015)
+++ trunk/LedgerSMB/DBObject/Report.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -1,351 +0,0 @@
-=head1 NAME
-
-LedgerSMB::DBObject::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
-
-=head1 INHERITS
-
-=over
-
-=item LedgerSMB::DBObject_Moose
-
-=back
-
-=cut
-
-package LedgerSMB::DBObject::Report;
-use Moose;
-with 'LedgerSMB::DBObject_Moose';
-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]');
-
-=back
-
-=head1 METHODS
-
-=over
-
-=item render
-
-This takes no arguments and simply renders the report as is.
-
-=cut
-
-sub render {
-    my ($self, $request) = @_;
-    my $template;
-
-    # 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,
-                         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..;
-}
-
-=item prepare_input
-
-Handles from_date and to_date fields, as well as from_month, from_year, and 
-interval, setting from_date and to_date to LedgerSMB::PGDate types, and setting
-from_amount and to_amount to LedgerSMB::PGNumber types.
-
-Valid values for interval are:
-
-=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: trunk/LedgerSMB/Report/Aging.pm
===================================================================
--- trunk/LedgerSMB/Report/Aging.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Aging.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,274 @@
+=head1 NAME
+
+LedgerSMB::Report::Aging - AR/AP Aging reports for LedgerSMB
+
+=head1 SYNPOSIS
+
+  my $agereport = LedgerSMB::Report::Aging->new(%$request);
+  $agereport->run;
+  $agereport->render($request, $format);
+
+=head1 DESCRIPTION
+
+This module provides reports that show how far overdue payments for invoices
+are.  This can be useful to help better manage collection of moneys owed, etc.
+
+This module is also capable of printing statements, which are basically aging
+reportins aimed at the customer in question.
+
+=cut
+
+package LedgerSMB::Report::Aging;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::DBObject::Business_Unit_Class;
+use LedgerSMB::DBObject::Business_Unit;
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=item select
+
+=item credit_account
+
+=item language
+
+=item invnumber
+
+=item order
+
+=item transdate
+
+=item duedate
+
+=item c0
+
+=item c30
+
+=item c60
+
+=item c90
+
+=item total
+
+=item one for each business unit class returned
+
+=back
+
+=cut
+
+
+
+
+sub columns {
+    my ($self) = @_;
+    our @COLUMNS = ();
+    my $credit_label;
+    if ($self->entity_class == 1) {
+        $credit_label = $LedgerSMB::App_State::Locale->text('Vendor');
+    } elsif ($self->entity_class == 2){
+        $credit_label = $LedgerSMB::App_State::Locale->text('Customer');
+    }
+    push @COLUMNS,
+      {col_id => 'select',
+         type => 'checkbox'},
+
+      {col_id => 'name',
+         name => $credit_label,
+         type => 'text',
+       pwidth => 1, },
+
+      {col_id => 'language',
+         name => $locale->text('Language'),
+         type => 'select',
+       pwidth => '0', };
+
+   if ($self->report_type eq 'detail'){
+     push @COLUMNS,
+          {col_id => 'invnumber',
+             name => $locale->text('Invoice'),
+             type => 'href',
+        href_base => '',
+           pwidth => '3', },
+
+          {col_id => 'ordnumber',
+             name => $locale->text('Description'),
+             type => 'text',
+           pwidth => '6', },
+
+          {col_id => 'transdate',
+             name => $locale->text('Date'),
+             type => 'text',
+           pwidth => '1', },
+
+          {col_id => 'duedate',
+             name => $locale->text('Due Date'),
+             type => 'text',
+           pwidth => '2', };
+    }
+
+    push @COLUMNS,
+    {col_id => 'c0',
+       name => $locale->text('Current'),
+       type => 'text',
+     pwidth => '2', },
+
+    {col_id => 'c30',
+       name => $locale->text('30'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'c60',
+       name => $locale->text('60'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'c90',
+       name => $locale->text('90'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'total',
+       name => $locale->text('Total'),
+       type => 'text',
+     pwidth => '1', };
+    return ..hidden..;
+}
+
+    # TODO:  business_units int[]
+
+=item filter_template
+
+Returns the template name for the filter.
+
+=cut
+
+sub filter_template {
+    return 'journal/search';
+}
+
+=item name
+
+Returns the localized template name
+
+=cut
+
+sub name {
+    return $locale->text('Aging Report');
+}
+
+=item template
+
+Returns the name of the template to use
+
+=cut
+
+sub template {
+    my ($self) = @_;
+    if (!$self->format or (uc($self->format) eq 'HTML') 
+           or (uc($self->format) eq 'PDF'))
+    {
+           return 'Reports/aging_report';
+    }
+    else {
+       return undef;
+    }
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [];
+}
+
+=back
+
+=head2 Criteria Properties
+
+Note that in all cases, undef matches everything.
+
+=over
+
+=item report_type
+
+Is 'summary' or 'detail'
+
+=cut
+
+has 'report_type' => (is => 'rw', isa => 'Str');
+
+=item accno
+
+Exact match for the account number for the AR/AP account
+
+=cut
+
+has 'accno'  => (is => 'rw', isa => 'Maybe[Str]');
+
+
+=item to_date
+
+Calculate report as on a specific date
+
+=cut
+
+has 'date_ref' => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item entity_class
+
+1 for vendor, 2 for customer
+
+=cut
+
+has 'entity_class' => (is => 'rw', isa => 'Maybe[Int]');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report()
+
+Runs the report, and assigns rows to $self->rows.
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'report__invoice_aging_' .
+                                                $self->report_type});
+    for my $row(@rows){
+        $row->{row_id} = "$row->{account_number}:$row->{entity_id}";
+        $row->{total} = $row->{c0} + $row->{c30} + $row->{c60} + $row->{c90};
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/Budget/Search.pm
===================================================================
--- trunk/LedgerSMB/Report/Budget/Search.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Budget/Search.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,228 @@
+=head1 NAME
+
+LedgerSMB::Reports::Budget::Search - Search for Budgets
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::Budget::Search->new(%$request);
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This is a basic search report for budgets.
+
+=cut
+
+package LedgerSMB::Report::Budget::Search;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::App_State;
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read only accessor.  This provides the columns for the report
+
+=over 
+
+=item start_date
+
+Start date of the budget
+
+=item end_date
+
+End date of the budget
+
+=item reference
+
+Reference/control code of the budget
+
+=item description
+
+Budget description
+
+=item entered_by_name
+
+Who entered the budget
+
+=item approved_by_name
+
+Who approved the budget
+
+=item obsolete_by_name
+
+Who marked the budget obsolete
+
+=back
+
+=cut
+
+sub columns {
+   return [ {col_id => 'start_date',
+               type => 'href',
+          href_base => 'budget_reports.pl?action=variance_report&id=',
+               name => $locale->text('Start Date') },
+
+            {col_id => 'end_date', 
+               type => 'href',
+          href_base => 'budget_reports.pl?action=variance_report&id=',
+               name => $locale->text('End Date') },
+
+            {col_id => 'reference', 
+               type => 'href',
+          href_base => 'budgets.pl?action=view_budget&id=',
+               name => $locale->text('Reference') },
+
+            {col_id => 'description', 
+               type => 'href',
+          href_base => 'budgets.pl?action=view_budget&id=',
+               name => $locale->text('Description') },
+
+            {col_id => 'entered_by_name', 
+               type => 'text',
+               name => $locale->text('Entered By') },
+
+            {col_id => 'approved_by_name', 
+               type => 'text',
+               name => $locale->text('Approved By') },
+
+            {col_id => 'obsolete_by_name', 
+               type => 'text',
+               name => $locale->text('Obsolete By') },
+   ];
+}
+
+
+=item name
+
+Returns the localized name of the template
+
+=cut
+
+sub name {
+   return $locale->text('Budget Search Results');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [{name => 'date_from',
+             text => $locale->text('Start Date')},
+            {name => 'date_to',
+             text => $locale->text('End Date')},
+            {name => 'accno',
+             text => $locale->text('Account Number')},
+            {name => 'reference',
+             text => $locale->text('Reference')},
+            {name => 'source',
+             text => $locale->text('Source')}];
+}
+
+=back
+
+=head1 CRITERIA PROPERTIES
+
+=over
+
+=item reference
+
+Matches the beginning of the reference of the budget
+
+=cut
+
+has 'reference' => (is=> 'rw', isa => 'Maybe[Str]');
+
+=item description
+
+Matched using full text rules against the description
+
+=cut
+
+has 'description' => (is=> 'rw', isa => 'Maybe[Str]');
+
+=item start_date
+
+Exact match for the start date
+
+=cut
+
+has 'start_date' => (is=> 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item end_date
+
+Exact match for end date.
+
+=cut
+
+has 'end_date' => (is=> 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item buisness_units
+
+This returns all budgets matching all business units listed here.
+
+=cut
+
+has 'business_units' => (is=> 'rw', isa => 'Maybe[ArrayRef[Int]]');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item prepare_criteria
+
+Creates criteria from web input to types expected
+
+=cut
+
+sub prepare_criteria {
+    my ($self, $request) = @_;
+    my @business_units;
+    for my $count(1 .. $request->{bclass_count}){
+       push @business_units, $request->{"business_unit_$count"} 
+                 if defined $request->{"business_unit_$count"};
+    }
+    $request->{business_units} = ..hidden..;
+}
+
+=item run_report
+
+Runs the report
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'budget__search'});
+    for my $r(@rows){
+        $r->{row_id} = $r->{id};
+    }
+    $self->rows(..hidden..);
+}
+
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2011 LedgerSMB Core Team.  This file is licensed under the GNU 
+General Public License version 2, or at your option any later version.  Please
+see the included License.txt for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+
+return 1;

Added: trunk/LedgerSMB/Report/Budget/Variance.pm
===================================================================
--- trunk/LedgerSMB/Report/Budget/Variance.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Budget/Variance.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,212 @@
+=head1 NAME
+
+LedgerSMB::Report::Budget::Variance - Variance Report per Budget
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::Budget::Variance->new(%$request);
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This is a basic variance report for budgets.  A variance report shows budgetted
+debits and credits along with those actually accrued during the stated period.
+It thus provides a way of measuring both current and historical expenditures
+against what was budgetted.
+
+=cut
+
+package LedgerSMB::Report::Budget::Variance;
+use Moose;
+extends 'LedgerSMB::Report';
+use LedgerSMB::App_State;
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read only accessor.  This provides the columns for the report
+
+=over 
+
+=item budget_description
+
+Description of he budget line item
+
+=item accno
+
+Account number budgetted
+
+=item account_label
+
+Account name
+
+=item budget_amount
+
+Amount (normalized left or right) budgetted
+
+=item used_amount
+
+Amount (normalized left or right) used
+
+=item variance
+
+Difference between budgetted and used.
+
+=back
+
+=cut
+
+sub columns {
+   return [
+      {col_id => 'budget_description', 
+         type => 'text', 
+         name => $locale->text('Description')},
+
+      {col_id => 'accno', 
+         type => 'text', 
+         name => $locale->text('Account Number')},
+
+      {col_id => 'account_label', 
+         type => 'text', 
+         name => $locale->text('Account Label')},
+
+      {col_id => 'budget_amount', 
+         type => 'text', 
+         name => $locale->text('Amount Budgetted')},
+
+      {col_id => 'used_amount', 
+         type => 'text', 
+         name => '- ' . $locale->text('Used')},
+
+      {col_id => 'variance', 
+         type => 'text', 
+         name => '= ' . $locale->text('Variance')},
+   ];
+}
+
+=item name
+
+Returns name of report
+
+=cut
+
+sub name {
+    return $locale->text('Budget Variance Report');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [{name => 'reference',
+             text => $locale->text('Budget Number')},
+            {name => 'description',
+             text => $locale->text('Description')},
+            {name => 'start_date',
+             text => $locale->text('Start Date')},
+            {name => 'end_date',
+             text => $locale->text('End Date')},];
+}
+
+=back
+
+=head1 CRITERIA PROPERTIES
+
+=over
+
+=item id
+
+Budget id for variance report.  This is the only search criteria currently 
+supported.
+
+=cut
+
+has id => (is => 'ro', isa => 'Int');
+
+=back
+
+=head1 HEADER PROPERTIES
+
+These are used to generate the header as displayed and are typically pulled in 
+from a budget object.
+
+=over
+
+=item reference
+
+=cut
+
+has  reference => (is => 'ro', isa => 'Str');
+
+=item description
+
+=cut
+
+has description => (is => 'ro', isa => 'Str');
+
+=item start_date
+
+=cut
+
+has start_date => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item end_date
+
+=cut
+
+has end_date => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=back 
+
+=head1 METHODS
+
+=over
+
+=item for_budget_id
+
+Retrieves budget info and creates variance report object for it.
+
+=cut
+
+sub for_budget_id {
+    my ($self, $id) = @_;
+    use LedgerSMB::DBObject::Budget;
+
+    my $budget = LedgerSMB::DBObject::Budget->get($id);
+    my $report = $self->new(%$budget); 
+    return $report;
+}
+
+=item run_report
+
+Runs the report, setting rows for rendering.
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'budget__variance_report'});
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2012 LedgerSMB Core Team.  This file is licensed under the GNU 
+General Public License version 2, or at your option any later version.  Please
+see the included License.txt for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+
+1;

Added: trunk/LedgerSMB/Report/COA.pm
===================================================================
--- trunk/LedgerSMB/Report/COA.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/COA.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,220 @@
+=head1 NAME
+
+LedgerSMB::Report::COA - Chart of Accounts List for LedgerSMB
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::COA->new(%$request);
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This module provides a Chart of Account report for LedgerSMB.  This account is
+useful regarding checking on current balances and managing the accounts.
+Typically columns are displayed based on the permissions of the user.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::COA;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.  Unless otherwise noted, each
+column is intended to be visible to all who have permissions to run the report.
+
+=over
+
+=item accno
+
+Displays the account number.  
+
+=item description
+
+Account description.  
+
+=item gifi_accno
+
+This is the GIFI account number. 
+
+=item debit_balance
+
+This is the debit balance (or blank if none or balance is credit).
+
+=item credit_balance 
+
+This is the credit balance (or blank if none or balance is debit)
+
+=item link
+
+This lists the link descriptions.  Each represents a group of drop-downs the
+user has access to.  This should be visible only to admin users.
+
+=item edit
+
+Link to edit the account.  Should be visible only to admin users.
+
+=item delete
+
+Link to delete the account if it has no transactions.  Should be visible only to
+admin users.
+
+=back
+
+=cut
+
+our @COLUMNS = (
+    {col_id => 'accno',
+       name => $locale->text('Account Number'),
+       type => 'href',
+   href_base => '',
+     pwidth => '2', },
+
+    {col_id => 'description',
+       name => $locale->text('Description'),
+       type => 'href',
+  href_base => '',
+     pwidth => '6', },
+
+    {col_id => 'gifi_accno',
+       name => $locale->text('GIFI'),
+       type => 'text',
+     pwidth => '1', },
+
+    {col_id => 'debit_balance',
+       name => $locale->text('Debits'),
+       type => 'text',
+     pwidth => '2', },
+
+    {col_id => 'credit_balance',
+       name => $locale->text('Credits'),
+       type => 'text',
+     pwidth => '2', },
+
+    {col_id => 'link',
+       name => $locale->text('Dropdowns'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'edit',
+       name => $locale->text('Edit'),
+       type => 'href',
+  href_base => '',
+     pwidth => '3', },
+
+    {col_id => 'delete',
+       name => $locale->text('Delete'),
+       type => 'href',
+  href_base => '',
+     pwidth => '3', },
+
+);
+
+sub columns {
+    return ..hidden..;
+}
+
+=item name
+
+Returns the localized template name
+
+=cut
+
+sub name {
+    return $locale->text('Chart of Accounts');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [];
+}
+
+=item subtotal_cols
+
+Returns list of columns for subtotals
+
+=cut
+
+sub subtotal_cols {
+    return [];
+}
+
+=back
+
+=head2 Criteria Properties
+
+No criteria required.
+
+=head1 METHODS
+
+=over
+
+=item run_report()
+
+Runs the report, and assigns rows to $self->rows.
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'report__coa'});
+    for my $r(@rows){
+        my $ct; 
+        if ($r->{is_heading}){
+           $ct = 'H';
+        } else {
+           $ct = 'A';
+        }
+        $r->{edit} = '['.$locale->text('Edit').']';
+        $r->{delete} = '['.$locale->text('Delete').']' 
+                  if !$r->{rowcount} and !$r->{is_heading};
+        $r->{edit_href_suffix} = 'account.pl?action=edit&id='.$r->{id} . 
+           "&charttype=$ct";
+        $r->{delete_href_suffix} = 'journal.pl?action=delete_account&id='.$r->{id} .
+           "&charttype=$ct";
+        $r->{accno_href_suffix} = 
+                'reports.pl?action=start_report&module_name=gl&report_name=gl' .
+                "&accno=$r->{accno}--$r->{description}" 
+                     unless $r->{is_heading};
+        $r->{description_href_suffix} = $r->{accno_href_suffix};
+        $r->{html_class} = 'listheading' if $r->{is_heading};
+        $r->{link} =~ s/:/\n/g;
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/Contact/History.pm
===================================================================
--- trunk/LedgerSMB/Report/Contact/History.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Contact/History.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,349 @@
+=head1 NAME
+
+LedgerSMB::Report::Contact::History - Purchase history reports
+and more.
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::Contact::History->new(%$request);
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This report provides purchase history reports.  It can be used to search for 
+both customers and vendors.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::Contact::History;
+use Moose;
+extends 'LedgerSMB::Report';
+use LedgerSMB::App_State;
+use LedgerSMB::PGDate;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=back
+
+=cut
+
+sub columns {
+    my ($self) = @_;
+    my $script = 'contacts.pl';
+    return [
+         {col_id => 'name',
+            type => 'text',
+            name => $locale->text('Name') },
+
+         {col_id => 'meta_number',
+            type => 'text',
+            name => $locale->text('Account Number') },
+
+         {col_id => 'invnumber',
+            type => 'href',
+       href_base => 'is.pl?action=edit&id=',
+            name => $locale->text('Invoice Number') },
+
+         {col_id => 'curr',
+            type => 'text',
+            name => $locale->text('Currency') },
+
+         {col_id => 'partnumber',
+            type => 'text',
+            name => $locale->text('Part Number') },
+
+         {col_id => 'description',
+            type => 'text',
+            name => $locale->text('Description') },
+
+         {col_id => 'qty',
+            type => 'text',
+            name => $locale->text('Qty') },
+
+         {col_id => 'unit',
+            type => 'text',
+            name => $locale->text('Unit') },
+
+         {col_id => 'sellprice',
+            type => 'text',
+            name => $locale->text('Sell Price') },
+
+         {col_id => 'discount',
+            type => 'text',
+            name => $locale->text('Disc') },
+
+         {col_id => 'delivery_date',
+            type => 'text',
+            name => $locale->text('Delivery Date') },
+
+         {col_id => 'serialnumber',
+            type => 'text',
+            name => $locale->text('Serial Number') },
+
+         {col_id => 'exchangerate',
+            type => 'text',
+            name => $locale->text('Exchange Rate') },
+
+         {col_id => 'salesperson_name',
+            type => 'text',
+            name => $locale->text('Salesperson') },
+
+    ];
+}
+
+=item name
+
+=cut
+
+sub name { return $locale->text('Purchase History') }
+
+=item header_lines
+
+=cut
+
+sub header_lines {
+     return [
+            {name => 'name',
+             text => $locale->text('Name')},
+      
+            {name => 'meta_number',
+             text => $locale->text('Account Number')},
+            {name => 'from_date',
+             text => $locale->text('Start Date')},
+
+            {name => 'to_date',
+             text => $locale->text('End Date')},
+
+      
+      ];
+}
+
+=back
+
+=head1 CRITERIA PROPERTIES
+
+=over
+
+=item account_class
+
+The account/entity class of the contact.  Required and an exact match.
+
+=cut
+
+has entity_class => (is => 'ro', isa => 'Int');
+
+=item name
+
+This is the name of the customer or vendor.  It is an exact match.
+
+=cut
+
+has name => (is => 'ro', isa => 'Maybe[Str]');
+
+=item meta_number
+
+Partial match on account number
+
+=cut
+
+has meta_number => (is => 'ro', isa => 'Maybe[Str]');
+
+=item contact_info
+
+Phone, email, etc to select on.  Partial match
+
+=cut
+
+has contact_info => (is => 'ro', isa => 'Maybe[Str]');
+
+=item address_line
+
+Partial match on any address line
+
+=cut
+
+has address_line => (is => 'ro', isa => 'Maybe[Str]');
+
+=item city
+
+Partial match on city name
+
+=cut
+
+has city => (is => 'ro', isa => 'Maybe[Str]');
+
+=item state
+
+Partial match on name of state or probince 
+
+=cut
+
+has state => (is => 'ro', isa => 'Maybe[Str]');
+
+=item zip
+
+Partial match on zip/mail_code
+
+=cut
+
+has zip => (is => 'ro', isa => 'Maybe[Str]');
+
+=item salesperson
+
+Partial match on salesperson name
+
+=cut
+
+has salesperson => (is => 'ro', isa => 'Maybe[Str]');
+
+=item notes
+
+Full text search on notes
+
+=cut
+
+has notes => (is => 'ro', isa => 'Maybe[Str]');
+
+=item country_id
+
+country id of customer
+
+=cut
+
+has country_id => (is => 'ro', isa => 'Maybe[Int]');
+
+=item from_date
+
+Include only invoices starting on this date
+
+=cut
+
+has from_date => (is => 'ro', coerce => 1, isa => 'LedgerSMB::DBObject::Date');
+
+=item to_date
+
+Include only invoices before this date
+
+=cut
+
+has to_date => (is => 'ro', coerce => 1, isa => 'LedgerSMB::DBObject::Date');
+
+=item type
+
+This is the type of document to be returned:
+
+=over
+
+=item i
+
+Invoices
+
+=item o
+
+Orders
+
+=item q
+
+Quotations
+
+=back
+
+=cut
+
+has type => (is => 'ro', isa =>'Str');
+
+=item start_from
+
+Include only customers active starting this date.
+
+=cut
+
+has start_from => (is => 'ro', coerce => 1, isa => 'LedgerSMB::DBObject::Date');
+
+=item start_to
+
+Include only customers becoming active no later than this date
+
+=cut
+
+has start_to => (is => 'ro', coerce => 1, isa => 'LedgerSMB::DBObject::Date');
+
+=item inc_open
+
+Include open invoices/orders/etc.
+
+=cut
+
+has inc_open => (is => 'ro', isa => 'Bool');
+
+=item inc_closed
+
+Include closed invoices/orders/etc.
+
+=cut
+
+has inc_closed => (is => 'ro', isa => 'Bool');
+
+
+=item is_summary
+
+If this is true it is a summary report.  Otherwise full details shown.
+
+=cut
+
+has is_summary => (is => 'ro', isa => 'Bool');
+
+=back
+
+=head1 METHODS
+
+=over 
+
+=item run_report
+
+Runs the report, populates rows.
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my $proc = 'eca__history';
+    $proc .= '_summary' if $self->is_summary; 
+    my @rows = $self->exec_method({funcname => $proc});
+    for my $r(@rows){
+        $r->{invnumber_href_suffix} = $r->{invoice_id};
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/Contact/Purchase.pm
===================================================================
--- trunk/LedgerSMB/Report/Contact/Purchase.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Contact/Purchase.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,329 @@
+=head1 NAME
+
+LedgerSMB::Report::Contact::Purchase - Search AR/AP Transactions and
+generate Reports
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::Contact::Purchase->new(%$request);
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This report provides the capacity to generate reports equivalent to the AR and
+AP transaction and outstanding reports in 1.3 and earlier.  General uses include
+reviewing outstanding transactions, transactions that were outstanding at a
+certain point, and locating specific transactions.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::Contact::Purchase;
+use Moose;
+extends 'LedgerSMB::Report';
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=back
+
+=cut
+
+sub columns {
+    return [
+         {col_id => 'running_number',
+            type => 'text',
+            name => '' },
+
+         {col_id => 'id',
+            type => 'text',
+            name => $locale->text('ID') },
+         {col_id => 'entity_name',
+            type => 'text',
+            name => $locale->text('Name') },
+
+         {col_id => 'invnumber',
+            type => 'href',
+       href_base => '',
+            name => $locale->text('Invoice Number') },
+
+         {col_id => 'ordnumber',
+            type => 'text',
+            name => $locale->text('Order Number') },
+
+         {col_id => 'ponumber',
+            type => 'text',
+            name => $locale->text('PO Number') },
+
+         {col_id => 'curr',
+            type => 'text',
+            name => $locale->text('Currency') },
+        
+         {col_id => 'amount',
+            type => 'text',
+            name => $locale->text('Amount') },
+
+         {col_id => 'tax',
+            type => 'text',
+            name => $locale->text('Tax') },
+
+         {col_id => 'paid',
+            type => 'text',
+            name => $locale->text('Paid') },
+
+         {col_id => 'due',
+            type => 'text',
+            name => $locale->text('Due') },
+
+         {col_id => 'date_paid',
+            type => 'text',
+            name => $locale->text('Date Paid') },
+
+         {col_id => 'due_date',
+            type => 'text',
+            name => $locale->text('Due Date') },
+
+         {col_id => 'notes',
+            type => 'text',
+            name => $locale->text('Notes') },
+
+         {col_id => 'shipping_point',
+            type => 'text',
+            name => $locale->text('Shipping Point') },
+
+         {col_id => 'ship_via',
+            type => 'text',
+            name => $locale->text('Ship Via') },
+    ];
+}
+
+=item name
+
+=cut
+
+sub name { 
+   my ($self) = @_;
+   if ($self->entity_class == 1){
+       return $locale->text('AP Transactions'); 
+   } elsif ($self->entity_class == 2){
+       return $locale->text('AR Transactions');
+   }
+}
+
+=item header_lines
+
+=cut
+
+sub header_lines {
+     return [
+            {name => 'name_part',
+             text => $locale->text('Name')},
+            {name => 'meta_number',
+             text => $locale->text('Account Number')}
+       ]; 
+}
+
+=back
+
+=head1 CRITERIA PROPERTIES
+
+=over
+
+=item entity_class
+
+Must be 1 for vendor or 2 for customer.  No other values will return any values.
+
+=cut
+
+has entity_class => (is => 'ro', isa => 'Int');
+
+=item accno
+
+Account Number for search.  If set can be either in the form of the actual 
+account number itself or in the form of accno--description (returned by the
+current ajaxselect implementation).
+
+=cut
+
+has accno => (is => 'rw', isa => 'Maybe[Str]');
+
+=item name_part
+
+Full text search on contact name.
+
+=cut
+
+has name_part => (is => 'ro', isa => 'Maybe[Str]');
+
+=item meta_number
+
+Matches the beginning of the meta_number for the entity credit account.
+
+=cut
+
+has meta_number => (is => 'ro', isa => 'Maybe[Str]');
+
+=item invnumber
+
+Invoice number.  Matches the beginning of the string.
+
+=cut
+
+has invnumber => (is => 'ro', isa => 'Maybe[Str]');
+
+=item ordnumber
+
+Order number.  Matches the beginning of the string.
+
+=cut
+
+has ordnumber => (is => 'ro', isa => 'Maybe[Str]');
+
+=item ponumber
+
+Purchas order number.  Matches the beginning of the string.
+
+=cut
+
+has ponumber => (is => 'ro', isa => 'Maybe[Str]');
+
+=item source
+
+Matches any source field in line item details.  This can be used to see which
+invoices were paid by a specific payment.
+
+=cut
+
+has source => (is => 'ro', isa => 'Maybe[Str]');
+
+=item description
+
+Full text search on transaction description
+
+=cut
+
+has description => (is => 'ro', isa => 'Maybe[Str]');
+
+=item notes
+
+Full text search on notes of invoice
+
+=cut
+
+has notes => (is => 'ro', isa => 'Maybe[Str]');
+
+=item ship_via
+
+Full text search on ship_via field.
+
+=cut
+
+has ship_via => (is => 'ro', isa => 'Maybe[Str]');
+
+=item from_date
+
+Invoices posted starting on this date
+
+=cut
+
+has from_date => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item to_date
+
+Invoices posted no later than this date
+
+=cut
+
+has to_date => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item as_of
+
+Shows invoice balances as of this date.
+
+=cut
+
+has as_of => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item summarize
+
+Tells whether to summarize the report (i.e. produce a summary report rather than
+a detail report).
+
+=cut
+
+has summarize => (is => 'ro', isa => 'Bool');
+
+=back
+
+=head1 METHODS
+
+=over 
+
+=item run_report
+
+Runs the report, populates rows.
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my @rows;
+    if ($self->summarize){
+       @rows = $self->exec_method({
+               funcname => 'ar_ap__transaction_search_summary'}
+       );
+    } else {
+       @rows = $self->exec_method({funcname => 'ar_ap__transaction_search'});
+       my $rn = 0;
+       for my $r (@rows){
+            $r->{running_number} = ++$rn;
+            my $href;
+            if ($r->{invoice}){
+                if ($self->entity_class == 1) {
+                    $href = 'ir.pl';
+                } else {
+                    $href = 'is.pl';
+                }
+            } else {
+                if ($self->entity_class == 1) {
+                    $href = 'ap.pl';
+                } else {
+                    $href = 'ar.pl';
+                }
+            } 
+            $r->{invnumber_href_suffix} = "$href?action=edit&id=$r->{id}";
+       }
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/Contact/Search.pm
===================================================================
--- trunk/LedgerSMB/Report/Contact/Search.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Contact/Search.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,268 @@
+=head1 NAME
+
+LedgerSMB::Report::Contact::Search - Search for Customers, Vendors,
+and more.
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::GL->new(%$request);
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This report provides contact search facilities.  It can be used to search for
+any sort of company or person, whether sales lead, vendor, customer, or
+referral.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::Contact::Search;
+use Moose;
+extends 'LedgerSMB::Report';
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=back
+
+=cut
+
+sub columns {
+    my ($self) = @_;
+    my $script = 'contacts.pl';
+
+    return [
+       {col_id => 'name',
+            type => 'text',
+            name => $locale->text('Name') },
+
+       {col_id => 'entity_control_code',
+            type => 'href',
+       href_base =>($self->entity_class == 3)
+                    ? "employee.pl?action=get"
+                    :"contact.pl?action=get&entity_class=".$self->entity_class,
+            name => $locale->text('Control Code') },
+
+       {col_id => 'meta_number',
+            type => 'href',
+       href_base => ($self->entity_class == 3) 
+                    ? "employee.pl?action=get"
+                    : "contact.pl?action=get&entity_class=".$self->entity_class,
+            name => $locale->text('Credit Account Number') },
+
+       {col_id => 'credit_description',
+            type => 'text',
+            name => $locale->text('Description') },
+
+       {col_id => 'business_type',
+            type => 'text',
+            name => $locale->text('Business Type') },
+
+       {col_id => 'curr',
+            type => 'text',
+            name => $locale->text('Currency') },
+    ];
+}
+
+=item name
+
+=cut
+
+sub name { return $locale->text('Contact Search') }
+
+=item header_lines
+
+=cut
+
+sub header_lines {
+     return [
+            {name => 'name_part',
+             text => $locale->text('Name')},
+            {name => 'meta_number',
+             text => $locale->text('Account Number')}
+       ]; 
+}
+
+=back
+
+=head1 CRITERIA PROPERTIES
+
+=over
+
+=item entity_class
+
+The account/entity class of the contact.  Required and an exact match.
+
+=cut
+
+has entity_class => (is => 'ro', isa => 'Int', required => 1);
+
+=item name_part
+
+Full text search on contact name.
+
+=cut
+
+has name_part => (is => 'ro', isa => 'Str', required => 0);
+
+=item control_code
+
+Matches the beginning of the control code string
+
+=cut
+
+has control_code => (is => 'ro', isa => 'Str', required => 0);
+
+=item contact_info 
+
+Aggregated from email, phone, fax, etc.  Aggregated by this report (internal).
+
+=cut
+
+has contact_info => (is => 'ro', isa => 'ArrayRef[Str]]', required => 0);
+
+=item email
+
+Email address, exact match on any email address.
+
+=cut
+
+has email => (is => 'ro', isa => 'Str', required => 0);
+
+=item phone
+
+Exact match on phone any phone number, fax, etc.
+
+=cut
+
+has phone => (is => 'ro', isa => 'Str', required => 0);
+
+=item meta_number
+
+Matches beginning of customer/vendor/etc. number.
+
+=cut
+
+has meta_number => (is => 'ro', isa => 'Str', required => 0);
+
+=item notes
+
+Full text search of all entity/eca notes
+
+=cut
+
+has notes => (is => 'ro', isa => 'Str', required => 0);
+
+=item address
+
+Full text search (fully matching) on any address line.
+
+=cut
+
+has address => (is => 'ro', isa => 'Str', required => 0);
+
+=item city
+
+Exact match on city
+
+=cut
+
+has city => (is => 'ro', isa => 'Str', required => 0);
+
+=item state
+
+Exact match on state/province
+
+=cut
+
+has state => (is => 'ro', isa => 'Str', required => 0);
+
+=item mail_code
+
+Match on beginning of mail or post code
+
+=cut
+
+has mail_code => (is => 'ro', isa => 'Str', required => 0);
+
+=item country
+
+Full or short name of country (i.e. US or United States, or CA or Canada).
+
+=cut
+
+has country => (is => 'ro', isa => 'Str', required => 0); 
+
+=item active_date_from
+
+Active items only from this date.
+
+=item active_date_to
+
+Active items only to this date.
+
+=cut
+
+has active_date_from => (is => 'ro', 
+                        isa => 'LedgerSMB::Moose::Date', 
+                     coerce => 1,
+                   required => 0);
+has active_date_to => (is => 'ro', 
+                      isa => 'LedgerSMB::Moose::Date', 
+                   coerce => 1,
+                 required => 0);
+
+=back
+
+=head1 METHODS
+
+=over 
+
+=item run_report
+
+Runs the report, populates rows.
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'contact__search'});
+    for my $r(@rows){
+        $r->{meta_number_href_suffix} = 
+               "&entity_id=$r->{entity_id}&meta_number=$r->{meta_number}";
+        $r->{entity_control_code_href_suffix} = $r->{meta_number_href_suffix};
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/GL.pm
===================================================================
--- trunk/LedgerSMB/Report/GL.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/GL.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,393 @@
+=head1 NAME
+
+LedgerSMB::Report::GL - GL Reports for LedgerSMB
+
+=head1 SYNPOSIS
+
+  my $glreport = LedgerSMB::Report::GL->new(%$request);
+  $glreport->run;
+  $glreport->render($request, $format);
+
+=head1 DESCRIPTION
+
+This module provides GL reports for LedgerSMB.  GL reports are useful for 
+searching for and reporting financial transactions.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::GL;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::DBObject::Business_Unit_Class;
+use LedgerSMB::DBObject::Business_Unit;
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=item id
+
+=item reference
+
+=item description
+
+=item transdate
+
+=item source
+
+=item memo
+
+=item debits
+
+=item credits
+
+=item entry_id
+
+=item cleared
+
+=item chart_id
+
+=item accno
+
+=item gifi_accno
+
+=item running_balance
+
+=item one for each business unit class returned
+
+=back
+
+=cut
+
+our @COLUMNS = (
+    {col_id => 'id',
+       name => $locale->text('ID'),
+       type => 'text',
+     pwidth => 1, },
+
+    {col_id => 'transdate',
+       name => $locale->text('Date'),
+       type => 'text',
+     pwidth => '4', },
+
+    {col_id => 'reference',
+       name => $locale->text('Reference'),
+       type => 'href',
+  href_base => '',
+     pwidth => '3', },
+
+    {col_id => 'description',
+       name => $locale->text('Description'),
+       type => 'text',
+     pwidth => '6', },
+
+    {col_id => 'entry_id',
+       name => $locale->text('Entry ID'),
+       type => 'text',
+     pwidth => '1', },
+
+    {col_id => 'debits',
+       name => $locale->text('Debits'),
+       type => 'text',
+     pwidth => '2', },
+
+    {col_id => 'credits',
+       name => $locale->text('Credits'),
+       type => 'text',
+     pwidth => '2', },
+
+    {col_id => 'source',
+       name => $locale->text('Source'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'memo',
+       name => $locale->text('Memo'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'cleared',
+       name => $locale->text('Cleared'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'till',
+       name => $locale->text('Till'),
+       type => 'text',
+     pwidth => '1', },
+
+    {col_id => 'chart_id',
+       name => $locale->text('Chart ID'),
+       type => 'text',
+     pwidth => '1', },
+
+    {col_id => 'accno',
+       name => $locale->text('Account No.'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'accname',
+       name => $locale->text('Account Name'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'gifi_accno',
+       name => $locale->text('GIFI'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'running_balance',
+       name => $locale->text('Balance'),
+       type => 'text',
+     pwidth => '3', },
+);
+
+sub columns {
+    my @bclasses = LedgerSMB::DBObject::Business_Unit_Class->list('1', 'gl');
+    my @COLS = @COLUMNS;
+    for my $class (@bclasses){
+        push @COLS, {col_id =>  "bc_" . $class->id,
+                       name => $locale->text($class->label),
+                       type => 'text',
+                     pwidth => '2'};
+    }
+    return ..hidden..;
+}
+
+=item filter_template
+
+Returns the template name for the filter.
+
+=cut
+
+sub filter_template {
+    return 'journal/search';
+}
+
+=item name
+
+Returns the localized template name
+
+=cut
+
+sub name {
+    return $locale->text('General Ledger Report');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [{name => 'from_date',
+             text => $locale->text('Start Date')},
+            {name => 'to_date',
+             text => $locale->text('End Date')},
+            {name => 'accno',
+             text => $locale->text('Account Number')},
+            {name => 'reference',
+             text => $locale->text('Reference')},
+            {name => 'source',
+             text => $locale->text('Source')}];
+}
+
+=item subtotal_cols
+
+Returns list of columns for subtotals
+
+=cut
+
+sub subtotal_cols {
+    return ['debits', 'credits'];
+}
+
+=back
+
+=head2 Criteria Properties
+
+Note that in all cases, undef matches everything.
+
+=over
+
+=item reference (text)
+
+Exact match on reference or invoice number.
+
+=cut
+
+has 'reference' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item accno
+
+Exact match for the account number
+
+=cut
+
+has 'accno'  => (is => 'rw', isa => 'Maybe[Str]');
+
+
+=item category
+
+Is one of A (Asset), L (Liability), Q (Equity), I (Income), or E (Expense).
+
+When set only matches lines attached to transactions of specfied type.
+
+=cut
+
+has 'category' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item source
+
+Exact match of source field
+
+=cut
+
+has 'source' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item memo
+
+Full text search of memo field
+
+=cut
+
+has 'memo' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item description
+
+Full text search of description field of GL transaction
+
+=cut
+
+has 'description' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item from_date
+
+Earliest date which matches the search
+
+=cut
+
+has 'from_date' => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item to_date
+
+Last date that matches the search
+
+=cut
+
+has 'to_date' => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item approved
+
+Unless false, only matches approved transactions.  When false, matches all 
+transactions.  This is the one exception to the general rule that undef matches
+all.
+
+=cut
+
+has 'approved' => (is => 'rw', isa => 'Maybe[Bool]');
+
+=item amount_from
+
+The lowest value that can match, amount-wise.
+
+=item amount_to
+
+The highest value that can match, amount-wise.
+
+=cut
+
+has 'amount_from' => (is => 'rw', coerce => 1, 
+                     isa => 'LedgerSMB::Moose::Number');
+has 'amount_to' => (is => 'rw', coerce => 1, 
+                   isa => 'LedgerSMB::Moose::Number');
+
+=item business_units
+
+Array of business unit id's
+
+=cut
+
+has 'business_units' => (is => 'rw', isa => 'Maybe[ArrayRef[Int]]');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report()
+
+Runs the report, and assigns rows to $self->rows.
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'report__gl'});
+    for my $ref(@rows){
+        if ($ref->{amount} < 0){
+            $ref->{debits} = $ref->{amount} * -1;
+            $ref->{credits} = 0;
+        } else {
+            $ref->{credits} = $ref->{amount};
+            $ref->{debits} = 0;
+        }
+        if ($ref->{type} eq 'gl'){
+           $ref->{reference_href_suffix} = "gl.pl?action=edit&id=$ref->{id}";
+        } elsif ($ref->{type} eq 'ar'){
+           if ($ref->{invoice}){
+                $ref->{reference_href_suffix} = 'is.pl';
+           } else {
+                $ref->{reference_href_suffix} = 'ar.pl';
+           }
+           $ref->{reference_href_suffix} .= "?action=edit&id=$ref->{id}";
+        } elsif ($ref->{type} eq 'ap'){
+           if ($ref->{invoice}){
+                $ref->{reference_href_suffix} = 'ir.pl';
+           } else {
+                $ref->{reference_href_suffix} = 'ap.pl';
+           }
+           $ref->{reference_href_suffix} .= "?action=edit&id=$ref->{id}";
+        }
+        if ($ref->{cleared}){
+            $ref->{cleared} = 'X';
+        } else {
+            $ref->{cleared} = '';
+        }
+        $self->process_bclasses($ref);
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/Inventory/Adj_Details.pm
===================================================================
--- trunk/LedgerSMB/Report/Inventory/Adj_Details.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Inventory/Adj_Details.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,137 @@
+=head1 NAME
+
+LedgerSMB::Report::Inventory::Adj_Details - Inventory Adjustment
+Details report for LedgerSMB
+
+=head1 SYNPOSIS
+
+ my $rpt = LedgerSMB::Report::Inventory::Adj_Details->new(%$request);
+ $rpt->run_report;
+ $rpt->render($request);
+
+=cut
+
+package LedgerSMB::Report::Inventory::Adj_Details;
+use Moose;
+use LedgerSMB::App_State;
+use LedgerSMB::Report::Inventory::Search_Adj;
+extends 'LedgerSMB::Report';
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 DESCRIPTION
+
+This report shows the details of an inventory adjustment report.
+
+=head1 CRITERIA PROPERTIES
+
+=over
+
+=item id
+
+This is the report id.
+
+=cut
+
+has id => (is => 'ro', isa => 'Int', required => 1);
+
+=back
+
+=head1 PROPERTIES FOR HEADER
+
+=over
+
+=item source 
+
+Matches the beginning of the source string on the report source string
+
+=cut
+
+has source => (is => 'ro', isa => 'Maybe[Str]');
+
+=back
+
+=head1 REPORT CONSTANT FUNCTIONS
+
+=over
+
+=item name
+
+=cut
+
+sub name { return $locale->text('Inventory Adjustment Details') }
+
+=item header_lines
+
+=cut
+
+sub header_lines {
+    return [{name => 'source', text => $locale->text('Source') }];
+}
+
+=item columns
+
+=cut
+
+sub columns {
+    return [
+      {col_id => 'partnumber',
+         type => 'href',
+    href_base => 'ic.pl?action=edit&id='.
+         name => $locale->text('Part Number') },
+      {col_id => 'description',
+         type => 'text',
+         name => $locale->text('Description') },
+      {col_id => 'counted',
+         type => 'text',
+         name => $locale->text('Counted') },
+      {col_id => 'expected',
+         type => 'text',
+         name => $locale->text('Expected') },
+      {col_id => 'variance',
+         type => 'text',
+         name => $locale->text('Variance') },
+    ];
+}
+
+=head1 METHODS
+
+=over
+
+=item run_report
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my ($rpt) = $self->exec_method({funcname => 'inventory_adj__get'});
+    $self->source($rpt->source);
+    my @rows = $self->exec_method({funcname => 'inventory_adj__details'});
+    for my $row (@rows){
+        $row->{row_id} = $row->{parts_id}; 
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 SEE ALSO
+
+=over
+
+=item LedgerSMB::Report;
+
+=item LedgerSMB::Report::Inventory::Search_Adj;
+
+=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;
+1;

Added: trunk/LedgerSMB/Report/Inventory/Search_Adj.pm
===================================================================
--- trunk/LedgerSMB/Report/Inventory/Search_Adj.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Inventory/Search_Adj.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,151 @@
+=head1 NAME
+
+LedgerSMB::Report::Inventory::Search_Adj - LedgerSMB report of 
+inventory adjustments
+
+=head1 SYNPOSIS
+
+ my $rpt = LedgerSMB::Report::Inventory::Search_Adj->new(%$request);
+ $rpt->run_report;
+ $rpt->render($request);
+
+=cut
+
+package LedgerSMB::Report::Inventory::Search_Adj;
+use Moose;
+extends 'LedgerSMB::Report';
+use LedgerSMB::App_State;
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 DESCRIPTION
+
+This is the report that searches for and displays inventory adjustments based
+on set criteria.
+
+=head1 CRITERIA PROPERTIES
+
+=over
+
+=item from_date 
+
+Standard start date
+
+=item to_date
+
+Standard to date
+
+=cut
+
+has 'from_date' => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+has 'to_date' => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item partnumber 
+
+Part number.  This is a full text search, in order to allow for space-separated
+alternatives
+
+=cut
+
+has partnumber => (is => 'ro', isa => 'Maybe[Str]');
+
+=item source 
+
+Matches the beginning of the source string on the report source string
+
+=cut
+
+has source => (is => 'ro', isa => 'Maybe[Str]');
+
+=back
+
+=head1 REPORT-RELATED CONSTANT FUNCTIONS
+
+=over
+
+=item name
+
+=cut
+
+sub name { return $locale->text('Inventory Adjustments') };
+
+=item header_lines
+
+=cut
+
+sub header_lines {
+    return [{name => 'from_date',
+             text => $locale->text('Start Date') },
+            {name => 'to_date',
+             text => $locale->text('End Date') },
+            {name => 'partnumber',
+             text => $locale->text('Including partnumber') },
+            {name => 'source',
+             text => $locale->text('Source starting with') },
+           ];
+}
+
+=item columns
+
+=cut
+
+sub columns {
+    return [{col_id => 'transdate',
+               type => 'href',
+          href_base => 'inv_reports.pl?action=adj_detail&id=',
+               name => $locale->text('Date')},
+            {col_id => 'source',
+               type => 'href',
+          href_base => 'inv_reports.pl?action=adj_detail&id=',
+               name => $locale->text('Reference')},
+            {col_id => 'ar_invnumber',
+               type => 'href',
+               name => $locale->text('AR Invoice'),
+          href_base => 'is.pl?action=edit&id='},
+            {col_id => 'ap_invnumber',
+               type => 'href',
+               name => $locale->text('AP Invoice'),
+          href_base => 'ir.pl?action=edit&id='},
+      ];
+}
+
+=head1 METHODS
+
+=over
+
+=item run_report
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'inventory_adj__search'});
+    for my $row (@rows) {
+        $row->{ar_invnumber_suffix} = $row->{ar_invoice_id};
+        $row->{ap_invnumber_suffix} = $row->{ap_invoice_id};
+        $row->{row_id} = $row->{id};
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 SEE ALSO
+
+=over
+
+=item LedgerSMB::Report;
+
+=item LedgerSMB::Report::Inventory::Adj_Details;
+
+=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;
+1;

Added: trunk/LedgerSMB/Report/Margin/ECA.pm
===================================================================
--- trunk/LedgerSMB/Report/Margin/ECA.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Margin/ECA.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,136 @@
+=head1 NAME
+
+LedgerSMB::Report::Margin::ECA - Report for profit vs COGS per ECA
+
+=head1 SYNOPSIS
+
+ my $report = LedgerSMB::Report::Margin::ECA->new(%$request);
+ $report->run_report;
+ $report->render($request);
+
+=cut
+
+package LedgerSMB::Report::Margin::ECA;
+use Moose;
+use LedgerSMB::App_State;
+extends 'LedgerSMB::Report';
+
+my $locale = LedgerSMB::App_State::Locale;
+
+=head1 DESCRIPTION
+
+This report provides a comparison of income vs direct expenses (COGS) for a
+given entity credit account (usually a customer).  Note that at present, unlike
+the income statement, this does not support clicking through to view
+transaction history.
+
+=head1 CRITERIA PROPERTIES
+
+=over 
+
+=item id
+
+The id of the customer
+
+=cut
+
+has id => (is => 'ro', isa => 'Maybe[Int]');
+
+=item meta_number
+
+The customer number
+
+=cut
+
+has meta_number => (is => 'ro', isa => 'Maybe[Str]');
+
+=item from_date
+
+standard start date attribute
+
+=item to_date
+
+Standard end date attribute
+
+=cut
+
+has 'from_date' => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+has 'to_date' => (is => 'ro', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=back
+
+=head1 REPORT CONSTANT FUNCTIONS
+
+=over
+
+=item name
+
+=cut
+
+sub name { return $locale->text('Margin Report for Customer'); }
+
+=item columns
+
+=cut 
+
+# We don't need to return anything here because we have our own template.
+
+sub columns {  return [] }
+
+=item header_lines
+
+=cut
+
+sub header_lines {
+    return [{ name => 'meta_number', 
+              text => $locale->text('Customer Number')}
+          ];
+}
+
+=item template
+
+=cut
+
+sub template { return 'Reports/PNL' };
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report
+
+Runs the report.  Takes either id or meta_number, but not both.  Dates are
+recognized
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my @rows = $self->exec_method->({funcname => 'pnl__customer' });
+    $self->rows(..hidden..);
+    return;
+}
+
+=back
+
+=head1 SEE ALSO
+
+=over
+
+=item LedgerSMB::Report
+
+=item LedgerSMB::Report::Margin::Invoice
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+1;

Added: trunk/LedgerSMB/Report/Margin/Invoice.pm
===================================================================
--- trunk/LedgerSMB/Report/Margin/Invoice.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Margin/Invoice.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,122 @@
+=head1 NAME
+
+LedgerSMB::Report::Margin::Invoice - Report for profit vs COGS per 
+Invoice
+
+=head1 SYNOPSIS
+
+ my $report = LedgerSMB::Report::Margin::ECA->new(%$request);
+ $report->run_report;
+ $report->render($request);
+
+=cut
+
+package LedgerSMB::Report::Margin::Invoice;
+use Moose;
+use LedgerSMB::App_State;
+extends 'LedgerSMB::Report';
+
+my $locale = LedgerSMB::App_State::Locale;
+
+=head1 DESCRIPTION
+
+This report provides a comparison of income vs direct expenses (COGS) for a
+given invoice.
+
+=head1 CRITERIA PROPERTIES
+
+=over 
+
+=item id
+
+The id of the invoice
+
+=cut
+
+has id => (is => 'ro', isa => 'Maybe[Int]');
+
+=item invnumber
+
+The invoice  number
+
+=cut
+
+has invnumber => (is => 'ro', isa => 'Maybe[Str]');
+
+=back
+
+=head1 REPORT CONSTANT FUNCTIONS
+
+=over
+
+=item name
+
+=cut
+
+sub name { return $locale->text('Margin Report for Invoice') };
+
+=item columns
+
+=cut
+
+# No need to return anything due to custom template
+
+sub columns { return [] }
+
+=item header_lines
+
+=cut
+
+sub header_lines {
+    return [{ name => 'invnumber',
+              text => $locale->text('Invoice Number')}
+          ];
+}
+
+
+=item template
+
+=cut
+
+sub template { return 'Reports/PNL' }
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report
+
+Runs the report.  Takes either id or invnumber, but not both.
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my @rows = $self->exec_method->({funcname => 'pnl__invoice' });
+    $self->rows(..hidden..);
+    return;
+}
+
+=back
+
+=head1 SEE ALSO
+
+=over
+
+=item LedgerSMB::Report
+
+=item LedgerSMB::Report::Margin::ECA
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+1;

Added: trunk/LedgerSMB/Report/Trial_Balance.pm
===================================================================
--- trunk/LedgerSMB/Report/Trial_Balance.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Trial_Balance.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,243 @@
+=head1 NAME
+
+LedgerSMB::Report::Trial_Balance - Trial Balance report for LedgerSMB
+
+=head1 SYNOPSYS
+
+Unlike other reports, trial balance reports can be saved:
+
+ my $report = LedgerSMB::Report::Trial_Balance->new(%$request);
+ $report->save;
+
+We can then run it:
+
+ $report->run_report;
+ $report->render($request);
+
+We can also retrieve a previous report from the database and run it:
+
+ my $report = LedgerSMB::Report::Trial_Balance->get($id);
+ $report->run_report;
+ $report->render($request);
+
+=cut
+
+package LedgerSMB::Report::Trial_Balance;
+use Moose;
+use LedgerSMB::App_State;
+extends 'LedgerSMB::Report';
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 DESCRIPTION
+
+The trial balance is a report used to test the books and whether they balance 
+in paper accounting systems.  In digital systems it tends to also be repurposed
+also as a general, quick look at accounting activity.  For this reason it is
+probably the second most important report in the system, behind only the GL
+reports.
+
+Unlike other reports, trial balance reports can be saved:
+
+=head1 	CRITERIA PRPERTIES
+
+Criteria sets can also be saved/loaded.
+
+=over
+
+=item id
+
+This is the id of the trial balance, only used to save over an existing 
+criteria set.
+
+=cut
+
+has id => (is => 'rw', isa => 'Maybe[Int]');
+
+=item date_from
+
+Standard start date for trial balance.
+
+=item date_to
+
+Standard end date for report.
+
+=cut
+
+has date_from => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+has date_to => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item desc
+
+Only used for saved criteria sets, is a human-readable description.
+
+=cut
+
+has desc => (is => 'rw', isa => 'Maybe[Str]');
+
+=item yearend
+
+This value holds information related to yearend handling.  It can be either
+'all', 'none', or 'last' each of which describes which yearends to ignore.
+
+=cut
+
+has yearend => (is => 'rw', isa => 'Str');
+
+
+=item heading
+
+If set, only select accounts under this heading
+
+=cut
+
+has heading => (is => 'rw', isa => 'Maybe[Int]')l
+
+=item accounts
+
+If set, only include these accounts
+
+=cut
+
+has accounts => (is => 'rw', isa => 'Maybe[ArrayRef[Int]]');
+
+=head1  REPORT CONSTANT FUNCTIONS
+
+See the documentation for LedgerSMB::Report for details on these
+methods.
+
+=over
+
+=item name
+
+=cut
+
+sub name {
+    return $locale->text('Trial Balance');
+};
+
+=item columns
+
+=cut
+
+sub columns {
+    return [
+      {col_id => 'account_number',
+         type => 'href',
+    href_base => 'journal.pl?action=search&col_transdate=Y&col_reference=Y&col_description=Y&col_debits=Y&col_credits=Y&col_source=Y&col_accno=Y',
+         name => $locale->text('Account Number') },
+
+      {col_id => 'account_desc',
+         type => 'href',
+    href_base => 'journal.pl?action=search&col_transdate=Y&col_reference=Y&col_description=Y&col_debits=Y&col_credits=Y&col_source=Y&col_accno=Y',
+         name => $locale->text('Account Description') },
+
+      {col_id => 'gifi_accno',
+         type => 'href',
+    href_base => 'journal.pl?action=search&col_transdate=Y&col_reference=Y&col_description=Y&col_debits=Y&col_credits=Y&col_source=Y&col_accno=Y',
+         name => $locale->text('GIFI') } ,
+
+      {col_id => 'starting_balance',
+         type => 'text',
+         name => $locale->text('Starting Balance') } ,
+
+      {col_id => 'debits',
+         type => 'text',
+         name => $locale->text('Debits') } ,
+
+      {col_id => 'credits',
+         type => 'text',
+         name => $locale->text('Credits') } ,
+
+      {col_id => 'ending_balance',
+         type => 'text',
+         name => $locale->text('Ending Balance') } ,
+
+    ];
+}
+
+=item header_lines 
+
+=cut
+
+sub header_lines {
+    return [{name => 'date_from'
+             text => $locale->text('From date') },
+            {name => 'date_to',
+             text => $locale->text('To Date') },
+            {name => 'yearend',
+             text => $locale->text('Ignore Yearends') },
+            ];
+}
+
+=back
+
+=head1  METHODS
+
+=over
+
+=item get
+
+Retrieves the trial balance for review and possibly running it.
+
+=cut
+
+sub get {
+    my ($self) = @_;
+    my $ref = __PACKAGE__->call_procedure(procname => 'trial_balance__get', 
+                                              args => [$id]);
+    return __PACKAGE__->new(%$ref);
+}
+
+=item save
+
+Saves the trial balance to be run again with the same parameters another time
+
+=cut
+
+sub save {
+    my ($self) = @_;
+    my ($ref) = $self->exec_method({funcname => 'trial_balance__save'});
+    $self->id(shift (values @$ref));
+}
+
+=item run_report
+
+Runs the trial balance report.
+
+=cut
+
+sub run_report {
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'report__gl'});
+    my $total_debits;
+    my $total_credits;
+    for my $ref(@rows){
+        my $href_suffix = "from_date=" . $self->from_date . 
+                          "&to_date=" . $self->to_date .
+                          "&accno=" . $ref->{account_number};
+        $total_debits += $ref->{debits}; 
+        $total_credits += $ref->{credits}; 
+        $ref->{account_number_href_suffix} = $href_suffix;
+        $ref->{account_desc_href_suffix} = $href_suffix;
+        $ref->{gifi_accno_href_suffix} = $href_suffix;
+        
+    }
+    push @rows {class => 'total', 
+               debits => $total_debits,
+              credits => $total_credits, };
+
+    $self->rows(..hidden..);
+}
+
+=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
+
+1;

Added: trunk/LedgerSMB/Report/Unapproved/Batch_Detail.pm
===================================================================
--- trunk/LedgerSMB/Report/Unapproved/Batch_Detail.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Unapproved/Batch_Detail.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,237 @@
+=head1 NAME
+
+LedgerSMB::Report::Unapproved::Batch_Detail - List Vouchers by Batch 
+in LedgerSMB
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::Unapproved::Batch_Detail->new(
+      %$request
+  );
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This provides an ability to search for (and approve or delete) pending
+transactions grouped in batches.  This report only handles the vouchers in the 
+bach themselves. For searching for batches, use
+LedgerSMB::Report::Unapproved::Batch_Overview instead.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::Unapproved::Batch_Detail;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::Business_Unit_Class;
+use LedgerSMB::Business_Unit;
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=item select
+
+Select boxes for selecting the returned items.
+
+=item id
+
+ID of transaction
+
+=item batch_class
+
+Text description of batch class
+
+=item transdate
+
+Post date of transaction
+use LedgerSMB::Report::Unapproved::Batch_Overview;
+
+=item reference text
+
+Invoice number or GL reference
+
+=item description
+
+Description of transaction
+
+=item amount
+
+Total on voucher.  For AR/AP amount, this is the total of the AR/AP account 
+before payments.  For payments, receipts, and GL, it is the sum of the credits.
+
+=back
+
+=cut
+
+our @COLUMNS = (
+    {col_id => 'select',
+       name => '',
+       type => 'checkbox' },
+
+    {col_id => 'id',
+       name => $locale->text('ID'),
+       type => 'text',
+     pwidth => 1, },
+
+    {col_id => 'batch_class',
+       name => $locale->text('Batch Class'),
+       type => 'text', 
+     pwidth => 2, },
+
+    {col_id => 'default_date',
+       name => $locale->text('Date'),
+       type => 'text',
+     pwidth => '4', },
+
+    {col_id => 'Reference',
+       name => $locale->text('Reference'),
+       type => 'href',
+  href_base => '',
+     pwidth => '3', },
+
+    {col_id => 'description',
+       name => $locale->text('Description'),
+       type => 'text',
+     pwidth => '6', },
+
+    {col_id => 'amount',
+       name => $locale->text('Amount'),
+       type => 'text',
+     pwidth => '2', },
+
+);
+
+sub columns {
+    return ..hidden..;
+}
+
+    # TODO:  business_units int[]
+
+=item name
+
+Returns the localized template name
+
+=cut
+
+sub name {
+    return $locale->text('Voucher List');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [{name => 'batch_id',
+             text => $locale->text('Batch ID')}, ]
+}
+
+=item subtotal_cols
+
+Returns list of columns for subtotals
+
+=cut
+
+sub subtotal_cols {
+    return [];
+}
+
+=back
+
+=head2 Criteria Properties
+
+Note that in all cases, undef matches everything.
+
+=over
+
+=item batch_id (Int)
+
+ID of batch to list vouchers of.
+
+=cut
+
+has 'batch_id' => (is => 'rw', isa => 'Int');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report()
+
+Runs the report, and assigns rows to $self->rows.
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    $self->buttons([{
+                    name  => 'action',
+                    type  => 'submit',
+                    text  => $locale->text('Post Batch'),
+                    value => 'batch_approve',
+                    class => 'submit',
+                 },{
+                    name  => 'action',
+                    type  => 'submit',
+                    text  => $locale->text('Delete Batch'),
+                    value => 'batch_delete',
+                    class => 'submit',
+                 },{
+                    name  => 'action',
+                    type  => 'submit',
+                    text  => $locale->text('Delete Vouchers'),
+                    value => 'vouchers_delete',
+                    class => 'submit',
+                }]);
+    my @rows = $self->exec_method({funcname => 'batch__search'});
+    for my $r (@rows){
+    for my $ref (@rows){
+        my $script;
+        my $class_to_script = {
+           1 => 'ap',
+           2 => 'ar',
+           5 => 'gl',
+           8 => 'is',
+           9 => 'ir',
+        };
+        $script = $class_to_script->{$ref->{batch_class}};
+        $ref->{reference_href_suffix} = "$script.pl?action=edit&id=$ref->{id}";
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/Unapproved/Batch_Overview.pm
===================================================================
--- trunk/LedgerSMB/Report/Unapproved/Batch_Overview.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Unapproved/Batch_Overview.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,249 @@
+=head1 NAME
+
+LedgerSMB::Report::Unapproved::Batch_Overview - Search Batches in 
+LedgerSMB
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::Unapproved::Batch_Overview->new(%$request);
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This provides an ability to search for (and approve or delete) pending
+transactions grouped in batches.  This report only handles the batches 
+themselves.  You cannot delete individual vouchers in this report.  For that,
+use LedgerSMB::Report::Unapproved::Batch_Detail instead.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::Unapproved::Batch_Overview;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::DBObject::Business_Unit_Class;
+use LedgerSMB::DBObject::Business_Unit;
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=item select
+
+Select boxes for selecting the returned items.
+
+=item id
+
+ID of transaction
+
+=item post_date
+
+Post date of transaction
+
+=item reference text
+
+Invoice number or GL reference
+
+=item description
+
+Description of transaction
+
+=item transaction_total
+
+Total of AR/AP/GL vouchers (GL vouchers credit side only is counted)
+
+=item payment_total
+
+Total of payment lines (credit side)
+
+Amount
+
+=back
+
+=cut
+
+our @COLUMNS = (
+    {col_id => 'select',
+       name => '',
+       type => 'checkbox' },
+
+    {col_id => 'id',
+       name => $locale->text('ID'),
+       type => 'text',
+     pwidth => 1, },
+
+    {col_id => 'default_date',
+       name => $locale->text('Date'),
+       type => 'text',
+     pwidth => '4', },
+
+    {col_id => 'control_code',
+       name => $locale->text('Control Code'),
+       type => 'href',
+  href_base => 'vouchers.pl?action=get_batch&id=',
+     pwidth => '3', },
+
+    {col_id => 'description',
+       name => $locale->text('Description'),
+       type => 'text',
+     pwidth => '6', },
+
+    {col_id => 'transaction_total',
+       name => $locale->text('AR/AP/GL Amount'),
+       type => 'text',
+     pwidth => '2', },
+
+    {col_id => 'payment_total',
+       name => $locale->text('Payment Amount'),
+       type => 'text',
+     pwidth => '2', },
+
+);
+
+sub columns {
+    return ..hidden..;
+}
+
+    # TODO:  business_units int[]
+
+=item name
+
+Returns the localized template name
+
+=cut
+
+sub name {
+    return $locale->text('Batch Search');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [{name => 'type',
+             text => $locale->text('Batch Type')},
+            {name => 'reference',
+             text => $locale->text('Reference')},
+            {name => 'amount_gt',
+             text => $locale->text('Amount Greater Than')},
+            {name => 'amount_lt',
+             text => $locale->text('Amount Less Than')}, ]
+}
+
+=item subtotal_cols
+
+Returns list of columns for subtotals
+
+=cut
+
+sub subtotal_cols {
+    return [];
+}
+
+=back
+
+=head2 Criteria Properties
+
+Note that in all cases, undef matches everything.
+
+=over
+
+=item reference (text)
+
+Exact match on reference or invoice number.
+
+=cut
+
+has 'reference' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item type
+
+ar for AR drafts, ap for AP drafts, gl for GL ones.
+
+=cut
+
+has 'type' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item amount_gt
+
+The amount of the draft must be greater than this for it to show up.
+
+=cut
+
+has 'amount_gt' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item amount_lt
+
+The amount of the draft must be less than this for it to show up.
+
+=cut
+
+has 'amount_lt' => (is => 'rw', isa => 'Maybe[Str]');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report()
+
+Runs the report, and assigns rows to $self->rows.
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    $self->buttons([{
+                    name  => 'action',
+                    type  => 'submit',
+                    text  => $locale->text('Post'),
+                    value => 'batch_approve',
+                    class => 'submit',
+                 },{
+                    name  => 'action',
+                    type  => 'submit',
+                    text  => $locale->text('Delete'),
+                    value => 'batch_delete',
+                    class => 'submit',
+                }]);
+    my @rows = $self->exec_method({funcname => 'batch__search'});
+    for my $r (@rows){
+       $r->{row_id} = $r->{id};
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/Unapproved/Drafts.pm
===================================================================
--- trunk/LedgerSMB/Report/Unapproved/Drafts.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/Unapproved/Drafts.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,228 @@
+=head1 NAME
+
+LedgerSMB::Report::Unapproved::Drafts - Unapproved Drafts (single 
+transactions) in LedgerSMB
+
+=head1 SYNPOSIS
+
+  my $report = LedgerSMB::Report::Unapproved::Drafts->new(%$request);
+  $report->run;
+  $report->render($request, $format);
+
+=head1 DESCRIPTION
+
+This provides an ability to search for (and approve or delete) pending
+transactions.  
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::Unapproved::Drafts;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::DBObject::Business_Unit_Class;
+use LedgerSMB::DBObject::Business_Unit;
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=item select
+
+Select boxes for selecting the returned items.
+
+=item id
+
+ID of transaction
+
+=item transdate
+
+Post date of transaction
+
+=item reference text
+
+Invoice number or GL reference
+
+=item description
+
+Description of transaction
+
+=item amount
+
+Amount
+
+=back
+
+=cut
+
+our @COLUMNS = (
+    {col_id => 'select',
+       name => '',
+       type => 'checkbox' },
+
+    {col_id => 'id',
+       name => $locale->text('ID'),
+       type => 'text',
+     pwidth => 1, },
+
+    {col_id => 'transdate',
+       name => $locale->text('Date'),
+       type => 'text',
+     pwidth => '4', },
+
+    {col_id => 'reference',
+       name => $locale->text('Reference'),
+       type => 'href',
+  href_base => '',
+     pwidth => '3', },
+
+    {col_id => 'description',
+       name => $locale->text('Description'),
+       type => 'text',
+     pwidth => '6', },
+
+    {col_id => 'amount',
+       name => $locale->text('AR/AP/GL Amount'),
+       type => 'text',
+     pwidth => '2', },
+
+);
+
+sub columns {
+    return ..hidden..;
+}
+
+    # TODO:  business_units int[]
+
+=item name
+
+Returns the localized template name
+
+=cut
+
+sub name {
+    return $locale->text('Draft Search');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [{name => 'type',
+             text => $locale->text('Draft Type')},
+            {name => 'reference',
+             text => $locale->text('Reference')},
+            {name => 'amount_gt',
+             text => $locale->text('Amount Greater Than')},
+            {name => 'amount_lt',
+             text => $locale->text('Amount Less Than')}, ]
+}
+
+=item subtotal_cols
+
+Returns list of columns for subtotals
+
+=cut
+
+sub subtotal_cols {
+    return [];
+}
+
+=back
+
+=head2 Criteria Properties
+
+Note that in all cases, undef matches everything.
+
+=over
+
+=item reference (text)
+
+Exact match on reference or invoice number.
+
+=cut
+
+has 'reference' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item type
+
+ar for AR drafts, ap for AP drafts, gl for GL ones.
+
+=cut
+
+has 'type' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item amount_gt
+
+The amount of the draft must be greater than this for it to show up.
+
+=cut
+
+has 'amount_gt' => (is => 'rw', coerce => 1, isa =>'LedgerSMB::Moose::Number');
+
+=item amount_lt
+
+The amount of the draft must be less than this for it to show up.
+
+=cut
+
+has 'amount_lt' => (is => 'rw', coerce => 1, isa =>'LedgerSMB::Moose::Number'););
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report()
+
+Runs the report, and assigns rows to $self->rows.
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'draft__search'});
+    for my $ref (@rows){
+        my $script = $self->type;
+        if ($ref->{invoice}){
+            $script = 'is' if $self->type eq 'ar';
+            $script = 'ir' if $self->type eq 'ap';
+        }
+        $ref->{reference_href_suffix} = "$script.pl?action=edit&id=$ref->{id}";
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/co/Balance_y_Mayor.pm
===================================================================
--- trunk/LedgerSMB/Report/co/Balance_y_Mayor.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/co/Balance_y_Mayor.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,187 @@
+=head1 NAME
+
+LedgerSMB::Report::co::Balance_y_Mayor - Colombian Balance/Ledger Rpt
+
+=head1 SYNPOSIS
+
+  my $bmreport = LedgerSMB::Report::co::Balance_y_Mayor->new(%$request);
+  $bmreport->run;
+  $bmreport->render($request, $format);
+
+=head1 DESCRIPTION
+
+This module provides Balance y Mayor reports for LedgerSMB to Colombian 
+standards. This report shows total activity over a time period.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::co::Balance_y_Mayor;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+my $doctypes = {};
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=item accno
+
+Account Number
+
+=item description
+
+Account name
+
+=item document_type
+
+=item debits
+
+=item credits
+
+=back
+
+=cut
+
+our @COLUMNS = (
+    {col_id => 'accno',
+       name => $locale->text('Account'),
+       type => 'href',
+     pwidth => 3,
+  href_base => '', },
+
+    {col_id => 'description',
+       name => $locale->text('Description'),
+       type => 'text',
+     pwidth => '12', },
+
+    {col_id => 'starting_balance',
+       name => $locale->text('Starting Balance'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'debits',
+       name => $locale->text('Debit'),
+       type => 'text',
+     pwidth => '4', },
+
+    {col_id => 'credits',
+       name => $locale->text('Credit'),
+       type => 'text',
+     pwidth => '4', },
+    {col_id => 'ending_balance',
+       name => $locale->text('Balance'),
+       type => 'text',
+     pwidth => '3', },
+
+);
+
+sub columns {
+    return ..hidden..;
+}
+
+
+=item filter_template
+
+Returns the template name for the filter.
+
+=cut
+
+sub filter_template {
+    return 'Reports/co/bm_filter';
+}
+
+=item name
+
+Returns the localized template name
+
+=cut
+
+sub name {
+    return $locale->text('Balance y Mayor');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [{name => 'date_from',
+             text => $locale->text('Start Date')},
+            {name => 'date_to',
+             text => $locale->text('End Date')},]
+}
+
+=back
+
+=head2 Criteria Properties
+
+Note that in all cases, undef matches everything.
+
+=over
+
+=item date_from (text)
+
+start date for the report
+
+=cut
+
+has 'date_from' => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item date_to
+
+End date for the report
+
+=cut
+
+has 'date_to'  => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report()
+
+Runs the report, and assigns rows to $self->rows.
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'report__general_balance'});
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report/co/Caja_Diaria.pm
===================================================================
--- trunk/LedgerSMB/Report/co/Caja_Diaria.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report/co/Caja_Diaria.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,206 @@
+=head1 NAME
+
+LedgerSMB::Report::co::Caja_Diaria - Caja Diaria Reports (Colombia)
+
+=head1 SYNPOSIS
+
+  my $cdreport = LedgerSMB::Report::co::Caja_Diaria->new(%$request);
+  $cdreport->run;
+  $cdreport->render($request, $format);
+
+=head1 DESCRIPTION
+
+This module provides Caja Diaria eports for LedgerSMB to Colombian standards.
+These reports provide an overview of cash activity to a set of accounts for a
+specific period.
+
+=head1 INHERITS
+
+=over
+
+=item LedgerSMB::Report;
+
+=back
+
+=cut
+
+package LedgerSMB::Report::co::Caja_Diaria;
+use Moose;
+extends 'LedgerSMB::Report';
+
+use LedgerSMB::App_State;
+
+my $locale = $LedgerSMB::App_State::Locale;
+my $doctypes = {};
+
+=head1 PROPERTIES
+
+=over
+
+=item columns
+
+Read-only accessor, returns a list of columns.
+
+=over
+
+=item accno
+
+Account Number
+
+=item description
+
+Account name
+
+=item document_type
+
+=item debits
+
+=item credits
+
+=back
+
+=cut
+
+our @COLUMNS = (
+    {col_id => 'accno',
+       name => $locale->text('Account'),
+       type => 'href',
+     pwidth => 3,
+  href_base => '', },
+
+    {col_id => 'description',
+       name => $locale->text('Description'),
+       type => 'text',
+     pwidth => '12', },
+
+    {col_id => 'document_type',
+       name => $locale->text('Document'),
+       type => 'text',
+     pwidth => '3', },
+
+    {col_id => 'debits',
+       name => $locale->text('Debit'),
+       type => 'text',
+     pwidth => '4', },
+
+    {col_id => 'credits',
+       name => $locale->text('Credit'),
+       type => 'text',
+     pwidth => '4', },
+
+);
+
+sub columns {
+    return ..hidden..;
+}
+
+
+=item filter_template
+
+Returns the template name for the filter.
+
+=cut
+
+sub filter_template {
+    return 'Reports/co/cj_filter';
+}
+
+=item name
+
+Returns the localized template name
+
+=cut
+
+sub name {
+    return $locale->text('Caja Diaria');
+}
+
+=item header_lines
+
+Returns the inputs to display on header.
+
+=cut
+
+sub header_lines {
+    return [{name => 'date_from',
+             text => $locale->text('Start Date')},
+            {name => 'date_to',
+             text => $locale->text('End Date')},
+            {name => 'accno',
+             text => $locale->text('Account Number Start')},
+            {name => 'reference',
+             text => $locale->text('Account Number End')},]
+}
+
+=back
+
+=head2 Criteria Properties
+
+Note that in all cases, undef matches everything.
+
+=over
+
+=item date_from (text)
+
+start date for the report
+
+=cut
+
+has 'date_from' => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+=item date_to
+
+End date for the report
+
+=cut
+
+has 'date_to'  => (is => 'rw', coerce => 1, isa => 'LedgerSMB::Moose::Date');
+
+
+=item from_accno
+
+=cut
+
+has 'from_accno' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item to_accno
+
+
+=cut
+
+has 'to_accno' => (is => 'rw', isa => 'Maybe[Str]');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report()
+
+Runs the report, and assigns rows to $self->rows.
+
+=cut
+
+sub run_report{
+    my ($self) = @_;
+    my @rows = $self->exec_method({funcname => 'report__cash_summary'});
+    for my $ref(@rows){
+        $ref->{document_type} = $doctypes->{$ref->{document_type}} 
+                if $doctypes->{$ref->{document_type}};
+    }
+    $self->rows(..hidden..);
+}
+
+=back
+
+=head1 COPYRIGHT
+
+COPYRIGHT (C) 2012 The LedgerSMB Core Team.  This file may be re-used following
+the terms of the GNU General Public License version 2 or at your option any
+later version.  Please see included LICENSE.TXT for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;

Added: trunk/LedgerSMB/Report.pm
===================================================================
--- trunk/LedgerSMB/Report.pm	                        (rev 0)
+++ trunk/LedgerSMB/Report.pm	2012-07-19 12:37:47 UTC (rev 5016)
@@ -0,0 +1,343 @@
+=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';
+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]');
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item render
+
+This takes no arguments and simply renders the report as is.
+
+=cut
+
+sub render {
+    my ($self, $request) = @_;
+    my $template;
+
+    # 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,
+                         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..;
+}
+
+=item prepare_input
+
+Handles from_date and to_date fields, as well as from_month, from_year, and 
+interval, setting from_date and to_date to LedgerSMB::PGDate types, and setting
+from_amount and to_amount to LedgerSMB::PGNumber types.
+
+Valid values for interval are:
+
+=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;

Modified: trunk/LedgerSMB/Scripts/budget_reports.pm

@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.