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>.
30 use Try::Tiny qw( catch try );
32 use vars qw(@ISA @EXPORT);
37 C4::RotatingCollections - Functions for managing rotating collections
45 @ISA = qw( Exporter );
57 RemoveItemFromCollection
60 GetCollectionItemBranches
62 isItemInThisCollection
66 =head2 CreateCollection
67 ( $success, $errorcode, $errormessage ) = CreateCollection( $title, $description );
69 Creates a new collection
72 $title: short description of the club or service
73 $description: long description of the club or service
76 $success: 1 if all database operations were successful, 0 otherwise
77 $errorCode: Code for reason of failure, good for translating errors in templates
78 $errorMessage: English description of error
82 sub CreateCollection {
83 my ( $title, $description ) = @_;
85 my $schema = Koha::Database->new()->schema();
86 my $duplicate_titles = $schema->resultset('Collection')->count({ colTitle => $title });
88 ## Check for all necessary parameters
90 return ( 0, 1, "NO_TITLE" );
91 } elsif ( $duplicate_titles ) {
92 return ( 0, 2, "DUPLICATE_TITLE" );
99 my $dbh = C4::Context->dbh;
102 $sth = $dbh->prepare(
103 "INSERT INTO collections ( colId, colTitle, colDesc )
104 VALUES ( NULL, ?, ? )"
106 $sth->execute( $title, $description ) or return ( 0, 3, $sth->errstr() );
112 =head2 UpdateCollection
114 ( $success, $errorcode, $errormessage ) = UpdateCollection( $colId, $title, $description );
119 $colId: id of the collection to be updated
120 $title: short description of the club or service
121 $description: long description of the club or service
124 $success: 1 if all database operations were successful, 0 otherwise
125 $errorCode: Code for reason of failure, good for translating errors in templates
126 $errorMessage: English description of error
130 sub UpdateCollection {
131 my ( $colId, $title, $description ) = @_;
133 my $schema = Koha::Database->new()->schema();
134 my $duplicate_titles = $schema->resultset('Collection')->count({ colTitle => $title, -not => { colId => $colId } });
136 ## Check for all necessary parameters
138 return ( 0, 1, "NO_ID" );
141 return ( 0, 2, "NO_TITLE" );
143 if ( $duplicate_titles ) {
144 return ( 0, 3, "DUPLICATE_TITLE" );
147 my $dbh = C4::Context->dbh;
149 $description ||= q{};
152 $sth = $dbh->prepare(
155 colTitle = ?, colDesc = ?
158 $sth->execute( $title, $description, $colId )
159 or return ( 0, 4, $sth->errstr() );
165 =head2 DeleteCollection
167 ( $success, $errorcode, $errormessage ) = DeleteCollection( $colId );
169 Deletes a collection of the given id
172 $colId : id of the Archetype to be deleted
175 $success: 1 if all database operations were successful, 0 otherwise
176 $errorCode: Code for reason of failure, good for translating errors in templates
177 $errorMessage: English description of error
181 sub DeleteCollection {
186 return ( 0, 1, "NO_ID" );
189 my $dbh = C4::Context->dbh;
193 $sth = $dbh->prepare("DELETE FROM collections WHERE colId = ?");
194 $sth->execute($colId) or return ( 0, 4, $sth->errstr() );
199 =head2 GetCollections
201 $collections = GetCollections();
203 Returns data about all collections
207 $results: Reference to an array of associated arrays
209 $errorCode: Code for reason of failure, good for translating errors in templates
210 $errorMessage: English description of error
216 my $dbh = C4::Context->dbh;
218 my $sth = $dbh->prepare("SELECT * FROM collections");
219 $sth->execute() or return ( 1, $sth->errstr() );
222 while ( my $row = $sth->fetchrow_hashref ) {
223 push( @results, $row );
229 =head2 GetItemsInCollection
231 ( $results, $success, $errorcode, $errormessage ) = GetItemsInCollection( $colId );
233 Returns information about the items in the given collection
236 $colId: The id of the collection
239 $results: Reference to an array of associated arrays
240 $success: 1 if all database operations were successful, 0 otherwise
241 $errorCode: Code for reason of failure, good for translating errors in templates
242 $errorMessage: English description of error
246 sub GetItemsInCollection {
251 return ( 0, 0, 1, "NO_ID" );
254 my $dbh = C4::Context->dbh;
256 my $sth = $dbh->prepare(
260 items.itemcallnumber,
262 FROM collections, collections_tracking, items, biblio
263 WHERE collections.colId = collections_tracking.colId
264 AND collections_tracking.itemnumber = items.itemnumber
265 AND items.biblionumber = biblio.biblionumber
266 AND collections.colId = ? ORDER BY biblio.title"
268 $sth->execute($colId) or return ( 0, 0, 2, $sth->errstr() );
271 while ( my $row = $sth->fetchrow_hashref ) {
272 push( @results, $row );
280 ( $colId, $colTitle, $colDesc, $colBranchcode ) = GetCollection( $colId );
282 Returns information about a collection
285 $colId: Id of the collection
287 $colId, $colTitle, $colDesc, $colBranchcode
294 my $dbh = C4::Context->dbh;
296 my ( $sth, @results );
297 $sth = $dbh->prepare("SELECT * FROM collections WHERE colId = ?");
298 $sth->execute($colId) or return 0;
300 my $row = $sth->fetchrow_hashref;
303 $$row{'colId'}, $$row{'colTitle'},
304 $$row{'colDesc'}, $$row{'colBranchcode'}
309 =head2 AddItemToCollection
311 ( $success, $errorcode, $errormessage ) = AddItemToCollection( $colId, $itemnumber );
313 Adds an item to a rotating collection.
316 $colId: Collection to add the item to.
317 $itemnumber: Item to be added to the collection
319 $success: 1 if all database operations were successful, 0 otherwise
320 $errorCode: Code for reason of failure, good for translating errors in templates
321 $errorMessage: English description of error
325 sub AddItemToCollection {
326 my ( $colId, $itemnumber ) = @_;
328 ## Check for all necessary parameters
330 return ( 0, 1, "NO_ID" );
332 if ( !$itemnumber ) {
333 return ( 0, 2, "NO_ITEM" );
336 if ( isItemInThisCollection( $itemnumber, $colId ) ) {
337 return ( 0, 2, "IN_COLLECTION" );
339 elsif ( isItemInAnyCollection($itemnumber) ) {
340 return ( 0, 3, "IN_COLLECTION_OTHER" );
343 my $dbh = C4::Context->dbh;
346 $sth = $dbh->prepare("
347 INSERT INTO collections_tracking (
352 $sth->execute( $colId, $itemnumber ) or return ( 0, 3, $sth->errstr() );
358 =head2 RemoveItemFromCollection
360 ( $success, $errorcode, $errormessage ) = RemoveItemFromCollection( $colId, $itemnumber );
362 Removes an item to a collection
365 $colId: Collection to add the item to.
366 $itemnumber: Item to be removed from collection
369 $success: 1 if all database operations were successful, 0 otherwise
370 $errorCode: Code for reason of failure, good for translating errors in templates
371 $errorMessage: English description of error
375 sub RemoveItemFromCollection {
376 my ( $colId, $itemnumber ) = @_;
378 ## Check for all necessary parameters
379 if ( !$itemnumber ) {
380 return ( 0, 2, "NO_ITEM" );
383 if ( !isItemInThisCollection( $itemnumber, $colId ) ) {
384 return ( 0, 2, "NOT_IN_COLLECTION" );
387 my $dbh = C4::Context->dbh;
390 $sth = $dbh->prepare(
391 "DELETE FROM collections_tracking
392 WHERE itemnumber = ?"
394 $sth->execute($itemnumber) or return ( 0, 3, $sth->errstr() );
399 =head2 TransferCollection
401 ( $success, $messages ) = TransferCollection( $colId, $colBranchcode );
403 Transfers a collection to another branch
406 $colId: id of the collection to be updated
407 $colBranchcode: branch where collection is moving to
410 $success: 1 if all database operations were successful, 0 otherwise
411 $messages: Arrayref of messages for user feedback
415 sub TransferCollection {
416 my ( $colId, $colBranchcode ) = @_;
418 ## Check for all necessary parameters
420 return ( 0, [{ type => 'error', code => 'NO_ID' }] );
422 if ( !$colBranchcode ) {
423 return ( 0, [{ type => 'error', code => 'NO_BRANCHCODE' }] );
426 my $dbh = C4::Context->dbh;
429 $sth = $dbh->prepare(
435 $sth->execute( $colBranchcode, $colId ) or return 0;
436 my $to_library = Koha::Libraries->find( $colBranchcode );
438 $sth = $dbh->prepare(q{
439 SELECT items.itemnumber, items.barcode FROM collections_tracking
440 LEFT JOIN items ON collections_tracking.itemnumber = items.itemnumber
441 LEFT JOIN issues ON items.itemnumber = issues.itemnumber
442 WHERE issues.borrowernumber IS NULL
443 AND collections_tracking.colId = ?
445 $sth->execute($colId) or return 0;
447 while ( my $item = $sth->fetchrow_hashref ) {
448 my $item_object = Koha::Items->find( $item->{itemnumber} );
450 $item_object->request_transfer(
453 reason => 'RotatingCollection',
456 ); # Request transfer
459 if ( $_->isa('Koha::Exceptions::Item::Transfer::InQueue') ) {
461 my $found_transfer = $_->transfer;
462 if ( $found_transfer->in_transit
463 || $found_transfer->reason eq 'Reserve' )
465 my $transfer = $item_object->request_transfer(
468 reason => "RotatingCollection",
477 item => $item_object,
478 found_transfer => $found_transfer
482 my $transfer = $item_object->request_transfer(
485 reason => "RotatingCollection",
489 ); # Replace transfer
490 # NOTE: If we just replaced a StockRotationAdvance,
491 # it will get enqueued afresh on the next cron run
494 elsif ( $_->isa('Koha::Exceptions::Item::Transfer::Limit') ) {
508 return (1, $messages);
511 =head2 GetCollectionItemBranches
513 my ( $holdingBranch, $collectionBranch ) = GetCollectionItemBranches( $itemnumber );
517 sub GetCollectionItemBranches {
518 my ($itemnumber) = @_;
520 if ( !$itemnumber ) {
524 my $dbh = C4::Context->dbh;
526 my ( $sth, @results );
527 $sth = $dbh->prepare(
528 "SELECT holdingbranch, colBranchcode FROM items, collections, collections_tracking
529 WHERE items.itemnumber = collections_tracking.itemnumber
530 AND collections.colId = collections_tracking.colId
531 AND items.itemnumber = ?"
533 $sth->execute($itemnumber);
535 my $row = $sth->fetchrow_hashref;
537 return ( $$row{'holdingbranch'}, $$row{'colBranchcode'}, );
540 =head2 isItemInThisCollection
542 $inCollection = isItemInThisCollection( $itemnumber, $colId );
546 sub isItemInThisCollection {
547 my ( $itemnumber, $colId ) = @_;
549 my $dbh = C4::Context->dbh;
551 my $sth = $dbh->prepare(
552 "SELECT COUNT(*) as inCollection FROM collections_tracking WHERE itemnumber = ? AND colId = ?"
554 $sth->execute( $itemnumber, $colId ) or return (0);
556 my $row = $sth->fetchrow_hashref;
558 return $$row{'inCollection'};
561 =head2 isItemInAnyCollection
563 my $inCollection = isItemInAnyCollection( $itemnumber );
567 sub isItemInAnyCollection {
568 my ($itemnumber) = @_;
570 my $dbh = C4::Context->dbh;
572 my $sth = $dbh->prepare(
573 "SELECT itemnumber FROM collections_tracking JOIN collections USING (colId) WHERE itemnumber = ?");
574 $sth->execute($itemnumber) or return (0);
576 my $row = $sth->fetchrow_hashref;
578 $itemnumber = $row->{itemnumber};
593 Kyle Hall <kylemhall@gmail.com>