From a6b3a980a2c24be783ed794a81a73d7d88194764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Sepp=C3=A4l=C3=A4?= <jseppal@student.uef.fi> Date: Mon, 18 Aug 2014 11:58:43 +0300 Subject: [PATCH] Bug 8836 - Resurrect Rotating Collections: additions This is patch is an enchancement patch based on our requirements (sending in hopes that it could be useful to someone) and is ment to be applied on top of my squashed rotating collections patch and focuses mainly on the interface, aiming to streamline workflow and and to reduce unnecessary page reloads. Core rotating collection functionality is also changed in that transfers are now handled on the item level instead of on the collection level. This allows individual items in the collection to have their own transfer branches - you can still of course have all items transferred to the same destination by using the collection transfer feature in the main view or in the additems-view. Note: as this is a fairly large change in how collections are handled, this patch cannot be used directly with collections managed by the old system. List of larger changes (of the top of my head): - transferCollection-view has been made redundant with the addition of a transfer button and branch select input in the main view. - editCollections-view has been made redundant with addition of the "edit" button in the main view. Note that "Edit collection" still exists - datatables used in all the views. - The main view table has been revamped and some columns have been moved around or removed. New columns: Owner(branch of the signed in user on creation), Items(count), Transferred(how many items in collection are transferred), Transfer collection, Edit and Delete. - New collections can be created directly from the main view using the "New collection"-button. - Item's original home branch (before a transfer) is now recorded on transfer (a new database column 'origin_branchcode' in collection_tracking). The old collection-level transfer branch in collections is no longer needed but is not touched by this patch. - Item's transfer location is now recored on item-level basis (a new database column: 'transfer_branch). - Item's tranfer status is now recorded (a new database column in collection_tracking: 'transferred'). - When removing a collection, all items (if any) in that collection get removed from collection_tracking and returned to their origin branch. - addItems-view: - Table now shows the item's origin branch, home branch and current loc. In addition to these, new columns: "Transferred", "Transfer", "Return" and "Remove". - Item's title and barcode are now links to the relevant page in catalogue. - Buttons for individual item transfer, return and removal. The transfer button can be used to transfer an individual item to a branch (branch selection happens in a bootsrap modal-view). The return button can be used to return an item to its origin branch. The remove button allows removing an item from the collection without the need for reading a barcode. - A button for whole collection transfer. Sadly, this is *not* a complete list of changes. --- C4/Circulation.pm | 2 +- C4/RotatingCollections.pm | 565 +++++++++++++++++++-- catalogue/detail.pl | 4 + circ/returns.pl | 8 +- installer/data/mysql/kohastructure.sql | 13 +- installer/data/mysql/updatedatabase.pl | 21 + .../prog/en/modules/catalogue/detail.tt | 7 +- .../en/modules/rotating_collections/addItems.tt | 340 ++++++++++++- .../rotating_collections/editCollections.tt | 176 +++++-- .../rotating_collections/rotatingCollections.tt | 367 ++++++++++++- .../rotating_collections/transferCollection.tt | 68 ++- rotating_collections/addItems.pl | 17 +- rotating_collections/editCollections.pl | 7 +- rotating_collections/rotatingCollections.pl | 6 +- rotating_collections/transferCollection.pl | 108 +++- 15 files changed, 1536 insertions(+), 173 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index eb4ffdd..20aff9f 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -42,7 +42,7 @@ use C4::Koha qw( GetKohaAuthorisedValueLib ); use C4::Overdues qw(CalcFine UpdateFine); -use C4::RotatingCollections qw(GetCollectionItemBranches); +use C4::RotatingCollections; use Algorithm::CheckDigits; use Data::Dumper; diff --git a/C4/RotatingCollections.pm b/C4/RotatingCollections.pm index 5a63cd8..c4a5eb2 100644 --- a/C4/RotatingCollections.pm +++ b/C4/RotatingCollections.pm @@ -27,6 +27,10 @@ use Modern::Perl; use C4::Context; use C4::Circulation; use C4::Reserves qw(GetReserveStatus); +use C4::Biblio; +use C4::Branch; +use C4::Items; +use C4::Reserves; use DBI; @@ -56,13 +60,22 @@ BEGIN { GetItemsInCollection GetCollection + GetCollectionByTitle GetCollections AddItemToCollection RemoveItemFromCollection TransferCollection + TransferCollectionItem + ReturnCollectionItemToOrigin + ReturnCollectionToOrigin GetCollectionItemBranches + + GetItemOriginBranch + GetItemsCollection + + isItemInAnyCollection ); } @@ -82,14 +95,26 @@ BEGIN { =cut sub CreateCollection { - my ( $title, $description ) = @_; + my ( $title, $description, $owningbranch ) = @_; ## Check for all neccessary parameters if ( !$title ) { - return ( 0, 1, "No Title Given" ); + return ( 0, 1, "No title given" ); } if ( !$description ) { - return ( 0, 2, "No Description Given" ); + return ( 0, 2, "No description given" ); + } + + if ( !$owningbranch ) { + return ( 0, 3, "No owning branch given" ); + } + + # Check whether a collection with the given title already exists + my $collections = GetCollections(); + for my $col (@$collections) { + if ($col->{'colTitle'} eq $title) { + return (0, 4, "A collection with the title '" . $title . "' already exists"); + } } my $success = 1; @@ -98,10 +123,10 @@ sub CreateCollection { my $sth; $sth = $dbh->prepare( - "INSERT INTO collections ( colId, colTitle, colDesc ) - VALUES ( NULL, ?, ? )" + "INSERT INTO collections ( colId, colTitle, colDesc, owningBranchcode ) + VALUES ( NULL, ?, ?, ? )" ); - $sth->execute( $title, $description ) or return ( 0, 3, $sth->errstr() ); + $sth->execute( $title, $description, $owningbranch ) or return ( 0, 5, $sth->errstr() ); return 1; @@ -139,6 +164,14 @@ sub UpdateCollection { return ( 0, 3, "No Description Given" ); } + # Check whether a collection with the given title already exists + my $collections = GetCollections(); + for my $col (@$collections) { + if ($col->{'colTitle'} eq $title) { + return (0, 4, "A collection with the title '" . $title . "' already exists"); + } + } + my $dbh = C4::Context->dbh; my $sth; @@ -178,6 +211,14 @@ sub DeleteCollection { return ( 0, 1, "No Collection Id Given" ); } + my $collectionItems = GetItemsInCollection($colId); + # KD-139: Actually remove all items from the collection before removing the collection itself. + for my $item (@$collectionItems) { + my $itembiblio = GetBiblioFromItemNumber(undef, $item->{'barcode'}); + my $itemnumber = $itembiblio->{'itemnumber'}; + RemoveItemFromCollection($colId, $itemnumber); + } + my $dbh = C4::Context->dbh; my $sth; @@ -205,12 +246,21 @@ sub DeleteCollection { sub GetCollections { my $dbh = C4::Context->dbh; + my $query = ' + SELECT * + FROM collections + LEFT JOIN branches ON owningBranchcode = branches.branchcode + '; - my $sth = $dbh->prepare("SELECT * FROM collections"); + my $sth = $dbh->prepare($query); $sth->execute() or return ( 1, $sth->errstr() ); my @results; while ( my $row = $sth->fetchrow_hashref ) { + my $colItemCount = GetCollectionItemCount($row->{'colId'}); + my $itemsTransferred = GetTransferredItemCount($row->{'colId'}); + $row->{'colItemsCount'} = $colItemCount; + $row->{'itemsTransferred'} = $itemsTransferred; push( @results, $row ); } @@ -246,19 +296,32 @@ sub GetItemsInCollection { my $sth = $dbh->prepare( "SELECT - biblio.title, - items.itemcallnumber, - items.barcode - FROM collections, collections_tracking, items, biblio - WHERE collections.colId = collections_tracking.colId + biblio.title, + biblio.biblionumber, + items.itemcallnumber, + items.barcode, + items.itemnumber, + items.holdingbranch, + items.homebranch, + branches.branchname, + collections_tracking.* + FROM collections, collections_tracking, items, biblio, branches + WHERE items.homebranch = branches.branchcode + AND collections.colId = collections_tracking.colId AND collections_tracking.itemnumber = items.itemnumber AND items.biblionumber = biblio.biblionumber - AND collections.colId = ? ORDER BY biblio.title" + 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 ) { + my $originbranchname = GetBranchName($row->{'origin_branchcode'}); + my $holdingbranchname = GetBranchName($row->{'holdingbranch'}); + $row->{'holdingbranchname'} = $holdingbranchname; + $row->{'origin_branchname'} = $originbranchname; + $row->{'intransit'} = GetTransfers($row->{'itemnumber'}); push( @results, $row ); } @@ -296,6 +359,68 @@ sub GetCollection { } +=head2 GetCollectionByTitle + + ($colId, $colTitle, $colDesc, $colBranchcode) = GetCollectionByTitle($colTitle); + +Returns information about a collection + + Input: + $colTitle: Title of the collection + Output: + $colId, $colTitle, $colDesc, $colBranchcode + +=cut + +sub GetCollectionByTitle { + my ($colId) = @_; + + my $dbh = C4::Context->dbh; + + my ( $sth, @results ); + $sth = $dbh->prepare("SELECT * FROM collections WHERE colTitle = ?"); + $sth->execute($colId) or return 0; + + my $row = $sth->fetchrow_hashref; + + return ( + $$row{'colId'}, $$row{'colTitle'}, + $$row{'colDesc'}, $$row{'colBranchcode'} + ); + +} + +=head2 GetItemsCollection + +$itemsCollection = GetItemsCollection($itemnumber) + +Returns an item's collection if it exists + + Input: + $itemnumber: itemnumber of the item + Output: + $colId of the item's collection or 0 if the item is not in a collection + +=cut + +sub GetItemsCollection { + my $itemnumber = shift; + + if (!isItemInAnyCollection($itemnumber)) { + return 0; + } + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare("SELECT * FROM collections_tracking WHERE itemnumber = ?"); + $sth->execute($itemnumber) or return 0; + + my $colItem = $sth->fetchrow_hashref; + if ($colItem) { + return $colItem->{'colId'}; + } + return 0; +} + =head2 AddItemToCollection ( $success, $errorcode, $errormessage ) = AddItemToCollection( $colId, $itemnumber ); @@ -322,13 +447,19 @@ sub AddItemToCollection { 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!" ); } + # Check item's reserve status + my ($reservedate, $borrowernumber, $branchcode, $reserve_id, $waitingdate) = GetReservesFromItemnumber($itemnumber); + return (0, 4, "The item is waiting for pickup and cannot be added to a collection!") if ($waitingdate); + + my $itembiblio = GetBiblioFromItemNumber($itemnumber, undef); + my $originbranchcode = $itembiblio->{'homebranch'}; + my $transferred = 0; my $dbh = C4::Context->dbh; @@ -336,10 +467,11 @@ sub AddItemToCollection { $sth = $dbh->prepare(" INSERT INTO collections_tracking ( colId, - itemnumber - ) VALUES ( ?, ? ) + itemnumber, + origin_branchcode + ) VALUES (?, ?, ?) "); - $sth->execute( $colId, $itemnumber ) or return ( 0, 3, $sth->errstr() ); + $sth->execute($colId, $itemnumber, $originbranchcode) or return ( 0, 3, $sth->errstr() ); return 1; @@ -374,8 +506,22 @@ sub RemoveItemFromCollection { return ( 0, 2, "Item is not in the collection!" ); } - my $dbh = C4::Context->dbh; + # KD-139: Attempt to transfer the item being removed if it has its origin branch + # set up. + my $itembiblio = GetBiblioFromItemNumber($itemnumber, undef); + my $currenthomebranchcode = $itembiblio->{'homebranch'}; + my $originbranchcode = GetItemOriginBranch($itemnumber); + my $barcode = $itembiblio->{'barcode'}; + my ($dotransfer, $messages, $iteminformation); + + if ($originbranchcode && $barcode) { + if (GetTransfers($itemnumber)) { + DeleteTransfer($itemnumber) + } + ($dotransfer, $messages, $iteminformation) = transferbook($originbranchcode, $barcode, 1); + } + my $dbh = C4::Context->dbh; my $sth; $sth = $dbh->prepare( "DELETE FROM collections_tracking @@ -383,6 +529,140 @@ sub RemoveItemFromCollection { ); $sth->execute($itemnumber) or return ( 0, 3, $sth->errstr() ); + # Transfer was not done - not considered an error here + if (!$dotransfer) { + return (1, 4, $messages); + } + + # Change the item's homebranch back to its pre-transfer status + ModItem({ homebranch => $originbranchcode }, undef, $itemnumber); + + return 1; +} + +=head2 ReturnCollectionToOrigin + + ($success, $errorcode, $errormessage) = ReturnCollectionToOrigin($colId); + +Marks a collection to be returned to their origin branch, e.g. the branch that was +the item's home branch when it was first added to the collection + + Input: + $colId: Collection the returned item belongs to + + Output: + $success: 1 if all database operations were successful, 0 otherwise + $errorcode: Code for reason of failure, good for translating errors in templates + $errormessages: English description of any errors with return operations +=cut + +sub ReturnCollectionToOrigin { + my $colId = shift; + + if (!$colId) { + return (0, 1, "No collection id given"); + } + + my $collectionItems = GetItemsInCollection($colId); + my $collectionItemsCount = scalar(@$collectionItems); + my ($colSuccess, $errorcode, @errormessages); + + for my $item (@$collectionItems) { + my $itemOriginBranch = GetItemOriginBranch($item->{'itemnumber'}); + my ($success, $errocode, $errormessage); + if ($itemOriginBranch) { + ($success, $errorcode, $errormessage) = + ReturnCollectionItemToOrigin($colId, $item->{'itemnumber'}); + if (!$success) { + push(@errormessages, $errormessage); + } + } + } + my $errorCount = scalar(@errormessages); + if ($errorCount == $collectionItemsCount) { + return (0, 2, "No items in collection transferred"); + } + else { + # Some items were succesfully returned - return info about failed transfers for template usage + return (1, 0, \@errormessages); + } +} + + + +=head2 ReturnCollectionItemToOrigin + + ($success, $errorcode, $errormessage) = ReturnCollectionItemToOrigin($colId, $itemnumber); + +Marks a collection item to be returned to their origin branch, e.g. the branch that was +the item's home branch when it was first added to the collection + + Input: + $colId: Collection the returned item belongs to + $itemnumber: Item in the collection to be returned to their origin branch + + 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 ReturnCollectionItemToOrigin { + my ($colId, $itemnumber) = @_; + my $originBranch = GetItemOriginBranch($itemnumber); + + ## Check for all neccessary parameters + if (!$colId) { + return (0, 1, "No collection id given"); + } + if (!$itemnumber) { + return (0, 2, "No itemnumber given"); + } + + if (!$originBranch) { + return (0, 3, "Item has no origin branch set"); + } + + if (!isItemTransferred($itemnumber)) { + return (0, 4, "Cannot return an item that is not transferred"); + } + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare(q{ + SELECT items.itemnumber, items.barcode, items.homebranch, items.holdingbranch 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 = ? AND collections_tracking.itemnumber = ? + }); + + $sth->execute($colId, $itemnumber) or return (0, 5, $sth->errstr); + my ($dotransfer, $messages, $iteminformation); + if (my $item = $sth->fetchrow_hashref) { + unless (GetReserveStatus($item->{itemnumber}) eq "Waiting") { + ($dotransfer, $messages, $iteminformation) + = transferbook($originBranch, $item->{barcode}, 1); + } + } + # Push all issues with the transfer into a list for template usage. + if (!$dotransfer) { + my @errorlist; + for my $message (keys %$messages) { + push(@errorlist, $message); + } + return (0, 6, \@errorlist); + } + + $sth = $dbh->prepare(q{ + UPDATE collections_tracking + SET + transfer_branch = NULL + WHERE itemnumber = ? + }); + $sth->execute($itemnumber) or return (0, 7, $sth->errstr); + ModItem({ homebranch => $originBranch }, undef, $itemnumber); + return 1; } @@ -404,46 +684,129 @@ Transfers a collection to another branch =cut sub TransferCollection { - my ( $colId, $colBranchcode ) = @_; + my ($colId, $colBranchcode) = @_; ## Check for all neccessary parameters - if ( !$colId ) { - return ( 0, 1, "No Id Given" ); + if (!$colId) { + return (0, 1, "No id given"); } - if ( !$colBranchcode ) { - return ( 0, 2, "No Branchcode Given" ); + if (!$colBranchcode) { + return (0, 2, "No branchcode given"); } - my $dbh = C4::Context->dbh; + my $colItems = GetItemsInCollection($colId); + my $colItemsCount = scalar(@$colItems); + my ($transfersuccess, $error, @errorlist); + my $problemItemCount = 0; + + for my $item (@$colItems) { + my $itemOriginBranch = GetItemOriginBranch($item->{'itemnumber'}); + my $itemCurHomeBranch = $item->{'homebranch'}; + my ($dotransfer, $errorcode, $errormessage) = TransferCollectionItem($colId, $item->{'itemnumber'}, $colBranchcode); + if (!$dotransfer) { + $problemItemCount++; + push(@errorlist, $item->{'title'} . ":"); + if (ref $errormessage eq "ARRAY") { + for my $message (@$errormessage) { + push(@errorlist, $message); + } + } + else { + push (@errorlist, $errormessage); + } + } + } - my $sth; - $sth = $dbh->prepare( - "UPDATE collections - SET - colBranchcode = ? - WHERE colId = ?" - ); - $sth->execute( $colBranchcode, $colId ) or return ( 0, 4, $sth->errstr() ); + if ($problemItemCount == $colItemsCount) { + return (0, 3, \@errorlist); + } + elsif ($problemItemCount < $colItemsCount) { + return (1, 0, \@errorlist); + } + else { + return 1; + } +} - $sth = $dbh->prepare(q{ - SELECT items.itemnumber, items.barcode FROM collections_tracking +=head2 TransferItem + + ($success, $errorcode, $errormessage) = TransferCollection($colId, $itemnumber, $transferBranch); + +Transfers an item to another branch + + Input: + $colId: id of the collection to be updated + $itemnumber: the itemnumber of the item in the collection being transferred + $transferBranch: branch where item is moving to + + 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 TransferCollectionItem { + my ($colId, $itemnumber, $transferBranch) = @_; + + if (!$colId) { + return (0, 1, "No collection id given"); + } + + if (!$itemnumber) { + return (0, 2, "No itemnumber given"); + } + + if (!$transferBranch) { + return (0, 3, "No transfer branch given"); + } + + if (isItemTransferred($itemnumber)) { + return (0, 4, "Item is already transferred"); + } + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare(q{ + SELECT items.itemnumber, items.barcode, items.homebranch 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 = ? + AND collections_tracking.colId = ? AND collections_tracking.itemnumber = ? }); - $sth->execute($colId) or return ( 0, 4, $sth->errstr ); - my @results; - while ( my $item = $sth->fetchrow_hashref ) { - transferbook( $colBranchcode, $item->{barcode}, - my $ignore_reserves = 1 ) - unless ( GetReserveStatus( $item->{itemnumber} ) eq "Waiting" ); + + $sth->execute($colId, $itemnumber) or return ( 0, 5, $sth->errstr ); + my ($dotransfer, $messages, $iteminformation); + if (my $item = $sth->fetchrow_hashref) { + unless (GetReserveStatus($item->{itemnumber}) eq "Waiting") { + ($dotransfer, $messages, $iteminformation) + = transferbook($transferBranch, $item->{barcode}, 1); + } } - return 1; + # Push all issues with the transfer into a list for template usage. + if (!$dotransfer) { + my @errorlist; + for my $message (keys %$messages) { + push(@errorlist, $message); + } + return (0, 6, \@errorlist); + } + my $transferred = 1; + $sth = $dbh->prepare(q{ + UPDATE collections_tracking + SET + transfer_branch = ?, + transferred = ? + WHERE itemnumber = ? + }); + $sth->execute($transferBranch, $transferred, $itemnumber) or return (0, 7, $sth->errstr); + ModItem({ homebranch => $transferBranch }, undef, $itemnumber); + + return 1; } + =head2 GetCollectionItemBranches my ( $holdingBranch, $collectionBranch ) = GetCollectionItemBranches( $itemnumber ); @@ -461,7 +824,7 @@ sub GetCollectionItemBranches { my ( $sth, @results ); $sth = $dbh->prepare( -"SELECT holdingbranch, colBranchcode FROM items, collections, collections_tracking +"SELECT holdingbranch, transfer_branch FROM items, collections, collections_tracking WHERE items.itemnumber = collections_tracking.itemnumber AND collections.colId = collections_tracking.colId AND items.itemnumber = ?" @@ -470,7 +833,49 @@ sub GetCollectionItemBranches { my $row = $sth->fetchrow_hashref; - return ( $$row{'holdingbranch'}, $$row{'colBranchcode'}, ); + return ( $$row{'holdingbranch'}, $$row{'transfer_branch'}, ); +} + +=head2 GetTransferredItemCount + + $transferredCount = GetTransferredItemCount($colId); + +=cut + +sub GetTransferredItemCount { + my $colId = shift; + + my $dbh = C4::Context->dbh; + my $query = "SELECT COUNT(*) + FROM collections_tracking + WHERE colId = ? AND transferred = 1 + "; + my $sth = $dbh->prepare($query); + $sth->execute($colId) or die $sth->errstr(); + + my $result = $sth->fetchrow(); + return $result; +} + +=head2 GetCollectionItemCount + + $colItemCount = GetCollectionItemCount($colId); + +=cut + +sub GetCollectionItemCount { + my $colId = shift; + + my $dbh = C4::Context->dbh; + my $query = "SELECT COUNT(colId) + FROM collections_tracking + WHERE colId = ? + "; + my $sth = $dbh->prepare($query); + $sth->execute($colId) or die $sth->errstr(); + + my $result = $sth->fetchrow(); + return $result; } =head2 isItemInThisCollection @@ -520,6 +925,78 @@ sub isItemInAnyCollection { } } +=head2 isItemTramsferred + +($transferred, $errorcode, $errormessage) = isItemTransferred($itemnumber); + +=cut + +sub isItemTransferred { + my $itemnumber = shift; + + my $dbh = C4::Context->dbh; + my $sth; + + my $query = ' + Select * FROM collections_tracking + WHERE itemnumber = ? + '; + + $sth = $dbh->prepare($query); + $sth->execute($itemnumber) or return (0, 1, $sth->errstr); + my $resultrow = $sth->fetchrow_hashref; + if (!$resultrow) { + return (0, 2, "Item is not in a collection"); + } + + if ($resultrow->{'transferred'}) { + return 1; + } + else { + return 0; + } + +} + + + +=head2 GetItemOriginBranch + +$originBranch = GetItemOriginBranch($itemnumber); + +Kd-139: Returns the given item's origin branch, e.g. the home branch at the time it was +being added to a collection or 0 the item has no origin + +=cut + +sub GetItemOriginBranch { + my $itemnumber = shift; + + my $dbh = C4::Context->dbh; + my $sth; + + my $query = ' + SELECT * + FROM collections_tracking + WHERE itemnumber = ? + '; + $sth = $dbh->prepare($query); + $sth->execute($itemnumber); + my $resultrow = $sth->fetchrow_hashref; + + if (!$resultrow) { + return 0; + } + + my $originBranchCode = $resultrow->{'origin_branchcode'}; + if ($originBranchCode) { + return $originBranchCode; + } + else { + return 0; + } +} + 1; __END__ diff --git a/catalogue/detail.pl b/catalogue/detail.pl index 967d71d..788ef67 100755 --- a/catalogue/detail.pl +++ b/catalogue/detail.pl @@ -44,6 +44,7 @@ use Koha::DateUtils; use C4::HTML5Media; use C4::CourseReserves qw(GetItemCourseReservesInfo); use C4::Acquisition qw(GetOrdersByBiblionumber); +use C4::RotatingCollections qw(GetItemsCollection); my $query = CGI->new(); @@ -258,6 +259,9 @@ foreach my $item (@items) { $item->{nocancel} = 1; } + # Check the item's rotating collection status + $item->{itemsCollection} = GetItemsCollection($item->{itemnumber}); + # item has a host number if its biblio number does not match the current bib if ($item->{biblionumber} ne $biblionumber){ $item->{hostbiblionumber} = $item->{biblionumber}; diff --git a/circ/returns.pl b/circ/returns.pl index 8a17a10..8dbd060 100755 --- a/circ/returns.pl +++ b/circ/returns.pl @@ -600,10 +600,10 @@ $template->param( BlockReturnOfWithdrawnItems => C4::Context->preference("BlockReturnOfWithdrawnItems"), ); -my $itemnumber = GetItemnumberFromBarcode( $query->param('barcode') ); -if ( $itemnumber ) { - my ( $holdingBranch, $collectionBranch ) = GetCollectionItemBranches( $itemnumber ); - if ( ! ( $holdingBranch eq $collectionBranch ) ) { +my $itemnumber = GetItemnumberFromBarcode($query->param('barcode')); +if ($itemnumber) { + my ($holdingBranch, $collectionBranch) = GetCollectionItemBranches($itemnumber); + if ($holdingBranch ne $collectionBranch) { $template->param( collectionItemNeedsTransferred => 1, collectionBranch => GetBranchName($collectionBranch), diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index c21ac83..eff86c3 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -481,14 +481,16 @@ CREATE TABLE collections ( colTitle varchar(100) NOT NULL DEFAULT '', colDesc text NOT NULL, colBranchcode varchar(10) DEFAULT NULL, -- 'branchcode for branch where item should be held.' + owningBranchcode varchar(10) DEFAULT NULL, PRIMARY KEY (colId) ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8; -- -- Constraints for table `collections` -- -ALTER TABLE `collections` - ADD CONSTRAINT `collections_ibfk_1` FOREIGN KEY (`colBranchcode`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE ON UPDATE CASCADE; +ALTER TABLE collections + ADD CONSTRAINT collections_ibfk_1 FOREIGN KEY (colBranchcode) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT collections_owning_1 FOREIGN KEY (owningBranchcode) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE; -- -- Table: collections_tracking @@ -498,7 +500,12 @@ CREATE TABLE collections_tracking ( collections_tracking_id integer(11) NOT NULL auto_increment, colId integer(11) NOT NULL DEFAULT 0 comment 'collections.colId', itemnumber integer(11) NOT NULL DEFAULT 0 comment 'items.itemnumber', - PRIMARY KEY (collections_tracking_id) + origin_branchcode varchar(10) DEFAULT NULL, + transfer_branch varchar(10) DEFAULT NULL, + transferred tinyint(1) DEFAULT '0', + PRIMARY KEY (collections_tracking_id), + CONSTRAINT collections_origin_1 FOREIGN KEY (origin_branchcode) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT collections_transfer_1 FOREIGN KEY (transfer_branch) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8; -- diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl index 078ba46..c614798 100755 --- a/installer/data/mysql/updatedatabase.pl +++ b/installer/data/mysql/updatedatabase.pl @@ -8629,6 +8629,27 @@ if ( CheckVersion($DBversion) ) { SetVersion($DBversion); } +$DBversion = "3.17.00.XXX"; +if ( CheckVersion($DBversion) ) { + $dbh->do(q{ + ALTER TABLE collections_tracking + ADD origin_branchcode VARCHAR(10) NULL DEFAULT NULL, + ADD transfer_branch VARCHAR(10) NULL DEFAULT NULL, + ADD CONSTRAINT collections_origin_1 FOREIGN KEY (origin_branchcode) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE, + ADD CONSTRAINT collections_transfer_1 FOREIGN KEY (transfer_branch) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE, + ADD transferred TINYINT(1) DEFAULT 0 + }); + + $dbh->do(q{ + ALTER TABLE collections + ADD owningBranchcode VARCHAR(10) NULL DEFAULT NULL, + ADD CONSTRAINT collections_owning_1 FOREIGN KEY (owningBranchcode) REFERENCES branches (branchcode) ON DELETE CASCADE ON UPDATE CASCADE + }); + + print "Upgrade to $DBversion done (Bug 8836 - Resurrect Rotating Collections additions)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 TableExists($table) diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt index e10d95f..3d2a931 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/catalogue/detail.tt @@ -580,7 +580,12 @@ function verify_images() { </td> [% END %] <td class="location">[% UNLESS ( singlebranchmode ) %][% item.branchname %] [% END %]</td> - <td class="homebranch">[% item.homebranch %]<span class="shelvingloc">[% item.location %]</span> </td> + <td class="homebranch">[% item.homebranch %]<span class="shelvingloc">[% item.location %]</span> + [% IF item.itemsCollection %] + <span class="shelvingloc">(Col.: <a href="/cgi-bin/koha/rotating_collections/addItems.pl?colId=[% item.itemsCollection %]">[% item.itemsCollection%]</a>)</span> + </td> + [% END %] + </td> [% IF ( itemdata_ccode ) %]<td>[% item.ccode %]</td>[% END %] <td class="itemcallnumber">[% IF ( item.itemcallnumber ) %] [% item.itemcallnumber %][% END %]</td> <td class="status"> diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/addItems.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/addItems.tt index 195b324..110971d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/addItems.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/addItems.tt @@ -1,11 +1,189 @@ [% INCLUDE 'doc-head-open.inc' %] -<title>Koha › Tools › Rotating collections › Add/Remove items</title> +<title>Koha › Tools › Rotating collections › Manage collection</title> [% INCLUDE 'doc-head-close.inc' %] +[% INCLUDE 'datatables.inc' %] +<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> <script type="text/javascript"> //<![CDATA[ $( document ).ready(function() { - $("#barcode").focus(); + $("#barcode").focus(); + + // KD-139: Handle button clicking events in the item table of this view. + $("body").on("click", "a[id^=remove-colitem]", function() { + var selectedItemBarcode = this.getAttribute("data-barcode"); + var selectedItemTitle = this.getAttribute("data-title"); + if (selectedItemBarcode) { + $("#barcode").val(selectedItemBarcode); + $("#modal-remove-body-message").text("Please confirm the removal of item with the barcode: " + selectedItemBarcode + + " and title: " + selectedItemTitle + " from the collection: " + "[% colTitle %]"); + $("input[name^=removeItem]").prop('checked', true); + } + }); + + $("body").on("click", "a[id^=return-colitem]", function() { + var selectedItemNumber = this.getAttribute("data-itemnumber"); + var selectedItemTitle = this.getAttribute("data-title"); + var selectedItemOrigin = this.getAttribute("data-originbranch"); + if (selectedItemNumber && selectedItemTitle && selectedItemOrigin) { + $("#btn-return-item-confirm").attr("data-itemnumber", selectedItemNumber) + $("#modal-return-body-message").text("Please confirm the return of the item '" + selectedItemTitle + + "' to " + selectedItemOrigin); + } + }); + + $("body").on("click", "a[id^=transfer-colitem]", function() { + var selectedItemNumber = this.getAttribute("data-itemnumber"); + var selectedItemTitle = this.getAttribute("data-title"); + if (selectedItemNumber) { + $("#modal-transfer-item-body-message").text("Please select a transfer location for the item: " + selectedItemTitle); + $("#btn-transfer-item-confirm").attr("data-itemnumber", selectedItemNumber); + } + }); + + $("#transfer-col").click(function() { + var collectionId = "[% colId %]"; + var collectionTitle = "[% colTitle %]"; + var collectionTransferText = $("select[id='transfer-branch'] option:selected").text(); + var collectionTransferTo = $("select[id=transfer-branch]").val(); + if (collectionId && collectionTransferTo) { + $("#btn-transfer-confirm").attr("data-transferto", collectionTransferTo); + $("#modal-transfer-body-message").text("Please confirm the transfer of collection \'" + + collectionTitle + "\' to " + + collectionTransferText); + } + }); + + $("#btn-transfer-confirm").click(function() { + var colToTransfer = this.getAttribute('data-colid'); + var colToTransferTo = this.getAttribute('data-transferto'); + if (colToTransfer && colToTransferTo) { + transferCollection(colToTransfer, colToTransferTo); + } + }); + + $("#btn-remove-confirm").click(function() { + $("form:last").submit(); + $("input[name^=removeItem]").prop('checked', false); + }); + + $("#btn-transfer-item-confirm").click(function() { + var itemToTransfer = this.getAttribute("data-itemnumber"); + var colToTransferTo = $("select[id=transfer-item-select]").val(); + var colId = "[% colId %]"; + if (itemToTransfer && colToTransferTo) { + transferItem(colId, itemToTransfer, colToTransferTo); + } + }); + + $("#btn-return-item-confirm").click(function() { + var itemToReturn = this.getAttribute("data-itemnumber"); + var colId = "[% colId %]"; + if (itemToReturn && colId) { + returnItem(colId, itemToReturn); + } + }); + + $("#btn-remove-cancel").click(function() { + $("#barcode").val(""); + $("input[name^=removeItem]").prop('checked', false); + }); + + $(document).ajaxStart(function (event) { + $("#alert-block").hide(); + $("#alert-block").after($(".loading").show()); + }); + $(document).ajaxStop(function () { + $(".loading").hide(); + $("#alert-block").show(); + }); + + var colTable = $("#table-col-items").dataTable($.extend(true, {}, dataTablesDefaults, { + 'bAutoWidth': true, + "aoColumnDefs": [ + { 'bSortable': false, 'aTargets': [ 'nosort' ] } + ] + })); + }); + + // KD-139: Performs a transfer on a collection using a standard ajax-call + function transferCollection(selectedCollectionId, selectedCollectionTransferTo) { + $.post("transferCollection.pl", + { + colId: selectedCollectionId, + toBranch: selectedCollectionTransferTo, + transferAction: "collectionTransfer" + }) + .done(function(response) { + var resultMsg = $(response).find("#alert-block").html(); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + reloadDataTable(); + } + }); + } + + function transferItem(selectedCollectionId, selectedItemNumber, selectedCollectionTransferTo) { + $.post("transferCollection.pl", + { + colId: selectedCollectionId, + toBranch: selectedCollectionTransferTo, + itemNumber: selectedItemNumber, + transferAction: "itemTransfer" + }) + .done(function(response) { + var resultMsg = $(response).find("#alert-block").html(); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + reloadDataTable(); + } + }); + } + + function returnItem(selectedCollectionId, selectedItemNumber) { + $.post("transferCollection.pl", + { + colId: selectedCollectionId, + itemNumber: selectedItemNumber, + transferAction: "itemReturn" + }) + .done(function(response) { + var resultMsg = $(response).find("#alert-block").html(); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + reloadDataTable(); + } }); + } + + function returnCollection(selectedCollectionId) { + $.post("transferCollection.pl", + { + colId: selectedCollectionId, + transferAction: "collectionReturn" + }) + .done(function(response) { + var resultMsg = $(response).find("#alert-block").html(); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + reloadDataTable(); + } + }); + } + + function reloadDataTable() { + $.get("addItems.pl?colId=[% colId %]", function(response) { + var newCollectionsTable = $(response).find("#table-col-items").parent().html(); + var oldCollectionsTable = $("#table-col-items").parent(); + oldCollectionsTable.replaceWith(newCollectionsTable); + $("#table-col-items").dataTable($.extend(true, {}, dataTablesDefaults, { + 'bAutoWidth': true, + "aoColumnDefs": [ + { 'bSortable': false, 'aTargets': [ 'nosort' ] } + ] + })); + }); + $("#barcode").focus(); + } //]]> </script> </head> @@ -19,30 +197,38 @@ <div id="bd"> <div class="yui-gb"> - <h1>Rotating collections: Add/Remove items</h1> + <h1>Rotating collections: Manage collection</h1> - <div> + <div id="alert-block"> <br /> [% IF ( previousActionAdd ) %] [% IF ( addSuccess ) %] - <div>Item with barcode '[% addedBarcode %]' Added successfully!</div> + <div class="alert-success">Item with barcode '[% addedBarcode %]' Added successfully!</div> [% ELSE %] - <div>Failed to add item with barcode '[% addedBarcode %]'!</div> - <div>Reason: <strong>[% failureMessage %]</strong></div> + <div class="alert-error">Failed to add item with barcode '[% addedBarcode %]'!</div> + <div class="alert-error">Reason: <strong>[% failureMessage %]</strong></div> [% END %] [% END %] [% IF ( previousActionRemove ) %] [% IF ( removeSuccess ) %] - <div>Item with barcode '[% addedBarcode %]' Removed successfully!</div> + <div class="alert-success">Item with barcode '[% removedBarcode %]' Removed successfully! + [% IF messages %] + Transfer messages: + <ul> + [% FOREACH message in messages %] + <li>[% message %]</li> + [% END %] + </ul> + [% END %] + </div> [% ELSE %] - <div>Failed to remove item with barcode '[% removedBarcode %]'!</div> - <div>Reason: <strong>[% failureMessage %]</strong></div> + <div class="alert-error">Failed to remove item with barcode '[% removedBarcode %]'!</div> + <div class="alert-error">Reason: <strong>[% failureMessage %]</strong></div> [% END %] [% END %] - - <h3>Add item to <i>[% colTitle %]</i></h3> </div> + <h3>Add items to <i>[% colTitle %]</i></h3> <div> <form action="addItems.pl" method="post"> @@ -64,20 +250,36 @@ </form> </div> + <h2>Items in this collection</h2> <div> - <h2>Items in this collection</h2> [% IF ( collectionItemsLoop ) %] - <table> - <tr> - <th>Title</th> - <th>Call number</th> - <th>Barcode</th> - </tr> + <table id="table-col-items"> + <thead> + <tr> + <th>Title</th> + <th>Call number</th> + <th>Barcode</th> + <th>Origin library</th> + <th>Home library</th> + <th>Current location</th> + <th>Transferred</th> + <th class="nosort">Transfer</th> + <th class="nosort">Return</th> + <th class="nosort">Remove</th> + </tr> + </thead> [% FOREACH collectionItemsLoo IN collectionItemsLoop %] <tr> - <td>[% collectionItemsLoo.title |html %]</td> + <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% collectionItemsLoo.biblionumber %]">[% collectionItemsLoo.title |html %]</a></td> <td>[% collectionItemsLoo.itemcallnumber %]</td> - <td>[% collectionItemsLoo.barcode %]</td> + <td><a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=[% collectionItemsLoo.biblionumber %]#item[% collectionItemsLoo.itemnumber %]">[% collectionItemsLoo.barcode %]</a></td> + <td>[% collectionItemsLoo.origin_branchname %]</td> + <td>[% collectionItemsLoo.branchname %]</td> + <td>[% collectionItemsLoo.holdingbranchname %]</td> + <td>[% IF collectionItemsLoo.transferred %]Yes[% ELSE %]No[% END %]</td> + <td><a id="transfer-colitem-[% collectionItemsLoo.barcode %]" data-toggle="modal" href="#transferItemModal" class="btn btn-small" data-itemnumber="[% collectionItemsLoo.itemnumber %]" data-barcode="[% collectionItemsLoo.barcode %]" data-title="[% collectionItemsLoo.title %]"><i class="icon-gift"></i> Transfer</a></td> + <td><a id="return-colitem-[% collectionItemsLoo.barcode %]" data-toggle="modal" href="#returnColItemModal" class="btn btn-small" data-itemnumber="[% collectionItemsLoo.itemnumber %]" data-title="[% collectionItemsLoo.title %]" data-originbranch="[% collectionItemsLoo.origin_branchname %]"><i class="icon-repeat"></i> Return</a></td> + <td><a id="remove-colitem-[% collectionItemsLoo.barcode %]" data-toggle="modal" href="#removeColItemModal" class="btn btn-small" data-barcode="[% collectionItemsLoo.barcode %]" data-title="[% collectionItemsLoo.title %]"><i class="icon-remove"></i> Remove</a></td> </tr> [% END %] </table> @@ -88,10 +290,102 @@ <div> <br/> - <input type="button" value="Return to rotating collections home" onclick="window.location.href='rotatingCollections.pl'"> + <a href="rotatingCollections.pl" class="btn btn-small"><i class="icon-home"></i> Return to rotating collections home</a> + <a href="#transferColModal" data-toggle="modal" id="transfer-col" class="btn btn-small"><i class="icon-gift"></i> Transfer this collection</a> + <select name="transfer-branch" id="transfer-branch"> + [% FOREACH branch IN branchesLoop %] + [% IF ( branch.selected ) %] + <option value="[% branch.value %]" selected="selected">[% branch.branchname %]</option> + [% ELSE %] + <option value="[% branch.value %]">[% branch.branchname %]</option> + [% END %] + [% END %] + </select></td> </div> - </div> </div> +<!-- Modal for confirm deletion box--> +<div class="modal hide" id="removeColItemModal" tabindex="-1" role="dialog" aria-labelledby="removeColItemModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="removeColItemModalHeader">Confirm item removal</h3> + </div> + <div class="modal-body"> + <strong><p id="modal-remove-body-message"></p></strong> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-remove-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-remove-confirm">Remove item</button> + </div> +</div> +<!-- Modal for item transfer--> +<div class="modal hide" id="transferItemModal" tabindex="-1" role="dialog" aria-labelledby="transferItemModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="transferItemModalHeader">Select item transfer location</h3> + </div> + <div class="modal-body"> + <strong><p id="modal-transfer-item-body-message"></p></strong> + <label for="transfer-item-select">Select transfer location: </label> + <select name="transfer-item-select" id="transfer-item-select"> + [% FOREACH branch IN branchesLoop %] + [% IF ( branch.selected ) %] + <option value="[% branch.value %]" selected="selected">[% branch.branchname %]</option> + [% ELSE %] + <option value="[% branch.value %]">[% branch.branchname %]</option> + [% END %] + [% END %] + </select> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-transfer-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-transfer-item-confirm" data-colid="[% colId %]" data-transferto="" data-itemnumber="" data-dismiss="modal">Transfer</button> + </div> +</div> +<!-- Modal for confirm item return box--> +<div class="modal hide" id="returnColItemModal" tabindex="-1" role="dialog" aria-labelledby="returnColItemModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="returnColItemModalHeader">Confirm item return</h3> + </div> + <div class="modal-body"> + <strong><p id="modal-return-body-message"></p></strong> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-return-item-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-return-item-confirm" data-itemnumber="" data-dismiss="modal">Return item</button> + </div> +</div> +<!-- Modal for confirm transfer box--> +<div class="modal hide" id="transferColModal" tabindex="-1" role="dialog" aria-labelledby="transferColModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="transferColModalHeader">Confirm collection transfer</h3> + </div> + <div class="modal-body"> + <strong><p id="modal-transfer-body-message"></p></strong> + <p id="modal-transfer-body-desc"></p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-transfer-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-transfer-confirm" data-colid="[% colId %]" data-transferto="" data-dismiss="modal">Transfer collection</button> + </div> +</div> +<!-- Modal for confirm return collection box--> +<div class="modal hide" id="returnColModal" tabindex="-1" role="dialog" aria-labelledby="returnColModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="returnColModalHeader">Confirm collection return</h3> + </div> + <div class="modal-body"> + <strong><p id="modal-return-body-message"></p></strong> + <p id="modal-return-body-desc"></p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-return-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-return-confirm" data-colid="[% colId %]" data-dismiss="modal">Return collection</button> + </div> +</div> +<div class="loading hide"><strong>Processing...</strong><img src="[% interface %]/[% theme %]/img/loading.gif" /></div> [% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/editCollections.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/editCollections.tt index e1bb2a8..249c988 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/editCollections.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/editCollections.tt @@ -1,6 +1,79 @@ [% INCLUDE 'doc-head-open.inc' %] <title>Koha › Tools › Rotating collections › Edit collections</title> [% INCLUDE 'doc-head-close.inc' %] +[% INCLUDE 'datatables.inc' %] +<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> +<script type="text/javascript"> + //<![CDATA[ + $( document ).ready(function() { + var my_table = $("#table-collections").dataTable($.extend(true, {}, dataTablesDefaults, { + 'bAutoWidth': true, + 'bPaginate': false, + 'bFilter': false, + 'bInfo': false, + "aoColumnDefs": [ + { 'bSortable': false, 'aTargets': [ 'nosort' ] } + ] + })); + + // KD-139: Handle collection removal clicks + $("button[id^=remove-col]").click(function() { + var selectedCollectionId = this.getAttribute('data-colId'); + var selectedCollectionTitle = this.getAttribute('data-colTitle'); + var selectedCollectionDesc = this.getAttribute('data-colDesc'); + if (selectedCollectionId && selectedCollectionTitle) { + $("#btn-remove-confirm").attr("data-colId", selectedCollectionId); + $("#modal-remove-body-message").text("Please confirm the removal of collection: " + selectedCollectionTitle); + $("#modal-remove-body-desc").text("Description: " + selectedCollectionDesc); + } + }); + + $("#btn-remove-confirm").click(function() { + var colToRemove = this.getAttribute('data-colid'); + if (colToRemove) { + removeCollection(colToRemove); + } + }); + + $(document).ajaxStart(function (event) { + $("#alert-block").hide(); + $("#alert-block").after($(".loading").show()); + }); + $(document).ajaxStop(function () { + $(".loading").hide(); + $("#alert-block").show(); + }); + + }); + + // KD-139: Removes a collection using a standard ajax-call + function removeCollection(selectedCollectionId) { + $.get("editCollections.pl?action=delete&colId=" + selectedCollectionId, function(response) { + var resultMsg = $(response).find("#alert-block"); + var rowToRemove = $("button[id=remove-col-" + selectedCollectionId + "]").closest('tr'); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + reloadDataTable(); + } + var collectionTableRows = $('#table-collections tr').length; + if (collectionTableRows < 2) { + window.location.reload(); + } + }); + } + + function reloadDataTable() { + $(document).ready(function() { + $.get("editCollections.pl", function(response) { + var newCollectionsTable = $(response).find("#table-collections"); + var oldCollectionsTable = $("#table-collections"); + $("#table-collections_wrapper #table-collections").remove(); + $("#create-edit-collection").after(newCollectionsTable.html()); + }); + }); + } + //]]> +</script> </head> <body id="rcoll_editCollections" class="tools rcoll"> [% INCLUDE 'header.inc' %] @@ -10,67 +83,40 @@ <div id="doc3"> <div id="bd"> - <div class="yui-gb"> + <div class="yui-gb"> <h1>Rotating collections: Edit collections</h1> -<!-- + <div id="alert-block"> [% IF ( previousActionCreate ) %] [% IF ( createSuccess ) %] - <div>Collection '[% createdTitle %]' Created successfully!</div> + <div class="alert-success">Collection '[% createdTitle %]' Created successfully!</div> [% ELSE %] - <div>Collection '[% createdTitle %]' Failed to be created!</div> - <div>Reason: <strong>[% failureMessage %]</strong></div> + <div class="alert-error">Collection '[% createdTitle %]' Failed to be created!</div> + <div class="alert-error">Reason: <strong>[% failureMessage %]</strong></div> [% END %] [% END %] [% IF ( previousActionDelete ) %] - [% IF ( DeleteSuccess ) %] - <div>Collection Deleted successfully!</div> + [% IF ( deleteSuccess ) %] + <div class="alert-success">Collection Deleted successfully!</div> [% ELSE %] - <div>Collection Failed to be deleted!</div> + <div class="alert-error">Collection Failed to be deleted!</div> [% END %] [% END %] ---> + [% IF ( previousActionUpdate ) %] [% IF ( updateSuccess ) %] - <div>Collection '[% updatedTitle %]' Updated successfully!</div> + <div class="alert-success">Collection '[% updatedTitle %]' Updated successfully!</div> [% ELSE %] - <div>Collection '[% updatedTitle %]' Failed to be updated!</div> - <div>Reason: <strong>[% failureMessage %]</strong></div> + <div class="alert-error">Collection '[% updatedTitle %]' Failed to be updated!</div> + <div class="alert-error">Reason: <strong>[% failureMessage %]</strong></div> [% END %] [% END %] - + </div><br /> <div> - [% IF ( collectionsLoop ) %] - <table> - <thead> - <tr> - <th>Title</th> - <th>Description</th> - <th>Holding library</th> - <th> </th> - <th> </th> - </tr> - <thead> - <tbody> - [% FOREACH collectionsLoo IN collectionsLoop %] - <tr> - <td>[% collectionsLoo.colTitle %]</td> - <td>[% collectionsLoo.colDesc %]</td> - <td>[% collectionsLoo.colBranchcode %]</td> - <td><a href="editCollections.pl?action=edit&colId=[% collectionsLoo.colId %]">Edit</a></td> - <td><a href="editCollections.pl?action=delete&colId=[% collectionsLoo.colId %]">Delete</a></td> - </tr> - [% END %] - </tbody> - </table> - [% ELSE %] - There are no collections currently defined. - [% END %] - </div> - <div> + <div id="create-edit-collection"> <br /> [% IF ( previousActionEdit ) %] @@ -120,13 +166,57 @@ </table> </form> </div> + <br /> + + [% IF ( collectionsLoop ) %] + <table id="table-collections"> + <thead> + <tr> + <th>Title</th> + <th>Description</th> + <th>Transferred to</th> + <th class="nosort">Edit</th> + <th class="nosort">Delete</th> + </tr> + <thead> + <tbody> + [% FOREACH collectionsLoo IN collectionsLoop %] + <tr> + <td>[% collectionsLoo.colTitle %]</td> + <td>[% collectionsLoo.colDesc %]</td> + <td>[% IF collectionsLoo.branchname %][% collectionsLoo.branchname %][% ELSE %]Not yet transferred[% END %]</td> + <td><a class="btn btn-small" href="editCollections.pl?action=edit&colId=[% collectionsLoo.colId %]"><i class="icon-edit"></i> Edit</a></td> + <td><a class="btn btn-small" id="remove-col-[% collectionsLoo.colId %]" data-toggle="modal" href="#removeColModal" data-coltitle="[% collectionsLoo.colTitle %]" data-colid="[% collectionsLoo.colId %]" data-coldesc="[% collectionsLoo.colDesc %]"><i class="icon-remove"></i> Delete</a></td> + </tr> + [% END %] + </tbody> + </table> + [% ELSE %] + There are no collections currently defined. + [% END %] + </div> <div> <br/> - <input type="button" value="Return to rotating collections home" onclick="window.location.href='rotatingCollections.pl'"> + <a href="rotatingCollections.pl" class="btn btn-small"><i class="icon-home"></i> Return to rotating collections home</a> </div> </div> </div> +<!-- Modal for confirm deletion box--> +<div class="modal hide" id="removeColModal" tabindex="-1" role="dialog" aria-labelledby="removeColModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="removeColModalHeader">Confirm collection removal</h3> + </div> + <div class="modal-body"> + <strong><p id="modal-remove-body-message"></p></strong> + <p id="modal-remove-body-desc"></p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-remove-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-remove-confirm" data-colId="" data-dismiss="modal">Remove collection</button> + </div> +</div> +<div class="loading hide"><strong>Processing...</strong><img src="/intranet-tmpl/prog/img/loading.gif" /></div> [% INCLUDE 'intranet-bottom.inc' %] - diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/rotatingCollections.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/rotatingCollections.tt index e1780ad..7470178 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/rotatingCollections.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/rotatingCollections.tt @@ -1,35 +1,257 @@ [% INCLUDE 'doc-head-open.inc' %] <title>Koha › Tools › Rotating collections</title> [% INCLUDE 'doc-head-close.inc' %] +[% INCLUDE 'datatables.inc' %] +<link rel="stylesheet" type="text/css" href="[% themelang %]/css/datatables.css" /> +<script type="text/javascript"> + //<![CDATA[ + $(document).ready(function() { + + var collectionsTable = $("#table-collections").dataTable($.extend(true, {}, dataTablesDefaults, { + 'bAutoWidth': true, + 'bPaginate': true, + 'bFilter': true, + 'bInfo': true, + "aoColumnDefs": [ + { 'bSortable': false, 'aTargets': [ 'nosort' ] } + ] + })); + + // KD-139: Handle collection removal clicks + $("body").on("click", "a[id^=remove-col]", function() { + var selectedCollectionId = this.getAttribute('data-colid'); + var selectedCollectionTitle = this.getAttribute('data-coltitle'); + var selectedCollectionDesc = this.getAttribute('data-coldesc'); + if (selectedCollectionId && selectedCollectionTitle) { + $("#btn-remove-confirm").attr("data-colid", selectedCollectionId); + $("#modal-remove-body-message").text("Please confirm the removal of collection: " + selectedCollectionTitle); + $("#modal-remove-body-desc").text("Description: " + selectedCollectionDesc); + } + }); + + // KD-139: Handle collection transfer clicks + $("body").on("click", "a[id^=transfer-col]", function() { + var selectedCollectionId = this.getAttribute('data-colid'); + var selectedCollectionTitle = this.getAttribute('data-coltitle'); + var selectedCollectionTransferText = $("select[id=transfer-branch-" + selectedCollectionId + "] option:selected").text(); + var selectedCollectionTransferTo = $("select[id=transfer-branch-" + selectedCollectionId + "]").val(); + if (selectedCollectionId && selectedCollectionTitle && selectedCollectionTransferTo) { + $("#btn-transfer-confirm").attr("data-colid", selectedCollectionId); + $("#btn-transfer-confirm").attr("data-transferto", selectedCollectionTransferTo); + $("#modal-transfer-body-message").text("Please confirm the transfer of collection \'" + + selectedCollectionTitle + "\' to " + + selectedCollectionTransferText); + } + }); + + // KD-139: Handle collection edit clicks + $("body").on("click", "a[id^=edit-col]", function() { + var selectedCollectionId = this.getAttribute('data-colid'); + var selectedCollectionTitle = this.getAttribute('data-coltitle'); + var selectedCollectionDesc = this.getAttribute('data-coldesc'); + if (selectedCollectionId && selectedCollectionTitle) { + $("#btn-edit-confirm").attr("data-colid", selectedCollectionId); + $("#modal-edit-desc").val(selectedCollectionDesc); + $("#modal-edit-title").val(selectedCollectionTitle); + } + }); + + $("#btn-transfer-confirm").click(function() { + var colToTransfer = this.getAttribute('data-colid'); + var colToTransferTo = this.getAttribute('data-transferto'); + if (colToTransfer && colToTransferTo) { + transferCollection(colToTransfer, colToTransferTo); + } + }); + + $("#btn-remove-confirm").click(function() { + var colToRemove = this.getAttribute('data-colid'); + if (colToRemove) { + removeCollection(colToRemove); + } + }); + + $("#btn-edit-confirm").click(function() { + var colToEdit = this.getAttribute('data-colid'); + var colTitle = $("#modal-edit-title").val(); + var colDesc = $("#modal-edit-desc").val(); + if (colToEdit && colTitle) { + editCollection(colToEdit, colTitle, colDesc); + } + }); + + $("#btn-new-confirm").click(function() { + var colTitle = $("#modal-new-title").val(); + var colDesc = $("#modal-new-desc").val(); + if (colTitle) { + newCollection(colTitle, colDesc); + } + }); + + $(document).ajaxStart(function (event) { + $("#alert-block").hide(); + $("#alert-block").after($(".loading").show()); + }); + $(document).ajaxStop(function () { + $(".loading").hide(); + $("#alert-block").show(); + }); + + }); + + // KD-139: Removes a collection using a standard ajax-call + function removeCollection(selectedCollectionId) { + $.get("editCollections.pl?action=delete&colId=" + selectedCollectionId, function(response) { + var resultMsg = $(response).find("#alert-block"); + var rowToRemove = $("button[id=remove-col-" + selectedCollectionId + "]").closest('tr'); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + reloadDataTable(); + } + var tableRows = $("#table-collections tr").length; + if (tableRows < 3) { + window.location.reload(); + } + }); + } + + // KD-139: Performs a transfer on a collection using a standard ajax-call + function transferCollection(selectedCollectionId, selectedCollectionTransferTo) { + $.post("transferCollection.pl", + { + colId: selectedCollectionId, + toBranch: selectedCollectionTransferTo, + transferAction: "collectionTransfer" + }) + .done(function(response) { + var resultMsg = $(response).find("#alert-block"); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + reloadDataTable(); + } + }); + } + + // KD-139: Edits the given item via an ajax-call + function editCollection(colId, colTitle, colDesc) { + $.post("editCollections.pl?action=edit&colId=" + colId, + { + colId: colId, + title: colTitle, + description: colDesc, + action: 'update' + }) + .done(function(response) { + var resultMsg = $(response).find("#alert-block"); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + reloadDataTable(); + } + }); + } + + function newCollection(colTitle, colDesc) { + $.post("editCollections.pl", + { + title: colTitle, + description: colDesc, + action: 'create' + }) + .done(function(response) { + var resultMsg = $(response).find("#alert-block"); + $("#alert-block").html(resultMsg); + if ($("#alert-block").find('.alert-success')) { + $("input[id^=modal-new]").val(""); + reloadDataTable(); + } + }); + } + + function reloadDataTable() { + $.get("rotatingCollections.pl", function(response) { + var newCollectionsTable = $(response).find("#table-collections").parent().html(); + var oldCollectionsTable = $("#table-collections").parent(); + if (oldCollectionsTable.html()) { + oldCollectionsTable.replaceWith(newCollectionsTable); + } + else { + $("#title-main").next().remove(); + $("#title-main").after(newCollectionsTable); + } + $("#table-collections").dataTable($.extend(true, {}, dataTablesDefaults, { + 'bAutoWidth': true, + 'bPaginate': true, + 'bFilter': true, + 'bInfo': true, + "aoColumnDefs": [ + { 'bSortable': false, 'aTargets': [ 'nosort' ] } + ] + })); + }); + } + + //]]> +</script> </head> <body id="rcoll_rotatingCollections" class="tools rcoll"> [% INCLUDE 'header.inc' %] [% INCLUDE 'cat-search.inc' %] <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › Rotating collections</div> - +<br /> +<div id="alert-block"> +</div> <div id="doc3"> <div id="bd"> <div class="yui-gb"> - <h1>Rotating collections</h1> + <h1 id="title-main">Rotating collections</h1> <div> [% IF ( collectionsLoop ) %] - <table> - <tr> - <th><strong>Title</strong></th> - <th>Description</strong></th> - <th>Current location</th> - <th>Add/Remove items</th> - <th>Transfer collection</th> - </tr> + <table id="table-collections"> + <thead> + <tr> + <th><strong>Title</strong></th> + <th>Description</strong></th> + <th>Owner</th> + <th>Items</th> + <th>Transferred</th> +<!-- <th class="nosort">Manage collection</th>--> + <th class="nosort">Transfer collection</th> + <th class="nosort">Edit</th> + <th class="nosort">Delete</th> + </tr> + </thead> [% FOREACH collectionsLoo IN collectionsLoop %] <tr> - <td>[% collectionsLoo.colTitle %]</td> - <td>[% collectionsLoo.colDesc %]</td> - <td>[% collectionsLoo.colBranchcode %]</td> - <td><a href="addItems.pl?colId=[% collectionsLoo.colId %]">Add/Remove Items</a></td> - <td><a href="transferCollection.pl?colId=[% collectionsLoo.colId %]">Transfer Collection</a></td> + <td><a href="addItems.pl?colId=[% collectionsLoo.colId %]">[% collectionsLoo.colTitle %]</a></td> + <td>[% collectionsLoo.colDesc %]</a></td> + <td>[% collectionsLoo.branchname %]</td> + <td>[% collectionsLoo.colItemsCount %]</td> + <td>[% IF collectionsLoo.itemsTransferred > 0 %] + [% IF collectionsLoo.itemsTransferred == collectionsLoo.colItemsCount %] + All items transferred + [% ELSE %] + [% collectionsLoo.itemsTransferred %] items transferred + [% END %] + [% ELSE %] + None transferred yet + [% END %] + </td> +<!-- <td><a href="addItems.pl?colId=[% collectionsLoo.colId %]">Manage collection</a></td>--> + <td><a class="btn btn-small" id="transfer-col-[% collectionsLoo.colId %]" data-toggle="modal" href="#transferColModal" class="btn btn-small" data-colid="[% collectionsLoo.colId %]" data-coltitle="[% collectionsLoo.colTitle %]" data-coldesc="[% collectionsLoo.colDesc %]"><i class="icon-gift"></i> Transfer collection</a> + <select name="transfer-branch-[% collectionsLoo.colId %]" id="transfer-branch-[% collectionsLoo.colId %]"> + [% FOREACH branch IN branchesLoop %] + [% IF ( branch.selected ) %] + <option value="[% branch.value %]" selected="selected">[% branch.branchname %]</option> + [% ELSE %] + <option value="[% branch.value %]">[% branch.branchname %]</option> + [% END %] + [% END %] + </select></td> + <td><a class="btn btn-small" id="edit-col-[% collectionsLoo.colId %]" href="#editColModal" data-toggle="modal" data-coltitle="[% collectionsLoo.colTitle %]" data-colid="[% collectionsLoo.colId %]" data-coldesc="[% collectionsLoo.colDesc %]"><i class="icon-edit"></i> Edit</a></td> + <td><a class="btn btn-small" id="remove-col-[% collectionsLoo.colId %]" href="#removeColModal" data-toggle="modal" data-coltitle="[% collectionsLoo.colTitle %]" data-colid="[% collectionsLoo.colId %]" data-coldesc="[% collectionsLoo.colDesc %]"><i class="icon-remove"></i> Delete</a></td> + </tr> </tr> [% END %] </table> @@ -39,9 +261,118 @@ </div> <div> - <br/> - <input type="button" value="Edit collections" onclick="window.location.href='editCollections.pl'"> + <br/> + <a class="btn btn-small" id="table-col-add" href="#newColModal" data-toggle="modal"><i class="icon-plus"></i> New collection</a> + <a class="btn btn-small" href="editCollections.pl"><i class="icon-edit"></i> Edit collections</a> </div> </div> </div> -[% INCLUDE 'intranet-bottom.inc' %] \ No newline at end of file +<!-- Modal for confirm deletion box--> +<div class="modal hide" id="removeColModal" tabindex="-1" role="dialog" aria-labelledby="removeColModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="removeColModalHeader">Confirm collection removal</h3> + </div> + <div class="modal-body"> + <strong><p id="modal-remove-body-message"></p></strong> + <p id="modal-remove-body-desc"></p> + <p class="alert-info"> + <strong>Note:</strong> any currently transferred items in the removed collection will be returned to their respective origin branch + via a branch transfer. Before deleting a collection, make sure that the collection is really no longer needed and that all items + in it are good to go for a transfer back to their origin branch. If you're unsure about certain items in the collection, deal with + those individually before deleting the collection. + </p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-remove-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-remove-confirm" data-colid="" data-dismiss="modal">Remove collection</button> + </div> +</div> +<!-- Modal for confirm transfer box--> +<div class="modal hide" id="transferColModal" tabindex="-1" role="dialog" aria-labelledby="transferColModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="transferColModalHeader">Confirm collection transfer</h3> + </div> + <div class="modal-body"> + <strong><p id="modal-transfer-body-message"></p></strong> + <p id="modal-transfer-body-desc"></p> + <p class="alert-info"> + <strong>Note:</strong> any items in the collection currently not transferred to a branch will be transferred to the selected + destination branch via a branch transfer. This action transfers the whole collection to the same destination - if you need + separate transfer destinations for individual items in the collection, open the collection and perform transfers on individual items. + </p> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-transfer-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-transfer-confirm" data-colid="" data-transferto="" data-dismiss="modal">Transfer collection</button> + </div> +</div> +<!-- Modal for edit collection box--> +<div class="modal hide" id="editColModal" tabindex="-1" role="dialog" aria-labelledby="editColModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="editColModalHeader">Edit collection</h3> + </div> + <div class="modal-edit-body"> + <table id="modal-edit-table"> + <tbody> + <tr> + <td> + <label for="title">Title: </label> + </td> + <td> + <input id="modal-edit-title" type="text" value="" name="title"> + </td> + </tr> + <tr> + <td> + <label for="description">Description: </label> + </td> + <td> + <input id="modal-edit-desc" type="text" value="" name="description" size="50"> + </td> + </tr> + </tbody> + </table> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-edit-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-edit-confirm" data-colid="" data-dismiss="modal">Save</button> + </div> +</div> +<!-- Modal for new collection box--> +<div class="modal hide" id="newColModal" tabindex="-1" role="dialog" aria-labelledby="newColModalLabel" aria-hidden="true"> + <div class="modal-header"> + <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button> + <h3 id="newColModalHeader">New collection</h3> + </div> + <div class="modal-new-body"> + <table id="modal-new-table"> + <tbody> + <tr> + <td> + <label for="title">Title: </label> + </td> + <td> + <input id="modal-new-title" type="text" value="" name="title"> + </td> + </tr> + <tr> + <td> + <label for="description">Description: </label> + </td> + <td> + <input id="modal-new-desc" type="text" value="" name="description" size="50"> + </td> + </tr> + </tbody> + </table> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-primary" id="btn-new-cancel" data-dismiss="modal">Cancel</button> + <button type="submit" class="btn btn-default" id="btn-new-confirm" data-colid="" data-dismiss="modal">Create</button> + </div> +</div> +<div class="loading hide"><strong>Processing...</strong><img src="/intranet-tmpl/prog/img/loading.gif" /></div> +[% INCLUDE 'intranet-bottom.inc' %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/transferCollection.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/transferCollection.tt index 25f2cb2..a322803 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/transferCollection.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/rotating_collections/transferCollection.tt @@ -9,23 +9,69 @@ <div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › <a href="/cgi-bin/koha/tools/tools-home.pl">Tools</a> › <a href="/cgi-bin/koha/rotating_collections/rotatingCollections.pl">Rotating collections</a> › Transfer collection</div> <div id="doc3"> <div id="bd"> - <div class="yui-gb"> + <div class="yui-gb"> <h1>Rotating collections: Transfer collection</h1> <br /> - [% IF ( transferSuccess ) %] - <div>Collection transferred successfully</div> - [% END %] - - [% IF ( transferFailure ) %] - <div>Failed to transfer collection!</div> - <div>Reason: <strong>[% errorMessage %]</strong></div> + <div id="alert-block"> + <!-- Success conditions --> + [% IF transferSuccess && previousAction == "collectionTransfer" %] + <div class="alert-success">Collection transferred successfully</div> + [% ELSIF transferSuccess && previousAction == "itemTransfer" %] + <div class="alert-success">Item transferred successfully</div> + [% ELSIF transferSuccess && previousAction == "itemReturn" %] + <div class="alert-success">Item returned successfully</div> + [% ELSIF transferSuccess && previousAction == "collectionReturn" && problemItems %] + <div class="alert-success">Some items returned succesfully, problematic items: <br /> + [% FOREACH item IN problemItems %] + [% item %]<br /> + [% END %] + </div> + [% ELSIF transferSuccess && previousAction == "collectionReturn" && !problemItems %] + <div class="alert-success">Collection returned succesfully</div> + <!-- Cases where not all items were transferred succesfully --> + [% ELSIF transferSuccess && previousAction == "collectionTransfer" && problemItems %] + <div class="alert-success">Some items transferred succesfully, problematic items: <br /> + [% FOREACH item IN problemItems %] + [% item %]<br /> + [% END %] + </div> + <!-- Failing conditions--> + [% ELSIF transferFailure && previousAction == "collectionTransfer" %] + <div class="alert-error">Failed to transfer any items in collection!</div> + <div class="alert-error">Problems: <br /> + [% FOREACH item IN problemItems %] + <strong>[% item %]</strong><br /> + [% END %] + </div> + [% ELSIF transferFailure && previousAction == "itemTransfer" %] + <div class="alert-error">Failed to transfer item!</div> + <div class="alert-error">Problems: <br /> + [% FOREACH error IN errorMessage %] + <strong>[% error %]</strong><br /> + [% END %] + </div> + [% ELSIF transferFailure && previousAction == "itemReturn" %] + <div class="alert-error">Failed to return item!</div> + <div class="alert-error">Problems: <br /> + [% FOREACH error IN errorMessage %] + <strong>[% error %]</strong><br /> + [% END %] + </div> + [% ELSIF transferFailure && previousAction == "collectionReturn" %] + <div class="alert-error">Failed to return any item in collection!</div> + <div class="alert-error">Problematic items: <br /> + [% FOREACH item IN errorMessages %] + <strong>[% item %]</strong><br /> + [% END %] + </div> [% END %] - + </div> [% IF ( transferSuccess ) %] [% ELSE %] <div> <form action="transferCollection.pl" method="post"> <input type="hidden" name="colId" value="[% colId %]"> + <input type="hidden" name="transferAction" value="collectionTransfer"> <label for="toBranch">Choose your library:</label> <select name="toBranch"> @@ -40,9 +86,9 @@ <div> <br/> - <input type="button" value="Return to rotating collections home" onclick="window.location.href='rotatingCollections.pl'"> + <a href="rotatingCollections.pl" class="btn btn-small"><i class="icon-home"></i> Return to rotating collections home</a> </div> - +</div> </div> </div> [% INCLUDE 'intranet-bottom.inc' %] diff --git a/rotating_collections/addItems.pl b/rotating_collections/addItems.pl index 9ef4f39..c570f0e 100755 --- a/rotating_collections/addItems.pl +++ b/rotating_collections/addItems.pl @@ -23,14 +23,14 @@ use C4::Auth; use C4::Context; use C4::RotatingCollections; use C4::Items; +use C4::Branch; use CGI; my $query = new CGI; - my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { - template_name => "rotating_collections/addItems.tmpl", + template_name => "rotating_collections/addItems.tt", query => $query, type => "intranet", authnotrequired => 0, @@ -77,11 +77,13 @@ if ( $query->param('action') eq 'addItem' ) { ); if ($success) { - $template->param( removeSuccess => 1 ); + $template->param(removeSuccess => 1); + # Item's transfer can fail even if the removal itself was succesful + $template->param(messages => $errorMessage) if ($errorMessage); } else { - $template->param( removeFailure => 1 ); - $template->param( failureMessage => $errorMessage ); + $template->param(removeFailure => 1); + $template->param(failureMessage => $errorMessage); } } @@ -90,10 +92,14 @@ if ( $query->param('action') eq 'addItem' ) { my ( $colId, $colTitle, $colDescription, $colBranchcode ) = GetCollection( $query->param('colId') ); my $collectionItems = GetItemsInCollection($colId); + if ($collectionItems) { + $template->param( collectionItemsLoop => $collectionItems ); } +my $branchesLoop = GetBranchesLoop(); + $template->param( intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"), @@ -104,6 +110,7 @@ $template->param( colTitle => $colTitle, colDescription => $colDescription, colBranchcode => $colBranchcode, + branchesLoop => $branchesLoop ); output_html_with_http_headers $query, $cookie, $template->output; diff --git a/rotating_collections/editCollections.pl b/rotating_collections/editCollections.pl index aa46f44..8d7f66e 100755 --- a/rotating_collections/editCollections.pl +++ b/rotating_collections/editCollections.pl @@ -27,10 +27,9 @@ use C4::Context; use C4::RotatingCollections; my $query = new CGI; - my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { - template_name => "rotating_collections/editCollections.tmpl", + template_name => "rotating_collections/editCollections.tt", query => $query, type => "intranet", authnotrequired => 0, @@ -43,9 +42,11 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( if ( $query->param('action') eq 'create' ) { my $title = $query->param('title'); my $description = $query->param('description'); + my $userenv = C4::Context->userenv; + my $owningbranch = $userenv->{'branch'}; my ( $createdSuccessfully, $errorCode, $errorMessage ) = - CreateCollection( $title, $description ); + CreateCollection( $title, $description, $owningbranch ); $template->param( previousActionCreate => 1, diff --git a/rotating_collections/rotatingCollections.pl b/rotating_collections/rotatingCollections.pl index 59bbcdb..357461a 100755 --- a/rotating_collections/rotatingCollections.pl +++ b/rotating_collections/rotatingCollections.pl @@ -23,13 +23,13 @@ use CGI; use C4::Output; use C4::Auth; use C4::Context; +use C4::Branch; use C4::RotatingCollections; my $query = new CGI; - my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { - template_name => "rotating_collections/rotatingCollections.tmpl", + template_name => "rotating_collections/rotatingCollections.tt", query => $query, type => "intranet", authnotrequired => 0, @@ -39,6 +39,7 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( ); my $branchcode = $query->cookie('branch'); +my $branchesLoop = GetBranchesLoop(); my $collections = GetCollections(); @@ -49,6 +50,7 @@ $template->param( IntranetNav => C4::Context->preference("IntranetNav"), collectionsLoop => $collections, + branchesLoop => $branchesLoop ); output_html_with_http_headers $query, $cookie, $template->output; diff --git a/rotating_collections/transferCollection.pl b/rotating_collections/transferCollection.pl index 630c222..301f34a 100755 --- a/rotating_collections/transferCollection.pl +++ b/rotating_collections/transferCollection.pl @@ -28,12 +28,14 @@ use CGI; my $query = new CGI; -my $colId = $query->param('colId'); +my $colId = $query->param('colId'); +my $itemNumber = $query->param('itemNumber'); my $toBranch = $query->param('toBranch'); +my $transferAction = $query->param('transferAction'); my ( $template, $loggedinuser, $cookie ) = get_template_and_user( { - template_name => "rotating_collections/transferCollection.tmpl", + template_name => "rotating_collections/transferCollection.tt", query => $query, type => "intranet", authnotrequired => 0, @@ -43,27 +45,103 @@ my ( $template, $loggedinuser, $cookie ) = get_template_and_user( ); ## Transfer collection -my ( $success, $errorCode, $errorMessage ); -if ($toBranch) { - ( $success, $errorCode, $errorMessage ) = - TransferCollection( $colId, $toBranch ); +if ($transferAction eq 'collectionTransfer') { + my ($success, $errorCode, $problemItems); + if ($toBranch) { + ($success, $errorCode, $problemItems) = + TransferCollection($colId, $toBranch); - if ($success) { - $template->param( transferSuccess => 1 ); + if ($success) { + $template->param( + transferSuccess => 1, + previousAction => 'collectionTransfer' + ); + } + else { + $template->param( + transferFailure => 1, + errorCode => $errorCode, + problemItems => $problemItems, + previousAction => 'collectionTransfer' + ); + } } - else { - $template->param( - transferFailure => 1, - errorCode => $errorCode, - errorMessage => $errorMessage - ); +} + +## Transfer an item +if ($transferAction eq 'itemTransfer') { + my ($success, $errorCode, $errorMessage); + if ($toBranch && $itemNumber) { + ($success, $errorCode, $errorMessage) = + TransferCollectionItem($colId, $itemNumber, $toBranch); + if ($success) { + $template->param( + transferSuccess => 1, + previousAction => 'itemTransfer' + ); + } + else { + $template->param( + transferFailure => 1, + errorCode => $errorCode, + errorMessage => $errorMessage, + previousAction => 'itemTransfer' + ); + } + } +} + +## Return an item +if ($transferAction eq 'itemReturn') { + my ($success, $errorCode, $errorMessage); + if ($colId && $itemNumber) { + ($success, $errorCode, $errorMessage) = + ReturnCollectionItemToOrigin($colId, $itemNumber); + if ($success) { + $template->param( + transferSuccess => 1, + previousAction => 'itemReturn' + ); + } + else { + $template->param( + transferFailure => 1, + errorCode => $errorCode, + errorMessage => $errorMessage, + previousAction => 'itemReturn' + ); + } + } +} + +## Return a collection +if ($transferAction eq 'collectionReturn') { + my ($success, $errorCode, $errorMessages); + if ($colId) { + ($success, $errorCode, $errorMessages) = + ReturnCollectionToOrigin($colId); + if ($success) { + $template->param( + transferSuccess => 1, + problemItems => $errorMessages, + previousAction => 'collectionReturn' + ); + } + else { + $template->param( + transferFailure => 1, + errorCode => $errorCode, + errorMessages => $errorMessages, + previousAction => 'collectionReturn' + ); + } } } ## Set up the toBranch select options my $branches = GetBranches(); my @branchoptionloop; -foreach my $br ( keys %$branches ) { +foreach my $br ( sort(keys %$branches) ) { my %branch; $branch{code} = $br; $branch{name} = $branches->{$br}->{'branchname'}; -- 1.9.1