Bugzilla – Attachment 181958 Details for
Bug 31698
Add ability to move a hold to a new bibliographic record/item
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 31698: Add ability to move holds to new items or new records
Bug-31698-Add-ability-to-move-holds-to-new-items-o.patch (text/plain), 29.54 KB, created by
Lucas Gass (lukeg)
on 2025-05-05 22:38:49 UTC
(
hide
)
Description:
Bug 31698: Add ability to move holds to new items or new records
Filename:
MIME Type:
Creator:
Lucas Gass (lukeg)
Created:
2025-05-05 22:38:49 UTC
Size:
29.54 KB
patch
obsolete
>From 0c2f42911746c2738f6d10daca6dc89d026a1702 Mon Sep 17 00:00:00 2001 >From: Lucas Gass <lucas@bywatersolutions.com> >Date: Wed, 12 Mar 2025 21:31:35 +0000 >Subject: [PATCH] Bug 31698: Add ability to move holds to new items or new > records > >Test plan: > >1. APPLY PATCH, updatedatabase, restart_all >2. Have two staff members. 1. Superlibrarian, 2. Staff with new permission to `alter_hold_targets` >3. Now place some holds on different record, you'll want some item level holds and some record level holds. >4. After placing some holds go to a record with some holds on it. >5. Go to the holds tab (reserve/request.p) >6. You should notice a disabled 'Move selected (0)' button, next to 'Cancel selected (0)' >7. Select some holds to move, ensure that the number updates accordingly. ( Move selected (2) ) >8. When you click the button you should see 2 options, 'Item level holds to a different item' and 'Record level holds to a different record' >9. Clicking on either should bring up a modal with information about the holds you selected to move. >10. If you have item level holds and you select 'Item level holds to a different item' those holds should appear pre-checked. >11. If you have item level holds and you select 'Record level holds to a different record' those holds checkboxes should be disabled by default, you should see the 'Problem' as 'Cannot move a waiting or record level hold' >12. If you are moving a item level hold you should see a searchbar labeled 'Enter the item barcode of new hold target:'. >13. Enter a full or partial barcode and click search >14. You should see your item, if it exists. >15. Check 'Move all selected item level holds to this item', once you do so the yellow 'Move selected holds' button should be enabled. >16. Click 'Move selected holds', the hold should be moved. >17. You should see a message like " Moved the following holds: > Hold ID: 1854 - Moved from The Arden edition of the works of William Shakespeare. to The Arden edition of the works of William Shakespeare." > >19. Do steps 12 - 17 again, but with a record level hold. >20. Now make or have many holds on a specific target record to test priority. Make note of the current priority >21. Now move a hold on to that record, testing both item and record level holds. >22. Now on the target record review the priority. The holds originally on the record should not have changed. The hold you move should now have the lowest priority on the record. >23. Check the original record, if a hold was moved all other priority should have been adjusted correctly. FOr example, if the hold you moved was 3 of 4 then the others should have adjusted priority of 1 2 3 now. > >24. Turn on HoldsLog if it is disabled. >25. Move some holds, both item and record ones, and review the logs after each one. There should be a correct MODIFY entry for each move. > >26. Make an item with a hold on it as damaged and turn on AllowHoldsOnDamagedItems. Try to move the hold, you should get an error telling you that the target item is damaged. > >27. Now login as the non-superlibrarian patron from step 2. If they have the `alter_hold_targets` permission they should see the 'Move selected' button. >28. Revoke the `alter_hold_targets` permission. The button should not appear now. >--- > Koha/Hold.pm | 61 ++++ > .../prog/en/includes/holds_table.inc | 10 +- > .../prog/en/modules/reserve/request.tt | 295 ++++++++++++++++++ > reserve/request.pl | 58 +++- > 4 files changed, 421 insertions(+), 3 deletions(-) > >diff --git a/Koha/Hold.pm b/Koha/Hold.pm >index b3bf4a02b76..f76c0189580 100644 >--- a/Koha/Hold.pm >+++ b/Koha/Hold.pm >@@ -178,6 +178,67 @@ sub delete { > return $deleted; > } > >+=head3 move_hold >+ >+$hold->move_hold(); >+ >+=cut >+ >+sub move_hold { >+ my ( $self, $args ) = @_; >+ >+ my $original = $self; >+ my $original_biblionumber = $self->biblionumber; >+ >+ my $patron = Koha::Patrons->find( { borrowernumber => $self->borrowernumber } ); >+ return { success => 0, error => 'Missing patron or target' } unless $patron; >+ >+ my ( $new_biblionumber, $new_itemnumber, $item, $canReserve ); >+ >+ if ( $args->{new_itemnumber} ) { >+ $item = Koha::Items->find( { itemnumber => $args->{new_itemnumber} } ) >+ or return { success => 0, error => 'Target item not found' }; >+ >+ $new_itemnumber = $item->itemnumber; >+ $new_biblionumber = $item->biblionumber; >+ >+ $canReserve = C4::Reserves::CanItemBeReserved( $patron, $item, $self->branchcode, { ignore_hold_counts => 1 } ); >+ } elsif ( $args->{new_biblionumber} ) { >+ $new_biblionumber = $args->{new_biblionumber}; >+ >+ $canReserve = C4::Reserves::CanBookBeReserved( >+ $patron->borrowernumber, $new_biblionumber, $self->branchcode, >+ { ignore_hold_counts => 1 } >+ ); >+ } else { >+ return { success => 0, error => 'Missing itemnumber or biblionumber' }; >+ } >+ >+ return { success => 0, error => $canReserve->{status} } >+ unless $canReserve->{status} eq 'OK'; >+ >+ my $max = Koha::Holds->search( >+ { biblionumber => $new_biblionumber }, >+ { order_by => { -desc => 'priority' }, rows => 1 } >+ )->next; >+ my $base_priority = $max ? $max->priority : 0; >+ my $priority = $base_priority + 1; >+ my $new_priority = C4::Reserves::_ShiftPriority( $new_biblionumber, $priority ); >+ >+ $self->update( >+ { >+ itemnumber => $new_itemnumber, # undef for biblio-level is fine >+ biblionumber => $new_biblionumber, >+ priority => $new_priority, >+ } >+ ); >+ >+ C4::Log::logaction( 'HOLDS', 'MODIFY', $self->reserve_id, $self, undef, $original ) >+ if C4::Context->preference('HoldsLog'); >+ >+ return { success => 1, hold => $self }; >+} >+ > =head3 set_transfer > > =cut >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc >index 2d65e83dc1f..0d26304999e 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc >@@ -49,7 +49,15 @@ > [%- END -%] > [% SET tr_class = hold.suspend ? 'suspend' : '' %] > <tr class="[% tr_class | html %]"> >- <td><input type="checkbox" class="select_hold" data-id="[% hold.reserve_id | html %]" /></td> >+ <td >+ ><input >+ type="checkbox" >+ class="select_hold" >+ data-id="[% hold.reserve_id | html %]" >+ data-item_level_hold="[% hold.item_level_hold | html %]" >+ data-itemnumber="[% hold.itemnumber | html %]" >+ data-biblionumber="[% hold.biblionumber | html %]" >+ /></td> > <td> > <input type="hidden" name="reserve_id" value="[% hold.reserve_id | html %]" /> > <input type="hidden" name="borrowernumber" value="[% hold.borrowernumber | html %]" /> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >index 3979fad94fe..6e82b1bfdcd 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt >@@ -105,6 +105,9 @@ > :disabled { > opacity: 0.5; > } >+ #toolbar { >+ align-items: center; >+ } > </style> > [% END %] > </head> >@@ -171,6 +174,60 @@ > </div> > [% END %] > >+ [% IF ( hold_move_successes ) %] >+ <div class="alert alert-success"> >+ <p>Moved the following holds:</p> >+ <ul> >+ [% FOREACH hold IN hold_move_successes %] >+ <li> >+ <label>Hold ID: </label> >+ <span>[% hold.hold_id | html %]</span> >+ <span> - Moved from [%- INCLUDE 'biblio-title.inc' biblio=hold.original_biblio link = 1 -%] to [%- INCLUDE 'biblio-title.inc' biblio=hold.target_biblio link = 1 -%]</span> >+ </li> >+ [% END %] >+ </ul> >+ </div> >+ [% END %] >+ [% IF ( hold_move_failures ) %] >+ <div class="alert alert-warning"> >+ <strong>One or more holds were not moved due to following errors:</strong> >+ <ul> >+ [% FOREACH fail IN hold_move_failures %] >+ <li> >+ <label>Hold ID: </label> >+ <span>[% fail.hold_id | html %]</span> >+ [% SWITCH fail.error %] >+ [% CASE 'cannotReserveFromOtherBranches' %] >+ <span>Target item cannot be reserved from other branches</span> >+ [% CASE 'ageRestricted' %] >+ <span>The target record and/or items are age restricted</span> >+ [% CASE 'alreadypossession' %] >+ <span>Target item is already checked out to patron</span> >+ [% CASE 'noReservesAllowed' %] >+ <span>No holds are allowed on the target item(s)</span> >+ [% CASE 'tooManyReservesToday' %] >+ <span>Target item has too many holds placed on it today</span> >+ [% CASE 'tooManyReserves' %] >+ <span>Target item has too many holds placed on it</span> >+ [% CASE 'notReservable' %] >+ <span>Target item is not reservable</span> >+ [% CASE 'cannotReserveFromOtherBranches' %] >+ <span>Target item cannot be placed on reserve for this branch</span> >+ [% CASE 'branchNotInHoldGroup' %] >+ <span>Tagret item is not in the local hold group</span> >+ [% CASE 'notforloan' %] >+ <span>Target item is not for loan</span> >+ [% CASE 'damaged' %] >+ <span>Target item is damaged</span> >+ [% CASE %] >+ <span>Error: [% fail.error | html %]</span> >+ [% END %] >+ </li> >+ [% END %] >+ </ul> >+ </div> >+ [% END %] >+ > [% IF ( failed_holds ) %] > <div class="alert alert-warning"> > <strong>One or more holds were not placed due to following errors:</strong> >@@ -1235,6 +1292,15 @@ > </select> > [% END %] > </fieldset> >+ [% IF ( CAN_user_reserveforothers_alter_hold_targets ) %] >+ <div class="btn-group"> >+ <a class="btn btn-default btn-xs dropdown-toggle move_selected_holds" id="item_record_choice" role="button" data-bs-toggle="dropdown" href="#" aria-expanded="false"></a> >+ <ul class="dropdown-menu" role="menu" aria-labelledby="item_record_choice" style=""> >+ <li><a class="dropdown-item move_hold_item" href="#">Item level holds to a different item</a></li> >+ <li><a class="dropdown-item move_hold_record" href="#">Record level holds to a different record</a></li> >+ </ul> >+ </div> >+ [% END %] > </div> > <div class="page-section"> > [% FOREACH biblioloo IN biblioloop %] >@@ -1416,6 +1482,104 @@ > </div> > </div> > </div> >+<div id="moveHoldItemModal" class="modal modal-lg" tabindex="-1" role="dialog" aria-hidden="true"> >+ <div class="modal-dialog"> >+ <div class="modal-content"> >+ <div class="modal-header"> >+ <h1 class="modal-title">Move hold(s) to a different item</h1> >+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> >+ </div> >+ <div class="modal-body"> >+ <div id="move_hold_item_selection"> >+ <h3>1. Review holds to move</h3> >+ <table class="table table-striped"> >+ <thead> >+ <tr> >+ <th>Hold ID</th> >+ <th>Original hold</th> >+ <th>Problem</th> >+ </tr> >+ </thead> >+ <tbody> </tbody> >+ </table> >+ </div> >+ <hr /> >+ <div id="move_hold_item_search" class="alert alert-danger" style="display:none;"></div> >+ <form id="itemSearchForm"> >+ <div id="move_hold_item_searchform"> >+ <h3>2. Enter the item barcode of new hold target: </h3> >+ <fieldset class="action"> >+ <input type="text" class="form-control" name="external_id" id="external_id" required /> >+ <button type="submit" class="btn btn-default mt-3">Search</button> >+ </fieldset> >+ </div> >+ </form> >+ <form id="move_hold_item_form" method="post" action="request.pl"> >+ <div id="itemResultMessage" class="mt-3"> </div> >+ <div id="move_hold_item_confirm" style="display:none;"> >+ <h3>3. Confirm moving of holds:</h3> >+ [% INCLUDE 'csrf-token.inc' %] >+ <input type="hidden" name="op" value="cud-move_hold_item" /> >+ <button type="submit" class="btn btn-primary mt-3">Move selected holds</button> >+ <input type="hidden" name="original_biblionumber" value="[% biblio.biblionumber %]" /> >+ </div> >+ </form> >+ </div> >+ <div class="modal-footer"> >+ <button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button> >+ </div> >+ </div> >+ </div> >+</div> >+<div id="moveHoldBiblioModal" class="modal modal-lg" tabindex="-1" role="dialog" aria-hidden="true"> >+ <div class="modal-dialog"> >+ <div class="modal-content"> >+ <div class="modal-header"> >+ <h1 class="modal-title">Move hold(s) to a different record</h1> >+ <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> >+ </div> >+ <div class="modal-body"> >+ <div id="move_hold_item_selection"> >+ <h3>1. Review holds to move</h3> >+ <table class="table table-striped"> >+ <thead> >+ <tr> >+ <th>Hold ID</th> >+ <th>Original hold</th> >+ <th>Problem</th> >+ </tr> >+ </thead> >+ <tbody> </tbody> >+ </table> >+ </div> >+ <hr /> >+ <div id="move_hold_biblio_search" class="alert alert-danger" style="display:none;"></div> >+ <form id="biblioSearchForm"> >+ <div id="move_hold_item_searchform"> >+ <h3>2. Enter the bibloinumber of the new hold target: </h3> >+ <fieldset class="action"> >+ <input type="text" class="form-control" name="biblio_id" id="biblio_id" required /> >+ <button type="submit" class="btn btn-default mt-3">Search</button> >+ </fieldset> >+ </div> >+ </form> >+ <form id="move_hold_biblio_form" method="post" action="request.pl"> >+ <div id="biblioResultMessage" class="mt-3"> </div> >+ <div id="move_hold_biblio_confirm" style="display:none;"> >+ <h3>3. Confirm moving of holds:</h3> >+ [% INCLUDE 'csrf-token.inc' %] >+ <input type="hidden" name="op" value="cud-move_hold_biblio" /> >+ <button type="submit" class="btn btn-primary mt-3">Move selected holds</button> >+ <input type="hidden" name="original_biblionumber" value="[% biblio.biblionumber %]" /> >+ </div> >+ </form> >+ </div> >+ <div class="modal-footer"> >+ <button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button> >+ </div> >+ </div> >+ </div> >+</div> > <div id="hold-actions"> > <form id="hold-actions-form"> [% INCLUDE 'csrf-token.inc' %] </form> > </div> >@@ -1468,6 +1632,7 @@ > > var MSG_CANCEL_SELECTED = _("Cancel selected (%s)"); > var MSG_CANCEL_ALERT = _("This action will cancel <span class='badge bg-danger'>%s</span> hold(s)."); >+ var MSG_MOVE_SELECTED = _("Move selected (%s)"); > $.fn.select2.defaults.set("width", "100%" ); > $.fn.select2.defaults.set("dropdownAutoWidth", true ); > >@@ -1731,6 +1896,91 @@ > } > > $(document).ready(function() { >+ $("#itemSearchForm").on("submit", function (event) { >+ event.preventDefault(); >+ >+ let externalID = $("#external_id").val(); >+ let apiUrl = `/api/v1/items?external_id=${encodeURIComponent(externalID)}`; >+ >+ $.ajax({ >+ url: apiUrl, >+ method: "GET", >+ dataType: "json", >+ success: function (data) { >+ if (data.length > 0) { >+ let resultHtml = ""; >+ $.each(data, function (index, item) { >+ resultHtml += ` >+ <div class="alert alert-success"> >+ <strong>Biblionumber:</strong> ${item.biblio_id} <br> >+ <strong>Item:</strong> ${item.external_id} <br> >+ <input id="new_itemnumber_${item.item_id}" name="new_itemnumber" type="checkbox" value="${item.item_id}"> >+ <label for="new_itemnumber_${item.item_id}">Move all selected item level holds to this item</label> >+ <input id="new_biblionumber_${item.item_id}" name="new_biblionumber" type="hidden" value="${item.biblio_id}"> >+ </div> >+ <hr /> >+ `; >+ }); >+ $("#itemResultMessage").html(resultHtml); >+ } else { >+ $("#itemResultMessage").html(` >+ <div class="alert alert-warning">No item found with barcode: ${externalID}.</div> >+ `); >+ } >+ }, >+ }); >+ }); >+ >+ $("#biblioSearchForm").on("submit", function (event) { >+ event.preventDefault(); >+ >+ let biblioID = $("#biblio_id").val(); >+ let apiUrl = `/api/v1/items?q={"biblio_id":"${encodeURIComponent(biblioID)}"}`; >+ >+ $.ajax({ >+ url: apiUrl, >+ method: "GET", >+ dataType: "json", >+ success: function (data) { >+ if (data.length > 0) { >+ let resultHtml = ""; >+ $.each(data, function (index, item) { >+ resultHtml += ` >+ <div class="alert alert-success"> >+ <strong>Biblionumber:</strong> ${item.biblio_id} <br> >+ <input id="new_biblionumber_${item.biblio_id}" name="new_biblionumber" type="checkbox" value="${item.biblio_id}"> >+ <label for="new_biblionumber_${item.biblio_id}">Move all selected record level holds to this record</label> >+ </div> >+ <hr /> >+ `; >+ }); >+ $("#biblioResultMessage").html(resultHtml); >+ } else { >+ $("#biblioResultMessage").html(` >+ <div class="alert alert-warning">No item found with barcode: ${biblioID}.</div> >+ `); >+ } >+ }, >+ }); >+ }); >+ >+ $(document).on("change", 'input[name="new_itemnumber"]', function() { >+ $('input[name="new_itemnumber"]').not(this).prop("checked", false); >+ if ( $('input[name="new_itemnumber"]:checked').length ){ >+ $('#move_hold_item_confirm').show(); >+ } else { >+ $('#move_hold_item_confirm').hide(); >+ } >+ }); >+ >+ $(document).on("change", 'input[name="new_biblionumber"]', function() { >+ $('input[name="new_biblionumber"]').not(this).prop("checked", false); >+ if ( $('input[name="new_biblionumber"]:checked').length ){ >+ $('#move_hold_biblio_confirm').show(); >+ } else { >+ $('#move_hold_biblio_confirm').hide(); >+ } >+ }); > > $("#always_show_holds").change(function(){ > if( $(this).prop('checked') ){ >@@ -1834,6 +2084,7 @@ > }); > > $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length)); >+ $('.move_selected_holds').html(MSG_MOVE_SELECTED.format($('.holds_table .select_hold:checked').length)); > > $('.holds_table .select_hold_all').click(function() { > var table = $(this).parents('.holds_table'); >@@ -1841,6 +2092,7 @@ > $('.select_hold', table).prop('checked', !count); > $(this).prop('checked', !count); > $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length)); >+ $('.move_selected_holds').html(MSG_MOVE_SELECTED.format($('.holds_table .select_hold:checked').length)); > $('#cancel_hold_alert').html( MSG_CANCEL_ALERT.format($('.holds_table .select_hold:checked').length)); > $('#cancel_hold_alert').show(); > localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')); >@@ -1851,11 +2103,54 @@ > var count = $('.select_hold:not(:checked)', table).length; > $('.select_hold_all', table).prop('checked', !count); > $('.cancel_selected_holds').html(MSG_CANCEL_SELECTED.format($('.holds_table .select_hold:checked').length)); >+ $('.move_selected_holds').html(MSG_MOVE_SELECTED.format($('.holds_table .select_hold:checked').length)); > $('#cancel_hold_alert').html( MSG_CANCEL_ALERT.format($('.holds_table .select_hold:checked').length)); > $('#cancel_hold_alert').show(); > localStorage.selectedHolds = $('.holds_table .select_hold:checked').toArray().map(el => $(el).data('id')); > }); > >+ $('.move_hold_item').click(function(e) { >+ e.preventDefault(); >+ if($('.holds_table .select_hold:checked').length) { >+ $('#itemResultMessage').empty(); >+ $('#move_hold_item_selection table tbody').empty(); >+ $('#moveHoldItemModal').modal('show'); >+ $('.select_hold:checked').each( function() { >+ let reserve_id = $(this).data('id'); >+ let reserve_biblionumber = $(this).data('biblionumber'); >+ let reserve_itemnumber = $(this).data('itemnumber'); >+ let item_level_hold = $(this).data('item_level_hold'); >+ let error_message = $(this).data('item_level_hold') ? "" : _("Cannot move a waiting or record level hold"); >+ let found_status = $(this).data('found'); >+ $('#move_hold_item_selection table').append(`<tr><td>${reserve_id}</td><td>Biblionumber: <a target="_blank" href="/cgi-bin/koha/reserve/request.pl?biblionumber=${reserve_biblionumber}">${reserve_biblionumber}</a> Itemnumber: <a target="_blank" href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=${reserve_biblionumber}#item${reserve_itemnumber}">${reserve_itemnumber}</a></td><td>${error_message}</td></tr>`) >+ if ( item_level_hold ) { >+ $('#move_hold_item_form').append(`<input type="hidden" name="hold_id" value="${reserve_id}">`); >+ } >+ }); >+ } >+ }); >+ >+ $('.move_hold_record').click(function(e) { >+ e.preventDefault(); >+ if($('.holds_table .select_hold:checked').length) { >+ $('#biblioResultMessage').empty(); >+ $('#move_hold_item_selection table tbody').empty(); >+ $('#moveHoldBiblioModal').modal('show'); >+ $('.select_hold:checked').each( function() { >+ let reserve_id = $(this).data('id'); >+ let reserve_biblionumber = $(this).data('biblionumber'); >+ let reserve_itemnumber = $(this).data('itemnumber'); >+ let item_level_hold = $(this).data('item_level_hold'); >+ let error_message = $(this).data('item_level_hold') ? _("Cannot move a waiting or item level hold") : ""; >+ let found_status = $(this).data('found'); >+ $('#move_hold_item_selection table').append(`<tr><td>${reserve_id}</td><td>Biblionumber: <a target="_blank" href="/cgi-bin/koha/reserve/request.pl?biblionumber=${reserve_biblionumber}">${reserve_biblionumber}</a></td><td>${error_message}</td></tr>`) >+ if ( !item_level_hold ) { >+ $('#move_hold_biblio_form').append(`<input type="hidden" name="hold_id" value="${reserve_id}">`); >+ } >+ }); >+ } >+ }); >+ > $('.cancel_selected_holds').click(function(e) { > e.preventDefault(); > if($('.holds_table .select_hold:checked').length) { >diff --git a/reserve/request.pl b/reserve/request.pl >index 5908ab692b7..30142834f39 100755 >--- a/reserve/request.pl >+++ b/reserve/request.pl >@@ -44,6 +44,7 @@ use C4::Search qw( enabled_staff_search_views ); > use Koha::Biblios; > use Koha::Checkouts; > use Koha::Holds; >+use Koha::Hold; > use Koha::CirculationRules; > use Koha::Items; > use Koha::ItemTypes; >@@ -90,6 +91,7 @@ my $exceeded_maxreserves; > my $exceeded_holds_per_record; > my @failed_holds = $input->multi_param('failed_holds'); > my $form_submitted = $input->param('form_submitted'); >+my @biblionumbers = $input->multi_param('biblionumber'); > > my $op = $input->param('op') || q{}; > >@@ -109,6 +111,60 @@ if ( $op eq 'cud-move' ) { > $next_priority, $first_priority, $last_priority > ); > } >+} elsif ( $op eq 'cud-move_hold_item' or $op eq 'cud-move_hold_biblio' ) { >+ my @hold_ids = $input->multi_param('hold_id'); >+ my $original_biblionumber = $input->param('original_biblionumber'); >+ my @moving_holds = Koha::Holds->search( >+ { reserve_id => \@hold_ids }, >+ { order_by => { -asc => 'priority' } } >+ )->as_list; >+ >+ my $new_biblionumber = $input->param('new_biblionumber'); >+ my $target_biblio = Koha::Biblios->find($new_biblionumber); >+ >+ my %args = ( >+ new_biblionumber => $new_biblionumber, >+ ); >+ >+ # Only pass new_itemnumber if this is an item level move >+ if ( $op eq 'cud-move_hold_item' ) { >+ $args{new_itemnumber} = $input->param('new_itemnumber'); >+ } >+ >+ my @success_messages; >+ my @error_messages; >+ >+ foreach my $hold (@moving_holds) { >+ my $original_biblio = Koha::Biblios->find( $hold->biblionumber ); >+ >+ my $result = $hold->move_hold( \%args ); >+ >+ if ( $result->{success} ) { >+ push @success_messages, { >+ hold_id => $hold->id, >+ success => 1, >+ original_biblio => $original_biblio, >+ target_biblio => $target_biblio, >+ }; >+ } else { >+ push @error_messages, { >+ hold_id => $hold->id, >+ success => 0, >+ original_biblio => $original_biblio, >+ target_biblio => $target_biblio, >+ error => $result->{error}, >+ }; >+ } >+ } >+ >+ #Fix the priority on the original record >+ C4::Reserves::_FixPriority( { biblionumber => $original_biblionumber } ); >+ >+ $template->param( >+ hold_move_successes => \@success_messages, >+ hold_move_failures => \@error_messages, >+ ); >+ > } elsif ( $op eq 'cud-cancel' ) { > my $reserve_id = $input->param('reserve_id'); > my $cancellation_reason = $input->param("cancellation-reason"); >@@ -172,8 +228,6 @@ if ($form_submitted) { > } > } > >-my @biblionumbers = $input->multi_param('biblionumber'); >- > my $multi_hold = @biblionumbers > 1; > $template->param( > multi_hold => $multi_hold, >-- >2.39.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 31698
:
179226
|
179235
|
179236
|
179279
|
179287
|
179290
|
179291
|
179292
|
179295
|
179704
|
179711
|
179713
|
181222
|
181223
|
181224
|
181225
|
181226
|
181228
|
181229
|
181230
|
181231
|
181232
|
181233
|
181234
|
181929
|
181930
|
181944
|
181945
|
181946
|
181947
|
181948
|
181951
|
181952
|
181953
|
181954
|
181955
|
181956
|
181957
| 181958 |
181959
|
181960
|
181961
|
181962
|
182639
|
182640
|
182641