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

(-)a/Koha/Hold.pm (+52 lines)
Lines 230-235 sub move_hold_item { Link Here
230
    return $self;
230
    return $self;
231
}
231
}
232
232
233
=head3 move_hold_biblio
234
235
$hold->move_hold_biblio();
236
237
=cut
238
239
sub move_hold_biblio {
240
    my ( $self, $args ) = @_;
241
242
    my $new_biblionumber = $args->{new_biblionumber};
243
244
    my $original              = $self;
245
    my $original_biblionumber = $self->biblionumber;
246
247
    my $patron = Koha::Patrons->find( { borrowernumber => $self->borrowernumber } );
248
249
    if ($new_biblionumber) {
250
251
        #check to see if moving this hold is allowed
252
        my $canReserve = C4::Reserves::CanBookBeReserved(
253
            $patron->borrowernumber, $new_biblionumber, $self->branchcode,
254
            { ignore_hold_counts => 1 }
255
        );
256
257
        if ( $canReserve->{status} eq 'OK' ) {
258
            my $max = Koha::Holds->search(
259
                { biblionumber => $new_biblionumber },
260
                { order_by     => { -desc => 'priority' }, rows => 1 }
261
            )->next;
262
            my $base_priority = $max ? $max->priority : 0;
263
            my $priority      = $base_priority + 1;
264
            my $new_priority  = C4::Reserves::_ShiftPriority( $new_biblionumber, $priority );
265
266
            $self->update(
267
                {
268
                    itemnumber   => undef,
269
                    biblionumber => $new_biblionumber,
270
                    priority     => $new_priority,
271
                }
272
            );
273
274
            C4::Log::logaction( 'HOLDS', 'MODIFY', $self->reserve_id, $self, undef, $original )
275
                if C4::Context->preference('HoldsLog');
276
277
            return { success => 1, hold => $self };
278
        } else {
279
            return { success => 0, error => $canReserve->{status} };
280
        }
281
    }
282
    return $self;
283
}
284
233
=head3 set_transfer
285
=head3 set_transfer
234
286
235
=cut
287
=cut
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (-6 / +119 lines)
Lines 1505-1511 Link Here
1505
                </div>
1505
                </div>
1506
                <hr />
1506
                <hr />
1507
                <div id="move_hold_item_search" class="alert alert-danger" style="display:none;"></div>
1507
                <div id="move_hold_item_search" class="alert alert-danger" style="display:none;"></div>
1508
                <form id="searchForm">
1508
                <form id="itemSearchForm">
1509
                    <div id="move_hold_item_searchform">
1509
                    <div id="move_hold_item_searchform">
1510
                        <h3>2. Enter the item barcode of new hold target: </h3>
1510
                        <h3>2. Enter the item barcode of new hold target: </h3>
1511
                        <fieldset class="action">
1511
                        <fieldset class="action">
Lines 1515-1526 Link Here
1515
                    </div>
1515
                    </div>
1516
                </form>
1516
                </form>
1517
                <form id="move_hold_item_form" method="post" action="request.pl">
1517
                <form id="move_hold_item_form" method="post" action="request.pl">
1518
                    <div id="resultMessage" class="mt-3"> </div>
1518
                    <div id="itemResultMessage" class="mt-3"> </div>
1519
                    <div id="move_hold_item_confirm" style="display:none;">
1519
                    <div id="move_hold_item_confirm" style="display:none;">
1520
                        <h3>3. Confirm moving of holds:</h3>
1520
                        <h3>3. Confirm moving of holds:</h3>
1521
                        [% INCLUDE 'csrf-token.inc' %]
1521
                        [% INCLUDE 'csrf-token.inc' %]
1522
                        <input type="hidden" name="op" value="cud-move_hold_item" />
1522
                        <input type="hidden" name="op" value="cud-move_hold_item" />
1523
                        <button type="submit" class="btn btn-primary mt-3">Move selected holds</button>
1523
                        <button type="submit" class="btn btn-primary mt-3">Move selected holds</button>
1524
                        <input type="hidden" name="original_biblionumber" value="[% biblio.biblionumber %]" />
1525
                    </div>
1526
                </form>
1527
            </div>
1528
            <div class="modal-footer">
1529
                <button type="button" class="btn btn-default" data-bs-dismiss="modal">Cancel</button>
1530
            </div>
1531
        </div>
1532
    </div>
1533
</div>
1534
<div id="moveHoldBiblioModal" class="modal modal-lg" tabindex="-1" role="dialog" aria-hidden="true">
1535
    <div class="modal-dialog">
1536
        <div class="modal-content">
1537
            <div class="modal-header">
1538
                <h1 class="modal-title">Move hold(s) to a different record</h1>
1539
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
1540
            </div>
1541
            <div class="modal-body">
1542
                <div id="move_hold_item_selection">
1543
                    <h3>1. Review holds to move</h3>
1544
                    <table class="table table-striped">
1545
                        <thead>
1546
                            <tr>
1547
                                <th>Hold ID</th>
1548
                                <th>Original hold</th>
1549
                                <th>Problem</th>
1550
                            </tr>
1551
                        </thead>
1552
                        <tbody> </tbody>
1553
                    </table>
1554
                </div>
1555
                <hr />
1556
                <div id="move_hold_biblio_search" class="alert alert-danger" style="display:none;"></div>
1557
                <form id="biblioSearchForm">
1558
                    <div id="move_hold_item_searchform">
1559
                        <h3>2. Enter the bibloinumber of the new hold target: </h3>
1560
                        <fieldset class="action">
1561
                            <input type="text" class="form-control" name="biblio_id" id="biblio_id" required />
1562
                            <button type="submit" class="btn btn-default mt-3">Search</button>
1563
                        </fieldset>
1564
                    </div>
1565
                </form>
1566
                <form id="move_hold_biblio_form" method="post" action="request.pl">
1567
                    <div id="biblioResultMessage" class="mt-3"> </div>
1568
                    <div id="move_hold_biblio_confirm" style="display:none;">
1569
                        <h3>3. Confirm moving of holds:</h3>
1570
                        [% INCLUDE 'csrf-token.inc' %]
1571
                        <input type="hidden" name="op" value="cud-move_hold_biblio" />
1572
                        <button type="submit" class="btn btn-primary mt-3">Move selected holds</button>
1573
                        <input type="hidden" name="original_biblionumber" value="[% biblio.biblionumber %]" />
1524
                    </div>
1574
                    </div>
1525
                </form>
1575
                </form>
1526
            </div>
1576
            </div>
Lines 1846-1852 Link Here
1846
        }
1896
        }
1847
1897
1848
         $(document).ready(function() {
1898
         $(document).ready(function() {
1849
            $("#searchForm").on("submit", function (event) {
1899
            $("#itemSearchForm").on("submit", function (event) {
1850
                event.preventDefault();
1900
                event.preventDefault();
1851
1901
1852
                let externalID = $("#external_id").val();
1902
                let externalID = $("#external_id").val();
Lines 1871-1879 Link Here
1871
                                    <hr />
1921
                                    <hr />
1872
                                `;
1922
                                `;
1873
                            });
1923
                            });
1874
                            $("#resultMessage").html(resultHtml);
1924
                            $("#itemResultMessage").html(resultHtml);
1875
                        } else {
1925
                        } else {
1876
                            $("#resultMessage").html(`
1926
                            $("#itemResultMessage").html(`
1877
                                <div class="alert alert-warning">No item found with barcode: ${externalID}.</div>
1927
                                <div class="alert alert-warning">No item found with barcode: ${externalID}.</div>
1878
                            `);
1928
                            `);
1879
                        }
1929
                        }
Lines 1881-1886 Link Here
1881
                });
1931
                });
1882
            });
1932
            });
1883
1933
1934
            $("#biblioSearchForm").on("submit", function (event) {
1935
                event.preventDefault();
1936
1937
                let biblioID = $("#biblio_id").val();
1938
                let apiUrl = `/api/v1/items?q={"biblio_id":"${encodeURIComponent(biblioID)}"}`;
1939
1940
                $.ajax({
1941
                    url: apiUrl,
1942
                    method: "GET",
1943
                    dataType: "json",
1944
                    success: function (data) {
1945
                        if (data.length > 0) {
1946
                            let resultHtml = "";
1947
                            $.each(data, function (index, item) {
1948
                                resultHtml += `
1949
                                    <div class="alert alert-success">
1950
                                        <strong>Biblionumber:</strong> ${item.biblio_id} <br>
1951
                                        <input id="new_biblionumber_${item.biblio_id}" name="new_biblionumber" type="checkbox" value="${item.biblio_id}">
1952
                                        <label for="new_biblionumber_${item.biblio_id}">Move all selected record level holds to this record</label>
1953
                                    </div>
1954
                                    <hr />
1955
                                `;
1956
                            });
1957
                            $("#biblioResultMessage").html(resultHtml);
1958
                        } else {
1959
                            $("#biblioResultMessage").html(`
1960
                                <div class="alert alert-warning">No item found with barcode: ${biblioID}.</div>
1961
                            `);
1962
                        }
1963
                    },
1964
                });
1965
            });
1966
1884
            $(document).on("change", 'input[name="new_itemnumber"]', function() {
1967
            $(document).on("change", 'input[name="new_itemnumber"]', function() {
1885
                $('input[name="new_itemnumber"]').not(this).prop("checked", false);
1968
                $('input[name="new_itemnumber"]').not(this).prop("checked", false);
1886
                if ( $('input[name="new_itemnumber"]:checked').length ){
1969
                if ( $('input[name="new_itemnumber"]:checked').length ){
Lines 1890-1895 Link Here
1890
                }
1973
                }
1891
            });
1974
            });
1892
1975
1976
            $(document).on("change", 'input[name="new_biblionumber"]', function() {
1977
                $('input[name="new_biblionumber"]').not(this).prop("checked", false);
1978
                if ( $('input[name="new_biblionumber"]:checked').length ){
1979
                    $('#move_hold_biblio_confirm').show();
1980
                } else {
1981
                    $('#move_hold_biblio_confirm').hide();
1982
                }
1983
            });
1984
1893
            $("#always_show_holds").change(function(){
1985
            $("#always_show_holds").change(function(){
1894
                if( $(this).prop('checked') ){
1986
                if( $(this).prop('checked') ){
1895
                    document.cookie = 'always_show_holds=DO';
1987
                    document.cookie = 'always_show_holds=DO';
Lines 2020-2026 Link Here
2020
            $('.move_hold_item').click(function(e) {
2112
            $('.move_hold_item').click(function(e) {
2021
                e.preventDefault();
2113
                e.preventDefault();
2022
                if($('.holds_table .select_hold:checked').length) {
2114
                if($('.holds_table .select_hold:checked').length) {
2023
                    $('#moveHoldItemModal #resultMessage').empty();
2115
                    $('#itemResultMessage').empty();
2024
                    $('#move_hold_item_selection table tbody').empty();
2116
                    $('#move_hold_item_selection table tbody').empty();
2025
                    $('#moveHoldItemModal').modal('show');
2117
                    $('#moveHoldItemModal').modal('show');
2026
                    $('.select_hold:checked').each( function() {
2118
                    $('.select_hold:checked').each( function() {
Lines 2038-2043 Link Here
2038
                }
2130
                }
2039
            });
2131
            });
2040
2132
2133
            $('.move_hold_record').click(function(e) {
2134
                e.preventDefault();
2135
                if($('.holds_table .select_hold:checked').length) {
2136
                    $('#biblioResultMessage').empty();
2137
                    $('#move_hold_item_selection table tbody').empty();
2138
                    $('#moveHoldBiblioModal').modal('show');
2139
                    $('.select_hold:checked').each( function() {
2140
                        let reserve_id = $(this).data('id');
2141
                        let reserve_biblionumber = $(this).data('biblionumber');
2142
                        let reserve_itemnumber = $(this).data('itemnumber');
2143
                        let item_level_hold = $(this).data('item_level_hold');
2144
                        let error_message = $(this).data('item_level_hold') ? _("Cannot move a waiting or item level hold") : "";
2145
                        let found_status = $(this).data('found');
2146
                        $('#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>`)
2147
                        if ( !item_level_hold ) {
2148
                            $('#move_hold_biblio_form').append(`<input type="hidden" name="hold_id" value="${reserve_id}">`);
2149
                        }
2150
                    });
2151
                }
2152
            });
2153
2041
            $('.cancel_selected_holds').click(function(e) {
2154
            $('.cancel_selected_holds').click(function(e) {
2042
                e.preventDefault();
2155
                e.preventDefault();
2043
                if($('.holds_table .select_hold:checked').length) {
2156
                if($('.holds_table .select_hold:checked').length) {
(-)a/reserve/request.pl (-20 / +22 lines)
Lines 111-146 if ( $op eq 'cud-move' ) { Link Here
111
            $next_priority, $first_priority, $last_priority
111
            $next_priority, $first_priority, $last_priority
112
        );
112
        );
113
    }
113
    }
114
} elsif ( $op eq 'cud-move_hold_item' ) {
114
} elsif ( $op eq 'cud-move_hold_item' or $op eq 'cud-move_hold_biblio' ) {
115
    my $new_itemnumber   = $input->param('new_itemnumber');
115
    my @hold_ids              = $input->multi_param('hold_id');
116
    my $new_biblionumber = $input->param('new_biblionumber');
116
    my $original_biblionumber = $input->param('original_biblionumber');
117
    my $target_biblio    = Koha::Biblios->find($new_biblionumber);
118
    my @hold_ids         = $input->multi_param('hold_id');
119
120
    my @success_messages;
121
    my @error_messages;
122
117
123
    #Get a list of all the holds to move, ordered by current priority
124
    my @moving_holds = Koha::Holds->search(
118
    my @moving_holds = Koha::Holds->search(
125
        { reserve_id => \@hold_ids },
119
        { reserve_id => \@hold_ids },
126
        { order_by   => { -asc => 'priority' } }
120
        { order_by   => { -asc => 'priority' } }
127
    )->as_list;
121
    )->as_list;
128
122
129
    #need to get the biblionumber of the original hold
123
    my $new_biblionumber = $input->param('new_biblionumber');
130
    my $original_biblionumber = $moving_holds[0]->biblionumber;
124
    my $target_biblio    = Koha::Biblios->find($new_biblionumber);
125
126
    my $move_method;
127
    my %args;
128
129
    if ( $op eq 'cud-move_hold_item' ) {
130
        $args{new_itemnumber}   = $input->param('new_itemnumber');
131
        $args{new_biblionumber} = $new_biblionumber;
132
        $move_method            = 'move_hold_item';
133
    } else {
134
        $args{new_biblionumber} = $new_biblionumber;
135
        $move_method = 'move_hold_biblio';
136
    }
137
138
    my @success_messages;
139
    my @error_messages;
131
140
132
    my $offset = 0;
133
    foreach my $hold (@moving_holds) {
141
    foreach my $hold (@moving_holds) {
134
        my $original_biblio = Koha::Biblios->find( $hold->biblionumber );
142
        my $original_biblio = Koha::Biblios->find( $hold->biblionumber );
135
143
136
        my $result = $hold->move_hold_item(
144
        my $result = $hold->$move_method( \%args );
137
            {
138
                new_itemnumber   => $new_itemnumber,
139
                new_biblionumber => $new_biblionumber,
140
            }
141
        );
142
145
143
        #push info about successes and errors to the template
144
        if ( $result->{success} ) {
146
        if ( $result->{success} ) {
145
            push @success_messages, {
147
            push @success_messages, {
146
                hold_id         => $hold->id,
148
                hold_id         => $hold->id,
Lines 166-171 if ( $op eq 'cud-move' ) { Link Here
166
        hold_move_successes => \@success_messages,
168
        hold_move_successes => \@success_messages,
167
        hold_move_failures  => \@error_messages,
169
        hold_move_failures  => \@error_messages,
168
    );
170
    );
171
169
} elsif ( $op eq 'cud-cancel' ) {
172
} elsif ( $op eq 'cud-cancel' ) {
170
    my $reserve_id          = $input->param('reserve_id');
173
    my $reserve_id          = $input->param('reserve_id');
171
    my $cancellation_reason = $input->param("cancellation-reason");
174
    my $cancellation_reason = $input->param("cancellation-reason");
172
- 

Return to bug 31698