reporter stuff
authormiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 17 Nov 2005 11:34:50 +0000 (11:34 +0000)
committermiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Thu, 17 Nov 2005 11:34:50 +0000 (11:34 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@2052 dcc99617-32d9-48b4-a31d-7c20da2025e4

26 files changed:
Open-ILS/src/Makefile
Open-ILS/src/perlmods/OpenILS/WWW/Reporter.pm
Open-ILS/src/perlmods/OpenILS/WWW/Reporter/transforms.pm [new file with mode: 0644]
Open-ILS/src/reporter/clark-kent.pl [new file with mode: 0755]
Open-ILS/src/reporter/config.sql
Open-ILS/src/reporter/report_base.example.xml
Open-ILS/src/reporter/tables.example.xml
Open-ILS/src/reporter/templates/class_manip
Open-ILS/src/reporter/templates/dashboard.ttk
Open-ILS/src/reporter/templates/html/body [new file with mode: 0644]
Open-ILS/src/reporter/templates/html/cell [new file with mode: 0644]
Open-ILS/src/reporter/templates/html/html [new file with mode: 0644]
Open-ILS/src/reporter/templates/html/row [new file with mode: 0644]
Open-ILS/src/reporter/templates/html/table [new file with mode: 0644]
Open-ILS/src/reporter/templates/logic_header.ttk
Open-ILS/src/reporter/templates/stage1.ttk
Open-ILS/src/reporter/templates/stage2.ttk
Open-ILS/src/reporter/templates/stage3.ttk
Open-ILS/src/reporter/templates/utils [new file with mode: 0644]
Open-ILS/src/reporter/templates/widget_manip
Open-ILS/src/reporter/templates/widgets/string-choose.multiselect
Open-ILS/src/sql/Pg/002.schema.config.sql
Open-ILS/src/sql/Pg/020.schema.functions.sql
Open-ILS/src/sql/Pg/040.schema.asset.sql
config.sh
install.sh

index b723fb1..8dd7265 100644 (file)
@@ -81,6 +81,17 @@ perl-install:
 
 # -----------------------------------------------------------------------------------
 
+reporter-install:
+       @echo $@
+       @echo "Installing Reporter templates to $(REPORTERDIR) and example configs to $(ETCDIR)"
+       cp reporter/report_base.example.xml $(ETCDIR)/reporter.example.xml
+       cp reporter/tables.example.xml $(ETCDIR)
+       cp reporter/widgets.example.xml $(ETCDIR)
+       mkdir -p $(REPORTERDIR)
+       cp -r reporter/templates/* $(REPORTERDIR)
+
+# -----------------------------------------------------------------------------------
+
 cgi-bootstrap:
        @echo "Installing cgi's to $(CGIDIR)"
        mkdir -p $(TMP)/cgi-bin
index 64b786a..ecbb273 100644 (file)
@@ -1,6 +1,8 @@
 package OpenILS::WWW::Reporter;
 use strict; use warnings;
 
+use vars qw/$dtype_xform_map $dtype_xform/;
+
 use Apache2 ();
 use Apache2::Log;
 use Apache2::Const -compile => qw(OK REDIRECT :log);
@@ -18,7 +20,7 @@ use XML::LibXML;
 
 use OpenSRF::Utils::SettingsParser;
 use OpenILS::Utils::Fieldmapper;
-
+use OpenILS::WWW::Reporter::transforms;
 
 
 # set the bootstrap config and template include directory when 
@@ -88,6 +90,8 @@ sub _process_template {
        my $ttk                         = $params{template}             || return undef;
        my $apache                      = $params{apache}                       || undef;
        my $param_hash          = $params{params}                       || {};
+       $$param_hash{dtype_xform_map} = $OpenILS::WWW::Reporter::dtype_xform_map;
+       $$param_hash{dtype_xform} = $OpenILS::WWW::Reporter::dtype_xform;
 
        my $template;
 
diff --git a/Open-ILS/src/perlmods/OpenILS/WWW/Reporter/transforms.pm b/Open-ILS/src/perlmods/OpenILS/WWW/Reporter/transforms.pm
new file mode 100644 (file)
index 0000000..d3b3c2d
--- /dev/null
@@ -0,0 +1,77 @@
+#!/usr/bin/perl
+
+package OpenILS::WWW::Reporter;
+
+our $dtype_xform_map = {
+        'int'                   => [ 'avg','stddev','sum','count','count_dist','numformat'],
+        'numeric'       => [ 'avg','stddev','sum','count','count_dist','numformat'],
+        'float' => [ 'avg','stddev','sum','count','count_dist','numformat'],
+        'time'  => [ 'count', 'dateformat'],
+        'date'  => [ 'count', 'age','dateformat'],
+        'timestamp'     => [ 'count', 'age','dateformat'],
+        'timestamptz'   => [ 'count', 'age','dateformat'],
+        'text'  => [ 'count','count_dist','lower','upper','substr','dewy','dewy_prefix'],
+};
+
+
+
+our $dtype_xforms = {
+        'avg'           => { 
+                'name'  => 'Average per group',
+                'select'        => 'AVG(?COLNAME?)',
+                'group' => 0 },
+        'stddev'        => {
+                'label' => 'Standard Deviation per group',
+                'select'        => 'STDDEV(?COLNAME?)',
+                'group' => 0 },
+        'sum'           => {
+                'label' => 'Sum per group',
+                'select'        => 'SUM(?COLNAME?)',
+                'group' => 0 }, 
+        'count'         => {    
+                'label' => 'Count per group',
+                'select'        => 'COUNT(?COLNAME?)',
+                'group' => 0 },
+        'count_dist'            => {
+                'label' => 'Distinct Count per group',
+                'select'        => 'COUNT(DISTINCT ?COLNAME?)',
+                'group' => 0 }, 
+        'dewy_prefix'         => {    
+                'label' => 'Extract Dewey number prefix from call number',
+                'select'        => 'call_number_dewey(?COLNAME?,?PARAM?)',
+                'param' => 1,           
+                'group' => 1 },
+        'dewy'         => {    
+                'label' => 'Extract Dewey number from call number',
+                'select'        => 'call_number_dewey(?COLNAME?)',
+                'group' => 1 },
+        'lower'         => {    
+                'label' => 'Transform string to lower case',
+                'select'        => 'LOWER(?COLNAME?)',
+                'group' => 1 },
+        'upper'         => {
+                'label' => 'Transform string to upper case',
+                'select'        => 'UPPER(?COLNAME?)',
+                'group' => 1 }, 
+        'substr'                => {
+                'label' => 'Trim string length',
+                'select'        => 'substr(?COLNAME?,1,?PARAM?)',
+                'param' => 1,           
+                'group' => 1 },                 
+        'age'           => {            
+                'label' => 'Age as of runtime -- day granularity',
+                'select'        => 'AGE(?COLNAME?::DATE)',
+                'group' => 1 },
+        'dateformat'            => { # see http://www.postgresql.org/docs/8.0/interactive/functions-formatting.html
+                'label' => 'Format date and time',
+                'select'        => 'TO_CHAR(?COLNAME?,?PARAM?)',
+                'param' => 1,           
+                'group' => 1 },                 
+        'numformat'             => { # see http://www.postgresql.org/docs/8.0/interactive/functions-formatting.html
+                'label' => 'Format Numeric data',
+                'select'        => 'TO_CHAR(?COLNAME?,?PARAM?)',
+                'param' => 1,                           
+                'group' => 1 },                         
+};                                      
+
+;
diff --git a/Open-ILS/src/reporter/clark-kent.pl b/Open-ILS/src/reporter/clark-kent.pl
new file mode 100755 (executable)
index 0000000..438efb6
--- /dev/null
@@ -0,0 +1,244 @@
+#!/usr/bin/perl -w
+
+use strict;
+use DBI;
+use XML::LibXML;
+use Getopt::Long;
+use DateTime;
+use DateTime::Format::ISO8601;
+use JSON;
+use Data::Dumper;
+use OpenILS::WWW::Reporter::transforms;
+
+my $current_time = DateTime->from_epoch( epoch => time() )->strftime('%FT%T%z');
+
+my ($base_xml, $count) = ('/openils/conf/reporter.xml', 1);
+
+GetOptions(
+       "file=s"        => \$base_xml,
+       "concurrency=i" => \$count,
+);
+
+my $parser = XML::LibXML->new;
+$parser->expand_xinclude(1);
+
+my $doc = $parser->parse_file($base_xml);
+
+warn $doc->toString;
+
+my $db_driver = $doc->findvalue('/reporter/setup/database/driver');
+my $db_host = $doc->findvalue('/reporter/setup/database/host');
+my $db_name = $doc->findvalue('/reporter/setup/database/name');
+my $db_user = $doc->findvalue('/reporter/setup/database/user');
+my $db_pw = $doc->findvalue('/reporter/setup/database/password');
+
+my $dsn = "dbi:" . $db_driver . ":dbname=" . $db_name .';host=' . $db_host;
+
+my $dbh = DBI->connect($dsn,$db_user,$db_pw);
+
+# make sure we're not already running $count reports
+my ($running) = $dbh->selectrow_array(<<SQL);
+SELECT count(*)
+  FROM reporter.run_queue
+  WHERE        state = 'running';
+SQL
+
+if ($count <= $running) {
+       print "Already running maximum ($running) concurrent reports\n";
+       exit 1;
+}
+
+# if we have some open slots then generate the sql
+my $run = $count - $running;
+my $sth = $dbh->prepare(<<SQL);
+SELECT *
+  FROM reporter.stage3
+  WHERE        runtime <= ?
+  ORDER BY runtime
+  LIMIT $run
+SQL
+
+$sth->execute($current_time);
+
+my @reports;
+while (my $r = $sth->fetchrow_hashref) {
+       $r->{sql} = generate_query( $r );
+       push @reports, $r;
+}
+$sth->finish;
+
+for my $r ( @reports ) {
+       my $sql = shift @{ $r->{sql} };
+
+       $sth = $dbh->prepare($sql);
+
+       $sth->execute(@{ $r->{sql} });
+       while (my $row = $sth->fetchrow_hashref) {
+               print join(', ', map {"$_\t=> $$row{$_}"} keys %$row)."\n";
+       }
+}
+
+
+#-------------------------------------------------------------------
+
+sub table_by_id {
+       my $id = shift;
+       my ($node) = $doc->findnodes("//*[\@id='$id']");
+       if ($node && $node->findvalue('@table')) {
+               ($node) = $doc->findnodes("//*[\@id='".$node->getAttribute('table')."']");
+       }
+       return $node;
+}
+
+sub generate_query {
+       my $s3 = shift;
+       warn Dumper($s3);
+
+       my $r = JSON->JSON2perl( $s3->{params} );
+       warn Dumper($r);
+
+       my $s2 = $dbh->selectrow_hashref(<<"    SQL", {}, $s3->{stage2});
+               SELECT  *
+                 FROM  reporter.stage2
+                 WHERE id = ?
+       SQL
+       warn Dumper($s2);
+
+       my @group_by;
+       my @aggs;
+       my $core = $s2->{stage1};
+       my @dims;
+
+       for my $t (keys %{$$r{filter}}) {
+               if ($t ne $core) {
+                       push @dims, $t;
+               }
+       }
+
+       for my $t (keys %{$$r{output}}) {
+               if ($t ne $core && !grep { $t } @dims ) {
+                       push @dims, $t;
+               }
+       }
+       warn Dumper(\@dims);
+
+       my @dim_select;
+       my @dim_from;
+       for my $d (@dims) {
+               my $t = table_by_id($d);
+               my $t_name = $t->findvalue('tablename');
+               push @dim_from, "$t_name AS \"$d\"";
+
+               my $k = $doc->findvalue("//*[\@id='$d']/\@key");
+               push @dim_select, "\"$d\".\"$k\" AS \"${d}_${k}\"";
+
+               for my $c ( keys %{$$r{output}{$d}} ) {
+                       push @dim_select, "\"$d\".\"$c\" AS \"${d}_${c}\"";
+               }
+
+               for my $c ( keys %{$$r{filter}{$d}} ) {
+                       next if (exists $$r{output}{$d}{$c});
+                       push @dim_select, "\"$d\".\"$c\" AS \"${d}_${c}\"";
+               }
+       }
+
+       my $d_select =
+               '(SELECT ' . join(',', @dim_select) .
+               '  FROM ' . join(',', @dim_from) . ') AS dims';
+       
+       warn "*** [$d_select]\n";
+
+       my $col = 1;
+       my @groupby;
+       my @output;
+       my @join;
+       for my $t ( keys %{$$r{output}} ) {
+               my $t_name = $t;
+               $t_name = "dims" if ($t ne $core);
+
+               my $t_node = table_by_id($t);
+
+               for my $c ( keys %{$$r{output}{$t}} ) {
+                       my $label = $t_node->findvalue("fields/field[\@name='$c']/label");
+
+                       my $full_col = $c;
+                       $full_col = "${t}_${c}" if ($t ne $t_name);
+                       $full_col = "\"$t_name\".\"$full_col\"";
+
+                       
+                       if (my $xform_type = $$r{xform}{type}{$t}{$c}) {
+                               my $xform = $$OpenILS::WWW::Reporter::dtype_xforms{$xform_type};
+                               if ($xform->{group}) {
+                                       push @groupby, $col;
+                               }
+                               $label = "$$xform{label} -- $label";
+
+                               my $tmp = $xform->{'select'};
+                               $tmp =~ s/\?COLNAME\?/$full_col/gs;
+                               $tmp =~ s/\?PARAM\?/$$r{xform}{param}{$t}{$c}/gs;
+                               $full_col = $tmp;
+                       } else {
+                               push @groupby, $col;
+                       }
+
+                       push @output, "$full_col AS \"$label\"";
+                       $col++;
+               }
+
+               if ($t ne $t_name) {
+                       my $k = $doc->findvalue("//*[\@id='$t']/\@key");
+                       my $f = $doc->findvalue("//*[\@id='$t']/\@field");
+                       push @join, "dims.\"${t}_${k}\" = \"$core\".\"$f\"";
+               }
+       }
+
+       my @where;
+       my @bind;
+       for my $t ( keys %{$$r{filter}} ) {
+               my $t_name = $t;
+               $t_name = "dims" if ($t ne $core);
+
+               my $t_node = table_by_id($t);
+
+               for my $c ( keys %{$$r{filter}{$t}} ) {
+                       my $label = $t_node->findvalue("fields/field[\@name='$c']/label");
+
+                       my $full_col = $c;
+                       $full_col = "${t}_${c}" if ($t ne $t_name);
+                       $full_col = "\"$t_name\".\"$full_col\"";
+
+                       # XXX make this use widget specific code
+
+                       my ($fam) = keys %{ $$r{filter}{$t}{$c} };
+                       my ($w) = keys %{ $$r{filter}{$t}{$c}{$fam} };
+                       my $val = $$r{filter}{$t}{$c}{$fam}{$w};
+
+                       if (ref $val) {
+                               push @where, "$full_col IN (".join(",",map {'?'}@$val).")";
+                               push @bind, @$val;
+                       } else {
+                               push @where, "$full_col = ?";
+                               push @bind, $val;
+                       }
+               }
+       }
+
+       my $t = table_by_id($core)->findvalue('tablename');
+       my $from = " FROM $t AS \"$core\" RIGHT JOIN $d_select ON (". join(' AND ', @join).")";
+       my $select =
+               "SELECT ".join(',', @output).
+                 $from.
+                 ' WHERE '.join(' AND ', @where).
+                 ' GROUP BY '.join(',',@groupby);
+
+       warn " !!! [$select]\n";
+       warn " !!! [".join(', ',@bind)."]\n";
+
+       return [ $select, @bind ];
+}
+
+
+
+
+
+
index d8454c6..9cc8bd8 100644 (file)
@@ -46,5 +46,30 @@ CREATE TABLE reporter.stage3 (
        recurrence      interval
 );
 
+CREATE TABLE reporter.run_queue (
+       id              serial                          primary key,
+       stage3          int                             not null
+                                                       references reporter.stage3 (id)
+                                                               on delete restrict
+                                                               deferrable
+                                                               initially deferred,
+       queue_time      timestamp with time zone        not null default now(),
+       run_time        timestamp with time zone,
+       complete_time   timestamp with time zone,
+       state           text                            check (state in ('wait','running','complete'))
+);
+
+CREATE TABLE reporter.output (
+       id              int             primary key,
+       stage3          int             not null
+                                       references reporter.stage3 (id)
+                                               on delete restrict
+                                               deferrable
+                                               initially deferred,
+       queue_time      timestamp with time zone        not null default now(),
+       run_time        timestamp with time zone        not null,
+       complete_time   timestamp with time zone        not null
+);
+
 COMMIT;
 
index a7cca59..ae03ac3 100644 (file)
@@ -3,12 +3,10 @@
 
        <setup>
                <files>
-                       <stage1>/tmp/reporter/</stage1>
-                       <stage2>/tmp/reporter/</stage2>
-                       <stage3>/tmp/reporter/</stage3>
-                       <widget-family>/tmp/reporter/</widget-family>
+                       <output_base>/tmp/reporter/</output_base>
                </files>
                <database>
+                       <driver>Pg</driver>
                        <host>10.0.0.2</host>
                        <name>demo-dev</name>
                        <user>postgres</user>
index 4d4ec28..a84287c 100644 (file)
@@ -1,7 +1,121 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <tables>
 
-       <table id="silly.fact" partition="true" fact-table="true">
+       <table id="wide-copy" partition="false" fact-table="true">
+               <label>Wide Copy info</label>
+               <description>Base table for creating snapshot reports on copy information</description>
+               <tablename>stats.fleshed_copy</tablename>
+
+               <fields>
+                       <field
+                         name="id"
+                         primary="true"
+                         create-type="serial"
+                         datatype="int">
+                               <label>ID</label>
+                               <description>Copy ID</description>
+                       </field>
+                       <field
+                         name="barcode"
+                         datatype="text">
+                               <label>Barcode</label>
+                               <description>Copy Barcode</description>
+                       </field>
+                       <field
+                         name="owning_lib"
+                         datatype="int"
+                         indexed="true">
+                               <label>Owner</label>
+                               <description>ID of the Owning Library</description>
+                       </field>
+                       <field
+                         name="circ_lib"
+                         datatype="int"
+                         indexed="true">
+                               <label>Circulator</label>
+                               <description>ID of the Circulating Library</description>
+                       </field>
+                       <field
+                         name="create_date"
+                         datatype="timestamptz"
+                         indexed="true"
+                         default="now()">
+                               <label>Create Date</label>
+                               <description>Timestamp of the copy's cataloging</description>
+                       </field>
+                       <field
+                         name="item_lang"
+                         datatype="text">
+                               <label>Language</label>
+                               <description>MARC Item Language</description>
+                       </field>
+                       <field
+                         name="item_form"
+                         datatype="text">
+                               <label>Form</label>
+                               <description>MARC Item Form of Material</description>
+                       </field>
+                       <field
+                         name="item_type"
+                         datatype="text">
+                               <label>Type</label>
+                               <description>MARC Item Type</description>
+                       </field>
+                       <field
+                         name="call_number_label"
+                         datatype="text">
+                               <label>Call Number</label>
+                               <description>Copy Call Number Label</description>
+                       </field>
+               </fields>
+
+               <links>
+                       <link
+                         field="owning_lib"
+                         table="org_unit"
+                         id="copy_owning_lib"
+                         key="id"
+                         type="has_a"/>
+                       <link
+                         field="circ_lib"
+                         table="org_unit"
+                         id="copy_circ_lib"
+                         key="id"
+                         type="has_a"/>
+               </links>
+
+       </table>
+               
+       <table id="org_unit" partition="false" fact-table="false">
+               <label>Organizational Units</label>
+               <description>Table containing library hierarchy definition</description>
+               <tablename>actor.org_unit</tablename>
+
+               <fields>
+                       <field
+                         name="id"
+                         primary="true"
+                         create-type="serial"
+                         datatype="int">
+                               <label>ID</label>
+                               <description>Library ID</description>
+                       </field>
+                       <field
+                         name="name"
+                         datatype="text">
+                               <label>Name</label>
+                               <description>Library Name</description>
+                       </field>
+                       <field
+                         name="shortname"
+                         datatype="text">
+                               <label>Short Name</label>
+                               <description>Library Short (Policy) Name</description>
+                       </field>
+               </fields>
+       </table>
+
+       <table id="silly.fact" partition="true" fact-table="false">
                <label>Silly Fact table</label>
                <description>Base table for creating reports on silly words</description>
                <tablename>stats.silly_fact</tablename>
index 5fdd59b..dd01c20 100644 (file)
@@ -2,67 +2,6 @@
 
 PROCESS inputs;
 
-dtype_xforms = {
-       'avg'           => {
-               'name'  => 'Average per group',
-               'select'        => 'AVG(?COLNAME?)',
-               'group' => 0 },
-       'stddev'        => {
-               'label' => 'Standard Deviation per group',
-               'select'        => 'STDDEV(?COLNAME?)',
-               'group' => 0 },
-       'sum'           => {
-               'label' => 'Sum per group',
-               'select'        => 'SUM(?COLNAME?)',
-               'group' => 0 },
-       'count'         => {
-               'label' => 'Count per group',
-               'select'        => 'COUNT(?COLNAME?)',
-               'group' => 0 },
-       'count_dist'            => {
-               'label' => 'Distinct Count per group',
-               'select'        => 'COUNT(DISTINCT ?COLNAME?)',
-               'group' => 0 },
-       'lower'         => {
-               'label' => 'Transform string to lower case',
-               'select'        => 'LOWER(?COLNAME?)',
-               'group' => 1 },
-       'upper'         => {
-               'label' => 'Transform string to upper case',
-               'select'        => 'UPPER(?COLNAME?)',
-               'group' => 1 },
-       'substr'                => {
-               'label' => 'Trim string length',
-               'select'        => 'substr(?COLNAME?,1,?PARAM?)',
-               'param' => 1,
-               'group' => 1 },
-       'age'           => {
-               'label' => 'Age as of runtime -- day granularity',
-               'select'        => 'AGE(?COLNAME?::DATE)',
-               'group' => 1 },
-       'dateformat'            => { # see http://www.postgresql.org/docs/8.0/interactive/functions-formatting.html
-               'label' => 'Format date and time',
-               'select'        => 'TO_CHAR(?COLNAME?,?PARAM?)',
-               'param' => 1,
-               'group' => 1 },
-       'numformat'             => { # see http://www.postgresql.org/docs/8.0/interactive/functions-formatting.html
-               'label' => 'Format Numeric data',
-               'select'        => 'TO_CHAR(?COLNAME?,?PARAM?)',
-               'param' => 1,
-               'group' => 1 },
-};
-
-dtype_xform_map = {
-       'int'                   => [ 'avg','stddev','sum','count','count_dist','numformat'], 
-       'numeric'       => [ 'avg','stddev','sum','count','count_dist','numformat'], 
-       'float' => [ 'avg','stddev','sum','count','count_dist','numformat'], 
-       'time'  => [ 'count', 'dateformat'], 
-       'date'  => [ 'count', 'age','dateformat'], 
-       'timestamp'     => [ 'count', 'age','dateformat'], 
-       'timestamptz'   => [ 'count', 'age','dateformat'], 
-       'text'  => [ 'count','count_dist','lower','upper','substr'],
-};
-
 BLOCK class_table;
        WRAPPER html/table width='100%' style='border-top: 1px solid black';
                WRAPPER html/row;
@@ -70,7 +9,7 @@ BLOCK class_table;
                                %]<b>Name:</b>[%
                        END;
                        WRAPPER html/cell;
-                               class.findvalue('label');
+                               classname.findvalue('label');
                        END;
                END;
                WRAPPER html/row;
@@ -78,10 +17,10 @@ BLOCK class_table;
                                %]<b>Description:</b>[%
                        END;
                        WRAPPER html/cell;
-                               class.findvalue('description');
+                               classname.findvalue('description');
                        END;
                END;
-               IF class.findvalue('@fact-table') == 'true' AND CGI.param('create_stage2') != 1;
+               IF classname.findvalue('@fact-table') == 'true' AND CGI.param('create_stage2') != 1;
                        WRAPPER html/row;
                                WRAPPER html/cell align="right";
                                        %]<b>Actions:</b>[%
@@ -100,7 +39,7 @@ BLOCK class_table;
                                WRAPPER html/cell;
                                        q = 'select * from reporter.stage2 ' _
                                                'where pub is true or owner = ' _ DBI.quote(user.id());
-                                       FOR r IN DBI.query(q);
+                                       FOR r = DBI.query(q);
                                                INCLUDE anchor
                                                        href="stage2?id=" _ r.id
                                                        content=utils.JSON2perl(r.params).templatename;
@@ -120,7 +59,7 @@ END;
 
 
 BLOCK class_fields;
-       FOR f IN class.findnodes('fields/field');
+       FOR f = classname.findnodes('fields/field');
                WRAPPER html/row;
                        WRAPPER html/cell align="right";
                                f.findvalue('label');
@@ -146,15 +85,15 @@ BLOCK class_detail;
 
        INCLUDE class_fields;
 
-       IF class.findvalue('@fact-table') == 'true' AND nosub != 1;
+       IF classname.findvalue('@fact-table') == 'true' AND nosub != 1;
                WRAPPER html/row;
                        WRAPPER html/cell align="right";
                                %]<b>Report Dimensions<br>and Attributes:</b>[%
                        END;
                        WRAPPER html/cell;
-                               incs = class.findnodes('links/link/@field');
+                               incs = classname.findnodes('links/link/@field');
 
-                               FOR dim IN incs;
+                               FOR dim = incs;
                                        link_xpath = '/reporter/tables/table[@id="' _ fact_table _'"]'_
                                                                                '/links/link[@field="' _ dim.value() _ '"]/@table';
                                        logme(link_xpath);
@@ -166,7 +105,7 @@ BLOCK class_detail;
                                                        
                                        dim_def = config.findnodes(dim_xpath);
 
-                                       INCLUDE class_table class = dim_def;
+                                       INCLUDE class_table classname = dim_def;
                                END;
                        END;
                END;
index 56edd33..e5a6f2b 100644 (file)
@@ -193,7 +193,9 @@ BLOCK fact_tables;
                        INCLUDE html/cell content='Fact table' nowrap='nowrap' col='lightgray' style='border:solid gray 1px;';
                        INCLUDE html/cell content='Description' nowrap='nowrap' col='lightgray' style='border:solid gray 1px;';
                END;
-               FOR tab IN config.findnodes("/reporter/tables/table[@fact-table='true']");
+
+               fact_table_xpath = "/reporter/tables/table[@fact-table='true']";
+               FOR tab = config.findnodes(fact_table_xpath);
                        tid = tab.findvalue('@id');
                        bg='lightblue';
                        IF loop.count % 2;
@@ -203,7 +205,7 @@ BLOCK fact_tables;
                                p = utils.JSON2perl( template.params );
                                INCLUDE html/cell
                                        col=bg
-                                       content=link(content=tab.findvalue('tablename'),href="stage1?id=$tid") style='border:solid gray 1px;';
+                                       content=link(content=tab.findvalue('label'),href="stage1?id=$tid") style='border:solid gray 1px;';
                                INCLUDE html/cell content=tab.findvalue('description') style='border:solid gray 1px;';
                        END;
                END;
diff --git a/Open-ILS/src/reporter/templates/html/body b/Open-ILS/src/reporter/templates/html/body
new file mode 100644 (file)
index 0000000..9593f6d
--- /dev/null
@@ -0,0 +1,25 @@
+[%
+
+       #--------------------------------------------------------------------------------- 
+       #html/body: <body>...</body> element for HTML pages
+       #
+       # ARGS:
+       #
+       # content         # body content
+       #--------------------------------------------------------------------------------- 
+
+       "<body";
+
+       IF onload; " onload='$onload'"; END;
+       IF onclick; " onclick='$onclick'"; END;
+       IF style; " style='$style'"; END;
+       IF class; " class='$class'"; END;
+       IF id; " id='$id'"; END;
+
+       ">";
+
+       content;
+
+       "</body>";
+
+%]
diff --git a/Open-ILS/src/reporter/templates/html/cell b/Open-ILS/src/reporter/templates/html/cell
new file mode 100644 (file)
index 0000000..890ab80
--- /dev/null
@@ -0,0 +1,24 @@
+[%# html/cell: an empty and orphaned HTML table cell, <td> . . . </td>
+  # ARGS:
+  #    col         # background colour (default: none)
+  #     align       # horizontal alignment (default: none)
+  #     valign      # vertical alignment (default: none)
+  #     colspan     # span multiple columns (defualt: none)
+  #     rowspan     # span multiple rows (defualt: none)
+  #     content     # box content
+-%]
+
+<td
+    [%- IF width %] width="[% width %]"[% END %]
+    [%- IF col %] bgcolor="[% col %]"[% END %]
+    [%- IF colspan %] colspan="[% colspan %]"[% END %]
+    [%- IF rowspan %] rowspan="[% rowspan %]"[% END %]
+    [%- IF  align %] align="[% align %]"[% END %]
+    [%- IF  class %] class="[% class %]"[% END %]
+    [%- IF  id %] id="[% id %]"[% END %]
+    [%- IF  valign %] valign="[% valign %]"[% END %]
+    [%- IF  nowrap %] nowrap="[% nowrap %]"[% END %]
+    [%- IF  style %] style="[% style %]"[% END %]>
+[%- content -%]
+</td>
+
diff --git a/Open-ILS/src/reporter/templates/html/html b/Open-ILS/src/reporter/templates/html/html
new file mode 100644 (file)
index 0000000..20f0245
--- /dev/null
@@ -0,0 +1,6 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd>
+
+<html>
+[% "\n" _ content _ "\n" %]
+</html>
diff --git a/Open-ILS/src/reporter/templates/html/row b/Open-ILS/src/reporter/templates/html/row
new file mode 100644 (file)
index 0000000..a1ecd26
--- /dev/null
@@ -0,0 +1,17 @@
+[%# row: an empty and orphaned HTML table row, <tr> . . . </tr>
+  # ARGS:
+  #     col         # background colour (default: none)
+  #     valign      # vertical alignment (default: none)
+  #     align       # horizontal alignment (default: none)
+  #     content     # box content
+-%]
+
+<tr
+    [%- IF col     %] bgcolor="[% col %]"[%     END %]
+    [%- IF id     %] id="[% id %]"[%     END %]
+    [%- IF align   %] align="[% align %]"[%     END %]
+    [%- IF class  %] class="[% class %]"[%   END %]
+    [%- IF valign  %] valign="[% valign %]"[%   END %]>
+[%- content -%]
+</tr>
+
diff --git a/Open-ILS/src/reporter/templates/html/table b/Open-ILS/src/reporter/templates/html/table
new file mode 100644 (file)
index 0000000..7b00959
--- /dev/null
@@ -0,0 +1,18 @@
+[%# table: an empty HTML table <table> . . . </table>
+  # ARGS:
+  #     border      # border width (default: 0)
+  #    col         # background colour (default: none)
+  #     width       # width of box (default: none, grow to fit content) 
+  #     pad         # cellpadding (default: none)
+  #     cellspace       # cellspacing (default: none)
+  #     content     # box content
+-%]
+<table border="[% border or 0 %]"
+       [%- IF col %] bgcolor="[% col %]"[% END %]
+       [%- IF width %] width="[% width %]"[% END %]
+       [%- IF pad.defined %] cellpadding="[% pad %]"[% END %]
+       [%- IF class %] class="[% class %]"[% END %]
+       [%- IF id %] id="[% id %]"[% END %]
+       [%- IF cellspace.defined %] cellspacing="[% cellspace %]"[% END %]>
+[%- content -%]
+</table>
index d7a0804..185be26 100644 (file)
@@ -5,6 +5,8 @@
 </style>
 [%
 
+PROCESS utils;
+
 BLOCK logme_block;
        "\n\t<!-- " _ x _ " -->\n";
 END;
@@ -17,15 +19,17 @@ USE WebSession;
 USE utils = WebUtils;
 USE config = XML.LibXML(config_xml, expand_xinclude => 1);
 
+
 dir = '/reporter/setup/files/' _ stage_dir;
 dir = config.findvalue(dir);
 
+dbdriver = config.findvalue('/reporter/setup/database/driver');
 dbname = config.findvalue('/reporter/setup/database/name');
 dbhost = config.findvalue('/reporter/setup/database/host');
 d_u = config.findvalue('/reporter/setup/database/user');
 d_p = config.findvalue('/reporter/setup/database/password');
 
-dsn = "dbi:Pg:dbname=" _ dbname _';host=' _ dbhost;
+dsn = "dbi:" _ dbdriver _ ":dbname=" _ dbname _';host=' _ dbhost;
 
 logme([dsn,d_u,d_p]);
 
index 82c8f15..8aed7c2 100644 (file)
@@ -47,7 +47,7 @@ BLOCK one_stage1;
        fact_table = table.findvalue('@id');
        logme(fact_table);
 
-       INCLUDE class_table class=table;
+       INCLUDE class_table classname=table;
 
        INCLUDE stage2_new IF CGI.param('create_stage2') == 1;
 
@@ -59,14 +59,14 @@ END;
 BLOCK all_stage1;
        '<ul>';
 
-       FOR tab IN config.findnodes("//tables/table[@fact-table='true']");
+       FOR tab = config.findnodes("/reporter/tables/table[@fact-table='true']");
 
                fact_table = tab.findvalue("@id");
                logme("Fact Table is $fact_table");
 
                '<li>';
 
-               INCLUDE class_table class=tab;
+               INCLUDE class_table classname=tab;
 
                IF loop.count != loop.size;
                '<hr>';
@@ -116,9 +116,10 @@ BLOCK stage2_new;
                INCLUDE widget_selector tableid=fact_table columns=config.findnodes(col_xpath) force=1;
        END;
 
-       dim_xpath = "/reporter/tables/table[@id='$fact_table']/links/link/@table";
-       FOR dim_table IN config.findnodes(dim_xpath);
-               dim_table = dim_table.value();
+       dim_xpath = "/reporter/tables/table[@id='$fact_table']/links/link";
+       FOR dim_link = config.findnodes(dim_xpath);
+               dim_table = dim_link.findvalue('@table');
+               link_id = dim_link.findvalue('@id');
                dimension = config.findnodes("/reporter/tables/table[@id='$dim_table']");
 
                '<br/><br/>';
@@ -138,12 +139,17 @@ BLOCK stage2_new;
                        WRAPPER html/row;
                                WRAPPER html/cell colspan=2;
                                        # checkbox input here ...
-                                       INCLUDE checkbox name="filter" value=dim_table checked=1;
+                                       INCLUDE checkbox name="filter" value=link_id checked=1;
+
+                                       link_label_xpath = '../../fields/field[@name="' _ dim_link.findvalue('@field') _ '"]/label';
+                                       dim_link.findvalue(link_label_xpath);
+
+                                       ' -- ';
                                        dimension.findvalue('label');
                                        ' Dimension';
                                END;
                        END;
-                       INCLUDE widget_selector tableid=dim_table;
+                       INCLUDE widget_selector tableid=link_id;
                END;
        END;
 
index 3928e7c..0bd913e 100644 (file)
@@ -41,7 +41,7 @@ BLOCK save_stage2;
        owner = user.id();
 
        p_obj = {};
-       FOR p IN CGI.param();
+       FOR p = CGI.param();
 
                logme([p,CGI.param(p)]);
 
@@ -52,9 +52,9 @@ BLOCK save_stage2;
                p4 = parts.3;
                
                IF p4
-                       AND (CGI.param("$p1:$p2:$p3") == p4)
-                       AND (CGI.param("$p1:$p2").list.grep(p3).size > 0)
-                       AND (CGI.param("$p1").list.grep(p2).size > 0);
+                       AND (CGI.param("$p1").list.grep("^$p2$").size > 0)
+                       AND (CGI.param("$p1:$p2").list.grep("^$p3$").size > 0)
+                       AND (CGI.param("$p1:$p2:$p3").list.grep("^$p4$").size > 0);
 
                        p_obj.$p1.$p2.$p3.$p4 = CGI.param(p);
 
@@ -113,19 +113,43 @@ BLOCK view_stage2;
                        INCLUDE html/cell colspan=4 content="<b>Filterable Attributes:</b>";
                END;
 
-               FOR f_table IN params.filter.keys;
-                       logme([f_table]);
+               core_table = params.stage1;
+
+               tables = params.filter.keys;
+               tables.unshift(core_table);
+               tables = tables.unique;
+
+               FOR t = tables;
+                       logme(['table id or link id', t]);
+
+                       f_table = INCLUDE find_table_id id=t;
+
                        table = config.findnodes( "/reporter/tables/table[@id='$f_table']");
                        WRAPPER html/row;
                                INCLUDE html/cell;
-                               INCLUDE html/cell colspan=4 align='left' content=table.findvalue( 'label' );
+                               WRAPPER html/cell colspan=4 align='left';
+
+                                       IF t != f_table;
+                                               link_xpath = '//*[@id="' _ t _ '"]';
+                                               dim_link = config.findnodes(link_xpath);
+
+                                               link_label_xpath =
+                                                       '../../fields/field[@name="' _
+                                                       dim_link.findvalue('@field') _ '"]/label';
+                                               dim_link.findvalue(link_label_xpath);
+
+                                               ' -- ';
+                                       END;
+
+                                       table.findvalue( 'label' );
+                               END;
                        END;
 
-                       FOR f_field IN params.filter.$f_table.keys;
+                       FOR f_field = params.filter.$t.keys;
                                logme([f_table,f_field]);
-                               FOR f_fam IN params.filter.$f_table.$f_field.keys;
+                               FOR f_fam = params.filter.$t.$f_field.keys;
                                        logme([f_table,f_field,f_fam]);
-                                       f_widget = params.filter.$f_table.$f_field.$f_fam;
+                                       f_widget = params.filter.$t.$f_field.$f_fam;
                                        logme([f_table,f_field,f_fam,f_widget]);
 
                                        WRAPPER html/row;
@@ -150,20 +174,44 @@ BLOCK view_stage2;
                        INCLUDE html/cell colspan=5 content="<b>Attributes Available for Output</b>";
                END;
 
-               FOR f_table IN params.dims.keys;
+               tables = params.dims.keys;
+               tables.unshift(core_table);
+               tables = tables.unique;
+
+               FOR t = tables;
+
+                       f_table = INCLUDE find_table_id id=t;
+                       
                        table = config.findnodes( "/reporter/tables/table[@id='$f_table']");
                        tname = table.findvalue( "label" );
                        tdesc = table.findvalue( "desription" );
 
-                       NEXT IF table.findvalue('@fact-table') == 'true';
+                       #NEXT IF table.findvalue('@fact-table') == 'true';
                        
                        WRAPPER html/row;
                                INCLUDE html/cell;
-                               INCLUDE html/cell colspan=4 align='left' content=tname;
+                               WRAPPER html/cell colspan=4 align='left';
+                                       IF t != f_table;
+                                               link_xpath = '//*[@id="' _ t _ '"]';
+                                               dim_link = config.findnodes(link_xpath);
+
+                                               link_label_xpath =
+                                                       '../../fields/field[@name="' _
+                                                       dim_link.findvalue('@field') _ '"]/label';
+                                               dim_link.findvalue(link_label_xpath);
+
+                                               ' -- ';
+                                       END;
+                                       tname;
+                               END;
                        END;
 
 
-                       FOR field IN table.findnodes('fields/field[not(@primary) or @primary != "true"]');
+                       FOR field = table.findnodes('fields/field[not(@primary) or @primary != "true"]');
+                               link_test = '../../links/link[@field="' _ field.findvalue('@name') _ '"]';
+                               logme(['link_test',link_test]);
+                               NEXT IF field.findnodes( link_test );
+
                                fname = field.findvalue( "label" );
                                fdesc = field.findvalue( "desription" );
 
@@ -180,9 +228,6 @@ BLOCK view_stage2;
 END;
 
 
-
-
-
 BLOCK run_stage2;
        logme(tmpl.params);
        params = utils.JSON2perl( tmpl.params );
@@ -209,18 +254,38 @@ BLOCK run_stage2;
                                INCLUDE html/cell colspan=4 content="<b>Filterable Attributes:</b>";
                        END;
 
-                       FOR f_table IN params.filter.keys;
+                       core_table = params.stage1;
+
+                       tables = params.filter.keys;
+                       tables.unshift(core_table);
+                       tables = tables.unique;
+
+                       FOR t = tables;
+                               f_table = INCLUDE find_table_id id=t;
                                logme([f_table]);
                                table = config.findnodes( "/reporter/tables/table[@id='$f_table']");
                                WRAPPER html/row;
-                                       INCLUDE html/cell colspan=3 align='left' content=table.findvalue( 'label' );
+                                       WRAPPER html/cell colspan=3 align='left';
+                                               IF t != f_table;
+                                                       link_xpath = '//*[@id="' _ t _ '"]';
+                                                       dim_link = config.findnodes(link_xpath);
+
+                                                       link_label_xpath =
+                                                               '../../fields/field[@name="' _
+                                                               dim_link.findvalue('@field') _ '"]/label';
+                                                       dim_link.findvalue(link_label_xpath);
+
+                                                       ' -- ';
+                                               END;
+                                               table.findvalue( 'label' );
+                                       END;
                                END;
 
-                               FOR f_field IN params.filter.$f_table.keys;
+                               FOR f_field = params.filter.$t.keys;
                                        logme([f_table,f_field]);
-                                       FOR f_fam IN params.filter.$f_table.$f_field.keys;
+                                       FOR f_fam = params.filter.$t.$f_field.keys;
                                                logme([f_table,f_field,f_fam]);
-                                               f_widget = params.filter.$f_table.$f_field.$f_fam;
+                                               f_widget = params.filter.$t.$f_field.$f_fam;
                                                logme([f_table,f_field,f_fam,f_widget]);
 
                                                WRAPPER html/row;
@@ -239,7 +304,7 @@ BLOCK run_stage2;
                                                                                widgetname = widget.findvalue('@name');
                                                                                famname = fam.findvalue('@name');
        
-                                                                               input_prefix = "filter:$classname:$fieldname:$famname:$widgetname";
+                                                                               input_prefix = "filter:$t:$fieldname:$famname:$widgetname";
        
                                                                                INCLUDE $w_file widget_family=fam;
                                                                CATCH;
@@ -259,66 +324,39 @@ BLOCK run_stage2;
                                INCLUDE html/cell colspan=4 content="<b>Attributes Available for Output</b>";
                        END;
 
-                       FOR f_table IN params.dims.keys;
-                               table = config.findnodes( "/reporter/tables/table[@id='$f_table']");
-                               classname = table.findvalue( "@id" );
-                               tname = table.findvalue( "label" );
-                               tdesc = table.findvalue( "desription" );
-                       
-                               WRAPPER html/row;
-                                       INCLUDE html/cell colspan=4 align='left' content=tname;
-                               END;
+                       table = config.findnodes( "/reporter/tables/table[@id='$core_table']" );
+                       classname = table.findvalue( "@id" );
+                       tname = table.findvalue( "label" );
+                       tdesc = table.findvalue( "desription" );
 
-                               IF loop.first;
-                                       pkey_field = table.findnodes('fields/field[@primary = "true"]');
-                                       pid = pkey_field.findvalue('@name');
-                                       plabel = pkey_field.findvalue('label');
-                                       
-                                       WRAPPER html/row;
-                                               WRAPPER html/cell align='right';
-                                                       INCLUDE checkbox checked='checked' name="output:$classname:$pid" value="include";
-                                                       INCLUDE hidden name="xform:type:$classname:$pid" value="count_dist";
-                                               END;
-                                               INCLUDE html/cell align='right' content="Per group count of $plabel";
-                                               INCLUDE html/cell align='center';
-                                       END;
+                       WRAPPER html/row;
+                               INCLUDE html/cell colspan=4 align='left' content=tname;
+                       END;
+
+                       pkey_field = table.findnodes('fields/field[@primary = "true"]');
+                       pid = pkey_field.findvalue('@name');
+                       plabel = pkey_field.findvalue('label');
+               
+                       WRAPPER html/row;
+                               WRAPPER html/cell align='right';
+                                       INCLUDE checkbox checked='checked' name="output:$classname:$pid" value="include";
+                                       INCLUDE hidden name="xform:type:$classname:$pid" value="count_dist";
                                END;
+                               INCLUDE html/cell align='right' content="Per group count of $plabel";
+                               INCLUDE html/cell align='center';
+                       END;
 
-                               fields_xpath =
-                                       'fields/field[not(@primary) or @primary != "true"]';
-                               FOR field IN table.findnodes(fields_xpath);
-                                       link_test = '../../links/link[@field="' _ field.findvalue('@name') _ '"]';
-                                       logme(['link_test',link_test]);
-                                       NEXT IF field.findnodes( link_test );
-       
-                                       fname = field.findvalue( "label" );
-                                       fid = field.findvalue( "@name" );
 
-                                       WRAPPER html/row;
+                       tables = params.dims.keys;
+                       tables.unshift(core_table);
+                       tables = tables.unique;
 
-                                               WRAPPER html/cell align='right';
-                                                       INCLUDE checkbox name="output:$classname:$fid" value="include";
-                                               END;
-                                               INCLUDE html/cell align='right' content=fname;
-                                               WRAPPER html/cell align='center';
-                                                       'Output Transformation: ';
-                                                       dtype = field.findvalue('@datatype');
-                                                       WRAPPER select name="xform:type:$classname:$fid";
-                                                               INCLUDE option value='' content='None' selected=1;
-                                                               FOR xform IN dtype_xform_map.$dtype;
-                                                                       xform_label = dtype_xforms.$xform.label;
-                                                                       IF dtype_xforms.$xform.param;
-                                                                               xform_label = "$xform_label (*)";
-                                                                       END;
-                                                                       INCLUDE option value=xform content=xform_label;
-                                                               END;
-                                                       END;
-                                                       '<br/>';
-                                                       '<small><super>*</super>Output Tranformation Parameter: </small>';
-                                                       INCLUDE text name="xform:param:$classname:$fid";
-                                               END;
-                                       END;
-                               END;
+                       core_done = 0;
+
+                       FOR f_table = tables;
+                               noheader = 0;
+                               noheader = 1 IF f_table == core_table;
+                               INCLUDE show_filter_atts;
                        END;
                END;
        
@@ -330,4 +368,67 @@ BLOCK run_stage2;
        END;
 END;
 
+BLOCK show_filter_atts;
+       t = f_table;
+       f_table = INCLUDE find_table_id id=t;
+       table = config.findnodes( "/reporter/tables/table[@id='$f_table']");
+       classname = table.findvalue( "@id" );
+       tname = table.findvalue( "label" );
+       tdesc = table.findvalue( "desription" );
+
+       IF ! noheader;
+               WRAPPER html/row;
+                       WRAPPER html/cell colspan=4 align='left';
+                               IF t != f_table;
+                                       link_xpath = '//*[@id="' _ t _ '"]';
+                                       dim_link = config.findnodes(link_xpath);
+
+                                       link_label_xpath =
+                                               '../../fields/field[@name="' _
+                                               dim_link.findvalue('@field') _ '"]/label';
+                                       dim_link.findvalue(link_label_xpath);
+
+                                       ' -- ';
+                               END;
+                               tname;
+                       END;
+               END;
+       END;
+
+       fields_xpath = 'fields/field[not(@primary) or @primary != "true"]';
+
+       FOR field = table.findnodes(fields_xpath);
+               link_test = '../../links/link[@field="' _ field.findvalue('@name') _ '"]';
+               logme(['link_test',link_test]);
+               NEXT IF field.findnodes( link_test );
+
+               fname = field.findvalue( "label" );
+               fid = field.findvalue( "@name" );
+
+               WRAPPER html/row;
+
+                       WRAPPER html/cell align='right';
+                               INCLUDE checkbox name="output:$t:$fid" value="include";
+                       END;
+                       INCLUDE html/cell align='right' content=fname;
+                       WRAPPER html/cell align='center';
+                               'Output Transformation: ';
+                               dtype = field.findvalue('@datatype');
+                               WRAPPER select name="xform:type:$t:$fid";
+                                       INCLUDE option value='' content='None' selected=1;
+                                       FOR xform = dtype_xform_map.$dtype;
+                                               xform_label = dtype_xforms.$xform.label;
+                                               IF dtype_xforms.$xform.param;
+                                                       xform_label = "$xform_label (*)";
+                                               END;
+                                               INCLUDE option value=xform content=xform_label;
+                                       END;
+                               END;
+                               '<br/>';
+                               '<small><super>*</super>Output Tranformation Parameter: </small>';
+                               INCLUDE text name="xform:param:$t:$fid";
+                       END;
+               END;
+       END;
+END;
 %]
index 16fd804..06a2c8a 100644 (file)
@@ -53,7 +53,7 @@ BLOCK schedule_stage3;
                        INCLUDE option value='months' content='Month(s)';
                END;
 
-               FOR p IN CGI.param();
+               FOR p = CGI.param();
                        NEXT IF p == 'action';
                        NEXT IF p == 'runtime';
                        INCLUDE hidden name=p value=CGI.param(p);
@@ -74,7 +74,7 @@ BLOCK save_stage3;
        owner = user.id();
 
        p_obj = {};
-       FOR p IN CGI.param();
+       FOR p = CGI.param();
 
                logme([p,CGI.param(p)]);
 
diff --git a/Open-ILS/src/reporter/templates/utils b/Open-ILS/src/reporter/templates/utils
new file mode 100644 (file)
index 0000000..f983766
--- /dev/null
@@ -0,0 +1,18 @@
+[%
+
+BLOCK find_table_id;
+        xpath = '//*[@id="' _ id _ '"]';
+        node = config.findnodes(xpath);
+        IF node;
+                t = node.findvalue('@table');
+                IF t;
+                        xpath = '//*[@id="' _ t _ '"]';
+                        node = config.findnodes(xpath);
+                END;
+                node.findvalue('@id');
+        ELSE;
+                logme(['arrrrrgggg!!!',id]);
+        END;
+END;
+
+%]
index 1d09eb8..a470b5b 100644 (file)
@@ -1,33 +1,45 @@
 [%
 
 PROCESS inputs;
+PROCESS utils;
 
 BLOCK widget_selector;
 
        logme("widget_selector called for table $tableid");
 
+       linkid = tableid;
+       tableid = INCLUDE find_table_id id=tableid;
+
+       choose_base_cols = 0;
+
        #   if we got some columns, use them. if not, get all non-primary columns
        IF ! columns;
+               columns = [];
+               choose_base_cols = 1;
                columns_xpath =
                        '/reporter/tables/table[@id="' _ tableid _
-                       '"]/fields/field[not(@primary) or @primary!="true"]'
-               columns = config.findnodes(columns_xpath);
-               logme("widget_selector had to grab columns for table $tableid!");
+                       '"]/fields/field[not(@primary) or @primary!="true"]';
+               FOR c = config.findnodes(columns_xpath);
+                       link_text_xpath = "../../links/link[@field='" _ c.findvalue('@name') _ "']";
+                       NEXT IF c.findnodes(link_text_xpath);
+                       columns.push(c);
+               END;
+               logme("widget_selector had to grab columns for table $tableid linked from $linkid");
        END;
 
        column_input_type="checkbox";
-       IF force;
+       IF force && ! choose_base_cols;
                column_input_type="hidden";
        END;
 
-       FOR column IN columns;
+       FOR column = columns;
                column_name=column.findvalue('@name');
 
                WRAPPER html/row;
                        WRAPPER html/cell valign='top' align='right';
                                # checkbox for column filter here ...
                                INCLUDE $column_input_type
-                                       name="filter:$tableid"
+                                       name="filter:$linkid"
                                        value=column_name
                                        checked=1; 
                                column.findvalue('label');
@@ -49,7 +61,7 @@ BLOCK widget_selector;
                                widget_fams = config.findnodes(col_widget_fams_xpath);
 
                                '<UL>';
-                               FOR fam IN widget_fams;
+                               FOR fam = widget_fams;
 
                                        fam_input = 'radio';
                                        IF loop.size == 1;
@@ -65,12 +77,12 @@ BLOCK widget_selector;
                                        # radio for widget family here ...
                                        '<LI>';
                                        INCLUDE $fam_input
-                                               name="filter:$tableid:$column_name"
+                                               name="filter:$linkid:$column_name"
                                                value= fam_name;
                                        fam.findvalue('label');
                                        '<UL>';
                                        
-                                       FOR widget IN fam.findnodes('widget');
+                                       FOR widget = fam.findnodes('widget');
 
                                                fam_input = 'radio';
                                                IF loop.size == 1;
@@ -86,7 +98,7 @@ BLOCK widget_selector;
                                                # radio for widget here ...
                                                '<LI>';
                                                INCLUDE $fam_input
-                                                       name="filter:$tableid:$column_name:$fam_name"
+                                                       name="filter:$linkid:$column_name:$fam_name"
                                                        value= widget_name;
                                                widget.findvalue('label');
                                                '</LI>';
index c012756..6e9019c 100644 (file)
@@ -2,7 +2,7 @@
 
 PROCESS inputs;
 
-q = 'SELECT * FROM ' _ table.findvalue('tablename') _ ' ORDER BY ' _ fieldname _ ';';
+q = 'SELECT DISTINCT ' _ fieldname _ ' FROM ' _ table.findvalue('tablename') _ ' ORDER BY ' _ fieldname _ ';';
 
 WRAPPER select name=input_prefix multi=1 size=3;
        FOR f = DBI.query(q);
index a4930ae..c395419 100644 (file)
@@ -1,7 +1,10 @@
 
+DROP SCHEMA stats CASCADE;
 DROP SCHEMA config CASCADE;
 
 BEGIN;
+CREATE SCHEMA stats;
+
 CREATE SCHEMA config;
 COMMENT ON SCHEMA config IS $$
 /*
index 64f7be3..04e361a 100644 (file)
@@ -10,6 +10,10 @@ CREATE OR REPLACE FUNCTION public.call_number_dewey( TEXT ) RETURNS TEXT AS $$
        }
 $$ LANGUAGE 'plperl' STRICT IMMUTABLE;
 
+CREATE OR REPLACE FUNCTION public.call_number_dewey( TEXT, INT ) RETURNS TEXT AS $$
+       SELECT SUBSTRING(call_number_dewey($1) FROM 1 FOR $2);
+$$ LANGUAGE SQL STRICT IMMUTABLE;
+
 CREATE OR REPLACE FUNCTION public.first_agg ( anyelement, anyelement ) RETURNS anyelement AS $$
        SELECT CASE WHEN $1 IS NULL THEN $2 ELSE $1 END;
 $$ LANGUAGE SQL STABLE;
index 0a569f5..38c4733 100644 (file)
@@ -133,4 +133,24 @@ CREATE TABLE asset.call_number_note (
 );
 
 
+CREATE VIEW stats.fleshed_copy AS 
+        SELECT  cp.*,
+                cn.label as call_number_label,
+                cn.owning_lib,
+                rd.item_lang,
+                rd.item_type,
+                rd.item_form
+        FROM    asset.copy cp
+                JOIN asset.call_number cn ON (cp.call_number = cn.id)
+                JOIN metabib.rec_descriptor rd ON (rd.record = cn.record);
+
+CREATE VIEW stats.fleshed_call_number AS 
+        SELECT  cn.*,
+                rd.item_lang,
+                rd.item_type,
+                rd.item_form
+        FROM    asset.call_number cn
+                JOIN metabib.rec_descriptor rd ON (rd.record = cn.record);
+
+
 COMMIT;
index 7363f40..223240d 100755 (executable)
--- a/config.sh
+++ b/config.sh
@@ -50,6 +50,7 @@ function buildConfig {
        TEMPLATEDIR="$PREFIX/var/templates";
        CIRCRULESDIR="$PREFIX/var/circ";
        XSLDIR="$PREFIX/var/xsl";
+       REPORTERDIR="$PREFIX/var/reporter";
        TMP="$(pwd)/.tmp";
 
        prompt "Web domain for OPAC in Staff Client [$NEW_OPAC_URL] "
@@ -91,6 +92,9 @@ function buildConfig {
        prompt "Bootstrapping Database Password [$DBPW] "
        read X; if [ ! -z "$X" ]; then DBPW="$X"; fi;
 
+       prompt "Reporter Template Directory [$REPORTERDIR] "
+       read X; if [ ! -z "$X" ]; then REPORTERDIR="$X"; fi;
+
        writeConfig;
 }
 
index 91a99ea..aa60575 100755 (executable)
@@ -119,7 +119,7 @@ function runInstall {
                MAKE="make $verbose APXS2=$APXS2 PREFIX=$PREFIX TMP=$TMP APR_HEADERS=$APR_HEADERS \
                        APACHE2_HEADERS=$APACHE2_HEADERS LIBXML2_HEADERS=$LIBXML2_HEADERS \
                        BINDIR=$BINDIR LIBDIR=$LIBDIR PERLDIR=$PERLDIR INCLUDEDIR=$INCLUDEDIR \
-                       WEBDIR=$WEBDIR TEMPLATEDIR=$TEMPLATEDIR ETCDIR=$ETCDIR \
+                       WEBDIR=$WEBDIR TEMPLATEDIR=$TEMPLATEDIR ETCDIR=$ETCDIR REPORTERDIR=$REPORTERDIR\
                        OPENSRFDIR=$OPENSRFDIR OPENILSDIR=$OPENILSDIR EVERGREENDIR=$EVERGREENDIR \
                        CIRCRULESDIR=$CIRCRULESDIR CGIDIR=$CGIDIR DBDRVR=$DBDRVR DBHOST=$DBHOST \
                        DBNAME=$DBNAME DBUSER=$DBUSER DBPW=$DBPW XSLDIR=$XSLDIR NEW_OPAC_URL=$NEW_OPAC_URL \
@@ -181,8 +181,11 @@ function runInstall {
                        "openils_web" )
                                if building; then $MAKE -C "$OPENILSDIR" "mod_xmlbuilder"; fi;
                                if building; then $MAKE -C "$OPENILSDIR" "mod_ils_rest_gateway"; fi;
-                               if installing; then $MAKE -C "$OPENILSDIR" "web-install"; fi;
-                               if installing; then $MAKE -C "$OPENILSDIR" "cgi-bootstrap"; fi;
+                               if installing; then
+                                       $MAKE -C "$OPENILSDIR" "web-install";
+                                       $MAKE -C "$OPENILSDIR" "cgi-bootstrap";
+                                       $MAKE -C "$OPENILSDIR" "reporter-install";
+                               fi;
                                ;;
 
                        "openils_marcdumper" )
@@ -196,6 +199,11 @@ function runInstall {
                                fi;
                                ;;
 
+                       "openils_reporter" )
+                               if installing; then 
+                                       $MAKE -C "$OPENILSDIR" "reporter-install";
+                               fi;
+                               ;;
 
                        # Evergreen ---