View | Details | Raw Unified | Return to bug 31698
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (+234 lines)
Lines 1243-1248 Link Here
1243
                            </select>
1243
                            </select>
1244
                        [% END %]
1244
                        [% END %]
1245
                    </fieldset>
1245
                    </fieldset>
1246
                    [% IF ( CAN_user_reserveforothers_alter_hold_targets ) %]
1247
                        <div class="btn-group">
1248
                            <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>
1249
                            <ul class="dropdown-menu" role="menu" aria-labelledby="item_record_choice" style="">
1250
                                <li><a class="dropdown-item move_hold_item" href="#">Item level holds to a different item</a></li>
1251
                                <li><a class="dropdown-item move_hold_record" href="#">Record level holds to a different record</a></li>
1252
                            </ul>
1253
                        </div>
1254
                    [% END %]
1246
                </div>
1255
                </div>
1247
                <div class="page-section">
1256
                <div class="page-section">
1248
                    [% FOREACH biblioloo IN biblioloop %]
1257
                    [% FOREACH biblioloo IN biblioloop %]
Lines 1387-1392 Link Here
1387
1396
1388
[% PROCESS 'cancel-hold-modal' form_action = 'request.pl' %]
1397
[% PROCESS 'cancel-hold-modal' form_action = 'request.pl' %]
1389
1398
1399
<div id="moveHoldItemModal" class="modal modal-lg" tabindex="-1" role="dialog" aria-hidden="true">
1400
    <div class="modal-dialog">
1401
        <div class="modal-content">
1402
            <div class="modal-header">
1403
                <h1 class="modal-title">Move hold(s) to a different item</h1>
1404
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1405
            </div>
1406
            <div class="modal-body">
1407
                <div id="move_hold_item_selection">
1408
                    <h3>1. Review holds to move</h3>
1409
                    <table class="table table-striped">
1410
                        <thead>
1411
                            <tr>
1412
                                <th>Hold ID</th>
1413
                                <th>Original hold</th>
1414
                                <th>Problem</th>
1415
                            </tr>
1416
                        </thead>
1417
                        <tbody> </tbody>
1418
                    </table>
1419
                </div>
1420
                <hr />
1421
                <div id="move_hold_item_search" class="alert alert-danger" style="display:none;"></div>
1422
                <form id="itemSearchForm">
1423
                    <div id="move_hold_item_searchform">
1424
                        <h3>2. Enter the item barcode of new hold target: </h3>
1425
                        <fieldset class="action">
1426
                            <input type="text" class="form-control" name="external_id" id="external_id" required />
1427
                            <button type="submit" class="btn btn-default mt-3">Search</button>
1428
                        </fieldset>
1429
                    </div>
1430
                </form>
1431
                <form id="move_hold_item_form" method="post" action="request.pl">
1432
                    <div id="itemResultMessage" class="mt-3"> </div>
1433
                    <div id="move_hold_item_confirm" style="display:none;">
1434
                        <h3>3. Confirm moving of holds:</h3>
1435
                        [% INCLUDE 'csrf-token.inc' %]
1436
                        <input type="hidden" name="op" value="cud-move_hold_item" />
1437
                        <button type="submit" class="btn btn-primary mt-3">Move selected holds</button>
1438
                        <input type="hidden" name="original_biblionumber" value="[% biblio.biblionumber %]" />
1439
                    </div>
1440
                </form>
1441
            </div>
1442
            <div class="modal-footer">
1443
                <button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button>
1444
            </div>
1445
        </div>
1446
    </div>
1447
</div>
1448
<div id="moveHoldBiblioModal" class="modal modal-lg" tabindex="-1" role="dialog" aria-hidden="true">
1449
    <div class="modal-dialog">
1450
        <div class="modal-content">
1451
            <div class="modal-header">
1452
                <h1 class="modal-title">Move hold(s) to a different record</h1>
1453
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1454
            </div>
1455
            <div class="modal-body">
1456
                <div id="move_hold_item_selection">
1457
                    <h3>1. Review holds to move</h3>
1458
                    <table class="table table-striped">
1459
                        <thead>
1460
                            <tr>
1461
                                <th>Hold ID</th>
1462
                                <th>Original hold</th>
1463
                                <th>Problem</th>
1464
                            </tr>
1465
                        </thead>
1466
                        <tbody> </tbody>
1467
                    </table>
1468
                </div>
1469
                <hr />
1470
                <div id="move_hold_biblio_search" class="alert alert-danger" style="display:none;"></div>
1471
                <form id="biblioSearchForm">
1472
                    <div id="move_hold_item_searchform">
1473
                        <h3>2. Enter the bibloinumber of the new hold target: </h3>
1474
                        <fieldset class="action">
1475
                            <input type="text" class="form-control" name="biblio_id" id="biblio_id" required />
1476
                            <button type="submit" class="btn btn-default mt-3">Search</button>
1477
                        </fieldset>
1478
                    </div>
1479
                </form>
1480
                <form id="move_hold_biblio_form" method="post" action="request.pl">
1481
                    <div id="biblioResultMessage" class="mt-3"> </div>
1482
                    <div id="move_hold_biblio_confirm" style="display:none;">
1483
                        <h3>3. Confirm moving of holds:</h3>
1484
                        [% INCLUDE 'csrf-token.inc' %]
1485
                        <input type="hidden" name="op" value="cud-move_hold_biblio" />
1486
                        <button type="submit" class="btn btn-primary mt-3">Move selected holds</button>
1487
                        <input type="hidden" name="original_biblionumber" value="[% biblio.biblionumber %]" />
1488
                    </div>
1489
                </form>
1490
            </div>
1491
            <div class="modal-footer">
1492
                <button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button>
1493
            </div>
1494
        </div>
1495
    </div>
1496
</div>
1390
<div id="hold-actions">
1497
<div id="hold-actions">
1391
    <form id="hold-actions-form"> [% INCLUDE 'csrf-token.inc' %] </form>
1498
    <form id="hold-actions-form"> [% INCLUDE 'csrf-token.inc' %] </form>
1392
</div>
1499
</div>
Lines 1699-1704 Link Here
1699
        }
1806
        }
1700
1807
1701
         $(document).ready(function() {
1808
         $(document).ready(function() {
1809
            $("#itemSearchForm").on("submit", function (event) {
1810
                event.preventDefault();
1811
1812
                let externalID = $("#external_id").val();
1813
                let apiUrl = `/api/v1/items?external_id=${encodeURIComponent(externalID)}`;
1814
1815
                $.ajax({
1816
                    url: apiUrl,
1817
                    method: "GET",
1818
                    dataType: "json",
1819
                    success: function (data) {
1820
                        if (data.length > 0) {
1821
                            let resultHtml = "";
1822
                            $.each(data, function (index, item) {
1823
                                resultHtml += `
1824
                                    <div class="alert alert-success">
1825
                                        <strong>Biblionumber:</strong> ${item.biblio_id} <br>
1826
                                        <strong>Item:</strong> ${item.external_id} <br>
1827
                                        <input id="new_itemnumber_${item.item_id}" name="new_itemnumber" type="checkbox" value="${item.item_id}">
1828
                                        <label for="new_itemnumber_${item.item_id}">Move all selected item level holds to this item</label>
1829
                                        <input id="new_biblionumber_${item.item_id}" name="new_biblionumber" type="hidden" value="${item.biblio_id}">
1830
                                    </div>
1831
                                    <hr />
1832
                                `;
1833
                            });
1834
                            $("#itemResultMessage").html(resultHtml);
1835
                        } else {
1836
                            $("#itemResultMessage").html(`
1837
                                <div class="alert alert-warning">No item found with barcode: ${externalID}.</div>
1838
                            `);
1839
                        }
1840
                    },
1841
                });
1842
            });
1843
1844
            $("#biblioSearchForm").on("submit", function (event) {
1845
                event.preventDefault();
1846
1847
                let biblioID = $("#biblio_id").val();
1848
                let apiUrl = `/api/v1/items?q={"biblio_id":"${encodeURIComponent(biblioID)}"}`;
1849
1850
                $.ajax({
1851
                    url: apiUrl,
1852
                    method: "GET",
1853
                    dataType: "json",
1854
                    success: function (data) {
1855
                        if (data.length > 0) {
1856
                            let resultHtml = "";
1857
                            $.each(data, function (index, item) {
1858
                                resultHtml += `
1859
                                    <div class="alert alert-success">
1860
                                        <strong>Biblionumber:</strong> ${item.biblio_id} <br>
1861
                                        <input id="new_biblionumber_${item.biblio_id}" name="new_biblionumber" type="checkbox" value="${item.biblio_id}">
1862
                                        <label for="new_biblionumber_${item.biblio_id}">Move all selected record level holds to this record</label>
1863
                                    </div>
1864
                                    <hr />
1865
                                `;
1866
                            });
1867
                            $("#biblioResultMessage").html(resultHtml);
1868
                        } else {
1869
                            $("#biblioResultMessage").html(`
1870
                                <div class="alert alert-warning">No item found with barcode: ${biblioID}.</div>
1871
                            `);
1872
                        }
1873
                    },
1874
                });
1875
            });
1876
1877
            $(document).on("change", 'input[name="new_itemnumber"]', function() {
1878
                $('input[name="new_itemnumber"]').not(this).prop("checked", false);
1879
                if ( $('input[name="new_itemnumber"]:checked').length ){
1880
                    $('#move_hold_item_confirm').show();
1881
                } else {
1882
                    $('#move_hold_item_confirm').hide();
1883
                }
1884
            });
1885
1886
            $(document).on("change", 'input[name="new_biblionumber"]', function() {
1887
                $('input[name="new_biblionumber"]').not(this).prop("checked", false);
1888
                if ( $('input[name="new_biblionumber"]:checked').length ){
1889
                    $('#move_hold_biblio_confirm').show();
1890
                } else {
1891
                    $('#move_hold_biblio_confirm').hide();
1892
                }
1893
            });
1702
1894
1703
            $("#always_show_holds").change(function(){
1895
            $("#always_show_holds").change(function(){
1704
                if( $(this).prop('checked') ){
1896
                if( $(this).prop('checked') ){
Lines 1800-1805 Link Here
1800
                });
1992
                });
1801
            [% END %]
1993
            [% END %]
1802
1994
1995
            $('.move_hold_item').click(function(e) {
1996
                e.preventDefault();
1997
                if($('.holds_table .select_hold:checked').length) {
1998
                    $('#itemResultMessage').empty();
1999
                    $('#move_hold_item_selection table tbody').empty();
2000
                    $('#moveHoldItemModal').modal('show');
2001
                    $('.select_hold:checked').each( function() {
2002
                        let reserve_id = $(this).data('id');
2003
                        let reserve_biblionumber = $(this).data('biblionumber');
2004
                        let reserve_itemnumber = $(this).data('itemnumber');
2005
                        let item_level_hold = $(this).data('item_level_hold');
2006
                        let error_message = $(this).data('item_level_hold') ? "" : _("Cannot move a waiting or record level hold");
2007
                        let found_status = $(this).data('found');
2008
                        $('#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>`)
2009
                        if ( item_level_hold ) {
2010
                            $('#move_hold_item_form').append(`<input type="hidden" name="hold_id" value="${reserve_id}">`);
2011
                        }
2012
                    });
2013
                }
2014
            });
2015
2016
            $('.move_hold_record').click(function(e) {
2017
                e.preventDefault();
2018
                if($('.holds_table .select_hold:checked').length) {
2019
                    $('#biblioResultMessage').empty();
2020
                    $('#move_hold_item_selection table tbody').empty();
2021
                    $('#moveHoldBiblioModal').modal('show');
2022
                    $('.select_hold:checked').each( function() {
2023
                        let reserve_id = $(this).data('id');
2024
                        let reserve_biblionumber = $(this).data('biblionumber');
2025
                        let reserve_itemnumber = $(this).data('itemnumber');
2026
                        let item_level_hold = $(this).data('item_level_hold');
2027
                        let error_message = $(this).data('item_level_hold') ? _("Cannot move a waiting or item level hold") : "";
2028
                        let found_status = $(this).data('found');
2029
                        $('#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>`)
2030
                        if ( !item_level_hold ) {
2031
                            $('#move_hold_biblio_form').append(`<input type="hidden" name="hold_id" value="${reserve_id}">`);
2032
                        }
2033
                    });
2034
                }
2035
            });
2036
1803
            $(".hold-arrow").click(function(e) {
2037
            $(".hold-arrow").click(function(e) {
1804
                e.preventDefault();
2038
                e.preventDefault();
1805
                let arrowForm = $("#hold-actions-form").attr({
2039
                let arrowForm = $("#hold-actions-form").attr({
(-)a/reserve/request.pl (-1 / +54 lines)
Lines 110-115 if ( $op eq 'cud-move' ) { Link Here
110
            $next_priority, $first_priority, $last_priority
110
            $next_priority, $first_priority, $last_priority
111
        );
111
        );
112
    }
112
    }
113
} elsif ( $op eq 'cud-move_hold_item' or $op eq 'cud-move_hold_biblio' ) {
114
    my @hold_ids              = $input->multi_param('hold_id');
115
    my $original_biblionumber = $input->param('original_biblionumber');
116
    my @moving_holds          = Koha::Holds->search(
117
        { reserve_id => \@hold_ids },
118
        { order_by   => { -asc => 'priority' } }
119
    )->as_list;
120
121
    my $new_biblionumber = $input->param('new_biblionumber');
122
    my $target_biblio    = Koha::Biblios->find($new_biblionumber);
123
124
    my %args = (
125
        new_biblionumber => $new_biblionumber,
126
    );
127
128
    # Only pass new_itemnumber if this is an item level move
129
    if ( $op eq 'cud-move_hold_item' ) {
130
        $args{new_itemnumber} = $input->param('new_itemnumber');
131
    }
132
133
    my @success_messages;
134
    my @error_messages;
135
136
    foreach my $hold (@moving_holds) {
137
        my $original_biblio = Koha::Biblios->find( $hold->biblionumber );
138
139
        my $result = $hold->move_hold( \%args );
140
141
        if ( $result->{success} ) {
142
            push @success_messages, {
143
                hold_id         => $hold->id,
144
                success         => 1,
145
                original_biblio => $original_biblio,
146
                target_biblio   => $target_biblio,
147
            };
148
        } else {
149
            push @error_messages, {
150
                hold_id         => $hold->id,
151
                success         => 0,
152
                original_biblio => $original_biblio,
153
                target_biblio   => $target_biblio,
154
                error           => $result->{error},
155
            };
156
        }
157
    }
158
159
    #Fix the priority on the original record
160
    C4::Reserves::_FixPriority( { biblionumber => $original_biblionumber } );
161
162
    $template->param(
163
        hold_move_successes => \@success_messages,
164
        hold_move_failures  => \@error_messages,
165
    );
166
113
} elsif ( $op eq 'cud-cancel' ) {
167
} elsif ( $op eq 'cud-cancel' ) {
114
    my $reserve_id          = $input->param('reserve_id');
168
    my $reserve_id          = $input->param('reserve_id');
115
    my $cancellation_reason = $input->param("cancellation-reason");
169
    my $cancellation_reason = $input->param("cancellation-reason");
116
- 

Return to bug 31698