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

(-)a/C4/Circulation.pm (-23 / +214 lines)
Lines 22-32 use Modern::Perl; Link Here
22
use DateTime;
22
use DateTime;
23
use POSIX qw( floor );
23
use POSIX qw( floor );
24
use Encode;
24
use Encode;
25
use JSON;
25
26
26
use C4::Context;
27
use C4::Context;
27
use C4::Stats qw( UpdateStats );
28
use C4::Stats qw( UpdateStats );
28
use C4::Reserves
29
use C4::Reserves
29
    qw( CheckReserves CanItemBeReserved MoveReserve ModReserve ModReserveMinusPriority RevertWaitingStatus IsAvailableForItemLevelRequest );
30
    qw( CheckReserves CanItemBeReserved MoveReserve ModReserve ModReserveMinusPriority RevertWaitingStatus IsItemOnHoldAndFound IsAvailableForItemLevelRequest );
30
use C4::Biblio qw( UpdateTotalIssues );
31
use C4::Biblio qw( UpdateTotalIssues );
31
use C4::Items  qw( ModItemTransfer ModDateLastSeen CartToShelf );
32
use C4::Items  qw( ModItemTransfer ModDateLastSeen CartToShelf );
32
use C4::Accounts;
33
use C4::Accounts;
Lines 109-114 BEGIN { Link Here
109
        transferbook
110
        transferbook
110
        TooMany
111
        TooMany
111
        GetTransfersFromTo
112
        GetTransfersFromTo
113
        updateWrongTransfer
112
        CalcDateDue
114
        CalcDateDue
113
        CheckValidBarcode
115
        CheckValidBarcode
114
        IsBranchTransferAllowed
116
        IsBranchTransferAllowed
Lines 319-324 A recall for this item was found, and the item needs to be transferred to the re Link Here
319
321
320
=cut
322
=cut
321
323
324
my $query = CGI->new;
325
326
my $stickyduedate      = $query->param('stickyduedate');
327
my $duedatespec        = $query->param('duedatespec');
328
my $restoreduedatespec = $query->param('restoreduedatespec') || $duedatespec;
329
if ( $restoreduedatespec && $restoreduedatespec eq "highholds_empty" ) {
330
    undef $restoreduedatespec;
331
}
332
my $issueconfirmed = $query->param('issueconfirmed');
333
my $cancelreserve  = $query->param('cancelreserve');
334
my $cancel_recall  = $query->param('cancel_recall');
335
my $recall_id      = $query->param('recall_id');
336
my $debt_confirmed = $query->param('debt_confirmed') || 0;     # Don't show the debt error dialog twice
337
my $charges        = $query->param('charges')        || q{};
338
322
sub transferbook {
339
sub transferbook {
323
    my $params   = shift;
340
    my $params   = shift;
324
    my $tbr      = $params->{to_branch};
341
    my $tbr      = $params->{to_branch};
Lines 816-824 sub CanBookBeIssued { Link Here
816
    my $circ_library = Koha::Libraries->find( _GetCircControlBranch( $item_object, $patron ) );
833
    my $circ_library = Koha::Libraries->find( _GetCircControlBranch( $item_object, $patron ) );
817
834
818
    my $now = dt_from_string();
835
    my $now = dt_from_string();
836
    my $message;
837
    my @message;
838
819
    $duedate ||= CalcDateDue( $now, $effective_itemtype, $circ_library->branchcode, $patron );
839
    $duedate ||= CalcDateDue( $now, $effective_itemtype, $circ_library->branchcode, $patron );
840
820
    if ( DateTime->compare( $duedate, $now ) == -1 ) {    # duedate cannot be before now
841
    if ( DateTime->compare( $duedate, $now ) == -1 ) {    # duedate cannot be before now
821
        $needsconfirmation{INVALID_DATE} = $duedate;
842
        $needsconfirmation{INVALID_DATE} = $duedate;
843
        if ($issueconfirmed) {
844
            if ($message) {
845
                $message = "$message + sticky due date is invalid or due date in the past";
846
            } else {
847
                $message = "sticky due date is invalid or due date in the past";
848
            }
849
            push( @message, "sticky due date is invalid or due date in the past" );
850
        }
851
822
    }
852
    }
823
853
824
    my $fees = Koha::Charges::Fees->new(
854
    my $fees = Koha::Charges::Fees->new(
Lines 864-869 sub CanBookBeIssued { Link Here
864
    }
894
    }
865
    if ( $patron->is_debarred ) {
895
    if ( $patron->is_debarred ) {
866
        $issuingimpossible{DEBARRED} = 1;
896
        $issuingimpossible{DEBARRED} = 1;
897
        if ($issueconfirmed) {
898
            if ($message) {
899
                $message = "$message + borrower is restricted";
900
            } else {
901
                $message = "borrower is restricted";
902
            }
903
            push( @message, "borrower is restricted" );
904
        }
867
    }
905
    }
868
906
869
    if ( $patron->is_expired ) {
907
    if ( $patron->is_expired ) {
Lines 936-945 sub CanBookBeIssued { Link Here
936
    } else {
974
    } else {
937
        if ( $patron_borrowing_status->{noissuescharge}->{overlimit} && $allowfineoverride ) {
975
        if ( $patron_borrowing_status->{noissuescharge}->{overlimit} && $allowfineoverride ) {
938
            $needsconfirmation{DEBT} = $patron_borrowing_status->{noissuescharge}->{charge};
976
            $needsconfirmation{DEBT} = $patron_borrowing_status->{noissuescharge}->{charge};
977
            if ($issueconfirmed) {
978
                if ($message) {
979
                    $message = "$message + borrower had amend";
980
                } else {
981
                    $message = "borrower had amend";
982
                }
983
                push( @message, "borrower had amend" );
984
            }
939
        } elsif ( $patron_borrowing_status->{noissuescharge}->{overlimit} && !$allowfineoverride ) {
985
        } elsif ( $patron_borrowing_status->{noissuescharge}->{overlimit} && !$allowfineoverride ) {
940
            $issuingimpossible{DEBT} = $patron_borrowing_status->{noissuescharge}->{charge};
986
            $issuingimpossible{DEBT} = $patron_borrowing_status->{noissuescharge}->{charge};
941
        } elsif ( $patron_borrowing_status->{noissuescharge}->{charge} > 0 && $allfinesneedoverride ) {
987
        } elsif ( $patron_borrowing_status->{noissuescharge}->{charge} > 0 && $allfinesneedoverride ) {
942
            $needsconfirmation{DEBT} = $patron_borrowing_status->{noissuescharge}->{charge};
988
            $needsconfirmation{DEBT} = $patron_borrowing_status->{noissuescharge}->{charge};
989
            if ($issueconfirmed) {
990
                if ($message) {
991
                    $message = "$message + borrower had amend";
992
                } else {
993
                    $message = "borrower had amend";
994
                }
995
                push( @message, "borrower had amend" );
996
            }
943
        }
997
        }
944
    }
998
    }
945
999
Lines 1020-1025 sub CanBookBeIssued { Link Here
1020
                $needsconfirmation{issued_surname}        = $patron->surname;
1074
                $needsconfirmation{issued_surname}        = $patron->surname;
1021
                $needsconfirmation{issued_cardnumber}     = $patron->cardnumber;
1075
                $needsconfirmation{issued_cardnumber}     = $patron->cardnumber;
1022
                $needsconfirmation{issued_borrowernumber} = $patron->borrowernumber;
1076
                $needsconfirmation{issued_borrowernumber} = $patron->borrowernumber;
1077
                if ($issueconfirmed) {
1078
                    if ($message) {
1079
                        $message = "$message + item is checked out for someone else ";
1080
                    } else {
1081
                        $message = "item is checked out for someone else";
1082
                    }
1083
                    push( @message, "item is checked out for someone else" );
1084
                }
1023
            }
1085
            }
1024
        }
1086
        }
1025
    }
1087
    }
Lines 1047-1052 sub CanBookBeIssued { Link Here
1047
            $needsconfirmation{current_loan_count}        = $toomany->{count};
1109
            $needsconfirmation{current_loan_count}        = $toomany->{count};
1048
            $needsconfirmation{max_loans_allowed}         = $toomany->{max_allowed};
1110
            $needsconfirmation{max_loans_allowed}         = $toomany->{max_allowed};
1049
            $needsconfirmation{circulation_rule_TOO_MANY} = $toomany->{circulation_rule};
1111
            $needsconfirmation{circulation_rule_TOO_MANY} = $toomany->{circulation_rule};
1112
            if ($issueconfirmed) {
1113
                if ($message) {
1114
                    $message = "$message + too many checkout";
1115
                } else {
1116
                    $message = "too many checkout";
1117
                }
1118
                push( @message, "too many checkout" );
1119
            }
1050
        } else {
1120
        } else {
1051
            $issuingimpossible{TOO_MANY}                  = $toomany->{reason};
1121
            $issuingimpossible{TOO_MANY}                  = $toomany->{reason};
1052
            $issuingimpossible{current_loan_count}        = $toomany->{count};
1122
            $issuingimpossible{current_loan_count}        = $toomany->{count};
Lines 1074-1079 sub CanBookBeIssued { Link Here
1074
        } else {
1144
        } else {
1075
            $needsconfirmation{NOT_FOR_LOAN_FORCING} = 1;
1145
            $needsconfirmation{NOT_FOR_LOAN_FORCING} = 1;
1076
            $needsconfirmation{item_notforloan}      = $item_object->notforloan;
1146
            $needsconfirmation{item_notforloan}      = $item_object->notforloan;
1147
            if ($issueconfirmed) {
1148
                if ($message) {
1149
                    $message = "$message + item not for loan";
1150
                } else {
1151
                    $message = "item not for loan";
1152
                }
1153
                push( @message, "item not for loan" );
1154
            }
1077
        }
1155
        }
1078
    } else {
1156
    } else {
1079
1157
Lines 1119-1124 sub CanBookBeIssued { Link Here
1119
        my $code = $av->count ? $av->next->lib : '';
1197
        my $code = $av->count ? $av->next->lib : '';
1120
        $needsconfirmation{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'confirm' );
1198
        $needsconfirmation{ITEM_LOST} = $code if ( C4::Context->preference("IssueLostItem") eq 'confirm' );
1121
        $alerts{ITEM_LOST}            = $code if ( C4::Context->preference("IssueLostItem") eq 'alert' );
1199
        $alerts{ITEM_LOST}            = $code if ( C4::Context->preference("IssueLostItem") eq 'alert' );
1200
        if ($issueconfirmed) {
1201
            if ($message) {
1202
                $message = "$message + item lost";
1203
            } else {
1204
                $message = "item lost";
1205
            }
1206
            push( @message, "item lost" );
1207
        }
1122
    }
1208
    }
1123
    if ( C4::Context->preference("IndependentBranches") ) {
1209
    if ( C4::Context->preference("IndependentBranches") ) {
1124
        my $userenv = C4::Context->userenv;
1210
        my $userenv = C4::Context->userenv;
Lines 1219-1224 sub CanBookBeIssued { Link Here
1219
                    $needsconfirmation{'resbranchcode'}     = $res->{branchcode};
1305
                    $needsconfirmation{'resbranchcode'}     = $res->{branchcode};
1220
                    $needsconfirmation{'reswaitingdate'}    = $res->{'waitingdate'};
1306
                    $needsconfirmation{'reswaitingdate'}    = $res->{'waitingdate'};
1221
                    $needsconfirmation{'reserve_id'}        = $res->{reserve_id};
1307
                    $needsconfirmation{'reserve_id'}        = $res->{reserve_id};
1308
1309
                    if ($issueconfirmed) {
1310
                        if ($message) {
1311
                            $message =
1312
                                "$message + item is on reserve and waiting, but has been reserved by some other patron.";
1313
                        } else {
1314
                            $message = "item is on reserve and waiting, but has been reserved by some other patron.";
1315
                        }
1316
                        push( @message, "item is on reserve and waiting, but has been reserved by some other patron" );
1317
                    }
1222
                } elsif ( $restype eq "Reserved" ) {
1318
                } elsif ( $restype eq "Reserved" ) {
1223
1319
1224
                    # The item is on reserve for someone else.
1320
                    # The item is on reserve for someone else.
Lines 1230-1235 sub CanBookBeIssued { Link Here
1230
                    $needsconfirmation{'resbranchcode'}     = $res->{branchcode};
1326
                    $needsconfirmation{'resbranchcode'}     = $res->{branchcode};
1231
                    $needsconfirmation{'resreservedate'}    = $res->{reservedate};
1327
                    $needsconfirmation{'resreservedate'}    = $res->{reservedate};
1232
                    $needsconfirmation{'reserve_id'}        = $res->{reserve_id};
1328
                    $needsconfirmation{'reserve_id'}        = $res->{reserve_id};
1329
1330
                    if ($issueconfirmed) {
1331
                        if ($message) {
1332
                            $message = "$message + item is on reserve for someone else";
1333
                        } else {
1334
                            $message = "item is on reserve for someone else";
1335
                        }
1336
                        push( @message, "item is on reserve for someone else" );
1337
                    }
1233
                } elsif ( $restype eq "Transferred" ) {
1338
                } elsif ( $restype eq "Transferred" ) {
1234
1339
1235
                    # The item is determined hold being transferred for someone else.
1340
                    # The item is determined hold being transferred for someone else.
Lines 1241-1246 sub CanBookBeIssued { Link Here
1241
                    $needsconfirmation{'resbranchcode'}     = $res->{branchcode};
1346
                    $needsconfirmation{'resbranchcode'}     = $res->{branchcode};
1242
                    $needsconfirmation{'resreservedate'}    = $res->{reservedate};
1347
                    $needsconfirmation{'resreservedate'}    = $res->{reservedate};
1243
                    $needsconfirmation{'reserve_id'}        = $res->{reserve_id};
1348
                    $needsconfirmation{'reserve_id'}        = $res->{reserve_id};
1349
1350
                    if ($issueconfirmed) {
1351
                        if ($message) {
1352
                            $message = "$message + item is determined hold being transferred for someone else";
1353
                        } else {
1354
                            $message = "item is determined hold being transferred for someone else";
1355
                        }
1356
                        push( @message, "item is determined hold being transferred for someone else" );
1357
                    }
1244
                } elsif ( $restype eq "Processing" ) {
1358
                } elsif ( $restype eq "Processing" ) {
1245
1359
1246
                    # The item is determined hold being processed for someone else.
1360
                    # The item is determined hold being processed for someone else.
Lines 1252-1257 sub CanBookBeIssued { Link Here
1252
                    $needsconfirmation{'resbranchcode'}     = $res->{branchcode};
1366
                    $needsconfirmation{'resbranchcode'}     = $res->{branchcode};
1253
                    $needsconfirmation{'resreservedate'}    = $res->{reservedate};
1367
                    $needsconfirmation{'resreservedate'}    = $res->{reservedate};
1254
                    $needsconfirmation{'reserve_id'}        = $res->{reserve_id};
1368
                    $needsconfirmation{'reserve_id'}        = $res->{reserve_id};
1369
1370
                    if ($issueconfirmed) {
1371
                        if ($message) {
1372
                            $message = "$message + item is determined hold being processed for someone else";
1373
                        } else {
1374
                            $message = "item is determined hold being processed for someone else";
1375
                        }
1376
                        push( @message, "item is determined hold being processed for someone else" );
1377
                    }
1255
                }
1378
                }
1256
            }
1379
            }
1257
        }
1380
        }
Lines 1295-1300 sub CanBookBeIssued { Link Here
1295
    if ( $restriction_age && $patron->dateofbirth && $restriction_age > $patron->get_age() ) {
1418
    if ( $restriction_age && $patron->dateofbirth && $restriction_age > $patron->get_age() ) {
1296
        if ( C4::Context->preference('AgeRestrictionOverride') ) {
1419
        if ( C4::Context->preference('AgeRestrictionOverride') ) {
1297
            $needsconfirmation{AGE_RESTRICTION} = "$agerestriction";
1420
            $needsconfirmation{AGE_RESTRICTION} = "$agerestriction";
1421
            if ($message) {
1422
                $message = "$message + age restriction";
1423
            } else {
1424
                $message = "age restriction";
1425
            }
1426
            push( @message, "age restriction" );
1298
        } else {
1427
        } else {
1299
            $issuingimpossible{AGE_RESTRICTION} = "$agerestriction";
1428
            $issuingimpossible{AGE_RESTRICTION} = "$agerestriction";
1300
        }
1429
        }
Lines 1353-1358 sub CanBookBeIssued { Link Here
1353
        }
1482
        }
1354
    }
1483
    }
1355
1484
1485
    my $borrower   = $patron;
1486
    my $user       = C4::Context->userenv->{number};
1487
    my $branchcode = C4::Context->userenv->{branch};
1488
    my $item       = Koha::Items->find( { barcode => $barcode } );
1489
    my $itemnumber = $item->itemnumber;
1490
1491
    # action, cardnumber, barcode, date, heure, user, branche
1492
    if ($issueconfirmed) {
1493
1494
        my $infos = (
1495
            {
1496
                message        => \@message,
1497
                borrowernumber => $borrower->borrowernumber,
1498
                barcode        => $barcode,
1499
                manager_id     => $user,
1500
                branchcode     => $branchcode,
1501
            }
1502
        );
1503
1504
        my $json_infos = JSON->new->utf8->pretty->encode($infos);
1505
        $json_infos =~ s/"/'/g;
1506
1507
        logaction(
1508
            "CIRCULATION", "ISSUE",
1509
            $borrower->{'borrowernumber'},
1510
            $json_infos,
1511
        ) if C4::Context->preference("IssueLog");
1512
    }
1513
1356
    return ( \%issuingimpossible, \%needsconfirmation, \%alerts, \%messages, );
1514
    return ( \%issuingimpossible, \%needsconfirmation, \%alerts, \%messages, );
1357
}
1515
}
1358
1516
Lines 2371-2378 sub AddReturn { Link Here
2371
                    if $message->message eq 'processing_refunded';
2529
                    if $message->message eq 'processing_refunded';
2372
                $messages->{'LostItemFeeRestored'} = 1
2530
                $messages->{'LostItemFeeRestored'} = 1
2373
                    if $message->message eq 'lost_restored';
2531
                    if $message->message eq 'lost_restored';
2374
                $messages->{'LostItemPaymentNotRefunded'} = 1
2375
                    if $message->message eq 'payment_not_refunded';
2376
2532
2377
                if ( $message->message eq 'lost_charge' ) {
2533
                if ( $message->message eq 'lost_charge' ) {
2378
                    $issue //= Koha::Old::Checkouts->search(
2534
                    $issue //= Koha::Old::Checkouts->search(
Lines 2413-2420 sub AddReturn { Link Here
2413
                $messages->{'TransferArrived'} = $transfer->frombranch;
2569
                $messages->{'TransferArrived'} = $transfer->frombranch;
2414
2570
2415
                # validTransfer=1 allows us returning the item back if the reserve is cancelled
2571
                # validTransfer=1 allows us returning the item back if the reserve is cancelled
2416
                $validTransfer = 1
2572
                $validTransfer = 1 if $transfer->reason eq 'Reserve';
2417
                    if defined $transfer->reason && $transfer->reason eq 'Reserve';
2418
            } else {
2573
            } else {
2419
                $messages->{'WrongTransfer'}     = $transfer->tobranch;
2574
                $messages->{'WrongTransfer'}     = $transfer->tobranch;
2420
                $messages->{'WrongTransferItem'} = $item->itemnumber;
2575
                $messages->{'WrongTransferItem'} = $item->itemnumber;
Lines 2430-2437 sub AddReturn { Link Here
2430
            } else {
2585
            } else {
2431
                $messages->{'TransferTrigger'} = $transfer->reason;
2586
                $messages->{'TransferTrigger'} = $transfer->reason;
2432
                if ( $transfer->frombranch eq $branch ) {
2587
                if ( $transfer->frombranch eq $branch ) {
2433
                    $messages->{'TransferTo'}    = $transfer->tobranch;
2588
                    $transfer->transit;
2434
                    $messages->{'WasTransfered'} = $transfer->id;
2589
                    $messages->{'WasTransfered'} = $transfer->tobranch;
2435
                } else {
2590
                } else {
2436
                    $messages->{'WrongTransfer'}     = $transfer->tobranch;
2591
                    $messages->{'WrongTransfer'}     = $transfer->tobranch;
2437
                    $messages->{'WrongTransferItem'} = $item->itemnumber;
2592
                    $messages->{'WrongTransferItem'} = $item->itemnumber;
Lines 2532-2538 sub AddReturn { Link Here
2532
            categorycode   => $categorycode,
2687
            categorycode   => $categorycode,
2533
            interface      => C4::Context->interface,
2688
            interface      => C4::Context->interface,
2534
        }
2689
        }
2535
    ) unless ( $skip_localuse && !$issue );
2690
    ) unless ( $skip_localuse && $stat_type eq 'localuse' );
2536
2691
2537
    # Send a check-in slip. # NOTE: borrower may be undef. Do not try to send messages then.
2692
    # Send a check-in slip. # NOTE: borrower may be undef. Do not try to send messages then.
2538
    if ($patron) {
2693
    if ($patron) {
Lines 2601-2612 sub AddReturn { Link Here
2601
                and !IsBranchTransferAllowed( $branch, $returnbranch, $item->$BranchTransferLimitsType ) )
2756
                and !IsBranchTransferAllowed( $branch, $returnbranch, $item->$BranchTransferLimitsType ) )
2602
            )
2757
            )
2603
        {
2758
        {
2604
            my $transfer = ModItemTransfer(
2759
            ModItemTransfer( $item->itemnumber, $branch, $returnbranch, $transfer_trigger, { skip_record_index => 1 } );
2605
                $item->itemnumber, $branch, $returnbranch, $transfer_trigger,
2760
            $messages->{'WasTransfered'}   = $returnbranch;
2606
                { skip_record_index => 1 }
2607
            );
2608
            $messages->{'TransferTo'}      = $returnbranch;
2609
            $messages->{'WasTransfered'}   = $transfer->id;
2610
            $messages->{'TransferTrigger'} = $transfer_trigger;
2761
            $messages->{'TransferTrigger'} = $transfer_trigger;
2611
        } else {
2762
        } else {
2612
            $messages->{'NeedsTransfer'}   = $returnbranch;
2763
            $messages->{'NeedsTransfer'}   = $returnbranch;
Lines 2719-2733 sub MarkIssueReturned { Link Here
2719
                $issue->returndate( \'NOW()' )->store->discard_changes;     # update and refetch
2870
                $issue->returndate( \'NOW()' )->store->discard_changes;     # update and refetch
2720
            }
2871
            }
2721
2872
2722
            $issue->checkin_library( C4::Context->userenv->{'branch'} );
2723
2724
            # Create the old_issues entry
2873
            # Create the old_issues entry
2725
            my $old_checkout = Koha::Old::Checkout->new( $issue->unblessed )->store;
2874
            my $old_checkout = Koha::Old::Checkout->new( $issue->unblessed )->store;
2726
2875
2727
            # Update accountlines
2728
            my $accountlines = Koha::Account::Lines->search( { issue_id => $issue->issue_id } );
2729
            $accountlines->update( { old_issue_id => $issue->issue_id, issue_id => undef } );
2730
2731
            # anonymise patron checkout immediately if $privacy set to 2 and AnonymousPatron is set to a valid borrowernumber
2876
            # anonymise patron checkout immediately if $privacy set to 2 and AnonymousPatron is set to a valid borrowernumber
2732
            if ( $privacy && $privacy == 2 ) {
2877
            if ( $privacy && $privacy == 2 ) {
2733
                $old_checkout->anonymize;
2878
                $old_checkout->anonymize;
Lines 3172-3177 sub CanBookBeRenewed { Link Here
3172
    return ( 0, "on_reserve" )
3317
    return ( 0, "on_reserve" )
3173
        if ( $item->current_holds->search( { non_priority => 0 } )->count );
3318
        if ( $item->current_holds->search( { non_priority => 0 } )->count );
3174
3319
3320
    my $issuing_rule = Koha::CirculationRules->get_effective_rules(
3321
        {
3322
            categorycode => $patron->categorycode,
3323
            itemtype     => $item->effective_itemtype,
3324
            branchcode   => $branchcode,
3325
            rules        => [
3326
                'renewalsallowed',
3327
                'lengthunit',
3328
                'unseen_renewals_allowed'
3329
            ]
3330
        }
3331
    );
3332
3333
    return ( 0, "too_many" )
3334
        if not $issuing_rule->{renewalsallowed}
3335
        or $issuing_rule->{renewalsallowed} <= $issue->renewals_count;
3336
3175
    my ( $status, $matched_reserve, $possible_holds ) = C4::Reserves::CheckReserves($item);
3337
    my ( $status, $matched_reserve, $possible_holds ) = C4::Reserves::CheckReserves($item);
3176
    my @fillable_holds = ();
3338
    my @fillable_holds = ();
3177
    foreach my $possible_hold ( @{$possible_holds} ) {
3339
    foreach my $possible_hold ( @{$possible_holds} ) {
Lines 3200-3206 sub CanBookBeRenewed { Link Here
3200
3362
3201
                foreach my $other_item (@other_items) {
3363
                foreach my $other_item (@other_items) {
3202
                    next if defined $matched_items{ $other_item->itemnumber };
3364
                    next if defined $matched_items{ $other_item->itemnumber };
3203
                    next if $other_item->holds->filter_by_found->count;
3365
                    next if IsItemOnHoldAndFound( $other_item->itemnumber );
3204
                    next unless IsAvailableForItemLevelRequest( $other_item, $patron_with_reserve, undef );
3366
                    next unless IsAvailableForItemLevelRequest( $other_item, $patron_with_reserve, undef );
3205
                    next
3367
                    next
3206
                        unless CanItemBeReserved(
3368
                        unless CanItemBeReserved(
Lines 3307-3314 fallback to a true value Link Here
3307
3469
3308
C<$automatic> is a boolean flag indicating the renewal was triggered automatically and not by a person ( librarian or patron )
3470
C<$automatic> is a boolean flag indicating the renewal was triggered automatically and not by a person ( librarian or patron )
3309
3471
3310
C<$skip_record_index> is an optional boolean flag to indicate whether queuing the search indexing
3472
C<$skip_record_index> is an optional boolean flag to indicate whether queuing the search indexing should be skipped for this renewal.
3311
should be skipped for this renewal.
3312
3473
3313
=cut
3474
=cut
3314
3475
Lines 3957-3962 sub SendCirculationAlert { Link Here
3957
    return;
4118
    return;
3958
}
4119
}
3959
4120
4121
=head2 updateWrongTransfer
4122
4123
  $items = updateWrongTransfer($itemNumber,$borrowernumber,$waitingAtLibrary,$FromLibrary);
4124
4125
This function validate the line of brachtransfer but with the wrong destination (mistake from a librarian ...), and create a new line in branchtransfer from the actual library to the original library of reservation 
4126
4127
=cut
4128
4129
sub updateWrongTransfer {
4130
    my ( $itemNumber, $waitingAtLibrary, $FromLibrary ) = @_;
4131
4132
    # first step: cancel the original transfer
4133
    my $item     = Koha::Items->find($itemNumber);
4134
    my $transfer = $item->get_transfer;
4135
    $transfer->set( { datecancelled => dt_from_string, cancellation_reason => 'WrongTransfer' } )->store();
4136
4137
    # second step: create a new transfer to the right location
4138
    my $new_transfer = $item->request_transfer(
4139
        {
4140
            to            => $transfer->to_library,
4141
            reason        => $transfer->reason,
4142
            comment       => $transfer->comments,
4143
            ignore_limits => 1,
4144
            enqueue       => 1
4145
        }
4146
    );
4147
4148
    return $new_transfer;
4149
}
4150
3960
=head2 CalcDateDue
4151
=head2 CalcDateDue
3961
4152
3962
$newdatedue = CalcDateDue($startdate,$itemtype,$branchcode,$borrower);
4153
$newdatedue = CalcDateDue($startdate,$itemtype,$branchcode,$borrower);
(-)a/circ/circulation.pl (-41 / +56 lines)
Lines 36-44 use C4::Auth qw( get_session get_template_and_user ); Link Here
36
use C4::Koha;
36
use C4::Koha;
37
use C4::Circulation qw( barcodedecode CanBookBeIssued AddIssue AddReturn );
37
use C4::Circulation qw( barcodedecode CanBookBeIssued AddIssue AddReturn );
38
use C4::Members;
38
use C4::Members;
39
use C4::Biblio   qw( TransformMarcToKoha );
39
use C4::Biblio qw( TransformMarcToKoha );
40
use C4::Search   qw( new_record_from_zebra );
40
use C4::Search qw( new_record_from_zebra );
41
use C4::Reserves qw( ModReserveAffect );
41
use C4::Reserves;
42
use C4::Log qw( logaction );
42
use Koha::Holds;
43
use Koha::Holds;
43
use C4::Context;
44
use C4::Context;
44
use CGI::Session;
45
use CGI::Session;
Lines 52-58 use Koha::Plugins; Link Here
52
use Koha::Database;
53
use Koha::Database;
53
use Koha::BiblioFrameworks;
54
use Koha::BiblioFrameworks;
54
use Koha::Items;
55
use Koha::Items;
55
use Koha::CirculationRules;
56
use Koha::SearchEngine;
56
use Koha::SearchEngine;
57
use Koha::SearchEngine::Search;
57
use Koha::SearchEngine::Search;
58
use Koha::Patron::Modifications;
58
use Koha::Patron::Modifications;
Lines 112-118 my ( $template, $loggedinuser, $cookie ) = get_template_and_user( Link Here
112
    }
112
    }
113
);
113
);
114
114
115
my $op                      = $query->param('op') // '';
115
my $op                      = $query->param('op');
116
my $override_high_holds     = $query->param('override_high_holds');
116
my $override_high_holds     = $query->param('override_high_holds');
117
my $override_high_holds_tmp = $query->param('override_high_holds_tmp');
117
my $override_high_holds_tmp = $query->param('override_high_holds_tmp');
118
118
Lines 239-245 if ( @$barcodes == 0 && $charges eq 'yes' ) { Link Here
239
# STEP 2 : FIND BORROWER
239
# STEP 2 : FIND BORROWER
240
# if there is a list of find borrowers....
240
# if there is a list of find borrowers....
241
#
241
#
242
my $message;
242
243
if ($findborrower) {
243
if ($findborrower) {
244
    Koha::Plugins->call( 'patron_barcode_transform', \$findborrower );
244
    Koha::Plugins->call( 'patron_barcode_transform', \$findborrower );
245
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
245
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
Lines 325-330 if ($patron) { Link Here
325
# STEP 3 : ISSUING
325
# STEP 3 : ISSUING
326
#
326
#
327
#
327
#
328
my $message;
329
my @message;
330
328
if ( @$barcodes && $op eq 'cud-checkout' ) {
331
if ( @$barcodes && $op eq 'cud-checkout' ) {
329
    my $checkout_infos;
332
    my $checkout_infos;
330
    for my $barcode (@$barcodes) {
333
    for my $barcode (@$barcodes) {
Lines 370-385 if ( @$barcodes && $op eq 'cud-checkout' ) { Link Here
370
        }
373
        }
371
374
372
        if ( $issuingimpossible->{'STATS'} ) {
375
        if ( $issuingimpossible->{'STATS'} ) {
373
            my ( $stats_return, $stats_messages, $stats_iteminformation, $stats_borrower ) =
376
            $template->param( STATS => 1 );
374
                AddReturn( $item->barcode, C4::Context->userenv->{'branch'}, undef, undef, 1 );
375
377
376
            $template->param(
378
            if ( $item->onloan ) {
377
                STATS     => 1,
379
                my ( $stats_return, $stats_messages, $stats_iteminformation, $stats_borrower ) =
378
                CHECKEDIN => $stats_return,
380
                    AddReturn( $item->barcode, C4::Context->userenv->{'branch'}, undef, undef, 1 );
379
                MESSAGES  => $stats_messages,
381
380
                ITEM      => $stats_iteminformation,
382
                $template->param(
381
                BORROWER  => $stats_borrower,
383
                    CHECKEDIN => $stats_return,
382
            );
384
                    MESSAGES  => $stats_messages,
385
                    ITEM      => $stats_iteminformation,
386
                    BORROWER  => $stats_borrower,
387
                );
388
            }
383
389
384
            #increment items.localuse
390
            #increment items.localuse
385
            my $localuse_count = $item->localuse;
391
            my $localuse_count = $item->localuse;
Lines 483-521 if ( @$barcodes && $op eq 'cud-checkout' ) { Link Here
483
                $template_params->{ADDITIONAL_MATERIALS} = $materials;
489
                $template_params->{ADDITIONAL_MATERIALS} = $materials;
484
                $template_params->{itemhomebranch}       = $item->homebranch;
490
                $template_params->{itemhomebranch}       = $item->homebranch;
485
491
486
                my $patron_session_confirmation = $query->cookie('patronSessionConfirmation') || undef;
487
                my ( $patron_for_session, $session_confirmations ) = split( /:/, $patron_session_confirmation, 2 );
488
                my $patron_match = $borrowernumber == $patron_for_session;
489
                my @conf_keys    = split( /\|/, $session_confirmations );
490
                $template_params->{sessionConfirmationKeys} = ();
491
492
                # pass needsconfirmation to template if issuing is possible and user hasn't yet confirmed.
492
                # pass needsconfirmation to template if issuing is possible and user hasn't yet confirmed.
493
                foreach my $needsconfirmation_key ( keys %$needsconfirmation ) {
493
                foreach my $needsconfirmation_key ( keys %$needsconfirmation ) {
494
                    if ( $needsconfirmation_key eq 'BOOKED_TO_ANOTHER' ) {
495
                        my $rule = Koha::CirculationRules->get_effective_rule(
496
                            {
497
                                rule_name  => 'bookings_lead_period',
498
                                itemtype   => $item->effective_itemtype,
499
                                branchcode => "*"
500
                            }
501
                        );
502
                        my $preparation_period = $rule ? $rule->rule_value : 1;
503
                        my $reduceddue = dt_from_string( $$needsconfirmation{$needsconfirmation_key}->start_date )
504
505
                            ->subtract( days => $preparation_period );
506
                        $template_params->{reduceddue} = $reduceddue;
507
                    }
508
                    next
509
                        if $patron_match
510
                        && scalar(@conf_keys) > 0
511
                        && grep( { $needsconfirmation_key eq $_ } @conf_keys );
512
513
                    $template_params->{$needsconfirmation_key}    = $needsconfirmation->{$needsconfirmation_key};
494
                    $template_params->{$needsconfirmation_key}    = $needsconfirmation->{$needsconfirmation_key};
514
                    $template_params->{getTitleMessageIteminfo}   = $biblio->title;
495
                    $template_params->{getTitleMessageIteminfo}   = $biblio->title;
515
                    $template_params->{getBarcodeMessageIteminfo} = $item->barcode;
496
                    $template_params->{getBarcodeMessageIteminfo} = $item->barcode;
516
                    $template_params->{NEEDSCONFIRMATION}         = 1;
497
                    $template_params->{NEEDSCONFIRMATION}         = 1;
517
                    $confirm_required                             = 1;
498
                    $confirm_required                             = 1;
518
                    push( @{ $template_params->{sessionConfirmationKeys} }, $needsconfirmation_key );
499
                    if ( $needsconfirmation_key eq 'BOOKED_TO_ANOTHER' ) {
500
                        my $reduceddue =
501
                            dt_from_string( $$needsconfirmation{$needsconfirmation_key}->start_date )
502
                            ->subtract( days => 1 );
503
                        $template_params->{reduceddue} = $reduceddue;
504
                    }
519
                }
505
                }
520
            }
506
            }
521
            unless ($confirm_required) {
507
            unless ($confirm_required) {
Lines 531-536 if ( @$barcodes && $op eq 'cud-checkout' ) { Link Here
531
                        }
517
                        }
532
                    );
518
                    );
533
                    $recall_id = ( $recall and $recall->id ) ? $recall->id : undef;
519
                    $recall_id = ( $recall and $recall->id ) ? $recall->id : undef;
520
534
                }
521
                }
535
522
536
                # If booked (alerts or confirmation) update datedue to end of booking
523
                # If booked (alerts or confirmation) update datedue to end of booking
Lines 548-553 if ( @$barcodes && $op eq 'cud-checkout' ) { Link Here
548
                    }
535
                    }
549
                );
536
                );
550
                $template_params->{issue} = $issue;
537
                $template_params->{issue} = $issue;
538
539
                my $borrower       = $patron;
540
                my $borrowernumber = $patron->borrowernumber;
541
                my $user           = C4::Context->userenv->{number};
542
                my $branchcode     = C4::Context->userenv->{branch};
543
                $message = "Restriction overridden temporarily";
544
                @message = ("Restriction overridden temporarily");
545
546
                if ($issueconfirmed) {
547
                    my $infos = (
548
                        {
549
                            message        => \@message,
550
                            borrowernumber => $borrowernumber,
551
                            barcode        => $barcode,
552
                            manager_id     => $user,
553
                            branchcode     => $branchcode,
554
                        }
555
                    );
556
557
                    my $json_infos = JSON->new->utf8->pretty->encode($infos);
558
                    $json_infos =~ s/"/'/g;
559
560
                    logaction(
561
                        "CIRCULATION", "ISSUE",
562
                        $borrower->{'borrowernumber'},
563
                        $json_infos,
564
                    ) if C4::Context->preference("IssueLog");
565
                }
551
                $session->clear('auto_renew');
566
                $session->clear('auto_renew');
552
                $inprocess = 1;
567
                $inprocess = 1;
553
            }
568
            }
(-)a/circ/renew.pl (-2 / +53 lines)
Lines 24-29 use C4::Context; Link Here
24
use C4::Auth        qw( get_template_and_user );
24
use C4::Auth        qw( get_template_and_user );
25
use C4::Output      qw( output_html_with_http_headers );
25
use C4::Output      qw( output_html_with_http_headers );
26
use C4::Circulation qw( barcodedecode CanBookBeRenewed GetLatestAutoRenewDate AddRenewal );
26
use C4::Circulation qw( barcodedecode CanBookBeRenewed GetLatestAutoRenewDate AddRenewal );
27
use C4::Log         qw( logaction );
27
use Koha::DateUtils qw( dt_from_string );
28
use Koha::DateUtils qw( dt_from_string );
28
use Koha::Database;
29
use Koha::Database;
29
use Koha::BiblioFrameworks;
30
use Koha::BiblioFrameworks;
Lines 64-71 if ( $op eq 'cud-renew' && $barcode ) { Link Here
64
        if ($checkout) {
65
        if ($checkout) {
65
66
66
            $patron = $checkout->patron;
67
            $patron = $checkout->patron;
67
68
            my $borrower       = $patron;
68
            if ( ( $patron->is_debarred || q{} ) lt dt_from_string()->ymd() ) {
69
            my $borrowernumber = $borrower->borrowernumber;
70
            my $user           = C4::Context->userenv->{number};
71
            my $branchcode     = C4::Context->userenv->{branch};
72
            my $message;
73
            my @message;
74
75
            if ( ( $borrower->debarred() || q{} ) lt dt_from_string()->ymd() ) {
69
                my $can_renew;
76
                my $can_renew;
70
                my $info;
77
                my $info;
71
                ( $can_renew, $error, $info ) = CanBookBeRenewed( $patron, $checkout, $override_limit );
78
                ( $can_renew, $error, $info ) = CanBookBeRenewed( $patron, $checkout, $override_limit );
Lines 74-79 if ( $op eq 'cud-renew' && $barcode ) { Link Here
74
                    if ($override_holds) {
81
                    if ($override_holds) {
75
                        $can_renew = 1;
82
                        $can_renew = 1;
76
                        $error     = undef;
83
                        $error     = undef;
84
85
                        $message = "Override Renew hold for another";
86
                        @message = ("Override Renew hold for another");
87
88
                        my $infos = (
89
                            {
90
                                message        => \@message,
91
                                borrowernumber => $borrowernumber,
92
                                barcode        => $barcode,
93
                                manager_id     => $user,
94
                                branchcode     => $branchcode,
95
                            }
96
                        );
97
98
                        my $json_infos = JSON->new->utf8->pretty->encode($infos);
99
                        $json_infos =~ s/"/'/g;
100
101
                        logaction(
102
                            "CIRCULATION", "RENEWAL",
103
                            $borrower->{'borrowernumber'},
104
                            $json_infos,
105
                        ) if C4::Context->preference("RenewalLog");
77
                    } else {
106
                    } else {
78
                        $can_renew = 0;
107
                        $can_renew = 0;
79
                    }
108
                    }
Lines 104-109 if ( $op eq 'cud-renew' && $barcode ) { Link Here
104
                        }
133
                        }
105
                    );
134
                    );
106
                    $template->param( date_due => $date_due );
135
                    $template->param( date_due => $date_due );
136
137
                    $message = "Override limit Renew";
138
                    @message = ("Override limit Renew");
139
140
                    my $infos = (
141
                        {
142
                            message        => \@message,
143
                            borrowernumber => $borrowernumber,
144
                            barcode        => $barcode,
145
                            manager_id     => $user,
146
                            branchcode     => $branchcode,
147
                        }
148
                    );
149
150
                    my $json_infos = JSON->new->utf8->pretty->encode($infos);
151
                    $json_infos =~ s/"/'/g;
152
153
                    logaction(
154
                        "CIRCULATION", "RENEWAL",
155
                        $borrower->{'borrowernumber'},
156
                        $json_infos,
157
                    ) if C4::Context->preference("RenewalLog");
107
                }
158
                }
108
            } else {
159
            } else {
109
                $error = "patron_restricted";
160
                $error = "patron_restricted";
(-)a/circ/returns.pl (-32 / +54 lines)
Lines 35-47 use CGI qw ( -utf8 ); Link Here
35
use DateTime;
35
use DateTime;
36
36
37
use C4::Auth        qw( get_template_and_user get_session haspermission );
37
use C4::Auth        qw( get_template_and_user get_session haspermission );
38
use C4::Circulation qw( barcodedecode GetBranchItemRule AddReturn LostItem );
38
use C4::Circulation qw( barcodedecode GetBranchItemRule AddReturn updateWrongTransfer LostItem );
39
use C4::Context;
39
use C4::Context;
40
use C4::Items qw( ModItemTransfer );
40
use C4::Members::Messaging;
41
use C4::Members::Messaging;
41
use C4::Members;
42
use C4::Members;
42
use C4::Output   qw( output_html_with_http_headers );
43
use C4::Output   qw( output_html_with_http_headers );
43
use C4::Reserves qw( ModReserve ModReserveAffect CheckReserves );
44
use C4::Reserves qw( ModReserve ModReserveAffect CheckReserves );
44
use C4::RotatingCollections;
45
use C4::RotatingCollections;
46
use C4::Log qw( logaction );
45
use Koha::AuthorisedValues;
47
use Koha::AuthorisedValues;
46
use Koha::BiblioFrameworks;
48
use Koha::BiblioFrameworks;
47
use Koha::Calendar;
49
use Koha::Calendar;
Lines 111-117 for my $counter ( $query->multi_param("checkin_counter") ) { Link Here
111
    last if ++$i >= $returned_counter;
113
    last if ++$i >= $returned_counter;
112
}
114
}
113
115
114
my $op = $query->param('op') // '';
116
my $op = $query->param('op');
115
117
116
############
118
############
117
# Deal with the requests....
119
# Deal with the requests....
Lines 151-163 if ( $query->param('reserve_id') && $op eq 'cud-affect_reserve' ) { Link Here
151
        ModReserveAffect( $itemnumber, $borrowernumber, $diffBranchSend, $reserve_id, $desk_id );
153
        ModReserveAffect( $itemnumber, $borrowernumber, $diffBranchSend, $reserve_id, $desk_id );
152
154
153
        if ($diffBranchSend) {
155
        if ($diffBranchSend) {
154
            my $tobranch = $hold->pickup_library();
156
            ModItemTransfer( $itemnumber, $userenv_branch, $diffBranchSend, 'Reserve' );
155
156
            # Add transfer, enqueue if one is already in the queue, and immediately set to in transit
157
            my $transfer = $item->request_transfer( { to => $tobranch, reason => 'Reserve', enqueue => 1 } );
158
            $transfer->transit;
159
        }
157
        }
160
    }
158
    }
159
160
    # check if we have other reserves for this document, if we have a result send the message of transfer
161
    # FIXME do we need to do this if we didn't take the cancel_reserve branch above?
162
    my ( undef, $nextreservinfo, undef ) = CheckReserves($item);
163
164
    if ( $userenv_branch ne $nextreservinfo->{'branchcode'} ) {
165
        my $patron = Koha::Patrons->find( $nextreservinfo->{'borrowernumber'} );
166
        $template->param(
167
            itemtitle        => $biblio->title,
168
            itembiblionumber => $biblio->biblionumber,
169
            iteminfo         => $biblio->author,
170
            patron           => $patron,
171
            diffbranch       => 1,
172
        );
173
    }
174
} else {
175
    my $message    = "return an element that is reserved";
176
    my @message    = ("return an element that is reserved");
177
    my $user       = C4::Context->userenv->{number};
178
    my $branchcode = C4::Context->userenv->{branch};
179
    my $barcode    = $query->param('barcode');
180
181
    my $infos = (
182
        {
183
            message => \@message,
184
185
            #'card number' => $cardnumber,
186
            barcode    => $barcode,
187
            manager_id => $user,
188
            branchcode => $branchcode,
189
        }
190
    );
191
192
    my $json_infos = JSON->new->utf8->pretty->encode($infos);
193
    $json_infos =~ s/"/'/g;
194
195
    logaction(
196
        "CIRCULATION", "RETURN",
197
        $session,
198
        $json_infos,
199
    ) if C4::Context->preference("ReturnLog");
161
}
200
}
162
201
163
if ( $query->param('recall_id') && $op eq 'cud-affect_recall' ) {
202
if ( $query->param('recall_id') && $op eq 'cud-affect_recall' ) {
Lines 218-232 if ($return_date_override) { Link Here
218
    }
257
    }
219
}
258
}
220
259
221
# If 'needstransfer' was set and the librarian has chosen to initiate the transfer
222
if ( $op eq 'cud-dotransfer' ) {
260
if ( $op eq 'cud-dotransfer' ) {
261
262
    # An item has been returned to a branch other than the homebranch, and the librarian has chosen to initiate a transfer
223
    my $transferitem = $query->param('transferitem');
263
    my $transferitem = $query->param('transferitem');
224
    my $item         = Koha::Items->find($transferitem);
264
    my $tobranch     = $query->param('tobranch');
225
    my $tobranchcode = $query->param('tobranch');
226
    my $tobranch     = Koha::Libraries->find($tobranchcode);
227
    my $trigger      = $query->param('trigger');
265
    my $trigger      = $query->param('trigger');
228
    my $transfer     = $item->request_transfer( { to => $tobranch, reason => $trigger } );
266
    ModItemTransfer( $transferitem, $userenv_branch, $tobranch, $trigger );
229
    $transfer->transit;
230
}
267
}
231
268
232
if ( $transit && $op eq 'cud-transfer' ) {
269
if ( $transit && $op eq 'cud-transfer' ) {
Lines 414-424 if ( $barcode && ( $op eq 'cud-checkin' || $op eq 'cud-affect_reserve' ) ) { Link Here
414
    }
451
    }
415
452
416
    # Mark missing bundle items as lost and report unexpected items
453
    # Mark missing bundle items as lost and report unexpected items
417
    if (   $item
454
    if ( $item && $item->is_bundle && $query->param('confirm_items_bundle_return') ) {
418
        && $item->is_bundle
419
        && $query->param('confirm_items_bundle_return')
420
        && !$query->param('do_not_verify_items_bundle_contents') )
421
    {
422
        my $BundleLostValue = C4::Context->preference('BundleLostValue');
455
        my $BundleLostValue = C4::Context->preference('BundleLostValue');
423
        my $barcodes        = $query->param('verify-items-bundle-contents-barcodes');
456
        my $barcodes        = $query->param('verify-items-bundle-contents-barcodes');
424
        my @barcodes        = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes );
457
        my @barcodes        = map { s/^\s+|\s+$//gr } ( split /\n/, $barcodes );
Lines 513-519 if ( $messages->{'WasTransfered'} ) { Link Here
513
    $template->param(
546
    $template->param(
514
        found      => 1,
547
        found      => 1,
515
        transfer   => $messages->{'WasTransfered'},
548
        transfer   => $messages->{'WasTransfered'},
516
        transferto => $messages->{'TransferTo'},
517
        trigger    => $messages->{'TransferTrigger'},
549
        trigger    => $messages->{'TransferTrigger'},
518
        itemnumber => $itemnumber,
550
        itemnumber => $itemnumber,
519
    );
551
    );
Lines 547-556 if ( $messages->{'WrongTransfer'} and not $messages->{'WasTransfered'} ) { Link Here
547
    );
579
    );
548
580
549
    # Update the transfer to reflect the new item holdingbranch
581
    # Update the transfer to reflect the new item holdingbranch
550
    my $item         = Koha::Items->find( $messages->{'WrongTransferItem'} );
582
    my $new_transfer =
551
    my $old_transfer = $item->get_transfer;
583
        updateWrongTransfer( $messages->{'WrongTransferItem'}, $messages->{'WrongTransfer'}, $userenv_branch );
552
    my $new_transfer = $item->request_transfer(
553
        { to => $old_transfer->to_library, reason => $old_transfer->reason, replace => 'WrongTransfer' } );
554
    $template->param( NewTransfer => $new_transfer->id );
584
    $template->param( NewTransfer => $new_transfer->id );
555
585
556
    my $reserve = $messages->{'ResFound'};
586
    my $reserve = $messages->{'ResFound'};
Lines 583-593 if ( $messages->{'ResFound'} ) { Link Here
583
        ModReserveAffect( $itemnumber, $reserve->{borrowernumber}, $diffBranchSend, $reserve->{reserve_id}, $desk_id );
613
        ModReserveAffect( $itemnumber, $reserve->{borrowernumber}, $diffBranchSend, $reserve->{reserve_id}, $desk_id );
584
614
585
        if ($diffBranchSend) {
615
        if ($diffBranchSend) {
586
            my $tobranch = Koha::Libraries->find( $reserve->{branchcode} );
616
            ModItemTransfer( $itemnumber, $item->holdingbranch, $reserve->{branchcode}, 'Reserve' );
587
588
            # Add transfer, enqueue if one is already in the queue, and immediately set to in transit
589
            my $transfer = $item->request_transfer( { to => $tobranch, reason => 'Reserve', enqueue => 1 } );
590
            $transfer->transit;
591
        }
617
        }
592
618
593
        $template->param(
619
        $template->param(
Lines 679-686 foreach my $code ( keys %$messages ) { Link Here
679
        $err{waslost} = 1;
705
        $err{waslost} = 1;
680
    } elsif ( $code eq 'LostItemFeeRefunded' ) {
706
    } elsif ( $code eq 'LostItemFeeRefunded' ) {
681
        $template->param( LostItemFeeRefunded => 1 );
707
        $template->param( LostItemFeeRefunded => 1 );
682
    } elsif ( $code eq 'LostItemPaymentNotRefunded' ) {
683
        $template->param( LostItemPaymentNotRefunded => 1 );
684
    } elsif ( $code eq 'LostItemFeeCharged' ) {
708
    } elsif ( $code eq 'LostItemFeeCharged' ) {
685
        $template->param( LostItemFeeCharged => 1 );
709
        $template->param( LostItemFeeCharged => 1 );
686
    } elsif ( $code eq 'LostItemFeeRestored' ) {
710
    } elsif ( $code eq 'LostItemFeeRestored' ) {
Lines 693-700 foreach my $code ( keys %$messages ) { Link Here
693
        ;    # FIXME... anything to do here?
717
        ;    # FIXME... anything to do here?
694
    } elsif ( $code eq 'WasTransfered' ) {
718
    } elsif ( $code eq 'WasTransfered' ) {
695
        ;    # FIXME... anything to do here?
719
        ;    # FIXME... anything to do here?
696
    } elsif ( $code eq 'TransferTo' ) {
697
        ;    # Handled above, along with WasTransfered
698
    } elsif ( $code eq 'withdrawn' ) {
720
    } elsif ( $code eq 'withdrawn' ) {
699
        $err{withdrawn} = 1;
721
        $err{withdrawn} = 1;
700
    } elsif ( $code eq 'WrongTransfer' ) {
722
    } elsif ( $code eq 'WrongTransfer' ) {
(-)a/reserve/request.pl (-31 / +49 lines)
Lines 26-31 script to place reserves/requests Link Here
26
=cut
26
=cut
27
27
28
use Modern::Perl;
28
use Modern::Perl;
29
use Data::Dumper;
29
30
30
use CGI             qw ( -utf8 );
31
use CGI             qw ( -utf8 );
31
use List::MoreUtils qw( uniq );
32
use List::MoreUtils qw( uniq );
Lines 33-45 use Date::Calc qw( Date_to_Days ); Link Here
33
use C4::Output      qw( output_html_with_http_headers );
34
use C4::Output      qw( output_html_with_http_headers );
34
use C4::Auth        qw( get_template_and_user );
35
use C4::Auth        qw( get_template_and_user );
35
use C4::Reserves
36
use C4::Reserves
36
    qw( RevertWaitingStatus AlterPriority ToggleLowestPriority CanBookBeReserved GetMaxPatronHoldsForRecord CanItemBeReserved IsAvailableForItemLevelRequest );
37
    qw( RevertWaitingStatus AlterPriority ToggleLowestPriority ToggleSuspend CanBookBeReserved GetMaxPatronHoldsForRecord CanItemBeReserved IsAvailableForItemLevelRequest );
37
use C4::Items       qw( get_hostitemnumbers_of );
38
use C4::Items       qw( get_hostitemnumbers_of );
38
use C4::Koha        qw( getitemtypeimagelocation );
39
use C4::Koha        qw( getitemtypeimagelocation );
39
use C4::Serials     qw( CountSubscriptionFromBiblionumber );
40
use C4::Serials     qw( CountSubscriptionFromBiblionumber );
40
use C4::Circulation qw( _GetCircControlBranch GetBranchItemRule );
41
use C4::Circulation qw( _GetCircControlBranch GetBranchItemRule );
41
use Koha::DateUtils qw( dt_from_string );
42
use Koha::DateUtils qw( dt_from_string );
42
use C4::Search      qw( enabled_staff_search_views );
43
use C4::Search      qw( enabled_staff_search_views );
44
use C4::Log         qw( logaction );
43
45
44
use Koha::Biblios;
46
use Koha::Biblios;
45
use Koha::Checkouts;
47
use Koha::Checkouts;
Lines 88-95 my $warnings; Link Here
88
my $messages;
90
my $messages;
89
my $exceeded_maxreserves;
91
my $exceeded_maxreserves;
90
my $exceeded_holds_per_record;
92
my $exceeded_holds_per_record;
91
my @failed_holds   = $input->multi_param('failed_holds');
93
my @failed_holds = $input->multi_param('failed_holds');
92
my $form_submitted = $input->param('form_submitted');
93
94
94
my $op = $input->param('op') || q{};
95
my $op = $input->param('op') || q{};
95
96
Lines 117-131 if ( $op eq 'cud-move' ) { Link Here
117
} elsif ( $op eq 'cud-setLowestPriority' ) {
118
} elsif ( $op eq 'cud-setLowestPriority' ) {
118
    my $reserve_id = $input->param('reserve_id');
119
    my $reserve_id = $input->param('reserve_id');
119
    ToggleLowestPriority($reserve_id);
120
    ToggleLowestPriority($reserve_id);
120
} elsif ( $op eq 'cud-suspend' ) {
121
} elsif ( $op eq 'cud-toggleSuspend' ) {
121
    my $reserve_id    = $input->param('reserve_id');
122
    my $reserve_id    = $input->param('reserve_id');
122
    my $suspend_until = $input->param('suspend_until');
123
    my $suspend_until = $input->param('suspend_until');
123
    my $hold          = Koha::Holds->find($reserve_id);
124
    ToggleSuspend( $reserve_id, $suspend_until );
124
    $hold->suspend_hold($suspend_until) if $hold;
125
} elsif ( $op eq 'cud-unsuspend' ) {
126
    my $reserve_id = $input->param('reserve_id');
127
    my $hold       = Koha::Holds->find($reserve_id);
128
    $hold->resume() if $hold;
129
} elsif ( $op eq 'cud-cancel_bulk' ) {
125
} elsif ( $op eq 'cud-cancel_bulk' ) {
130
    my $cancellation_reason = $input->param("cancellation-reason");
126
    my $cancellation_reason = $input->param("cancellation-reason");
131
    my @hold_ids            = split( ',', scalar $input->param("ids") );
127
    my @hold_ids            = split( ',', scalar $input->param("ids") );
Lines 146-174 if ($findborrower) { Link Here
146
    $borrowernumber_hold = $patron->borrowernumber if $patron;
142
    $borrowernumber_hold = $patron->borrowernumber if $patron;
147
}
143
}
148
144
149
if ($form_submitted) {
145
if ($findclub) {
150
    if ($findclub) {
146
    my $club = Koha::Clubs->find( { name => $findclub } );
151
        my $club = Koha::Clubs->find( { name => $findclub } );
147
    if ($club) {
152
        if ($club) {
148
        $club_hold = $club->id;
153
            $club_hold = $club->id;
149
    } else {
150
        my @clubs = Koha::Clubs->search(
151
            [
152
                { name        => { like => '%' . $findclub . '%' } },
153
                { description => { like => '%' . $findclub . '%' } }
154
            ]
155
        )->as_list;
156
        if ( scalar @clubs == 1 ) {
157
            $club_hold = $clubs[0]->id;
158
        } elsif (@clubs) {
159
            $template->param( clubs => \@clubs );
154
        } else {
160
        } else {
155
            my @clubs = Koha::Clubs->search(
161
            $messageclub = "'$findclub'";
156
                [
157
                    { name        => { like => '%' . $findclub . '%' } },
158
                    { description => { like => '%' . $findclub . '%' } }
159
                ]
160
            )->as_list;
161
            if ( scalar @clubs == 1 ) {
162
                $club_hold = $clubs[0]->id;
163
            } elsif (@clubs) {
164
                $template->param( clubs => \@clubs );
165
            } else {
166
                $messageclub = "'$findclub'";
167
            }
168
        }
162
        }
169
    } else {
170
        my @clubs = Koha::Clubs->search()->as_list;
171
        $template->param( clubs => \@clubs );
172
    }
163
    }
173
}
164
}
174
165
Lines 561-566 if ( ( $findborrower && $borrowernumber_hold || $findclub && $club_hold ) Link Here
561
                            $num_alreadyheld++;
552
                            $num_alreadyheld++;
562
                        }
553
                        }
563
554
555
                        my $borrower       = $patron;
556
                        my $borrowernumber = $patron->borrowernumber;
557
                        my $user           = C4::Context->userenv->{number};
558
                        my $branchcode     = C4::Context->userenv->{branch};
559
                        my $message        = "Override limitation of hold";
560
                        my @message        = ("Override limitation of hold");
561
                        my $barcode        = $item->{barcode};
562
563
                        my $infos = (
564
                            {
565
                                message        => \@message,
566
                                borrowernumber => $borrowernumber,
567
                                barcode        => $barcode,
568
                                manager_id     => $user,
569
                                branchcode     => $branchcode,
570
                            }
571
                        );
572
573
                        my $json_infos = JSON->new->utf8->pretty->encode($infos);
574
                        $json_infos =~ s/"/'/g;
575
576
                        logaction(
577
                            "HOLD", "ISSUE",
578
                            $borrower->{'borrowernumber'},
579
                            $json_infos,
580
                        ) if C4::Context->preference("IssueLog");
581
564
                        push( @available_itemtypes, $item->{itype} );
582
                        push( @available_itemtypes, $item->{itype} );
565
                    } else {
583
                    } else {
566
584
(-)a/svc/renew (-1 / +54 lines)
Lines 26-31 use Try::Tiny; Link Here
26
use C4::Circulation qw( AddRenewal CanBookBeRenewed );
26
use C4::Circulation qw( AddRenewal CanBookBeRenewed );
27
use C4::Context;
27
use C4::Context;
28
use C4::Auth qw(check_cookie_auth);
28
use C4::Auth qw(check_cookie_auth);
29
use C4::Log  qw( logaction );
29
30
30
use Koha::DateUtils qw(output_pref dt_from_string);
31
use Koha::DateUtils qw(output_pref dt_from_string);
31
32
Lines 53-58 my $date_due; Link Here
53
if ( $input->param('date_due') ) {
54
if ( $input->param('date_due') ) {
54
    $date_due = dt_from_string( scalar $input->param('date_due') );
55
    $date_due = dt_from_string( scalar $input->param('date_due') );
55
}
56
}
57
my $borrower = Koha::Patrons->find($borrowernumber);
58
my $user     = C4::Context->userenv->{'number'};
59
my $message;
60
my @message;
56
61
57
my $data;
62
my $data;
58
$data->{itemnumber}     = $itemnumber;
63
$data->{itemnumber}     = $itemnumber;
Lines 69-74 my $item = Koha::Items->find($itemnumber); Link Here
69
if ( $data->{error} && $data->{error} eq 'on_reserve' && C4::Context->preference('AllowRenewalOnHoldOverride') ) {
74
if ( $data->{error} && $data->{error} eq 'on_reserve' && C4::Context->preference('AllowRenewalOnHoldOverride') ) {
70
    $data->{renew_okay} = 1;
75
    $data->{renew_okay} = 1;
71
    $data->{error}      = undef;
76
    $data->{error}      = undef;
77
78
    $message = "Override Renew hold for another";
79
    @message = ("Override Renew hold for another");
80
81
    my $infos = (
82
        {
83
            message        => \@message,
84
            borrowernumber => $borrowernumber,
85
            barcode        => $item->barcode,
86
            manager_id     => $user,
87
            branchcode     => $branchcode,
88
        }
89
    );
90
91
    my $json_infos = JSON->new->utf8->pretty->encode($infos);
92
    $json_infos =~ s/"/'/g;
93
94
    logaction(
95
        "CIRCULATION", "RENEWAL",
96
        $borrower->{'borrowernumber'},
97
        $json_infos,
98
    ) if C4::Context->preference("IssueLog");
99
}
100
101
if ( $data->{error} && $data->{error} eq 'too_many' && C4::Context->preference('AllowRenewalLimitOverride') ) {
102
    $data->{renew_okay} = 1;
103
    $data->{error}      = undef;
104
105
    $message = "Override limit Renew";
106
    @message = ("Override limit Renew");
107
108
    my $infos = (
109
        {
110
            message        => \@message,
111
            borrowernumber => $borrowernumber,
112
            barcode        => $item->barcode,
113
            manager_id     => $user,
114
            branchcode     => $branchcode,
115
        }
116
    );
117
118
    my $json_infos = JSON->new->utf8->pretty->encode($infos);
119
    $json_infos =~ s/"/'/g;
120
121
    logaction(
122
        "CIRCULATION", "RENEWAL",
123
        $borrower->{'borrowernumber'},
124
        $json_infos,
125
    ) if C4::Context->preference("IssueLog");
72
}
126
}
73
127
74
if ( $data->{renew_okay} || ( $seen && $data->{error} eq 'too_unseen' ) ) {
128
if ( $data->{renew_okay} || ( $seen && $data->{error} eq 'too_unseen' ) ) {
75
- 

Return to bug 9762