Bug 3706 Label templates/layouts do not save properly
[koha_gimpoz] / C4 / Labels / Lib.pm
index 1aec793..2229c60 100644 (file)
@@ -19,7 +19,7 @@ package C4::Labels::Lib;
 
 use strict;
 use warnings;
-use Sys::Syslog qw(syslog);
+
 use Data::Dumper;
 
 use C4::Context;
@@ -31,17 +31,48 @@ BEGIN {
     our @EXPORT_OK = qw(get_all_templates
                         get_all_layouts
                         get_all_profiles
+                        get_batch_summary
+                        get_label_summary
                         get_barcode_types
                         get_label_types
                         get_font_types
                         get_text_justification_types
+                        get_label_output_formats
                         get_column_names
                         get_table_names
                         get_unit_values
-                        SELECT
+                        html_table
     );
 }
 
+#=head2 C4::Labels::Lib::_SELECT()
+#
+#    This function returns a recordset upon success and 1 upon failure. Errors are logged to the Apache log.
+#
+#    examples:
+#
+#        my $field_value = _SELECT(field_name, table_name, condition);
+#
+#=cut
+
+sub _SELECT {
+    my @params = @_;
+    my $query = "SELECT $params[0] FROM $params[1]";
+    $params[2] ? $query .= " WHERE $params[2];" : $query .= ';';
+    my $sth = C4::Context->dbh->prepare($query);
+#    $sth->{'TraceLevel'} = 3;
+    $sth->execute();
+    if ($sth->err) {
+        warn sprintf('Database returned the following error: %s', $sth->errstr);
+        return 1;
+    }
+    my $record_set = [];
+    while (my $row = $sth->fetchrow_hashref()) {
+        push(@$record_set, $row);
+    }
+    return $record_set;
+}
+
 my $barcode_types = [
     {type => 'CODE39',          name => 'Code 39',              desc => 'Translates the characters 0-9, A-Z, \'-\', \'*\', \'+\', \'$\', \'%\', \'/\', \'.\' and \' \' to a barcode pattern.',                                  selected => 0},
     {type => 'CODE39MOD',       name => 'Code 39 + Modulo43',   desc => 'Translates the characters 0-9, A-Z, \'-\', \'*\', \'+\', \'$\', \'%\', \'/\', \'.\' and \' \' to a barcode pattern. Encodes Mod 43 checksum.',         selected => 0},
@@ -95,24 +126,31 @@ my $unit_values = [
     {type       => 'CM',         desc    => 'SI Centimeters',     value   => 28.3464567,        selected => 0},
 ];
 
+my $label_output_formats = [
+    {type       => 'pdf',       desc    => 'PDF File'},
+    {type       => 'csv',       desc    => 'CSV File'},
+];
+
 =head2 C4::Labels::Lib::get_all_templates()
 
-    This function returns a reference to a hash containing all templates upon success and 1 upon failure. Errors are logged to the syslog.
+    This function returns a reference to a hash containing all templates upon success and 1 upon failure. Errors are logged to the Apache log.
 
     examples:
 
-        my $templates = C4::Labels::Lib::get_all_templates();
+        my $templates = get_all_templates();
 
 =cut
 
 sub get_all_templates {
+    my %params = @_;
     my @templates = ();
-    my $query = "SELECT * FROM labels_templates;";
+    my $query = "SELECT " . ($params{'field_list'} ? $params{'field_list'} : '*') . " FROM labels_templates";
+    $query .= ($params{'filter'} ? " WHERE $params{'filter'};" : ';');
     my $sth = C4::Context->dbh->prepare($query);
     $sth->execute();
     if ($sth->err) {
-        syslog("LOG_ERR", "C4::Labels::Lib::get_all_templates : Database returned the following error: %s", $sth->errstr);
-        return 1;
+        warn sprintf('Database returned the following error: %s', $sth->errstr);
+        return -1;
     }
     ADD_TEMPLATES:
     while (my $template = $sth->fetchrow_hashref) {
@@ -123,22 +161,25 @@ sub get_all_templates {
 
 =head2 C4::Labels::Lib::get_all_layouts()
 
-    This function returns a reference to a hash containing all layouts upon success and 1 upon failure. Errors are logged to the syslog.
+    This function returns a reference to a hash containing all layouts upon success and 1 upon failure. Errors are logged to the Apache log.
 
     examples:
 
-        my $layouts = C4::Labels::Lib::get_all_layouts();
+        my $layouts = get_all_layouts();
 
 =cut
 
 sub get_all_layouts {
+    my %params = @_;
     my @layouts = ();
-    my $query = "SELECT * FROM labels_layouts;";
+    #my $query = "SELECT * FROM labels_layouts;";
+    my $query = "SELECT " . ($params{'field_list'} ? $params{'field_list'} : '*') . " FROM labels_layouts";
+    $query .= ($params{'filter'} ? " WHERE $params{'filter'};" : ';');
     my $sth = C4::Context->dbh->prepare($query);
     $sth->execute();
     if ($sth->err) {
-        syslog("LOG_ERR", "C4::Labels::Lib::get_all_layouts : Database returned the following error: %s", $sth->errstr);
-        return 1;
+        warn sprintf('Database returned the following error: %s', $sth->errstr);
+        return -1;
     }
     ADD_LAYOUTS:
     while (my $layout = $sth->fetchrow_hashref) {
@@ -150,7 +191,7 @@ sub get_all_layouts {
 =head2 C4::Labels::Lib::get_all_profiles()
 
     This function returns an arrayref whose elements are hashes containing all profiles upon success and 1 upon failure. Errors are logged
-    to the syslog. Two parameters are accepted. The first limits the field(s) returned. This parameter should be string of comma separted
+    to the Apache log. Two parameters are accepted. The first limits the field(s) returned. This parameter should be string of comma separted
     fields. ie. "field_1, field_2, ...field_n" The second limits the records returned based on a string containing a valud SQL 'WHERE' filter.
     NOTE: Do not pass in the keyword 'WHERE.'
 
@@ -170,16 +211,104 @@ sub get_all_profiles {
 #    $sth->{'TraceLevel'} = 3 if $debug;
     $sth->execute();
     if ($sth->err) {
-        syslog("LOG_ERR", "C4::Labels::Lib::get_all_profiles : Database returned the following error: %s", $sth->errstr);
-        return 1;
+        warn sprintf('Database returned the following error: %s', $sth->errstr);
+        return -1;
     }
-    ADD_LAYOUTS:
+    ADD_PROFILES:
     while (my $profile = $sth->fetchrow_hashref) {
         push(@profiles, $profile);
     }
     return \@profiles;
 }
 
+=head2 C4::Labels::Lib::get_batch_summary()
+
+    This function returns an arrayref whose elements are hashes containing the batch_ids of current batches along with the item count
+    for each batch upon success and 1 upon failure. Item counts are stored under the key '_item_count' Errors are logged to the Apache log.
+    One parameter is accepted which limits the records returned based on a string containing a valud SQL 'WHERE' filter.
+    
+    NOTE: Do not pass in the keyword 'WHERE.'
+
+    examples:
+
+        my $batches = get_batch_summary();
+        my $batches = get_batch_summary(filter => filter_string);
+
+=cut
+
+sub get_batch_summary {
+    my %params = @_;
+    my @batches = ();
+    my $query = "SELECT DISTINCT batch_id FROM labels_batches";
+    $query .= ($params{'filter'} ? " WHERE $params{'filter'};" : ';');
+    my $sth = C4::Context->dbh->prepare($query);
+#    $sth->{'TraceLevel'} = 3;
+    $sth->execute();
+    if ($sth->err) {
+        warn sprintf('Database returned the following error on attempted SELECT: %s', $sth->errstr);
+        return -1;
+    }
+    ADD_BATCHES:
+    while (my $batch = $sth->fetchrow_hashref) {
+        my $query = "SELECT count(item_number) FROM labels_batches WHERE batch_id=?;";
+        my $sth1 = C4::Context->dbh->prepare($query);
+        $sth1->execute($batch->{'batch_id'});
+        if ($sth1->err) {
+            warn sprintf('Database returned the following error on attempted SELECT count: %s', $sth1->errstr);
+            return -1;
+        }
+        my $count = $sth1->fetchrow_arrayref;
+        $batch->{'_item_count'} = @$count[0];
+        push(@batches, $batch);
+    }
+    return \@batches;
+}
+
+=head2 C4::Labels::Lib::get_label_summary()
+
+    This function returns an arrayref whose elements are hashes containing the label_ids of current labels along with the item count
+    for each label upon success and 1 upon failure. Item counts are stored under the key '_item_count' Errors are logged to the Apache log.
+    One parameter is accepted which limits the records returned based on a string containing a valud SQL 'WHERE' filter.
+    
+    NOTE: Do not pass in the keyword 'WHERE.'
+
+    examples:
+
+        my $labels = get_label_summary();
+        my $labels = get_label_summary(items => @item_list);
+
+=cut
+
+sub get_label_summary {
+    my %params = @_;
+    my $label_number = 0;
+    my @label_summaries = ();
+    my $query = "SELECT b.title, b.author, bi.itemtype, i.barcode, i.biblionumber FROM biblio AS b, biblioitems AS bi ,items AS i, labels_batches AS l WHERE itemnumber=? AND l.item_number=i.itemnumber AND i.biblioitemnumber=bi.biblioitemnumber AND bi.biblionumber=b.biblionumber AND l.batch_id=?;";
+    my $sth = C4::Context->dbh->prepare($query);
+    foreach my $item (@{$params{'items'}}) {
+        $label_number++;
+        $sth->execute($item->{'item_number'}, $params{'batch_id'});
+        if ($sth->err) {
+            warn sprintf('Database returned the following error on attempted SELECT: %s', $sth->errstr);
+            return -1;
+        }
+        my $record = $sth->fetchrow_hashref;
+        my $label_summary->{'_label_number'} = $label_number;
+        $record->{'author'} =~ s/[^\.|\w]$// if $record->{'author'};  # strip off ugly trailing chars... but not periods or word chars
+        $record->{'title'} =~ s/\W*$//;  # strip off ugly trailing chars
+        # FIXME contructing staff interface URLs should be done *much* higher up the stack - for the most part, C4 module code
+        # should not know that it's part of a web app
+        $record->{'title'} = '<a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=' . $record->{'biblionumber'} . '"> ' . $record->{'title'} . '</a>';
+        $label_summary->{'_summary'} = $record->{'title'} . " | " . ($record->{'author'} ? $record->{'author'} : 'N/A');
+        $label_summary->{'_item_type'} = $record->{'itemtype'};
+        $label_summary->{'_barcode'} = $record->{'barcode'};
+        $label_summary->{'_item_number'} = $item->{'item_number'};
+        $label_summary->{'_label_id'} = $item->{'label_id'};
+        push (@label_summaries, $label_summary);
+    }
+    return \@label_summaries;
+}
+
 =head2 C4::Labels::Lib::get_barcode_types()
 
     This function returns a reference to an array of hashes containing all barcode types along with their name and description.
@@ -251,6 +380,20 @@ sub get_unit_values {
     return $unit_values;
 }
 
+=head2 C4::Labels::Lib::get_label_output_formats()
+
+    This function returns a reference to an array of hashes containing all label output formats along with their description.
+
+    examples:
+
+        my $label_output_formats = get_label_output_formats();
+
+=cut
+
+sub get_label_output_formats {
+    return $label_output_formats;
+}
+
 =head2 C4::Labels::Lib::get_column_names($table_name)
 
 Return an arrayref of an array containing the column names of the supplied table.
@@ -285,32 +428,80 @@ sub get_table_names {
     return $table_names;
 }
 
-=head2 C4::Labels::Lib::SELECT()
+=head2 C4::Labels::Lib::html_table()
 
-    This function returns a recordset upon success and 1 upon failure. Errors are logged to the syslog.
+    This function returns an arrayref of an array of hashes contianing the supplied data formatted suitably to
+    be passed off as a T::P template parameter and used to build an html table.
 
     examples:
 
-        my $field_value = SELECT(field_name, table_name, condition);
+        my $table = html_table(header_fields, array_of_row_data);
 
 =cut
 
-sub SELECT {
-    my @params = @_;
-    my $query = "SELECT $params[0] FROM $params[1]";
-    $params[2] ? $query .= " WHERE $params[2];" : $query .= ';';
-    my $sth = C4::Context->dbh->prepare($query);
-#    $sth->{'TraceLevel'} = 3;
-    $sth->execute();
-    if ($sth->err) {
-        syslog("LOG_ERR", "C4::Labels::Lib::get_single_field_value : Database returned the following error: %s", $sth->errstr);
-        return 1;
+sub html_table {
+    my $headers = shift;
+    my $data = shift;
+    return undef if scalar(@$data) == 0;      # no need to generate a table if there is not data to display
+    my $table = [];
+    my $fields = [];
+    my @headers = ();
+    my @table_columns = ();
+    my ($row_index, $col_index) = (0,0);
+    my $cols = 0;       # number of columns to wrap on
+    my $field_count = 0;
+    my $select_value = undef;
+    my $link_field = undef;
+    POPULATE_HEADER:
+    foreach my $header (@$headers) {
+        my @key = keys %$header;
+        if ($key[0] eq 'select' ) {
+            push (@table_columns, $key[0]);
+            $$fields[$col_index] = {hidden => 0, select_field => 0, field_name => ($key[0]), field_label => $header->{$key[0]}{'label'}};
+            # do special formatting stuff....
+            $select_value = $header->{$key[0]}{'value'};
+        }
+        else {
+            # do special formatting stuff....
+            $link_field->{$key[0]} = ($header->{$key[0]}{'link_field'} == 1 ? 1 : 0);
+            push (@table_columns, $key[0]);
+            $$fields[$col_index] = {hidden => 0, select_field => 0, field_name => ($key[0]), field_label => $header->{$key[0]}{'label'}};
+        }
+        $field_count++;
+        $col_index++;
     }
-    my $record_set = [];
-    while (my $row = $sth->fetchrow_hashref()) {
-        push(@$record_set, $row);
+    $$table[$row_index] = {header_fields => $fields};
+    $cols = $col_index;
+    $field_count *= scalar(@$data);     # total fields to be displayed in the table
+    $col_index = 0;
+    $row_index++;
+    $fields = [];
+    POPULATE_TABLE:
+    foreach my $db_row (@$data) {
+        POPULATE_ROW:
+        foreach my $table_column (@table_columns) {
+            if (grep {$table_column eq $_} keys %$db_row) {
+                $$fields[$col_index] = {hidden => 0, link_field => $link_field->{$table_column}, select_field => 0, field_name => ($table_column . "_tbl"), field_value => $db_row->{$table_column}};
+                $col_index++;
+                next POPULATE_ROW;
+            }
+            elsif ($table_column =~ m/^_((.*)_(.*$))/) {   # this a special case
+                my $table_name = get_table_names($2);
+                my $record_set = _SELECT($1, @$table_name[0], $2 . "_id = " . $db_row->{$2 . "_id"});
+                $$fields[$col_index] = {hidden => 0, link_field => $link_field->{$table_column}, select_field => 0, field_name => ($table_column . "_tbl"), field_value => $$record_set[0]{$1}};
+                $col_index++;
+                next POPULATE_ROW;
+            }
+            elsif ($table_column eq 'select' ) {
+                $$fields[$col_index] = {hidden => 0, select_field => 1, field_name => 'select', field_value => $db_row->{$select_value}};
+            }
+        }
+        $$table[$row_index] = {text_fields => $fields};
+        $col_index = 0;
+        $row_index++;
+        $fields = [];
     }
-    return $record_set;
+    return $table;
 }
 
 1;