From a192e57f00d6123a8d11fc52ef8f13e51f99e5a5 Mon Sep 17 00:00:00 2001 From: Chris Nighswonger Date: Tue, 1 Sep 2009 12:33:52 -0400 Subject: [PATCH] [15/40] Initial work on label batch edit interface. --- C4/Labels/Batch.pm | 115 ++++++-------- C4/Labels/Lib.pm | 150 ++++++++++++++++-- .../includes/tools-labels-batches-toolbar.inc | 85 ---------- .../en/modules/labels/label-edit-batch.tmpl | 127 +++++++++++++++ .../prog/en/modules/labels/label-manage.tmpl | 16 +- labels/label-edit-batch.pl | 92 +++++++++++ labels/label-manage.pl | 13 +- 7 files changed, 426 insertions(+), 172 deletions(-) delete mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/tools-labels-batches-toolbar.inc create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tmpl create mode 100755 labels/label-edit-batch.pl diff --git a/C4/Labels/Batch.pm b/C4/Labels/Batch.pm index 0d72f3290d..8972032fff 100644 --- a/C4/Labels/Batch.pm +++ b/C4/Labels/Batch.pm @@ -101,9 +101,18 @@ sub new { sub add_item { my $self = shift; - my $item_num = shift; - push (@{$self->{'items'}}, $item_num); + my $item_number = shift; + my $query = "INSERT INTO labels_batches (batch_id, item_number, branch_code) VALUES (?,?,?);"; + my $sth = C4::Context->dbh->prepare($query); +# $sth->{'TraceLevel'} = 3; + $sth->execute($item_number, $self->{'batch_id'}); + if ($sth->err) { + syslog("LOG_ERR", "C4::Labels::Batch->add_item : Database returned the following error on attempted INSERT: %s", $sth->errstr); + return -1; + } + push (@{$self->{'items'}}, $item_number); $self->{'batch_stat'} = 0; + return 0; } =head2 $batch->get_attr() @@ -120,34 +129,36 @@ sub get_attr { return $self->{$_[0]}; } -=head2 $batch->delete_item() +=head2 $batch->remove_item() - Invoking the I method will delete the supplied item from the batch object. + Invoking the I method will remove the supplied item from the batch object. example: - $batch->delete_item(); + $batch->remove_item(); =cut -sub delete_item { +sub remove_item { my $self = shift; - my $item_num = shift; - my $index = 0; - ++$index until $$self->{'items'}[$index] == $item_num or $index > $#$self->{'items'}; - if ($index > $#$self->{'items'}) { - syslog("LOG_ERR", "C4::Labels::Batch->delete_item : Item %s does not exist in batch %s.", $item_num, $self->{'batch_id'}); + my $item_number = shift; + my $query = "DELETE FROM labels_batches WHERE item_number=? AND batch_id=?;"; + my $sth = C4::Context->dbh->prepare($query); +# $sth->{'TraceLevel'} = 3; + $sth->execute($item_number, $self->{'batch_id'}); + if ($sth->err) { + syslog("LOG_ERR", "C4::Labels::Batch->remove_item : Database returned the following error on attempted DELETE: %s", $sth->errstr); return -1; } - delete ($$self->{'items'}[$index]); - $self->{'batch_stat'} = 0; + @{$self->{'items'}} = grep{$_ != $item_number} @{$self->{'items'}}; + $self->{'batch_stat'} = 1; + return 0; } =head2 $batch->save() - Invoking the I method attempts to insert the batch into the database if the batch is new and - update the existing batch record if the batch exists. The method returns the new record batch_id upon - success and -1 upon failure (This avoids conflicting with a record batch_id of 1). Errors are - logged to the syslog. + Invoking the I method attempts to insert the batch into the database. The method returns + the new record batch_id upon success and -1 upon failure (This avoids conflicting with a record + batch_id of 1). Errors are logged to the syslog. example: my $exitstat = $batch->save(); # to save the record behind the $batch object @@ -156,53 +167,31 @@ sub delete_item { sub save { my $self = shift; - if ($self->{'batch_id'} > 0) { - foreach my $item_number (@$self->{'items'}) { - my $query = "UPDATE labels_batches SET item_number=?, branch_code=? WHERE batch_id=?;"; - warn "DEBUG: Updating: $query\n" if $debug; - my $sth->C4::Context->dbh->prepare($query); - $sth->execute($item_number, $self->{'branch_code'}, $self->{'batch_id'}); - if ($sth->err) { - syslog("LOG_ERR", "C4::Labels::Batch->save : Database returned the following error on attempted UPDATE: %s", $sth->errstr); - return -1; - } - } - } - else { - my $sth1 = C4::Context->dbh->prepare("SELECT MAX(batch_id) FROM labels_batches;"); - $sth1->execute(); - my $batch_id = $sth1->fetchrow_array; - $self->{'batch_id'} = $batch_id++; - foreach my $item_number (@$self->{'items'}) { - my $query = "INSERT INTO labels_batches (batch_id, item_number, branch_code) VALUES (?,?,?);"; - warn "DEBUG: Inserting: $query\n" if $debug; - my $sth->C4::Context->dbh->prepare($query); - $sth->execute($self->{'batch_id'}, $item_number, $self->{'branch_code'}); - if ($sth->err) { - syslog("LOG_ERR", "C4::Labels::Batch->save : Database returned the following error on attempted INSERT: %s", $sth->errstr); - return -1; - } - return $self->{'batch_id'}; + my $sth = C4::Context->dbh->prepare("SELECT MAX(batch_id) FROM labels_batches;"); + $sth->execute(); + my $batch_id = $sth->fetchrow_array; + $self->{'batch_id'} = $batch_id++; + foreach my $item_number (@{$self->{'items'}}) { + my $query = "INSERT INTO labels_batches (batch_id, item_number, branch_code) VALUES (?,?,?);"; + my $sth1 = C4::Context->dbh->prepare($query); + $sth1->execute($self->{'batch_id'}, $item_number, $self->{'branch_code'}); + if ($sth1->err) { + syslog("LOG_ERR", "C4::Labels::Batch->save : Database returned the following error on attempted INSERT: %s", $sth1->errstr); + return -1; } + $self->{'batch_stat'} = 1; + return $self->{'batch_id'}; } - $self->{'batch_stat'} = 1; } -=head2 C4::Labels::Template->retrieve(template_id) +=head2 C4::Labels::Batch->retrieve(batch_id) - Invoking the I method constructs a new template object containing the current values for template_id. The method returns - a new object upon success and 1 upon failure. Errors are logged to the syslog. Two further options may be accessed. See the example - below for further description. + Invoking the I method constructs a new batch object containing the current values for batch_id. The method returns + a new object upon success and 1 upon failure. Errors are logged to the syslog. examples: - my $template = C4::Labels::Template->retrieve(template_id => 1); # Retrieves template record 1 and returns an object containing the record - - my $template = C4::Labels::Template->retrieve(template_id => 1, convert => 1); # Retrieves template record 1, converts the units to points, - and returns an object containing the record - - my $template = C4::Labels::Template->retrieve(template_id => 1, profile_id => profile_id); # Retrieves template record 1, converts the units - to points, applies the given profile id, and returns an object containing the record + my $batch = C4::Labels::Batch->retrieve(batch_id => 1); # Retrieves batch record 1 and returns an object containing the record =cut @@ -230,7 +219,7 @@ sub retrieve { return $self; } -=head2 C4::Labels::Batch->delete(batch_id => batch_id) | $batch->delete() +=head2 C4::Labels::Batch->delete(batch_id => batch_id) | $batch->delete() Invoking the delete method attempts to delete the batch from the database. The method returns 0 upon success and 1 upon failure. Errors are logged to the syslog. @@ -245,25 +234,25 @@ sub delete { my $self = {}; my %opts = (); my $call_type = ''; - my $query_param = ''; + my @query_params = (); if (ref($_[0])) { $self = shift; # check to see if this is a method call $call_type = 'C4::Labels::Batch->delete'; - $query_param = $self->{'batch_id'}; + @query_params = ($self->{'batch_id'}, $self->{'branch_code'}); } else { %opts = @_; $call_type = 'C4::Labels::Batch::delete'; - $query_param = $opts{'batch_id'}; + @query_params = ($opts{'batch_id'}, $opts{'branch_code'}); } - if ($query_param eq '') { # If there is no template id then we cannot delete it + if ($query_params[0] eq '') { # If there is no template id then we cannot delete it syslog("LOG_ERR", "%s : Cannot delete batch as the batch id is invalid or non-existant.", $call_type); return -1; } - my $query = "DELETE FROM labels_batches WHERE batch_id = ?"; + my $query = "DELETE FROM labels_batches WHERE batch_id = ? AND branch_code =?"; my $sth = C4::Context->dbh->prepare($query); # $sth->{'TraceLevel'} = 3; - $sth->execute($query_param); + $sth->execute(@query_params); if ($sth->err) { syslog("LOG_ERR", "%s : Database returned the following error on attempted INSERT: %s", $call_type, $sth->errstr); return -1; diff --git a/C4/Labels/Lib.pm b/C4/Labels/Lib.pm index 8ab8aa95a9..ead58fcfeb 100644 --- a/C4/Labels/Lib.pm +++ b/C4/Labels/Lib.pm @@ -32,6 +32,7 @@ BEGIN { get_all_layouts get_all_profiles get_batch_summary + get_label_summary get_barcode_types get_label_types get_font_types @@ -39,10 +40,39 @@ BEGIN { get_column_names get_table_names get_unit_values + html_table SELECT ); } +#=head2 C4::Labels::Lib::_SELECT() +# +# This function returns a recordset upon success and 1 upon failure. Errors are logged to the syslog. +# +# 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) { + syslog("LOG_ERR", "C4::Labels::Lib::get_single_field_value : 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}, @@ -226,6 +256,48 @@ sub get_batch_summary { 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 syslog. + 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_number (@{$params{'items'}}) { + $label_number++; + $sth->execute($item_number, $params{'batch_id'}); + if ($sth->err) { + syslog("LOG_ERR", "C4::Labels::Lib::get_label_summary : 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*[^.]$//; # strip off ugly trailing chars... but not periods + $record->{'title'} =~ s/\W*$//; # strip off ugly trailing chars + $record->{'title'} = ' ' . $record->{'title'} . ''; + $label_summary->{'_summary'} = $record->{'title'} . " | " . $record->{'author'}; + $label_summary->{'_item_type'} = $record->{'itemtype'}; + $label_summary->{'_barcode'} = $record->{'barcode'}; + $label_summary->{'_item_number'} = $item_number; + 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. @@ -331,32 +403,76 @@ 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; + my $table = []; + my $fields = []; + my @db_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; + POPULATE_HEADER: + foreach my $db_column (@$headers) { + my @key = keys %$db_column; + if ($key[0] eq 'select' ) { + push (@db_columns, $key[0]); + $$fields[$col_index] = {hidden => 0, select_field => 0, field_name => ($key[0]), field_label => $db_column->{$key[0]}{'label'}}; + $select_value = $db_column->{$key[0]}{'value'} + # do stuff.... + } + else { + push (@db_columns, $key[0]); + $$fields[$col_index] = {hidden => 0, select_field => 0, field_name => ($key[0]), field_label => $db_column->{$key[0]}}; + } + $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) { +# my $element_id = 0; + POPULATE_ROW: + foreach my $db_column (@db_columns) { + if (grep {$db_column eq $_} keys %$db_row) { +# $element_id = $db_row->{$db_column} if $db_column =~ m/id/; + $$fields[$col_index] = {hidden => 0, select_field => 0, field_name => ($db_column . "_tbl"), field_value => $db_row->{$db_column}}; + $col_index++; + next POPULATE_ROW; + } + elsif ($db_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"}); + $db_row->{$db_column} = $$record_set[0]{$1}; + next POPULATE_ROW; + } + elsif ($db_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; diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-labels-batches-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-labels-batches-toolbar.inc deleted file mode 100644 index 52946b5488..0000000000 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-labels-batches-toolbar.inc +++ /dev/null @@ -1,85 +0,0 @@ - -
- -
- -
- -
- diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tmpl new file mode 100644 index 0000000000..4914d2165d --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-edit-batch.tmpl @@ -0,0 +1,127 @@ + + Koha › Tools › Labels › Manage Label Batches + + + + + + + +
+
+
+
+ +
+
+
Current Branch:
+
+

Items in batch number

+ + + + + + + + + + + + + + + + + + + + +
">
+
+
+ + + + +
+
+ +
+
+ WARNING: An error was encountered and Please have your system administrator check the syslog for details. +
+
+ +
+
+
+
+ +
+
+ diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-manage.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-manage.tmpl index c86d274009..7ca155ea7f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-manage.tmpl +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/labels/label-manage.tmpl @@ -38,10 +38,22 @@ }; }; function selected_layout() { + if (document.layouts.action.length) { for (i=0;i."); return (-1); @@ -89,12 +101,12 @@ -
+
diff --git a/labels/label-edit-batch.pl b/labels/label-edit-batch.pl new file mode 100755 index 0000000000..52c1d25ffa --- /dev/null +++ b/labels/label-edit-batch.pl @@ -0,0 +1,92 @@ +#!/usr/bin/perl +# +# Copyright 2006 Katipo Communications. +# Parts Copyright 2009 Foundations Bible College. +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use strict; +use warnings; +use vars qw($debug); + +use Sys::Syslog qw(syslog); +use Switch qw(Perl6); +use CGI; +use HTML::Template::Pro; +use Data::Dumper; + +use C4::Auth; +use C4::Output; +use C4::Context; +use C4::Branch qw(get_branch_code_from_name); +use C4::Debug; +use C4::Labels::Lib 1.000000 qw(get_label_summary html_table); +use C4::Labels::Batch 1.000000; + +my $cgi = new CGI; +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => "labels/label-edit-batch.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { catalogue => 1 }, + debug => 1, + } +); +my $err = 0; +my $errstr = undef; +my $db_rows = {}; +my $batch = undef; +my $display_columns = [ {_label_number => 'Label Number'}, + {_summary => 'Summary'}, + {_item_type => 'Item Type'}, + {_barcode => 'Barcode'}, + {select => {label => 'Select', value => '_item_number'}}, + ]; +my $op = $cgi->param('op') || undef; +my $label_id = $cgi->param('label_id') || undef; +my $batch_id = $cgi->param('element_id') || $cgi->param('batch_id') || undef; +my $branch_code = get_branch_code_from_name($template->param('LoginBranchname')); + +if ($op eq 'remove') { + $batch = C4::Labels::Batch->retrieve(batch_id => $batch_id); + $err = $batch->remove_item($label_id); + $errstr = "item $label_id was not removed." if $err; +} +elsif ($op eq 'delete') { + $err = C4::Labels::Batch::delete(batch_id => $batch_id, branch_code => $branch_code); + $errstr = "batch $batch_id was not deleted." if $err; +} +else{ + $batch = C4::Labels::Batch->retrieve(batch_id => $batch_id); +} + +my $items = $batch->get_attr('items'); +$db_rows = get_label_summary(items => $items, batch_id => $batch_id); + +my $table = html_table($display_columns, $db_rows); + +$template->param( err => $err, + errstr => $errstr, + ) if ($err ne 0); +$template->param( + op => $op, + batch_id => $batch_id, + table_loop => $table, +); + +output_html_with_http_headers $cgi, $cookie, $template->output; diff --git a/labels/label-manage.pl b/labels/label-manage.pl index 3d155b02b1..00e3795b97 100755 --- a/labels/label-manage.pl +++ b/labels/label-manage.pl @@ -59,22 +59,22 @@ my $display_columns = { layout => [ #db column => display column {barcode_type => 'Barcode Type'}, {printing_type => 'Print Type'}, {format_string => 'Fields to Print'}, - {select => 'Select'}, + {select => {label => 'Select', value => 'layout_id'}}, ], template => [ {template_id => 'Template ID'}, {template_code => 'Template Name'}, {template_desc => 'Description'}, - {select => 'Select'}, + {select => {label => 'Select', value => 'template_id'}}, ], profile => [ {profile_id => 'Profile ID'}, {printer_name => 'Printer Name'}, {paper_bin => 'Paper Bin'}, {_template_code => 'Template Name'}, # this display column does not have a corrisponding db column in the profile table, hence the underscore - {select => 'Select'}, + {select => {label => 'Select', value => 'profile_id'}}, ], batch => [ {batch_id => 'Batch ID'}, {_item_count => 'Item Count'}, - {select => 'Select'}, + {select => {label => 'Select', value => 'batch_id'}}, ], }; @@ -139,9 +139,12 @@ if ($op eq 'delete') { when 'layout' {$error = C4::Labels::Layout::delete(layout_id => $element_id); last;} when 'template' {$error = C4::Labels::Template::delete(template_id => $element_id); last;} when 'profile' {$error = C4::Labels::Profile::delete(profile_id => $element_id); last;} - when 'batch' {$error = C4::Labels::Batch::delete(batch_id => $element_id); last;} + when 'batch' {$error = C4::Labels::Batch::delete(batch_id => $element_id, branch_code => $branch_code); last;} default {} # FIXME: Some error trapping code } +# FIXME: this does not allow us to process any errors +# print $cgi->redirect("label-manage.pl?label_element=$label_element"); +# exit; } given ($label_element) { -- 2.39.5