Bug 21722: Use Koha::Account->add_debit in chargelostitem
[koha.git] / C4 / RotatingCollections.pm
index 254453f..709eaf2 100644 (file)
@@ -1,42 +1,40 @@
 package C4::RotatingCollections;
 
-# $Id: RotatingCollections.pm,v 0.1 2007/04/20 kylemhall 
+# $Id: RotatingCollections.pm,v 0.1 2007/04/20 kylemhall
 
 # This package is inteded to keep track of what library
-# Items of a certain collection should be at. 
+# Items of a certain collection should be at.
 
 # Copyright 2007 Kyle Hall
 #
 # 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 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 3 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.
+# 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
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
 
-use strict;
-
-require Exporter;
+use Modern::Perl;
 
 use C4::Context;
 use C4::Circulation;
+use C4::Reserves qw(CheckReserves);
+use Koha::Database;
 
 use DBI;
 
 use Data::Dumper;
 
-use vars qw($VERSION @ISA @EXPORT);
+use vars qw(@ISA @EXPORT);
 
-# set the version for version checking
-$VERSION = 0.01;
 
 =head1 NAME
 
@@ -44,29 +42,30 @@ C4::RotatingCollections - Functions for managing rotating collections
 
 =head1 FUNCTIONS
 
-=over 2
-
 =cut
 
-@ISA = qw( Exporter );
-@EXPORT = qw( 
-  CreateCollection
-  UpdateCollection
-  DeleteCollection
-  
-  GetItemsInCollection
-
-  GetCollection
-  GetCollections
-  
-  AddItemToCollection
-  RemoveItemFromCollection
-  TransferCollection  
-
-  GetCollectionItemBranches
-);
-
-=item  CreateCollection
+BEGIN {
+    require Exporter;
+    @ISA    = qw( Exporter );
+    @EXPORT = qw(
+      CreateCollection
+      UpdateCollection
+      DeleteCollection
+
+      GetItemsInCollection
+
+      GetCollection
+      GetCollections
+
+      AddItemToCollection
+      RemoveItemFromCollection
+      TransferCollection
+
+      GetCollectionItemBranches
+    );
+}
+
+=head2  CreateCollection
  ( $success, $errorcode, $errormessage ) = CreateCollection( $title, $description );
  Creates a new collection
 
@@ -78,35 +77,44 @@ C4::RotatingCollections - Functions for managing rotating collections
    $success: 1 if all database operations were successful, 0 otherwise
    $errorCode: Code for reason of failure, good for translating errors in templates
    $errorMessage: English description of error
+
 =cut
+
 sub CreateCollection {
-  my ( $title, $description ) = @_;
+    my ( $title, $description ) = @_;
+
+    my $schema = Koha::Database->new()->schema();
+    my $duplicate_titles = $schema->resultset('Collection')->count({ colTitle => $title });
+
+    ## Check for all necessary parameters
+    if ( !$title ) {
+        return ( 0, 1, "NO_TITLE" );
+    } elsif ( $duplicate_titles ) {
+        return ( 0, 2, "DUPLICATE_TITLE" );
+    }
+
+    $description ||= q{};
 
-  ## Check for all neccessary parameters
-  if ( ! $title ) {
-    return ( 0, 1, "No Title Given" );
-  } 
-  if ( ! $description ) {
-    return ( 0, 2, "No Description Given" );
-  } 
+    my $success = 1;
 
-  my $success = 1;
+    my $dbh = C4::Context->dbh;
 
-  my $dbh = C4::Context->dbh;
+    my $sth;
+    $sth = $dbh->prepare(
+        "INSERT INTO collections ( colId, colTitle, colDesc )
+                        VALUES ( NULL, ?, ? )"
+    );
+    $sth->execute( $title, $description ) or return ( 0, 3, $sth->errstr() );
 
-  my $sth;
-  $sth = $dbh->prepare("INSERT INTO collections ( colId, colTitle, colDesc ) 
-                        VALUES ( NULL, ?, ? )");
-  $sth->execute( $title, $description ) or return ( 0, 3, $sth->errstr() );
-  $sth->finish;
+    return 1;
 
-  return 1;
-  
 }
 
-=item UpdateCollection
+=head2 UpdateCollection
+
  ( $success, $errorcode, $errormessage ) = UpdateCollection( $colId, $title, $description );
- Updates a collection
+
+Updates a collection
 
  Input:
    $colId: id of the collection to be updated
@@ -117,67 +125,79 @@ sub CreateCollection {
    $success: 1 if all database operations were successful, 0 otherwise
    $errorCode: Code for reason of failure, good for translating errors in templates
    $errorMessage: English description of error
+
 =cut
+
 sub UpdateCollection {
-  my ( $colId, $title, $description ) = @_;
-
-  ## Check for all neccessary parameters
-  if ( ! $colId ) {
-    return ( 0, 1, "No Id Given" );
-  }
-  if ( ! $title ) {
-    return ( 0, 2, "No Title Given" );
-  } 
-  if ( ! $description ) {
-    return ( 0, 3, "No Description Given" );
-  } 
-
-  my $dbh = C4::Context->dbh;
-
-  my $sth;
-  $sth = $dbh->prepare("UPDATE collections
+    my ( $colId, $title, $description ) = @_;
+
+    my $schema = Koha::Database->new()->schema();
+    my $duplicate_titles = $schema->resultset('Collection')->count({ colTitle => $title,  -not => { colId => $colId } });
+
+    ## Check for all necessary parameters
+    if ( !$colId ) {
+        return ( 0, 1, "NO_ID" );
+    }
+    if ( !$title ) {
+        return ( 0, 2, "NO_TITLE" );
+    }
+    if ( $duplicate_titles ) {
+        return ( 0, 3, "DUPLICATE_TITLE" );
+    }
+
+    my $dbh = C4::Context->dbh;
+
+    $description ||= q{};
+
+    my $sth;
+    $sth = $dbh->prepare(
+        "UPDATE collections
                         SET 
                         colTitle = ?, colDesc = ? 
-                        WHERE colId = ?");
-  $sth->execute( $title, $description, $colId ) or return ( 0, 4, $sth->errstr() );
-  $sth->finish;
-  
-  return 1;
-  
+                        WHERE colId = ?"
+    );
+    $sth->execute( $title, $description, $colId )
+      or return ( 0, 4, $sth->errstr() );
+
+    return 1;
+
 }
 
-=item DeleteCollection
+=head2 DeleteCollection
+
  ( $success, $errorcode, $errormessage ) = DeleteCollection( $colId );
  Deletes a collection of the given id
 
  Input:
-   $colId : id of the Archtype to be deleted
+   $colId : id of the Archetype to be deleted
 
  Output:
    $success: 1 if all database operations were successful, 0 otherwise
    $errorCode: Code for reason of failure, good for translating errors in templates
    $errorMessage: English description of error
+
 =cut
+
 sub DeleteCollection {
-  my ( $colId ) = @_;
+    my ($colId) = @_;
+
+    ## Parameter check
+    if ( !$colId ) {
+        return ( 0, 1, "NO_ID" );
+    }
 
-  ## Paramter check
-  if ( ! $colId ) {
-    return ( 0, 1, "No Collection Id Given" );;
-  }
-  
-  my $dbh = C4::Context->dbh;
+    my $dbh = C4::Context->dbh;
 
-  my $sth;
+    my $sth;
 
-  $sth = $dbh->prepare("DELETE FROM collections WHERE colId = ?");
-  $sth->execute( $colId ) or return ( 0, 4, $sth->errstr() );
-  $sth->finish;
+    $sth = $dbh->prepare("DELETE FROM collections WHERE colId = ?");
+    $sth->execute($colId) or return ( 0, 4, $sth->errstr() );
 
-  return 1;
+    return 1;
 }
 
-=item GetCollections
+=head2 GetCollections
+
  $collections = GetCollections();
  Returns data about all collections
 
@@ -187,26 +207,28 @@ sub DeleteCollection {
   On Failure:
    $errorCode: Code for reason of failure, good for translating errors in templates
    $errorMessage: English description of error
+
 =cut
+
 sub GetCollections {
 
-  my $dbh = C4::Context->dbh;
-  
-  my $sth = $dbh->prepare("SELECT * FROM collections");
-  $sth->execute() or return ( 1, $sth->errstr() );
-  
-  my @results;
-  while ( my $row = $sth->fetchrow_hashref ) {
-    push( @results , $row );
-  }
-  
-  $sth->finish;
-  
-  return \@results;
+    my $dbh = C4::Context->dbh;
+
+    my $sth = $dbh->prepare("SELECT * FROM collections");
+    $sth->execute() or return ( 1, $sth->errstr() );
+
+    my @results;
+    while ( my $row = $sth->fetchrow_hashref ) {
+        push( @results, $row );
+    }
+
+    return \@results;
 }
 
-=item GetItemsInCollection
+=head2 GetItemsInCollection
+
  ( $results, $success, $errorcode, $errormessage ) = GetItemsInCollection( $colId );
+
  Returns information about the items in the given collection
  
  Input:
@@ -217,72 +239,77 @@ sub GetCollections {
    $success: 1 if all database operations were successful, 0 otherwise
    $errorCode: Code for reason of failure, good for translating errors in templates
    $errorMessage: English description of error
+
 =cut
+
 sub GetItemsInCollection {
-  my ( $colId ) = @_;
+    my ($colId) = @_;
 
-  ## Paramter check
-  if ( ! $colId ) {
-    return ( 0, 0, 1, "No Collection Id Given" );;
-  }
+    ## Parameter check
+    if ( !$colId ) {
+        return ( 0, 0, 1, "NO_ID" );
+    }
 
-  my $dbh = C4::Context->dbh;
-  
-  my $sth = $dbh->prepare("SELECT 
+    my $dbh = C4::Context->dbh;
+
+    my $sth = $dbh->prepare(
+        "SELECT
                              biblio.title,
+                             biblio.biblionumber,
                              items.itemcallnumber,
                              items.barcode
                            FROM collections, collections_tracking, items, biblio
                            WHERE collections.colId = collections_tracking.colId
                            AND collections_tracking.itemnumber = items.itemnumber
                            AND items.biblionumber = biblio.biblionumber
-                           AND collections.colId = ? ORDER BY biblio.title");
-  $sth->execute( $colId ) or return ( 0, 0, 2, $sth->errstr() );
-  
-  my @results;
-  while ( my $row = $sth->fetchrow_hashref ) {
-    push( @results , $row );
-  }
-  
-  $sth->finish;
-  
-  return \@results;
+                           AND collections.colId = ? ORDER BY biblio.title"
+    );
+    $sth->execute($colId) or return ( 0, 0, 2, $sth->errstr() );
+
+    my @results;
+    while ( my $row = $sth->fetchrow_hashref ) {
+        push( @results, $row );
+    }
+
+    return \@results;
 }
 
-=item GetCollection
+=head2 GetCollection
+
  ( $colId, $colTitle, $colDesc, $colBranchcode ) = GetCollection( $colId );
- Returns information about a collection
+
+Returns information about a collection
 
  Input:
    $colId: Id of the collection
  Output:
    $colId, $colTitle, $colDesc, $colBranchcode
+
 =cut
+
 sub GetCollection {
-  my ( $colId ) = @_;
-
-  my $dbh = C4::Context->dbh;
-
-  my ( $sth, @results );
-  $sth = $dbh->prepare("SELECT * FROM collections WHERE colId = ?");
-  $sth->execute( $colId ) or return 0;
-    
-  my $row = $sth->fetchrow_hashref;
-  
-  $sth->finish;
-  
-  return (
-      $$row{'colId'},
-      $$row{'colTitle'},
-      $$row{'colDesc'},
-      $$row{'colBranchcode'}
-  );
-    
+    my ($colId) = @_;
+
+    my $dbh = C4::Context->dbh;
+
+    my ( $sth, @results );
+    $sth = $dbh->prepare("SELECT * FROM collections WHERE colId = ?");
+    $sth->execute($colId) or return 0;
+
+    my $row = $sth->fetchrow_hashref;
+
+    return (
+        $$row{'colId'},   $$row{'colTitle'},
+        $$row{'colDesc'}, $$row{'colBranchcode'}
+    );
+
 }
 
-=item AddItemToCollection
+=head2 AddItemToCollection
+
  ( $success, $errorcode, $errormessage ) = AddItemToCollection( $colId, $itemnumber );
- Adds an item to a rotating collection.
+
+Adds an item to a rotating collection.
 
  Input:
    $colId: Collection to add the item to.
@@ -291,39 +318,47 @@ sub GetCollection {
    $success: 1 if all database operations were successful, 0 otherwise
    $errorCode: Code for reason of failure, good for translating errors in templates
    $errorMessage: English description of error
+
 =cut
+
 sub AddItemToCollection {
-  my ( $colId, $itemnumber ) = @_;
-
-  ## Check for all neccessary parameters
-  if ( ! $colId ) {
-    return ( 0, 1, "No Collection Given" );
-  } 
-  if ( ! $itemnumber ) {
-    return ( 0, 2, "No Itemnumber Given" );
-  } 
-  
-  if ( isItemInThisCollection( $itemnumber, $colId ) ) {
-    return ( 0, 2, "Item is already in the collection!" );
-  } elsif ( isItemInAnyCollection( $itemnumber ) ) {
-    return ( 0, 3, "Item is already in a different collection!" );
-  }
-
-  my $dbh = C4::Context->dbh;
-
-  my $sth;
-  $sth = $dbh->prepare("INSERT INTO collections_tracking ( ctId, colId, itemnumber ) 
-                        VALUES ( NULL, ?, ? )");
-  $sth->execute( $colId, $itemnumber ) or return ( 0, 3, $sth->errstr() );
-  $sth->finish;
-
-  return 1;
-  
+    my ( $colId, $itemnumber ) = @_;
+
+    ## Check for all necessary parameters
+    if ( !$colId ) {
+        return ( 0, 1, "NO_ID" );
+    }
+    if ( !$itemnumber ) {
+        return ( 0, 2, "NO_ITEM" );
+    }
+
+    if ( isItemInThisCollection( $itemnumber, $colId ) ) {
+        return ( 0, 2, "IN_COLLECTION" );
+    }
+    elsif ( isItemInAnyCollection($itemnumber) ) {
+        return ( 0, 3, "IN_COLLECTION_OTHER" );
+    }
+
+    my $dbh = C4::Context->dbh;
+
+    my $sth;
+    $sth = $dbh->prepare("
+        INSERT INTO collections_tracking (
+            colId,
+            itemnumber
+        ) VALUES ( ?, ? )
+    ");
+    $sth->execute( $colId, $itemnumber ) or return ( 0, 3, $sth->errstr() );
+
+    return 1;
+
 }
 
-=item  RemoveItemFromCollection
+=head2  RemoveItemFromCollection
+
  ( $success, $errorcode, $errormessage ) = RemoveItemFromCollection( $colId, $itemnumber );
- Removes an item to a collection
+
+Removes an item to a collection
 
  Input:
    $colId: Collection to add the item to.
@@ -333,33 +368,38 @@ sub AddItemToCollection {
    $success: 1 if all database operations were successful, 0 otherwise
    $errorCode: Code for reason of failure, good for translating errors in templates
    $errorMessage: English description of error
+
 =cut
+
 sub RemoveItemFromCollection {
-  my ( $colId, $itemnumber ) = @_;
-
-  ## Check for all neccessary parameters
-  if ( ! $itemnumber ) {
-    return ( 0, 2, "No Itemnumber Given" );
-  } 
-  
-  if ( ! isItemInThisCollection( $itemnumber, $colId ) ) {
-    return ( 0, 2, "Item is not in the collection!" );
-  } 
-
-  my $dbh = C4::Context->dbh;
-
-  my $sth;
-  $sth = $dbh->prepare("DELETE FROM collections_tracking 
-                        WHERE itemnumber = ?");
-  $sth->execute( $itemnumber ) or return ( 0, 3, $sth->errstr() );
-  $sth->finish;
-
-  return 1;
+    my ( $colId, $itemnumber ) = @_;
+
+    ## Check for all necessary parameters
+    if ( !$itemnumber ) {
+        return ( 0, 2, "NO_ITEM" );
+    }
+
+    if ( !isItemInThisCollection( $itemnumber, $colId ) ) {
+        return ( 0, 2, "NOT_IN_COLLECTION" );
+    }
+
+    my $dbh = C4::Context->dbh;
+
+    my $sth;
+    $sth = $dbh->prepare(
+        "DELETE FROM collections_tracking
+                        WHERE itemnumber = ?"
+    );
+    $sth->execute($itemnumber) or return ( 0, 3, $sth->errstr() );
+
+    return 1;
 }
 
-=item TransferCollection
+=head2 TransferCollection
+
  ( $success, $errorcode, $errormessage ) = TransferCollection( $colId, $colBranchcode );
- Transfers a collection to another branch
+
+Transfers a collection to another branch
 
  Input:
    $colId: id of the collection to be updated
@@ -369,89 +409,130 @@ sub RemoveItemFromCollection {
    $success: 1 if all database operations were successful, 0 otherwise
    $errorCode: Code for reason of failure, good for translating errors in templates
    $errorMessage: English description of error
+
 =cut
+
 sub TransferCollection {
-  my ( $colId, $colBranchcode ) = @_;
+    my ( $colId, $colBranchcode ) = @_;
 
-  ## Check for all neccessary parameters
-  if ( ! $colId ) {
-    return ( 0, 1, "No Id Given" );
-  }
-  if ( ! $colBranchcode ) {
-    return ( 0, 2, "No Branchcode Given" );
-  } 
+    ## Check for all necessary parameters
+    if ( !$colId ) {
+        return ( 0, 1, "NO_ID" );
+    }
+    if ( !$colBranchcode ) {
+        return ( 0, 2, "NO_BRANCHCODE" );
+    }
 
-  my $dbh = C4::Context->dbh;
+    my $dbh = C4::Context->dbh;
 
-  my $sth;
-  $sth = $dbh->prepare("UPDATE collections
+    my $sth;
+    $sth = $dbh->prepare(
+        "UPDATE collections
                         SET 
                         colBranchcode = ? 
-                        WHERE colId = ?");
-  $sth->execute( $colBranchcode, $colId ) or return ( 0, 4, $sth->errstr() );
-  $sth->finish;
-  
-  $sth = $dbh->prepare("SELECT barcode FROM items, collections_tracking 
+                        WHERE colId = ?"
+    );
+    $sth->execute( $colBranchcode, $colId ) or return ( 0, 4, $sth->errstr() );
+
+    $sth = $dbh->prepare(q{
+        SELECT items.itemnumber, items.barcode FROM collections_tracking
+        LEFT JOIN items ON collections_tracking.itemnumber = items.itemnumber
+        LEFT JOIN issues ON items.itemnumber = issues.itemnumber
+        WHERE issues.borrowernumber IS NULL
+          AND collections_tracking.colId = ?
+    });
+    $sth->execute($colId) or return ( 0, 4, $sth->errstr );
+    my @results;
+    while ( my $item = $sth->fetchrow_hashref ) {
+        my ($status) = CheckReserves( $item->{itemnumber} );
+        my @transfers = C4::Circulation::GetTransfers( $item->{itemnumber} );
+        C4::Circulation::transferbook( $colBranchcode, $item->{barcode}, my $ignore_reserves = 1 ) unless ( $status eq 'Waiting' || @transfers );
+    }
+
+    return 1;
+
+}
+
+=head2 GetCollectionItemBranches
+
+  my ( $holdingBranch, $collectionBranch ) = GetCollectionItemBranches( $itemnumber );
+
+=cut
+
+sub GetCollectionItemBranches {
+    my ($itemnumber) = @_;
+
+    if ( !$itemnumber ) {
+        return;
+    }
+
+    my $dbh = C4::Context->dbh;
+
+    my ( $sth, @results );
+    $sth = $dbh->prepare(
+"SELECT holdingbranch, colBranchcode FROM items, collections, collections_tracking
                         WHERE items.itemnumber = collections_tracking.itemnumber
-                        AND collections_tracking.colId = ?");
-  $sth->execute( $colId ) or return ( 0, 4, $sth->errstr );
-  my @results;
-  while ( my $item = $sth->fetchrow_hashref ) {
-    my ( $dotransfer, $messages, $iteminformation ) = transferbook( $colBranchcode, $item->{'barcode'}, my $ignore_reserves = 1);
-  }
-  
-
-  
-  return 1;
-  
+                        AND collections.colId = collections_tracking.colId
+                        AND items.itemnumber = ?"
+    );
+    $sth->execute($itemnumber);
+
+    my $row = $sth->fetchrow_hashref;
+
+    return ( $$row{'holdingbranch'}, $$row{'colBranchcode'}, );
 }
 
+=head2 isItemInThisCollection
+
+  $inCollection = isItemInThisCollection( $itemnumber, $colId );
+
+=cut
 
-=item isItemInThisCollection
-$inCollection = isItemInThisCollection( $itemnumber, $colId );
-=cut            
 sub isItemInThisCollection {
-  my ( $itemnumber, $colId ) = @_;
-  
-  my $dbh = C4::Context->dbh;
-  
-  my $sth = $dbh->prepare("SELECT COUNT(*) as inCollection FROM collections_tracking WHERE itemnumber = ? AND colId = ?");
-  $sth->execute( $itemnumber, $colId ) or return( 0 );
-      
-  my $row = $sth->fetchrow_hashref;
-        
-  return $$row{'inCollection'};
+    my ( $itemnumber, $colId ) = @_;
+
+    my $dbh = C4::Context->dbh;
+
+    my $sth = $dbh->prepare(
+"SELECT COUNT(*) as inCollection FROM collections_tracking WHERE itemnumber = ? AND colId = ?"
+    );
+    $sth->execute( $itemnumber, $colId ) or return (0);
+
+    my $row = $sth->fetchrow_hashref;
+
+    return $$row{'inCollection'};
 }
 
-=item isItemInAnyCollection
+=head2 isItemInAnyCollection
+
 $inCollection = isItemInAnyCollection( $itemnumber );
+
 =cut
+
 sub isItemInAnyCollection {
-  my ( $itemnumber ) = @_;
-  
-  my $dbh = C4::Context->dbh;
-  
-  my $sth = $dbh->prepare("SELECT itemnumber FROM collections_tracking WHERE itemnumber = ?");
-  $sth->execute( $itemnumber ) or return( 0 );
-      
-  my $row = $sth->fetchrow_hashref;
-        
-  my $itemnumber = $$row{'itemnumber'};
-  $sth->finish;
-            
-  if ( $itemnumber ) {
-    return 1;
-  } else {
-    return 0;
-  }
+    my ($itemnumber) = @_;
+
+    my $dbh = C4::Context->dbh;
+
+    my $sth = $dbh->prepare(
+        "SELECT itemnumber FROM collections_tracking WHERE itemnumber = ?");
+    $sth->execute($itemnumber) or return (0);
+
+    my $row = $sth->fetchrow_hashref;
+
+    $itemnumber = $row->{itemnumber};
+    if ($itemnumber) {
+        return 1;
+    }
+    else {
+        return 0;
+    }
 }
 
 1;
 
 __END__
 
-=back
-
 =head1 AUTHOR
 
 Kyle Hall <kylemhall@gmail.com>