1 package C4::RotatingCollections;
3 # $Id: RotatingCollections.pm,v 0.1 2007/04/20 kylemhall
5 # This package is inteded to keep track of what library
6 # Items of a certain collection should be at.
8 # Copyright 2007 Kyle Hall
10 # This file is part of Koha.
12 # Koha is free software; you can redistribute it and/or modify it
13 # under the terms of the GNU General Public License as published by
14 # the Free Software Foundation; either version 3 of the License, or
15 # (at your option) any later version.
17 # Koha is distributed in the hope that it will be useful, but
18 # WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
22 # You should have received a copy of the GNU General Public License
23 # along with Koha; if not, see <http://www.gnu.org/licenses>.
28 use C4::Reserves qw(CheckReserves);
31 use Try::Tiny qw( catch try );
33 use vars qw(@ISA @EXPORT);
38 C4::RotatingCollections - Functions for managing rotating collections
46 @ISA = qw( Exporter );
58 RemoveItemFromCollection
61 GetCollectionItemBranches
63 isItemInThisCollection
67 =head2 CreateCollection
68 ( $success, $errorcode, $errormessage ) = CreateCollection( $title, $description );
70 Creates a new collection
73 $title: short description of the club or service
74 $description: long description of the club or service
77 $success: 1 if all database operations were successful, 0 otherwise
78 $errorCode: Code for reason of failure, good for translating errors in templates
79 $errorMessage: English description of error
83 sub CreateCollection {
84 my ( $title, $description ) = @_;
86 my $schema = Koha::Database->new()->schema();
87 my $duplicate_titles = $schema->resultset('Collection')->count({ colTitle => $title });
89 ## Check for all necessary parameters
91 return ( 0, 1, "NO_TITLE" );
92 } elsif ( $duplicate_titles ) {
93 return ( 0, 2, "DUPLICATE_TITLE" );
100 my $dbh = C4::Context->dbh;
103 $sth = $dbh->prepare(
104 "INSERT INTO collections ( colId, colTitle, colDesc )
105 VALUES ( NULL, ?, ? )"
107 $sth->execute( $title, $description ) or return ( 0, 3, $sth->errstr() );
113 =head2 UpdateCollection
115 ( $success, $errorcode, $errormessage ) = UpdateCollection( $colId, $title, $description );
120 $colId: id of the collection to be updated
121 $title: short description of the club or service
122 $description: long description of the club or service
125 $success: 1 if all database operations were successful, 0 otherwise
126 $errorCode: Code for reason of failure, good for translating errors in templates
127 $errorMessage: English description of error
131 sub UpdateCollection {
132 my ( $colId, $title, $description ) = @_;
134 my $schema = Koha::Database->new()->schema();
135 my $duplicate_titles = $schema->resultset('Collection')->count({ colTitle => $title, -not => { colId => $colId } });
137 ## Check for all necessary parameters
139 return ( 0, 1, "NO_ID" );
142 return ( 0, 2, "NO_TITLE" );
144 if ( $duplicate_titles ) {
145 return ( 0, 3, "DUPLICATE_TITLE" );
148 my $dbh = C4::Context->dbh;
150 $description ||= q{};
153 $sth = $dbh->prepare(
156 colTitle = ?, colDesc = ?
159 $sth->execute( $title, $description, $colId )
160 or return ( 0, 4, $sth->errstr() );
166 =head2 DeleteCollection
168 ( $success, $errorcode, $errormessage ) = DeleteCollection( $colId );
170 Deletes a collection of the given id
173 $colId : id of the Archetype to be deleted
176 $success: 1 if all database operations were successful, 0 otherwise
177 $errorCode: Code for reason of failure, good for translating errors in templates
178 $errorMessage: English description of error
182 sub DeleteCollection {
187 return ( 0, 1, "NO_ID" );
190 my $dbh = C4::Context->dbh;
194 $sth = $dbh->prepare("DELETE FROM collections WHERE colId = ?");
195 $sth->execute($colId) or return ( 0, 4, $sth->errstr() );
200 =head2 GetCollections
202 $collections = GetCollections();
204 Returns data about all collections
208 $results: Reference to an array of associated arrays
210 $errorCode: Code for reason of failure, good for translating errors in templates
211 $errorMessage: English description of error
217 my $dbh = C4::Context->dbh;
219 my $sth = $dbh->prepare("SELECT * FROM collections");
220 $sth->execute() or return ( 1, $sth->errstr() );
223 while ( my $row = $sth->fetchrow_hashref ) {
224 push( @results, $row );
230 =head2 GetItemsInCollection
232 ( $results, $success, $errorcode, $errormessage ) = GetItemsInCollection( $colId );
234 Returns information about the items in the given collection
237 $colId: The id of the collection
240 $results: Reference to an array of associated arrays
241 $success: 1 if all database operations were successful, 0 otherwise
242 $errorCode: Code for reason of failure, good for translating errors in templates
243 $errorMessage: English description of error
247 sub GetItemsInCollection {
252 return ( 0, 0, 1, "NO_ID" );
255 my $dbh = C4::Context->dbh;
257 my $sth = $dbh->prepare(
261 items.itemcallnumber,
263 FROM collections, collections_tracking, items, biblio
264 WHERE collections.colId = collections_tracking.colId
265 AND collections_tracking.itemnumber = items.itemnumber
266 AND items.biblionumber = biblio.biblionumber
267 AND collections.colId = ? ORDER BY biblio.title"
269 $sth->execute($colId) or return ( 0, 0, 2, $sth->errstr() );
272 while ( my $row = $sth->fetchrow_hashref ) {
273 push( @results, $row );
281 ( $colId, $colTitle, $colDesc, $colBranchcode ) = GetCollection( $colId );
283 Returns information about a collection
286 $colId: Id of the collection
288 $colId, $colTitle, $colDesc, $colBranchcode
295 my $dbh = C4::Context->dbh;
297 my ( $sth, @results );
298 $sth = $dbh->prepare("SELECT * FROM collections WHERE colId = ?");
299 $sth->execute($colId) or return 0;
301 my $row = $sth->fetchrow_hashref;
304 $$row{'colId'}, $$row{'colTitle'},
305 $$row{'colDesc'}, $$row{'colBranchcode'}
310 =head2 AddItemToCollection
312 ( $success, $errorcode, $errormessage ) = AddItemToCollection( $colId, $itemnumber );
314 Adds an item to a rotating collection.
317 $colId: Collection to add the item to.
318 $itemnumber: Item to be added to the collection
320 $success: 1 if all database operations were successful, 0 otherwise
321 $errorCode: Code for reason of failure, good for translating errors in templates
322 $errorMessage: English description of error
326 sub AddItemToCollection {
327 my ( $colId, $itemnumber ) = @_;
329 ## Check for all necessary parameters
331 return ( 0, 1, "NO_ID" );
333 if ( !$itemnumber ) {
334 return ( 0, 2, "NO_ITEM" );
337 if ( isItemInThisCollection( $itemnumber, $colId ) ) {
338 return ( 0, 2, "IN_COLLECTION" );
340 elsif ( isItemInAnyCollection($itemnumber) ) {
341 return ( 0, 3, "IN_COLLECTION_OTHER" );
344 my $dbh = C4::Context->dbh;
347 $sth = $dbh->prepare("
348 INSERT INTO collections_tracking (
353 $sth->execute( $colId, $itemnumber ) or return ( 0, 3, $sth->errstr() );
359 =head2 RemoveItemFromCollection
361 ( $success, $errorcode, $errormessage ) = RemoveItemFromCollection( $colId, $itemnumber );
363 Removes an item to a collection
366 $colId: Collection to add the item to.
367 $itemnumber: Item to be removed from collection
370 $success: 1 if all database operations were successful, 0 otherwise
371 $errorCode: Code for reason of failure, good for translating errors in templates
372 $errorMessage: English description of error
376 sub RemoveItemFromCollection {
377 my ( $colId, $itemnumber ) = @_;
379 ## Check for all necessary parameters
380 if ( !$itemnumber ) {
381 return ( 0, 2, "NO_ITEM" );
384 if ( !isItemInThisCollection( $itemnumber, $colId ) ) {
385 return ( 0, 2, "NOT_IN_COLLECTION" );
388 my $dbh = C4::Context->dbh;
391 $sth = $dbh->prepare(
392 "DELETE FROM collections_tracking
393 WHERE itemnumber = ?"
395 $sth->execute($itemnumber) or return ( 0, 3, $sth->errstr() );
400 =head2 TransferCollection
402 ( $success, $messages ) = TransferCollection( $colId, $colBranchcode );
404 Transfers a collection to another branch
407 $colId: id of the collection to be updated
408 $colBranchcode: branch where collection is moving to
411 $success: 1 if all database operations were successful, 0 otherwise
412 $messages: Arrayref of messages for user feedback
416 sub TransferCollection {
417 my ( $colId, $colBranchcode ) = @_;
419 ## Check for all necessary parameters
421 return ( 0, [{ type => 'error', code => 'NO_ID' }] );
423 if ( !$colBranchcode ) {
424 return ( 0, [{ type => 'error', code => 'NO_BRANCHCODE' }] );
427 my $dbh = C4::Context->dbh;
430 $sth = $dbh->prepare(
436 $sth->execute( $colBranchcode, $colId ) or return 0;
437 my $to_library = Koha::Libraries->find( $colBranchcode );
439 $sth = $dbh->prepare(q{
440 SELECT items.itemnumber, items.barcode FROM collections_tracking
441 LEFT JOIN items ON collections_tracking.itemnumber = items.itemnumber
442 LEFT JOIN issues ON items.itemnumber = issues.itemnumber
443 WHERE issues.borrowernumber IS NULL
444 AND collections_tracking.colId = ?
446 $sth->execute($colId) or return 0;
448 while ( my $item = $sth->fetchrow_hashref ) {
449 my $item_object = Koha::Items->find( $item->{itemnumber} );
451 $item_object->request_transfer(
454 reason => 'RotatingCollection',
457 ); # Request transfer
460 if ( $_->isa('Koha::Exceptions::Item::Transfer::InQueue') ) {
462 my $found_transfer = $_->transfer;
463 if ( $found_transfer->in_transit
464 || $found_transfer->reason eq 'Reserve' )
466 my $transfer = $item_object->request_transfer(
469 reason => "RotatingCollection",
478 item => $item_object,
479 found_transfer => $found_transfer
483 my $transfer = $item_object->request_transfer(
486 reason => "RotatingCollection",
490 ); # Replace transfer
491 # NOTE: If we just replaced a StockRotationAdvance,
492 # it will get enqueued afresh on the next cron run
495 elsif ( $_->isa('Koha::Exceptions::Item::Transfer::Limit') ) {
509 return (1, $messages);
512 =head2 GetCollectionItemBranches
514 my ( $holdingBranch, $collectionBranch ) = GetCollectionItemBranches( $itemnumber );
518 sub GetCollectionItemBranches {
519 my ($itemnumber) = @_;
521 if ( !$itemnumber ) {
525 my $dbh = C4::Context->dbh;
527 my ( $sth, @results );
528 $sth = $dbh->prepare(
529 "SELECT holdingbranch, colBranchcode FROM items, collections, collections_tracking
530 WHERE items.itemnumber = collections_tracking.itemnumber
531 AND collections.colId = collections_tracking.colId
532 AND items.itemnumber = ?"
534 $sth->execute($itemnumber);
536 my $row = $sth->fetchrow_hashref;
538 return ( $$row{'holdingbranch'}, $$row{'colBranchcode'}, );
541 =head2 isItemInThisCollection
543 $inCollection = isItemInThisCollection( $itemnumber, $colId );
547 sub isItemInThisCollection {
548 my ( $itemnumber, $colId ) = @_;
550 my $dbh = C4::Context->dbh;
552 my $sth = $dbh->prepare(
553 "SELECT COUNT(*) as inCollection FROM collections_tracking WHERE itemnumber = ? AND colId = ?"
555 $sth->execute( $itemnumber, $colId ) or return (0);
557 my $row = $sth->fetchrow_hashref;
559 return $$row{'inCollection'};
562 =head2 isItemInAnyCollection
564 my $inCollection = isItemInAnyCollection( $itemnumber );
568 sub isItemInAnyCollection {
569 my ($itemnumber) = @_;
571 my $dbh = C4::Context->dbh;
573 my $sth = $dbh->prepare(
574 "SELECT itemnumber FROM collections_tracking JOIN collections USING (colId) WHERE itemnumber = ?");
575 $sth->execute($itemnumber) or return (0);
577 my $row = $sth->fetchrow_hashref;
579 $itemnumber = $row->{itemnumber};
594 Kyle Hall <kylemhall@gmail.com>