In general, common controls and the like have been centralized to ensure consistency of interfaces for both user and developer. Not only does the user get to see common date selection routines, for example, but the developer can count on dates being available to the report.
Common Controls
The report_base.html template contains a number of basic controls used for data entry. In general these are the best way to add certain kinds of common data to a report because they ensure a consistent API and user experience. To use one of these controls, just PROCESS them like:<?lsmb PROCESS date_row_div ?>
We offer the following common controls for report filter screens in the report_base.html template:
- business_classes, a table row for selecting the business reporting class (project, department, and the like)
- business_classes_div, similar to business_classes above but in a div instead of a table row
- entity_class, a table row for selecting entity class (customer, vendor, etc)
- gifi_or_standard, a radio button set for selecting GIFI or standard reports (table row)
- igore_yearend, a table row for selecting whether yearends should be ignored or not (options: all, none, or last)
- date_row is a set of two table rows for selecting date, either by year, month, and period or by from and two dates identifying a range.
- date_row_div uses divs instead of table rows.
- employee_row is a row for selecting an employee for a report
General Functionality Available
For reports only requiring general functionality you can simply put the filter screen in UI/Reports/filters/ with a name based on the report name (myreport.html for example) and then call it with a URL like: http://myhost/ledgersmb/reports.pl&action=start_report&report_name=myreport&module=gl.
The module option determines which business unit classes are available for selection.
The following are added to the request hash before passing it on to the template:
- heading_list is a list of account headings
- account_list is a list of accounts
- all_years is a list of years for which there is financial activity (does not include uninvoiced orders)
- all_months is a list of localized months for the date selection dropdown
- batch_classes is a list of batch classes
- bu_classes is an array of business unit classes, for the appropriate common control
- b_units is an array of business units by class, for the common control
- country_list is a list of countries
- entity_classes is an array of entity classes for the common control
- employees is a list of employees for the common control
Handling Custom Selection Boxes
There are of course times when one needs more option sets than these. The best way to handle this is to add a new workflow script, which preprocesses the $request hash before passing this on to same function.
For example the relevant code for searching for orders is (abbreviated):
use LedgerSMB::Scripts::reports;
use LedgerSMB::Report::Orders;
sub get_criteria {
my ($request) = @_;
my $locale = $LedgerSMB::App_State::Locale;
$request->{entity_class} = $request->{oe_class_id} % 2 + 1;
$request->{report_name} = 'orders';
$request->{open} = 1 if $request->{search_type} ne 'search';
if ($request->{oe_class_id} == 1){
if ($request->{search_type} eq 'search'){
$request->{title} = $locale->text('Search Sales Orders');
} elsif ($request->{search_type} eq 'generate'){
$request->{title} =
$locale->text('Generate Purchase Orders from Sales Orders');
} elsif ($request->{search_type} eq 'combine'){
$request->{title} = $locale->text('Combine Sales Orders');
} elsif ($request->{search_type} eq 'ship'){
$request->{title} = $locale->text('Ship');
}
} elsif ($request->{oe_class_id} == 2){
if ($request->{search_type} eq 'search'){
$request->{title} = $locale->text('Search Purchase Orders');
} elsif ($request->{search_type} eq 'combine'){
$request->{title} = $locale->text('Combine Purchase Orders');
} elsif ($request->{search_type} eq 'generate'){
$request->{title} =
$locale->text('Generate Sales Orders from Purchase Orders');
} elsif ($request->{search_type} eq 'ship'){
$request->{title} = $locale->text('Receive');
}
} elsif ($request->{oe_class_id} == 3){
if ($request->{search_type} eq 'search'){
$request->{title} = $locale->text('Search Quotations');
}
} elsif ($request->{oe_class_id} == 4){
if ($request->{search_type} eq 'search'){
$request->{title} = $locale->text('Search Requests for Quotation');
}
}
LedgerSMB::Scripts::reports::start_report($request);
}
The point is you can effectively put whatever logic you want before passing on to our general functionality.
You can use the templates in UI/Reports/filters as examples for coding the template itself.
Conclusions
The filter screen system is intended to make it relatively easy to create filters for report inputs. In the future we will probably add more common controls and the like. However this gives you the basic information needed to start writing reports.
Others in Series
1. Overview
3. Stored Procedure Best Practices
4. (Mostly) Declarative Reporting Perl Modules
5. Conclusions