| File: | C4/Creators/Batch.pm |
| Coverage: | 13.8% |
| line | stmt | bran | cond | sub | time | code |
|---|---|---|---|---|---|---|
| 1 | package C4::Creators::Batch; | |||||
| 2 | ||||||
| 3 | 6 6 6 | 900 40 131 | use strict; | |||
| 4 | 6 6 6 | 75 18 202 | use warnings; | |||
| 5 | ||||||
| 6 | 6 6 6 | 1208 4190 92 | use autouse 'Data::Dumper' => qw(Dumper); | |||
| 7 | ||||||
| 8 | 6 6 6 | 1224 46 128 | use C4::Context; | |||
| 9 | 6 6 6 | 59 28 701 | use C4::Debug; | |||
| 10 | ||||||
| 11 | BEGIN { | |||||
| 12 | 6 6 6 6 | 432 5208 84 442 | use version; our $VERSION = qv('1.0.0_1'); | |||
| 13 | } | |||||
| 14 | ||||||
| 15 | sub _check_params { | |||||
| 16 | 0 | my $given_params = {}; | ||||
| 17 | 0 | my $exit_code = 0; | ||||
| 18 | 0 | my @valid_template_params = ( | ||||
| 19 | 'label_id', | |||||
| 20 | 'batch_id', | |||||
| 21 | 'item_number', | |||||
| 22 | 'card_number', | |||||
| 23 | 'branch_code', | |||||
| 24 | 'creator', | |||||
| 25 | ); | |||||
| 26 | 0 | if (scalar(@_) >1) { | ||||
| 27 | 0 | $given_params = {@_}; | ||||
| 28 | 0 0 | foreach my $key (keys %{$given_params}) { | ||||
| 29 | 0 | if (!(grep m/$key/, @valid_template_params)) { | ||||
| 30 | 0 | warn sprintf('Unrecognized parameter type of "%s".', $key); | ||||
| 31 | 0 | $exit_code = 1; | ||||
| 32 | } | |||||
| 33 | } | |||||
| 34 | } | |||||
| 35 | else { | |||||
| 36 | 0 | if (!(grep m/$_/, @valid_template_params)) { | ||||
| 37 | 0 | warn sprintf('Unrecognized parameter type of %s', $_); | ||||
| 38 | 0 | $exit_code = 1; | ||||
| 39 | } | |||||
| 40 | } | |||||
| 41 | 0 | return $exit_code; | ||||
| 42 | } | |||||
| 43 | ||||||
| 44 | sub new { | |||||
| 45 | 0 | my ($invocant) = shift; | ||||
| 46 | 0 | my $type = ref($invocant) || $invocant; | ||||
| 47 | 0 | my $self = { | ||||
| 48 | batch_id => 0, | |||||
| 49 | items => [], | |||||
| 50 | branch_code => 'NB', | |||||
| 51 | batch_stat => 0, # False if any data has changed and the db has not been updated | |||||
| 52 | @_, | |||||
| 53 | }; | |||||
| 54 | 0 | my $sth = C4::Context->dbh->prepare("SELECT MAX(batch_id) FROM creator_batches;"); | ||||
| 55 | 0 | $sth->execute(); | ||||
| 56 | 0 | my $batch_id = $sth->fetchrow_array; | ||||
| 57 | 0 | $self->{'batch_id'} = ++$batch_id unless $self->{'batch_id'} != 0; # this allows batch_id to be passed in for individual label printing | ||||
| 58 | 0 | bless ($self, $type); | ||||
| 59 | 0 | return $self; | ||||
| 60 | } | |||||
| 61 | ||||||
| 62 | sub add_item { | |||||
| 63 | 0 | my $self = shift; | ||||
| 64 | 0 | my $number = shift; | ||||
| 65 | 0 | ref($self) =~ m/C4::(.+)::.+$/; | ||||
| 66 | 0 | my $number_type = ($1 eq 'Patroncards' ? 'borrower_number' : 'item_number'); | ||||
| 67 | 0 | my $query = "INSERT INTO creator_batches (batch_id, $number_type, branch_code, creator) VALUES (?,?,?,?);"; | ||||
| 68 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
| 69 | # $sth->{'TraceLevel'} = 3; | |||||
| 70 | 0 | $sth->execute($self->{'batch_id'}, $number, $self->{'branch_code'}, $1); | ||||
| 71 | 0 | if ($sth->err) { | ||||
| 72 | 0 | warn sprintf('Database returned the following error on attempted INSERT: %s', $sth->errstr); | ||||
| 73 | 0 | return -1; | ||||
| 74 | } | |||||
| 75 | 0 | $query = "SELECT max(label_id) FROM creator_batches WHERE batch_id=? AND $number_type=? AND branch_code=?;"; | ||||
| 76 | 0 | my $sth1 = C4::Context->dbh->prepare($query); | ||||
| 77 | 0 | $sth1->execute($self->{'batch_id'}, $number, $self->{'branch_code'}); | ||||
| 78 | 0 | my $label_id = $sth1->fetchrow_array; | ||||
| 79 | 0 0 | push (@{$self->{'items'}}, {$number_type => $number, label_id => $label_id}); | ||||
| 80 | 0 | $self->{'batch_stat'} = 1; | ||||
| 81 | 0 | return 0; | ||||
| 82 | } | |||||
| 83 | ||||||
| 84 | sub get_attr { | |||||
| 85 | 0 | my $self = shift; | ||||
| 86 | 0 | return $self->{$_[0]}; | ||||
| 87 | } | |||||
| 88 | ||||||
| 89 | sub remove_item { | |||||
| 90 | 0 | my $self = shift; | ||||
| 91 | 0 | my $label_id = shift; | ||||
| 92 | 0 | my $query = "DELETE FROM creator_batches WHERE label_id=? AND batch_id=?;"; | ||||
| 93 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
| 94 | # $sth->{'TraceLevel'} = 3; | |||||
| 95 | 0 | $sth->execute($label_id, $self->{'batch_id'}); | ||||
| 96 | 0 | if ($sth->err) { | ||||
| 97 | 0 | warn sprintf('Database returned the following error on attempted DELETE: %s', $sth->errstr); | ||||
| 98 | 0 | return -1; | ||||
| 99 | } | |||||
| 100 | 0 0 0 0 | @{$self->{'items'}} = grep{$_->{'label_id'} != $label_id} @{$self->{'items'}}; | ||||
| 101 | 0 | $self->{'batch_stat'} = 1; | ||||
| 102 | 0 | return 0; | ||||
| 103 | } | |||||
| 104 | ||||||
| 105 | # FIXME: This method is effectively useless the way the current add_item method is written. Ideally, the items should be added to the object | |||||
| 106 | # and then the save method called. This does not work well in practice due to the inability to pass objects accross cgi script calls. | |||||
| 107 | # I'm leaving it here because it should be here and for consistency's sake and once memcached support is fully implimented this should be as well. -cnighswonger | |||||
| 108 | # | |||||
| 109 | #=head2 $batch->save() | |||||
| 110 | # | |||||
| 111 | # Invoking the I<save> method attempts to insert the batch into the database. The method returns | |||||
| 112 | # the new record batch_id upon success and -1 upon failure (This avoids conflicting with a record | |||||
| 113 | # batch_id of 1). Errors are logged to the Apache log. | |||||
| 114 | # | |||||
| 115 | # example: | |||||
| 116 | # my $exitstat = $batch->save(); # to save the record behind the $batch object | |||||
| 117 | # | |||||
| 118 | #=cut | |||||
| 119 | # | |||||
| 120 | #sub save { | |||||
| 121 | # my $self = shift; | |||||
| 122 | # foreach my $item_number (@{$self->{'items'}}) { | |||||
| 123 | # my $query = "INSERT INTO creator_batches (batch_id, item_number, branch_code) VALUES (?,?,?);"; | |||||
| 124 | # my $sth1 = C4::Context->dbh->prepare($query); | |||||
| 125 | # $sth1->execute($self->{'batch_id'}, $item_number->{'item_number'}, $self->{'branch_code'}); | |||||
| 126 | # if ($sth1->err) { | |||||
| 127 | # warn sprintf('Database returned the following error on attempted INSERT: %s', $sth1->errstr); | |||||
| 128 | # return -1; | |||||
| 129 | # } | |||||
| 130 | # $self->{'batch_stat'} = 1; | |||||
| 131 | # return $self->{'batch_id'}; | |||||
| 132 | # } | |||||
| 133 | #} | |||||
| 134 | ||||||
| 135 | sub retrieve { | |||||
| 136 | 0 | my $invocant = shift; | ||||
| 137 | 0 | my %opts = @_; | ||||
| 138 | 0 | my $type = ref($invocant) || $invocant; | ||||
| 139 | 0 | $type =~ m/C4::(.+)::.+$/; | ||||
| 140 | 0 | my $number_type = ($1 eq 'Patroncards' ? 'borrower_number' : 'item_number'); | ||||
| 141 | 0 | my $record_flag = 0; | ||||
| 142 | 0 | my $query = "SELECT * FROM creator_batches WHERE batch_id = ? ORDER BY label_id"; | ||||
| 143 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
| 144 | # $sth->{'TraceLevel'} = 3; | |||||
| 145 | 0 | $sth->execute($opts{'batch_id'}); | ||||
| 146 | 0 | my $self = { | ||||
| 147 | batch_id => $opts{'batch_id'}, | |||||
| 148 | items => [], | |||||
| 149 | }; | |||||
| 150 | 0 | while (my $record = $sth->fetchrow_hashref) { | ||||
| 151 | 0 | $self->{'branch_code'} = $record->{'branch_code'}; | ||||
| 152 | 0 | $self->{'creator'} = $record->{'creator'}; | ||||
| 153 | 0 0 | push (@{$self->{'items'}}, {$number_type => $record->{$number_type}, label_id => $record->{'label_id'}}); | ||||
| 154 | 0 | $record_flag = 1; # true if one or more rows were retrieved | ||||
| 155 | } | |||||
| 156 | 0 | return -2 if $record_flag == 0; # a hackish sort of way of indicating no such record exists | ||||
| 157 | 0 | if ($sth->err) { | ||||
| 158 | 0 | warn sprintf('Database returned the following error on attempted SELECT: %s', $sth->errstr); | ||||
| 159 | 0 | return -1; | ||||
| 160 | } | |||||
| 161 | 0 | $self->{'batch_stat'} = 1; | ||||
| 162 | 0 | bless ($self, $type); | ||||
| 163 | 0 | return $self; | ||||
| 164 | } | |||||
| 165 | ||||||
| 166 | sub delete { | |||||
| 167 | 0 | my $self = {}; | ||||
| 168 | 0 | my %opts = (); | ||||
| 169 | 0 | my $call_type = ''; | ||||
| 170 | 0 | my @query_params = (); | ||||
| 171 | 0 | if (ref($_[0])) { | ||||
| 172 | 0 | $self = shift; # check to see if this is a method call | ||||
| 173 | 0 | $call_type = 'C4::Labels::Batch->delete'; # seems hackish | ||||
| 174 | 0 | @query_params = ($self->{'batch_id'}, $self->{'branch_code'}); | ||||
| 175 | } | |||||
| 176 | else { | |||||
| 177 | 0 | shift @_; | ||||
| 178 | 0 | %opts = @_; | ||||
| 179 | 0 | $call_type = 'C4::Labels::Batch::delete'; | ||||
| 180 | 0 | @query_params = ($opts{'batch_id'}, $opts{'branch_code'}); | ||||
| 181 | } | |||||
| 182 | 0 | if ($query_params[0] eq '') { # If there is no template id then we cannot delete it | ||||
| 183 | 0 | warn sprintf('%s : Cannot delete batch as the batch id is invalid or non-existent.', $call_type); | ||||
| 184 | 0 | return -1; | ||||
| 185 | } | |||||
| 186 | 0 | my $query = "DELETE FROM creator_batches WHERE batch_id = ? AND branch_code =?"; | ||||
| 187 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
| 188 | # $sth->{'TraceLevel'} = 3; | |||||
| 189 | 0 | $sth->execute(@query_params); | ||||
| 190 | 0 | if ($sth->err) { | ||||
| 191 | 0 | warn sprintf('%s : Database returned the following error on attempted INSERT: %s', $call_type, $sth->errstr); | ||||
| 192 | 0 | return -1; | ||||
| 193 | } | |||||
| 194 | 0 | return 0; | ||||
| 195 | } | |||||
| 196 | ||||||
| 197 | sub remove_duplicates { | |||||
| 198 | 0 | my $self = shift; | ||||
| 199 | 0 | my %seen=(); | ||||
| 200 | 0 | my $query = "DELETE FROM creator_batches WHERE label_id = ?;"; # ORDER BY timestamp ASC LIMIT ?;"; | ||||
| 201 | 0 | my $sth = C4::Context->dbh->prepare($query); | ||||
| 202 | 0 0 0 | my @duplicate_items = grep{$seen{$_->{'item_number'}}++} @{$self->{'items'}}; | ||||
| 203 | 0 | foreach my $item (@duplicate_items) { | ||||
| 204 | 0 | $sth->execute($item->{'label_id'}); | ||||
| 205 | 0 | if ($sth->err) { | ||||
| 206 | 0 | warn sprintf('Database returned the following error on attempted DELETE for label_id %s: %s', $item->{'label_id'}, $sth->errstr); | ||||
| 207 | 0 | return -1; | ||||
| 208 | } | |||||
| 209 | 0 | $sth->finish(); # Per DBI.pm docs: "If execute() is called on a statement handle that's still active ($sth->{Active} is true) then it should effectively call finish() to tidy up the previous execution results before starting this new execution." | ||||
| 210 | 0 0 0 0 | @{$self->{'items'}} = grep{$_->{'label_id'} != $item->{'label_id'}} @{$self->{'items'}}; # the correct label/item must be removed from the current batch object as well; this should be done *after* each sql DELETE in case the DELETE fails | ||||
| 211 | } | |||||
| 212 | 0 | return scalar(@duplicate_items); | ||||
| 213 | } | |||||
| 214 | ||||||
| 215 | 1; | |||||