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

(-)a/C4/Circulation.pm (-506 / +426 lines)
Lines 27-39 use C4::Koha; Link Here
27
use C4::Biblio;
27
use C4::Biblio;
28
use C4::Items;
28
use C4::Items;
29
use C4::Members;
29
use C4::Members;
30
use C4::Dates;
30
use C4::IssuingRules;
31
use C4::Dates qw/format_date/;
31
use C4::Calendar;
32
use C4::Calendar;
32
use C4::Accounts;
33
use C4::Accounts;
34
use C4::Overdues ;
33
use C4::ItemCirculationAlertPreference;
35
use C4::ItemCirculationAlertPreference;
34
use C4::Dates qw(format_date);
36
use C4::Dates qw(format_date);
35
use C4::Message;
37
use C4::Message;
36
use C4::Debug;
38
use C4::Debug;
39
use YAML;
37
use Date::Calc qw(
40
use Date::Calc qw(
38
  Today
41
  Today
39
  Today_and_Now
42
  Today_and_Now
Lines 42-47 use Date::Calc qw( Link Here
42
  Date_to_Days
45
  Date_to_Days
43
  Day_of_Week
46
  Day_of_Week
44
  Add_Delta_Days	
47
  Add_Delta_Days	
48
  Delta_Days
49
  check_date
50
  Add_Delta_Days
45
);
51
);
46
use POSIX qw(strftime);
52
use POSIX qw(strftime);
47
use C4::Branch; # GetBranches
53
use C4::Branch; # GetBranches
Lines 73-81 BEGIN { Link Here
73
		&GetItemIssues
79
		&GetItemIssues
74
		&GetBorrowerIssues
80
		&GetBorrowerIssues
75
		&GetIssuingCharges
81
		&GetIssuingCharges
76
		&GetIssuingRule
77
        &GetBranchBorrowerCircRule
78
        &GetBranchItemRule
79
		&GetBiblioIssues
82
		&GetBiblioIssues
80
		&GetOpenIssue
83
		&GetOpenIssue
81
		&AnonymiseIssueHistory
84
		&AnonymiseIssueHistory
Lines 98-103 BEGIN { Link Here
98
                &CreateBranchTransferLimit
101
                &CreateBranchTransferLimit
99
                &DeleteBranchTransferLimits
102
                &DeleteBranchTransferLimits
100
	);
103
	);
104
	
105
	# subs to deal with offline circulation
106
	push @EXPORT, qw(
107
      &GetOfflineOperations
108
		&GetOfflineOperation
109
		&AddOfflineOperation
110
		&DeleteOfflineOperation
111
		&ProcessOfflineOperation
112
	);	
101
}
113
}
102
114
103
=head1 NAME
115
=head1 NAME
Lines 346-461 sub TooMany { Link Here
346
	my $item		= shift;
358
	my $item		= shift;
347
    my $cat_borrower    = $borrower->{'categorycode'};
359
    my $cat_borrower    = $borrower->{'categorycode'};
348
    my $dbh             = C4::Context->dbh;
360
    my $dbh             = C4::Context->dbh;
349
	my $branch;
361
	my $exactbranch;
350
	# Get which branchcode we need
362
	# Get which branchcode we need
351
	$branch = _GetCircControlBranch($item,$borrower);
363
	$exactbranch = _GetCircControlBranch($item,$borrower);
352
	my $type = (C4::Context->preference('item-level_itypes')) 
364
	my $itype = (C4::Context->preference('item-level_itypes')) 
353
  			? $item->{'itype'}         # item-level
365
  			? $item->{'itype'}         # item-level
354
			: $item->{'itemtype'};     # biblio-level
366
			: $item->{'itemtype'};     # biblio-level
355
 
367
 
356
    # given branch, patron category, and item type, determine
368
    # given branch, patron category, and item type, determine
357
    # applicable issuing rule
369
    # applicable issuing rule
358
    my $issuing_rule = GetIssuingRule($cat_borrower, $type, $branch);
370
    my $branchfield = C4::Context->Preference('HomeOrHoldingBranch') || "homebranch";
359
371
    #By default, Patron is supposed not to be able to borrow
360
    # if a rule is found and has a loan limit set, count
372
    my $toomany = 1;
361
    # how many loans the patron already has that meet that
373
362
    # rule
374
    foreach my $branch ( $exactbranch, '*' ) {
363
    if (defined($issuing_rule) and defined($issuing_rule->{'maxissueqty'})) {
375
        foreach my $type ( $itype, '*' ) {
364
        my @bind_params;
376
            my $issuing_rule = GetIssuingRule( $cat_borrower, $type, $branch );
365
        my $count_query = "SELECT COUNT(*) FROM issues
377
366
                           JOIN items USING (itemnumber) ";
378
            # if a rule is found and has a loan limit set, count
367
379
            # how many loans the patron already has that meet that
368
        my $rule_itemtype = $issuing_rule->{itemtype};
380
            # rule
369
        if ($rule_itemtype eq "*") {
381
            if ( defined($issuing_rule) and defined( $issuing_rule->{'maxissueqty'} ) ) {
370
            # matching rule has the default item type, so count only
382
                my @bind_params;
371
            # those existing loans that don't fall under a more
383
                my $count_query = "SELECT COUNT(*) FROM issues
372
            # specific rule
384
                                   JOIN items USING (itemnumber) ";
373
            if (C4::Context->preference('item-level_itypes')) {
385
374
                $count_query .= " WHERE items.itype NOT IN (
386
                my $rule_itemtype = $issuing_rule->{itemtype};
375
                                    SELECT itemtype FROM issuingrules
387
                if ($rule_itemtype eq "*") {
376
                                    WHERE branchcode = ?
388
                    # matching rule has the default item type, so count all the items issued for that branch no
377
                                    AND   (categorycode = ? OR categorycode = ?)
389
                    # those existing loans that don't fall under a more
378
                                    AND   itemtype <> '*'
390
                    # specific rule Not QUITE
379
                                  ) ";
391
                    if (C4::Context->preference('item-level_itypes')) {
380
            } else { 
392
                        $count_query .= " WHERE items.itype NOT IN (
381
                $count_query .= " JOIN  biblioitems USING (biblionumber) 
393
                                                SELECT itemtype FROM issuingrules
382
                                  WHERE biblioitems.itemtype NOT IN (
394
                                                WHERE branchcode = ?
383
                                    SELECT itemtype FROM issuingrules
395
                                                AND   (categorycode = ? OR categorycode = ?)
384
                                    WHERE branchcode = ?
396
                                                AND   itemtype <> '*'
385
                                    AND   (categorycode = ? OR categorycode = ?)
397
                                           )";
386
                                    AND   itemtype <> '*'
398
                    } else {
387
                                  ) ";
399
                        $count_query .= " JOIN  biblioitems USING (biblionumber)
388
            }
400
                                            WHERE biblioitems.itemtype NOT IN (
389
            push @bind_params, $issuing_rule->{branchcode};
401
                                                SELECT itemtype FROM issuingrules
390
            push @bind_params, $issuing_rule->{categorycode};
402
                                                WHERE branchcode = ?
391
            push @bind_params, $cat_borrower;
403
                                                AND   (categorycode = ? OR categorycode = ?)
392
        } else {
404
                                                AND   itemtype <> '*'
393
            # rule has specific item type, so count loans of that
405
                                           )";
394
            # specific item type
406
                    }
395
            if (C4::Context->preference('item-level_itypes')) {
407
                    push @bind_params, $issuing_rule->{branchcode};
396
                $count_query .= " WHERE items.itype = ? ";
408
                    push @bind_params, $issuing_rule->{categorycode};
397
            } else { 
409
                    push @bind_params, $cat_borrower;
398
                $count_query .= " JOIN  biblioitems USING (biblionumber) 
410
                } else {
399
                                  WHERE biblioitems.itemtype= ? ";
411
                    # rule has specific item type, so count loans of that
400
            }
412
                    # specific item type
401
            push @bind_params, $type;
413
                    if (C4::Context->preference('item-level_itypes')) {
402
        }
414
                        $count_query .= " WHERE items.itype = ? ";
403
415
                    } else { 
404
        $count_query .= " AND borrowernumber = ? ";
416
                        $count_query .= " JOIN  biblioitems USING (biblionumber) 
405
        push @bind_params, $borrower->{'borrowernumber'};
417
                                      WHERE biblioitems.itemtype= ? ";
406
        my $rule_branch = $issuing_rule->{branchcode};
418
                    }
407
        if ($rule_branch ne "*") {
419
                    push @bind_params, $type;
408
            if (C4::Context->preference('CircControl') eq 'PickupLibrary') {
420
                }
409
                $count_query .= " AND issues.branchcode = ? ";
410
                push @bind_params, $branch;
411
            } elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') {
412
                ; # if branch is the patron's home branch, then count all loans by patron
413
            } else {
414
                $count_query .= " AND items.homebranch = ? ";
415
                push @bind_params, $branch;
416
            }
417
        }
418
419
        my $count_sth = $dbh->prepare($count_query);
420
        $count_sth->execute(@bind_params);
421
        my ($current_loan_count) = $count_sth->fetchrow_array;
422
421
423
        my $max_loans_allowed = $issuing_rule->{'maxissueqty'};
422
                $count_query .= " AND borrowernumber = ? ";
424
        if ($current_loan_count >= $max_loans_allowed) {
423
                push @bind_params, $borrower->{'borrowernumber'};
425
            return ($current_loan_count, $max_loans_allowed);
424
                my $rule_branch = $issuing_rule->{branchcode};
426
        }
425
                if ( $rule_branch ne "*" ) {
427
    }
426
                    if ( C4::Context->preference('CircControl') eq 'PickupLibrary' ) {
427
                        $count_query .= " AND issues.branchcode = ? ";
428
                        push @bind_params, $branch;
429
                    } elsif ( C4::Context->preference('CircControl') eq 'PatronLibrary' ) {
430
                        ;    # if branch is the patron's home branch, then count all loans by patron
431
                    } else {
432
                        $count_query .= " AND items.$branchfield = ? ";
433
                        push @bind_params, $branch;
434
                    }
435
                }
428
436
429
    # Now count total loans against the limit for the branch
437
                my $count_sth = $dbh->prepare($count_query);
430
    my $branch_borrower_circ_rule = GetBranchBorrowerCircRule($branch, $cat_borrower);
438
                $count_sth->execute(@bind_params);
431
    if (defined($branch_borrower_circ_rule->{maxissueqty})) {
439
                my ($current_loan_count) = $count_sth->fetchrow_array;
432
        my @bind_params = ();
433
        my $branch_count_query = "SELECT COUNT(*) FROM issues 
434
                                  JOIN items USING (itemnumber)
435
                                  WHERE borrowernumber = ? ";
436
        push @bind_params, $borrower->{borrowernumber};
437
438
        if (C4::Context->preference('CircControl') eq 'PickupLibrary') {
439
            $branch_count_query .= " AND issues.branchcode = ? ";
440
            push @bind_params, $branch;
441
        } elsif (C4::Context->preference('CircControl') eq 'PatronLibrary') {
442
            ; # if branch is the patron's home branch, then count all loans by patron
443
        } else {
444
            $branch_count_query .= " AND items.homebranch = ? ";
445
            push @bind_params, $branch;
446
        }
447
        my $branch_count_sth = $dbh->prepare($branch_count_query);
448
        $branch_count_sth->execute(@bind_params);
449
        my ($current_loan_count) = $branch_count_sth->fetchrow_array;
450
440
451
        my $max_loans_allowed = $branch_borrower_circ_rule->{maxissueqty};
441
                my $max_loans_allowed = $issuing_rule->{'maxissueqty'};
452
        if ($current_loan_count >= $max_loans_allowed) {
442
                if ( $current_loan_count >= $max_loans_allowed ) {
453
            return ($current_loan_count, $max_loans_allowed);
443
                    return 1,$current_loan_count,$max_loans_allowed;
444
                }
445
                else {
446
                    $toomany=0;
447
                }
448
            }
454
        }
449
        }
455
    }
450
    }
456
451
    return $toomany;
457
    # OK, the patron can issue !!!
458
    return;
459
}
452
}
460
453
461
=head2 itemissues
454
=head2 itemissues
Lines 684-690 sub CanBookBeIssued { Link Here
684
        my $branch = _GetCircControlBranch($item,$borrower);
677
        my $branch = _GetCircControlBranch($item,$borrower);
685
        my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'};
678
        my $itype = ( C4::Context->preference('item-level_itypes') ) ? $item->{'itype'} : $biblioitem->{'itemtype'};
686
        my $loanlength = GetLoanLength( $borrower->{'categorycode'}, $itype, $branch );
679
        my $loanlength = GetLoanLength( $borrower->{'categorycode'}, $itype, $branch );
687
        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $loanlength, $branch, $borrower );
680
        unless ($loanlength or C4::Context->preference("AllowNotForLoanOverride")) {
681
             $issuingimpossible{LOAN_LENGTH_UNDEFINED} = "$borrower->{'categorycode'}, $itype, $branch";
682
        }
683
        $duedate = CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $loanlength, $branch, $borrower ) ;
688
684
689
        # Offline circ calls AddIssue directly, doesn't run through here
685
        # Offline circ calls AddIssue directly, doesn't run through here
690
        #  So issuingimpossible should be ok.
686
        #  So issuingimpossible should be ok.
Lines 712-726 sub CanBookBeIssued { Link Here
712
        $issuingimpossible{CARD_LOST} = 1;
708
        $issuingimpossible{CARD_LOST} = 1;
713
    }
709
    }
714
    if ( $borrower->{flags}->{'DBARRED'} ) {
710
    if ( $borrower->{flags}->{'DBARRED'} ) {
715
        $issuingimpossible{DEBARRED} = 1;
711
		if (my $dateenddebarred=$borrower->{flags}->{'DBARRED'}->{'dateend'}){
712
        	$issuingimpossible{DEBARRED} = format_date($dateenddebarred);
713
		}
714
		else {
715
        	$issuingimpossible{DEBARRED} = 1;
716
		}
716
    }
717
    }
717
    if ( $borrower->{'dateexpiry'} eq '0000-00-00') {
718
    if ( $borrower->{'dateexpiry'} eq '0000-00-00') {
718
        $issuingimpossible{EXPIRED} = 1;
719
        $issuingimpossible{EXPIRED} = 1;
719
    } else {
720
    } else {
720
        my @expirydate=  split /-/,$borrower->{'dateexpiry'};
721
        my @expirydate = split (/-/, $borrower->{'dateexpiry'});
721
        if($expirydate[0]==0 || $expirydate[1]==0|| $expirydate[2]==0 ||
722
        if (   $expirydate[0] == 0
722
            Date_to_Days(Today) > Date_to_Days( @expirydate )) {
723
            || $expirydate[1] == 0
723
            $issuingimpossible{EXPIRED} = 1;                                   
724
            || $expirydate[2] == 0
725
            || Date_to_Days(Today) > Date_to_Days(@expirydate) ) {
726
            $issuingimpossible{EXPIRED} = 1;
724
        }
727
        }
725
    }
728
    }
726
    #
729
    #
Lines 769-786 sub CanBookBeIssued { Link Here
769
#
772
#
770
    # JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS
773
    # JB34 CHECKS IF BORROWERS DONT HAVE ISSUE TOO MANY BOOKS
771
    #
774
    #
772
	my ($current_loan_count, $max_loans_allowed) = TooMany( $borrower, $item->{biblionumber}, $item );
775
    my @toomany = TooMany( $borrower, $item->{biblionumber}, $item );
773
    # if TooMany max_loans_allowed returns 0 the user doesn't have permission to check out this book
776
774
    if ($max_loans_allowed eq 0) {
777
    if ( $toomany[0] == 1 && scalar(@toomany)<3) {
775
        $needsconfirmation{PATRON_CANT} = 1;
778
        $needsconfirmation{PATRON_CANT} = 1;
776
    } else {
779
    } elsif (scalar(@toomany)==3) {
777
        if($max_loans_allowed){
780
        $needsconfirmation{TOO_MANY} = "$toomany[1] / $toomany[2]";
778
            $needsconfirmation{TOO_MANY} = 1;
779
            $needsconfirmation{current_loan_count} = $current_loan_count;
780
            $needsconfirmation{max_loans_allowed} = $max_loans_allowed;
781
        }
782
    }
781
    }
783
782
783
784
    #
784
    #
785
    # ITEM CHECKING
785
    # ITEM CHECKING
786
    #
786
    #
Lines 817-824 sub CanBookBeIssued { Link Here
817
            }
817
            }
818
        }
818
        }
819
    }
819
    }
820
    if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} == 1 )
820
    if ( $item->{'damaged'} && $item->{'damaged'} > 0 ){
821
    {
821
        $needsconfirmation{DAMAGED} = $item->{'damaged'};
822
        my $fw                      = GetFrameworkCode($item->{biblionumber});
823
        my $category                = GetAuthValCode('items.damaged',$fw);
824
        my $authorizedvalues        = GetAuthorisedValues($category, $item->{damaged});
825
        
826
        foreach my $authvalue (@$authorizedvalues){
827
            $needsconfirmation{DAMAGED} = $authvalue->{lib} if $authvalue->{'authorised_value'} eq $item->{'damaged'};
828
        }
829
        
830
    }
831
    if ( $item->{'wthdrawn'} && $item->{'wthdrawn'} == 1 ) {
822
        $issuingimpossible{WTHDRAWN} = 1;
832
        $issuingimpossible{WTHDRAWN} = 1;
823
    }
833
    }
824
    if (   $item->{'restricted'}
834
    if (   $item->{'restricted'}
Lines 826-840 sub CanBookBeIssued { Link Here
826
    {
836
    {
827
        $issuingimpossible{RESTRICTED} = 1;
837
        $issuingimpossible{RESTRICTED} = 1;
828
    }
838
    }
839
    my $userenv = C4::Context->userenv;
840
    my $branch=$userenv->{branch};
841
    my $hbr= $item->{ C4::Context->preference("HomeOrHoldingBranch") };
829
    if ( C4::Context->preference("IndependantBranches") ) {
842
    if ( C4::Context->preference("IndependantBranches") ) {
830
        my $userenv = C4::Context->userenv;
831
        if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) {
843
        if ( ($userenv) && ( $userenv->{flags} % 2 != 1 ) ) {
832
            $issuingimpossible{ITEMNOTSAMEBRANCH} = 1
844
            $issuingimpossible{ITEMNOTSAMEBRANCH} = 1
833
              if ( $item->{C4::Context->preference("HomeOrHoldingBranch")} ne $userenv->{branch} );
845
              if ( $hbr ne $branch );
834
            $needsconfirmation{BORRNOTSAMEBRANCH} = GetBranchName( $borrower->{'branchcode'} )
846
            $needsconfirmation{BORRNOTSAMEBRANCH} = GetBranchName( $borrower->{'branchcode'} )
835
              if ( $borrower->{'branchcode'} ne $userenv->{branch} );
847
              if ( $borrower->{'branchcode'} ne $userenv->{branch} );
836
        }
848
        }
837
    }
849
    }
850
    my $branchtransferfield=C4::Context->preference("BranchTransferLimitsType") eq "ccode" ? "ccode" : "itype";
851
    if  ( C4::Context->preference("UseBranchTransferLimits")
852
                and !IsBranchTransferAllowed( $branch, $hbr, $item->{ $branchtransferfield } ) ) {
853
        $needsconfirmation{BRANCH_TRANSFER_NOT_ALLOWED} = $hbr;
854
    }
855
838
856
839
    #
857
    #
840
    # CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER
858
    # CHECK IF BOOK ALREADY ISSUED TO THIS BORROWER
Lines 875-904 sub CanBookBeIssued { Link Here
875
		my ( $resborrower ) = C4::Members::GetMemberDetails( $resbor, 0 );
893
		my ( $resborrower ) = C4::Members::GetMemberDetails( $resbor, 0 );
876
		my $branches  = GetBranches();
894
		my $branches  = GetBranches();
877
		my $branchname = $branches->{ $res->{'branchcode'} }->{'branchname'};
895
		my $branchname = $branches->{ $res->{'branchcode'} }->{'branchname'};
878
        if ( $resbor ne $borrower->{'borrowernumber'} && $restype eq "Waiting" )
896
        if( $resbor ne $borrower->{'borrowernumber'}){
879
        {
897
            if ( $restype eq "Waiting" ) {
880
            # The item is on reserve and waiting, but has been
898
                # The item is on reserve and waiting, but has been
881
            # reserved by some other patron.
899
                # reserved by some other patron.
882
            $needsconfirmation{RESERVE_WAITING} = 1;
900
                $needsconfirmation{RESERVE_WAITING} =
883
            $needsconfirmation{'resfirstname'} = $resborrower->{'firstname'};
901
    "$resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'}, $branchname)";
884
            $needsconfirmation{'ressurname'} = $resborrower->{'surname'};
902
            }
885
            $needsconfirmation{'rescardnumber'} = $resborrower->{'cardnumber'};
903
            elsif ( $restype eq "Reserved" ) {
886
            $needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'};
904
                # The item is on reserve for someone else.
887
            $needsconfirmation{'resbranchname'} = $branchname;
905
                $needsconfirmation{RESERVED} =
888
            $needsconfirmation{'reswaitingdate'} = format_date($res->{'waitingdate'});
906
    "$res->{'reservedate'} : $resborrower->{'firstname'} $resborrower->{'surname'} ($resborrower->{'cardnumber'})";
889
        }
907
            }
890
        elsif ( $restype eq "Reserved" ) {
891
            # The item is on reserve for someone else.
892
            $needsconfirmation{RESERVED} = 1;
893
            $needsconfirmation{'resfirstname'} = $resborrower->{'firstname'};
894
            $needsconfirmation{'ressurname'} = $resborrower->{'surname'};
895
            $needsconfirmation{'rescardnumber'} = $resborrower->{'cardnumber'};
896
            $needsconfirmation{'resborrowernumber'} = $resborrower->{'borrowernumber'};
897
            $needsconfirmation{'resbranchname'} = $branchname;
898
            $needsconfirmation{'resreservedate'} = format_date($res->{'reservedate'});
899
        }
908
        }
900
    }
909
    }
901
	return ( \%issuingimpossible, \%needsconfirmation );
910
    return ( \%issuingimpossible, \%needsconfirmation );
902
}
911
}
903
912
904
=head2 AddIssue
913
=head2 AddIssue
Lines 979-985 sub AddIssue { Link Here
979
				# who wants to borrow it now. mark it returned before issuing to the new borrower
988
				# who wants to borrow it now. mark it returned before issuing to the new borrower
980
				AddReturn(
989
				AddReturn(
981
					$item->{'barcode'},
990
					$item->{'barcode'},
982
					C4::Context->userenv->{'branch'}
991
					C4::Context->userenv->{'branch'},
992
					undef,
993
					undef,
994
					1
983
				);
995
				);
984
			}
996
			}
985
997
Lines 1012-1018 sub AddIssue { Link Here
1012
					ModReserve(1,
1024
					ModReserve(1,
1013
						$res->{'biblionumber'},
1025
						$res->{'biblionumber'},
1014
						$res->{'borrowernumber'},
1026
						$res->{'borrowernumber'},
1015
						$res->{'branchcode'}
1027
						$res->{'branchcode'},
1028
						undef,
1029
						$res->{'reservenumber'}
1016
					);
1030
					);
1017
				}
1031
				}
1018
			}
1032
			}
Lines 1102-1111 sub AddIssue { Link Here
1102
                branch   => $branch,
1116
                branch   => $branch,
1103
            });
1117
            });
1104
        }
1118
        }
1119
1120
        logaction( "CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $item->{'itemnumber'}  )
1121
          if C4::Context->preference("IssueLog");
1105
    }
1122
    }
1106
1123
1107
    logaction("CIRCULATION", "ISSUE", $borrower->{'borrowernumber'}, $biblio->{'biblionumber'})
1108
        if C4::Context->preference("IssueLog");
1109
  }
1124
  }
1110
  return ($datedue);	# not necessarily the same as when it came in!
1125
  return ($datedue);	# not necessarily the same as when it came in!
1111
}
1126
}
Lines 1120-1373 Get loan length for an itemtype, a borrower type and a branch Link Here
1120
1135
1121
sub GetLoanLength {
1136
sub GetLoanLength {
1122
    my ( $borrowertype, $itemtype, $branchcode ) = @_;
1137
    my ( $borrowertype, $itemtype, $branchcode ) = @_;
1123
    my $dbh = C4::Context->dbh;
1138
    my $loanlength=GetIssuingRule($borrowertype,$itemtype,$branchcode);
1124
    my $sth =
1139
    return $loanlength->{issuelength};
1125
      $dbh->prepare(
1126
"select issuelength from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null"
1127
      );
1128
# warn "in get loan lenght $borrowertype $itemtype $branchcode ";
1129
# try to find issuelength & return the 1st available.
1130
# check with borrowertype, itemtype and branchcode, then without one of those parameters
1131
    $sth->execute( $borrowertype, $itemtype, $branchcode );
1132
    my $loanlength = $sth->fetchrow_hashref;
1133
    return $loanlength->{issuelength}
1134
      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
1135
1136
    $sth->execute( $borrowertype, "*", $branchcode );
1137
    $loanlength = $sth->fetchrow_hashref;
1138
    return $loanlength->{issuelength}
1139
      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
1140
1141
    $sth->execute( "*", $itemtype, $branchcode );
1142
    $loanlength = $sth->fetchrow_hashref;
1143
    return $loanlength->{issuelength}
1144
      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
1145
1146
    $sth->execute( "*", "*", $branchcode );
1147
    $loanlength = $sth->fetchrow_hashref;
1148
    return $loanlength->{issuelength}
1149
      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
1150
1151
    $sth->execute( $borrowertype, $itemtype, "*" );
1152
    $loanlength = $sth->fetchrow_hashref;
1153
    return $loanlength->{issuelength}
1154
      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
1155
1156
    $sth->execute( $borrowertype, "*", "*" );
1157
    $loanlength = $sth->fetchrow_hashref;
1158
    return $loanlength->{issuelength}
1159
      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
1160
1161
    $sth->execute( "*", $itemtype, "*" );
1162
    $loanlength = $sth->fetchrow_hashref;
1163
    return $loanlength->{issuelength}
1164
      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
1165
1166
    $sth->execute( "*", "*", "*" );
1167
    $loanlength = $sth->fetchrow_hashref;
1168
    return $loanlength->{issuelength}
1169
      if defined($loanlength) && $loanlength->{issuelength} ne 'NULL';
1170
1171
    # if no rule is set => 21 days (hardcoded)
1172
    return 21;
1173
}
1174
1175
=head2 GetIssuingRule
1176
1177
  my $irule = &GetIssuingRule($borrowertype,$itemtype,branchcode)
1178
1179
FIXME - This is a copy-paste of GetLoanLength
1180
as a stop-gap.  Do not wish to change API for GetLoanLength 
1181
this close to release, however, Overdues::GetIssuingRules is broken.
1182
1183
Get the issuing rule for an itemtype, a borrower type and a branch
1184
Returns a hashref from the issuingrules table.
1185
1186
=cut
1187
1188
sub GetIssuingRule {
1189
    my ( $borrowertype, $itemtype, $branchcode ) = @_;
1190
    my $dbh = C4::Context->dbh;
1191
    my $sth =  $dbh->prepare( "select * from issuingrules where categorycode=? and itemtype=? and branchcode=? and issuelength is not null"  );
1192
    my $irule;
1193
1194
	$sth->execute( $borrowertype, $itemtype, $branchcode );
1195
    $irule = $sth->fetchrow_hashref;
1196
    return $irule if defined($irule) ;
1197
1198
    $sth->execute( $borrowertype, "*", $branchcode );
1199
    $irule = $sth->fetchrow_hashref;
1200
    return $irule if defined($irule) ;
1201
1202
    $sth->execute( "*", $itemtype, $branchcode );
1203
    $irule = $sth->fetchrow_hashref;
1204
    return $irule if defined($irule) ;
1205
1206
    $sth->execute( "*", "*", $branchcode );
1207
    $irule = $sth->fetchrow_hashref;
1208
    return $irule if defined($irule) ;
1209
1210
    $sth->execute( $borrowertype, $itemtype, "*" );
1211
    $irule = $sth->fetchrow_hashref;
1212
    return $irule if defined($irule) ;
1213
1214
    $sth->execute( $borrowertype, "*", "*" );
1215
    $irule = $sth->fetchrow_hashref;
1216
    return $irule if defined($irule) ;
1217
1218
    $sth->execute( "*", $itemtype, "*" );
1219
    $irule = $sth->fetchrow_hashref;
1220
    return $irule if defined($irule) ;
1221
1222
    $sth->execute( "*", "*", "*" );
1223
    $irule = $sth->fetchrow_hashref;
1224
    return $irule if defined($irule) ;
1225
1226
    # if no rule matches,
1227
    return undef;
1228
}
1229
1230
=head2 GetBranchBorrowerCircRule
1231
1232
  my $branch_cat_rule = GetBranchBorrowerCircRule($branchcode, $categorycode);
1233
1234
Retrieves circulation rule attributes that apply to the given
1235
branch and patron category, regardless of item type.  
1236
The return value is a hashref containing the following key:
1237
1238
maxissueqty - maximum number of loans that a
1239
patron of the given category can have at the given
1240
branch.  If the value is undef, no limit.
1241
1242
This will first check for a specific branch and
1243
category match from branch_borrower_circ_rules. 
1244
1245
If no rule is found, it will then check default_branch_circ_rules
1246
(same branch, default category).  If no rule is found,
1247
it will then check default_borrower_circ_rules (default 
1248
branch, same category), then failing that, default_circ_rules
1249
(default branch, default category).
1250
1251
If no rule has been found in the database, it will default to
1252
the buillt in rule:
1253
1254
maxissueqty - undef
1255
1256
C<$branchcode> and C<$categorycode> should contain the
1257
literal branch code and patron category code, respectively - no
1258
wildcards.
1259
1260
=cut
1261
1262
sub GetBranchBorrowerCircRule {
1263
    my $branchcode = shift;
1264
    my $categorycode = shift;
1265
1266
    my $branch_cat_query = "SELECT maxissueqty
1267
                            FROM branch_borrower_circ_rules
1268
                            WHERE branchcode = ?
1269
                            AND   categorycode = ?";
1270
    my $dbh = C4::Context->dbh();
1271
    my $sth = $dbh->prepare($branch_cat_query);
1272
    $sth->execute($branchcode, $categorycode);
1273
    my $result;
1274
    if ($result = $sth->fetchrow_hashref()) {
1275
        return $result;
1276
    }
1277
1278
    # try same branch, default borrower category
1279
    my $branch_query = "SELECT maxissueqty
1280
                        FROM default_branch_circ_rules
1281
                        WHERE branchcode = ?";
1282
    $sth = $dbh->prepare($branch_query);
1283
    $sth->execute($branchcode);
1284
    if ($result = $sth->fetchrow_hashref()) {
1285
        return $result;
1286
    }
1287
1288
    # try default branch, same borrower category
1289
    my $category_query = "SELECT maxissueqty
1290
                          FROM default_borrower_circ_rules
1291
                          WHERE categorycode = ?";
1292
    $sth = $dbh->prepare($category_query);
1293
    $sth->execute($categorycode);
1294
    if ($result = $sth->fetchrow_hashref()) {
1295
        return $result;
1296
    }
1297
  
1298
    # try default branch, default borrower category
1299
    my $default_query = "SELECT maxissueqty
1300
                          FROM default_circ_rules";
1301
    $sth = $dbh->prepare($default_query);
1302
    $sth->execute();
1303
    if ($result = $sth->fetchrow_hashref()) {
1304
        return $result;
1305
    }
1306
    
1307
    # built-in default circulation rule
1308
    return {
1309
        maxissueqty => undef,
1310
    };
1311
}
1312
1313
=head2 GetBranchItemRule
1314
1315
  my $branch_item_rule = GetBranchItemRule($branchcode, $itemtype);
1316
1317
Retrieves circulation rule attributes that apply to the given
1318
branch and item type, regardless of patron category.
1319
1320
The return value is a hashref containing the following key:
1321
1322
holdallowed => Hold policy for this branch and itemtype. Possible values:
1323
  0: No holds allowed.
1324
  1: Holds allowed only by patrons that have the same homebranch as the item.
1325
  2: Holds allowed from any patron.
1326
1327
This searches branchitemrules in the following order:
1328
1329
  * Same branchcode and itemtype
1330
  * Same branchcode, itemtype '*'
1331
  * branchcode '*', same itemtype
1332
  * branchcode and itemtype '*'
1333
1334
Neither C<$branchcode> nor C<$categorycode> should be '*'.
1335
1336
=cut
1337
1338
sub GetBranchItemRule {
1339
    my ( $branchcode, $itemtype ) = @_;
1340
    my $dbh = C4::Context->dbh();
1341
    my $result = {};
1342
1343
    my @attempts = (
1344
        ['SELECT holdallowed
1345
            FROM branch_item_rules
1346
            WHERE branchcode = ?
1347
              AND itemtype = ?', $branchcode, $itemtype],
1348
        ['SELECT holdallowed
1349
            FROM default_branch_circ_rules
1350
            WHERE branchcode = ?', $branchcode],
1351
        ['SELECT holdallowed
1352
            FROM default_branch_item_rules
1353
            WHERE itemtype = ?', $itemtype],
1354
        ['SELECT holdallowed
1355
            FROM default_circ_rules'],
1356
    );
1357
1358
    foreach my $attempt (@attempts) {
1359
        my ($query, @bind_params) = @{$attempt};
1360
1361
        # Since branch/category and branch/itemtype use the same per-branch
1362
        # defaults tables, we have to check that the key we want is set, not
1363
        # just that a row was returned
1364
        return $result if ( defined( $result->{'holdallowed'} = $dbh->selectrow_array( $query, {}, @bind_params ) ) );
1365
    }
1366
    
1367
    # built-in default circulation rule
1368
    return {
1369
        holdallowed => 2,
1370
    };
1371
}
1140
}
1372
1141
1373
=head2 AddReturn
1142
=head2 AddReturn
Lines 1445-1452 patron who last borrowed the book. Link Here
1445
=cut
1214
=cut
1446
1215
1447
sub AddReturn {
1216
sub AddReturn {
1448
    my ( $barcode, $branch, $exemptfine, $dropbox ) = @_;
1217
    my ( $barcode, $branch, $exemptfine, $dropbox, $force) = @_;
1449
    if ($branch and not GetBranchDetail($branch)) {
1218
    if ( $branch and not GetBranchDetail($branch) ) {
1450
        warn "AddReturn error: branch '$branch' not found.  Reverting to " . C4::Context->userenv->{'branch'};
1219
        warn "AddReturn error: branch '$branch' not found.  Reverting to " . C4::Context->userenv->{'branch'};
1451
        undef $branch;
1220
        undef $branch;
1452
    }
1221
    }
Lines 1490-1498 sub AddReturn { Link Here
1490
        my $branches = GetBranches();    # a potentially expensive call for a non-feature.
1259
        my $branches = GetBranches();    # a potentially expensive call for a non-feature.
1491
        $branches->{$hbr}->{PE} and $messages->{'IsPermanent'} = $hbr;
1260
        $branches->{$hbr}->{PE} and $messages->{'IsPermanent'} = $hbr;
1492
    }
1261
    }
1493
1262
    my $branchtransferfield=C4::Context->preference("BranchTransferLimitsType") eq "ccode" ? "ccode" : "itype";
1263
    $debug && warn "$branch, $hbr, ",C4::Context->preference("BranchTransferLimitsType")," ,",$item->{ $branchtransferfield } ;
1264
    $debug && warn Dump($item);
1265
    $debug && warn IsBranchTransferAllowed( $branch, $hbr, $item->{ C4::Context->preference("BranchTransferLimitsType") } );
1494
    # if indy branches and returning to different branch, refuse the return
1266
    # if indy branches and returning to different branch, refuse the return
1495
    if ($hbr ne $branch && C4::Context->preference("IndependantBranches")){
1267
    if ( !$force && ($hbr ne $branch)
1268
		&& (C4::Context->preference("IndependantBranches") 
1269
			or ( C4::Context->preference("UseBranchTransferLimits")
1270
                and !IsBranchTransferAllowed( $branch, $hbr, $item->{$branchtransferfield } ) )
1271
		    )
1272
		){
1496
        $messages->{'Wrongbranch'} = {
1273
        $messages->{'Wrongbranch'} = {
1497
            Wrongbranch => $branch,
1274
            Wrongbranch => $branch,
1498
            Rightbranch => $hbr,
1275
            Rightbranch => $hbr,
Lines 1503-1509 sub AddReturn { Link Here
1503
        # FIXME - even in an indy branches situation, there should
1280
        # FIXME - even in an indy branches situation, there should
1504
        # still be an option for the library to accept the item
1281
        # still be an option for the library to accept the item
1505
        # and transfer it to its owning library.
1282
        # and transfer it to its owning library.
1506
        return ( $doreturn, $messages, $issue, $borrower );
1507
    }
1283
    }
1508
1284
1509
    if ( $item->{'wthdrawn'} ) { # book has been cancelled
1285
    if ( $item->{'wthdrawn'} ) { # book has been cancelled
Lines 1514-1525 sub AddReturn { Link Here
1514
    # case of a return of document (deal with issues and holdingbranch)
1290
    # case of a return of document (deal with issues and holdingbranch)
1515
    if ($doreturn) {
1291
    if ($doreturn) {
1516
        $borrower or warn "AddReturn without current borrower";
1292
        $borrower or warn "AddReturn without current borrower";
1517
		my $circControlBranch;
1293
        my $circControlBranch;
1518
        if ($dropbox) {
1294
        if ($dropbox) {
1519
            # define circControlBranch only if dropbox mode is set
1295
            $circControlBranch = _GetCircControlBranch( $item, $borrower );
1520
            # don't allow dropbox mode to create an invalid entry in issues (issuedate > today)
1296
            # don't allow dropbox mode to create an invalid entry in issues (issuedate > returndate) FIXME: actually checks eq, not gt
1521
            # FIXME: check issuedate > returndate, factoring in holidays
1297
            undef($dropbox) if ( $item->{'issuedate'} eq C4::Dates->today('iso') );
1522
            $circControlBranch = _GetCircControlBranch($item,$borrower) unless ( $item->{'issuedate'} eq C4::Dates->today('iso') );;
1523
        }
1298
        }
1524
1299
1525
        if ($borrowernumber) {
1300
        if ($borrowernumber) {
Lines 1527-1541 sub AddReturn { Link Here
1527
            $messages->{'WasReturned'} = 1;    # FIXME is the "= 1" right?  This could be the borrower hash.
1302
            $messages->{'WasReturned'} = 1;    # FIXME is the "= 1" right?  This could be the borrower hash.
1528
        }
1303
        }
1529
1304
1530
        ModItem({ onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'});
1305
        ModItem( { renewals=>0, onloan => undef }, $issue->{'biblionumber'}, $item->{'itemnumber'} );
1306
    	# the holdingbranch is updated if the document is returned to another location.
1307
    	# this is always done regardless of whether the item was on loan or not
1308
    	if ( $item->{'holdingbranch'} ne $branch ) {
1309
       	    UpdateHoldingbranch( $branch, $item->{'itemnumber'} );
1310
            $item->{'holdingbranch'} = $branch;    # update item data holdingbranch too
1311
	    }	   
1531
    }
1312
    }
1532
1313
1533
    # the holdingbranch is updated if the document is returned to another location.
1534
    # this is always done regardless of whether the item was on loan or not
1535
    if ($item->{'holdingbranch'} ne $branch) {
1536
        UpdateHoldingbranch($branch, $item->{'itemnumber'});
1537
        $item->{'holdingbranch'} = $branch; # update item data holdingbranch too
1538
    }
1539
    ModDateLastSeen( $item->{'itemnumber'} );
1314
    ModDateLastSeen( $item->{'itemnumber'} );
1540
1315
1541
    # check if we have a transfer for this document
1316
    # check if we have a transfer for this document
Lines 1562-1572 sub AddReturn { Link Here
1562
        _FixAccountForLostAndReturned($item->{'itemnumber'}, $borrowernumber, $barcode);    # can tolerate undef $borrowernumber
1337
        _FixAccountForLostAndReturned($item->{'itemnumber'}, $borrowernumber, $barcode);    # can tolerate undef $borrowernumber
1563
        $messages->{'WasLost'} = 1;
1338
        $messages->{'WasLost'} = 1;
1564
    }
1339
    }
1340
    if ($item->{'notforloan'}){
1341
        $messages->{'NotForLoan'} = $item->{'notforloan'};
1342
    }
1343
    if ($item->{'damaged'}){
1344
        $messages->{'Damaged'} = $item->{'damaged'};
1345
    }
1565
1346
1566
    # fix up the overdues in accounts...
1347
    if ($borrowernumber && $doreturn) {
1567
    if ($borrowernumber) {
1348
        # fix up the overdues in accounts...
1568
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
1349
        my $fix = _FixOverduesOnReturn($borrowernumber, $item->{itemnumber}, $exemptfine, $dropbox);
1569
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
1350
        defined($fix) or warn "_FixOverduesOnReturn($borrowernumber, $item->{itemnumber}...) failed!";  # zero is OK, check defined
1351
    
1352
        # fix fine days
1353
        my $debardate = _FixFineDaysOnReturn($borrower, $item, $issue->{date_due});
1354
        $messages->{'Debarred'} = $debardate if($debardate);
1355
1356
        # get fines for the borrower
1357
        my $fineamount = C4::Overdues::GetFine($borrowernumber);
1358
        $messages->{'HaveFines'} = $fineamount if($fineamount);
1359
        
1570
    }
1360
    }
1571
1361
1572
    # find reserves.....
1362
    # find reserves.....
Lines 1602-1621 sub AddReturn { Link Here
1602
            branch   => $branch,
1392
            branch   => $branch,
1603
        });
1393
        });
1604
    }
1394
    }
1605
    
1395
1606
    logaction("CIRCULATION", "RETURN", $borrowernumber, $item->{'biblionumber'})
1396
    logaction( "CIRCULATION", "RETURN", $borrowernumber, $item->{'itemnumber'} )
1607
        if C4::Context->preference("ReturnLog");
1397
      if C4::Context->preference("ReturnLog");
1608
    
1398
1609
    # FIXME: make this comment intelligible.
1399
    # FIXME: make this comment intelligible.
1610
    #adding message if holdingbranch is non equal a userenv branch to return the document to homebranch
1400
    #adding message if holdingbranch is non equal a userenv branch to return the document to homebranch
1611
    #we check, if we don't have reserv or transfert for this document, if not, return it to homebranch .
1401
    #we check, if we don't have reserv or transfert for this document, if not, return it to homebranch .
1612
1402
1613
    if ($doreturn and ($branch ne $hbr) and not $messages->{'WrongTransfer'} and ($validTransfert ne 1) ){
1403
    if ( $doreturn and ( $branch ne $hbr ) and not $messages->{'WrongTransfer'} and ( $validTransfert ne 1 ) ) {
1614
        if ( C4::Context->preference("AutomaticItemReturn"    ) or
1404
        if (C4::Context->preference("AutomaticItemReturn")
1615
            (C4::Context->preference("UseBranchTransferLimits") and
1405
            or ( C4::Context->preference("UseBranchTransferLimits")
1616
             ! IsBranchTransferAllowed($branch, $hbr, $item->{C4::Context->preference("BranchTransferLimitsType")} )
1406
                and !IsBranchTransferAllowed( $branch, $hbr, $item->{ $branchtransferfield } ) )
1617
           )) {
1407
          ) {
1618
            $debug and warn sprintf "about to call ModItemTransfer(%s, %s, %s)", $item->{'itemnumber'},$branch, $hbr;
1408
            $debug and warn sprintf "about to call ModItemTransfer(%s, %s, %s)", $item->{'itemnumber'}, $branch, $hbr;
1619
            $debug and warn "item: " . Dumper($item);
1409
            $debug and warn "item: " . Dumper($item);
1620
            ModItemTransfer($item->{'itemnumber'}, $branch, $hbr);
1410
            ModItemTransfer($item->{'itemnumber'}, $branch, $hbr);
1621
            $messages->{'WasTransfered'} = 1;
1411
            $messages->{'WasTransfered'} = 1;
Lines 1690-1695 sub MarkIssueReturned { Link Here
1690
    $sth_del->execute($borrowernumber, $itemnumber);
1480
    $sth_del->execute($borrowernumber, $itemnumber);
1691
}
1481
}
1692
1482
1483
=head2 _FixFineDaysOnReturn
1484
1485
    &_FixFineDaysOnReturn($borrower, $item, $datedue);
1486
1487
C<$borrower> borrower hashref
1488
1489
C<$item> item hashref
1490
1491
C<$datedue> date due
1492
1493
Internal function, called only by AddReturn that calculate and update the user fine days, and debars him
1494
1495
=cut
1496
1497
sub _FixFineDaysOnReturn {
1498
    my ($borrower, $item, $datedue) = @_;
1499
    
1500
    if($datedue){
1501
        $datedue = C4::Dates->new($datedue,"iso");
1502
    }else{
1503
        return;
1504
    }
1505
    
1506
    my $branchcode  =_GetCircControlBranch($item, $borrower);
1507
    my $calendar    = C4::Calendar->new( branchcode => $branchcode );
1508
    my $today       = C4::Dates->new();
1509
1510
    my $deltadays = $calendar->daysBetween($datedue, C4::Dates->new());
1511
1512
    my $circcontrol = C4::Context::preference('CircControl');
1513
    my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode);
1514
    my $finedays    = $issuingrule->{finedays};
1515
    # exit if no finedays defined
1516
    return unless $finedays;
1517
    my $grace       = $issuingrule->{firstremind};
1518
1519
    if( $deltadays - $grace > 0){
1520
        my @newdate     = Add_Delta_Days(Today(), $deltadays * $finedays );
1521
        my $isonewdate  = join('-',@newdate);
1522
        my ($deby, $debm, $debd) = split(/-/,$borrower->{debarred});
1523
        if(check_date($deby, $debm, $debd)){
1524
            my @olddate = split(/-/, $borrower->{debarred});
1525
1526
            if(Delta_Days(@olddate,@newdate) > 0){
1527
                C4::Members::DebarMember($borrower->{borrowernumber}, $isonewdate);
1528
                return $isonewdate;
1529
            }
1530
        }else{
1531
            C4::Members::DebarMember($borrower->{borrowernumber}, $isonewdate);
1532
            return $isonewdate;
1533
        }
1534
    }
1535
}
1536
1537
1693
=head2 _FixOverduesOnReturn
1538
=head2 _FixOverduesOnReturn
1694
1539
1695
   &_FixOverduesOnReturn($brn,$itm, $exemptfine, $dropboxmode);
1540
   &_FixOverduesOnReturn($brn,$itm, $exemptfine, $dropboxmode);
Lines 1864-1870 sub _GetCircControlBranch { Link Here
1864
    my $circcontrol = C4::Context->preference('CircControl');
1709
    my $circcontrol = C4::Context->preference('CircControl');
1865
    my $branch;
1710
    my $branch;
1866
1711
1867
    if ($circcontrol eq 'PickupLibrary') {
1712
    if ($circcontrol eq 'PickupLibrary' && C4::Context->userenv->{'branch'}) {
1868
        $branch= C4::Context->userenv->{'branch'};
1713
        $branch= C4::Context->userenv->{'branch'};
1869
    } elsif ($circcontrol eq 'PatronLibrary') {
1714
    } elsif ($circcontrol eq 'PatronLibrary') {
1870
        $branch=$borrower->{branchcode};
1715
        $branch=$borrower->{branchcode};
Lines 1901-1907 sub GetItemIssue { Link Here
1901
    my ($itemnumber) = @_;
1746
    my ($itemnumber) = @_;
1902
    return unless $itemnumber;
1747
    return unless $itemnumber;
1903
    my $sth = C4::Context->dbh->prepare(
1748
    my $sth = C4::Context->dbh->prepare(
1904
        "SELECT *
1749
        "SELECT *, issues.renewals as 'issues.renewals'
1905
        FROM issues 
1750
        FROM issues 
1906
        LEFT JOIN items ON issues.itemnumber=items.itemnumber
1751
        LEFT JOIN items ON issues.itemnumber=items.itemnumber
1907
        WHERE issues.itemnumber=?");
1752
        WHERE issues.itemnumber=?");
Lines 1972-1978 sub GetItemIssues { Link Here
1972
    }
1817
    }
1973
    my $results = $sth->fetchall_arrayref({});
1818
    my $results = $sth->fetchall_arrayref({});
1974
    foreach (@$results) {
1819
    foreach (@$results) {
1975
        $_->{'overdue'} = ($_->{'date_due'} lt $today) ? 1 : 0;
1820
        $_->{'overdue'} = ( $_->{'date_due'} lt $today && !defined($_->{return_date}) ) ? 1 : 0;
1976
    }
1821
    }
1977
    return $results;
1822
    return $results;
1978
}
1823
}
Lines 2078-2146 already renewed the loan. $error will contain the reason the renewal can not pro Link Here
2078
sub CanBookBeRenewed {
1923
sub CanBookBeRenewed {
2079
1924
2080
    # check renewal status
1925
    # check renewal status
2081
    my ( $borrowernumber, $itemnumber, $override_limit ) = @_;
1926
    my ( $borrowernumber, $itemnumber ) = @_;
2082
    my $dbh       = C4::Context->dbh;
1927
    my $dbh       = C4::Context->dbh;
2083
    my $renews    = 1;
1928
    my $renews    = 1;
2084
    my $renewokay = 0;
1929
    my $renewokay = 1;
2085
	my $error;
1930
    my $error;
2086
1931
2087
    # Look in the issues table for this item, lent to this borrower,
1932
    # Look in the issues table for this item, lent to this borrower,
2088
    # and not yet returned.
1933
    # and not yet returned.
2089
1934
2090
    # Look in the issues table for this item, lent to this borrower,
1935
    # Look in the issues table for this item, lent to this borrower,
2091
    # and not yet returned.
1936
    # and not yet returned.
2092
    my %branch = (
1937
    my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return undef;
2093
            'ItemHomeLibrary' => 'items.homebranch',
1938
    my $item = GetItem($itemnumber) or return undef;
2094
            'PickupLibrary'   => 'items.holdingbranch',
1939
    my $itemissue = GetItemIssue($itemnumber) or return undef;
2095
            'PatronLibrary'   => 'borrowers.branchcode'
1940
    my $branchcode = _GetCircControlBranch($item, $borrower);
2096
            );
1941
    if ($itemissue->{'overdue'}){
2097
    my $controlbranch = $branch{C4::Context->preference('CircControl')};
1942
       $renewokay=0;
2098
    my $itype         = C4::Context->preference('item-level_itypes') ? 'items.itype' : 'biblioitems.itemtype';
1943
       $error->{message}='overdue'; 
1944
    }
2099
    
1945
    
2100
    my $sthcount = $dbh->prepare("
1946
    my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode);
2101
                   SELECT 
1947
    
2102
                    borrowers.categorycode, biblioitems.itemtype, issues.renewals, renewalsallowed, $controlbranch
1948
    if ( $issuingrule->{renewalsallowed} <= $itemissue->{'issues.renewals'} )  {
2103
                   FROM  issuingrules, 
1949
        $renewokay=0;
2104
                   issues 
1950
        $error->{message} = "too_many";
2105
                   LEFT JOIN items USING (itemnumber) 
1951
    }
2106
                   LEFT JOIN borrowers USING (borrowernumber) 
2107
                   LEFT JOIN biblioitems USING (biblioitemnumber)
2108
                   
2109
                   WHERE
2110
                    (issuingrules.categorycode = borrowers.categorycode OR issuingrules.categorycode = '*')
2111
                   AND
2112
                    (issuingrules.itemtype = $itype OR issuingrules.itemtype = '*')
2113
                   AND
2114
                    (issuingrules.branchcode = $controlbranch OR issuingrules.branchcode = '*') 
2115
                   AND 
2116
                    borrowernumber = ? 
2117
                   AND
2118
                    itemnumber = ?
2119
                   ORDER BY
2120
                    issuingrules.categorycode desc,
2121
                    issuingrules.itemtype desc,
2122
                    issuingrules.branchcode desc
2123
                   LIMIT 1;
2124
                  ");
2125
2126
    $sthcount->execute( $borrowernumber, $itemnumber );
2127
    if ( my $data1 = $sthcount->fetchrow_hashref ) {
2128
        
2129
        if ( ( $data1->{renewalsallowed} && $data1->{renewalsallowed} > $data1->{renewals} ) || $override_limit ) {
2130
            $renewokay = 1;
2131
        }
2132
        else {
2133
			$error="too_many";
2134
		}
2135
		
2136
        my ( $resfound, $resrec ) = C4::Reserves::CheckReserves($itemnumber);
2137
        if ($resfound) {
2138
            $renewokay = 0;
2139
			$error="on_reserve"
2140
        }
2141
1952
1953
    my ( $resfound, $resrec ) = C4::Reserves::CheckReserves($itemnumber);
1954
    if ($resfound) {
1955
        $renewokay = 0;
1956
        $error->{message} = "on_reserve";
2142
    }
1957
    }
2143
    return ($renewokay,$error);
1958
    $error->{renewals}       = $itemissue->{'issues.renewals'};
1959
    $error->{renewalsallowed}= $issuingrule->{renewalsallowed};
1960
1961
    return ( $renewokay, $error );
2144
}
1962
}
2145
1963
2146
=head2 AddRenewal
1964
=head2 AddRenewal
Lines 2195-2216 sub AddRenewal { Link Here
2195
    # based on the value of the RenewalPeriodBase syspref.
2013
    # based on the value of the RenewalPeriodBase syspref.
2196
    unless ($datedue) {
2014
    unless ($datedue) {
2197
2015
2198
        my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return undef;
2016
        my $borrower   = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return undef;
2199
        my $loanlength = GetLoanLength(
2017
        my $branchcode = _GetCircControlBranch($item, $borrower);
2200
                    $borrower->{'categorycode'},
2018
        my $loanlength = GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode );
2201
                    (C4::Context->preference('item-level_itypes')) ? $biblio->{'itype'} : $biblio->{'itemtype'} ,
2019
2202
			        $issuedata->{'branchcode'}  );   # that's the circ control branch.
2020
        $datedue =
2021
          ( C4::Context->preference('RenewalPeriodBase') eq 'date_due' )
2022
          ? C4::Dates->new( $issuedata->{date_due}, 'iso' )
2023
          : C4::Dates->new();
2024
2025
        my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'};
2026
        my $controlbranch = _GetCircControlBranch( $item, $borrower );
2027
        my $renewalperiod = $loanlength->{renewalperiod} || GetLoanLength( $borrower->{'categorycode'}, $itype, $controlbranch );
2028
2029
        $datedue = CalcDateDue( $datedue, $renewalperiod, $issuedata->{'branchcode'}, $borrower );
2203
2030
2204
        $datedue = (C4::Context->preference('RenewalPeriodBase') eq 'date_due') ?
2205
                                        C4::Dates->new($issuedata->{date_due}, 'iso') :
2206
                                        C4::Dates->new();
2207
        $datedue =  CalcDateDue($datedue,$loanlength,$issuedata->{'branchcode'},$borrower);
2208
    }
2031
    }
2209
2032
2210
    # Update the issues record to have the new due date, and a new count
2033
    # Update the issues record to have the new due date, and a new count
2211
    # of how many times it has been renewed.
2034
    # of how many times it has been renewed.
2212
    my $renews = $issuedata->{'renewals'} + 1;
2035
    my $renews = $issuedata->{'renewals'} + 1;
2213
    $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2036
    $sth = $dbh->prepare(
2037
        "UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ?
2214
                            WHERE borrowernumber=? 
2038
                            WHERE borrowernumber=? 
2215
                            AND itemnumber=?"
2039
                            AND itemnumber=?"
2216
    );
2040
    );
Lines 2218-2225 sub AddRenewal { Link Here
2218
    $sth->finish;
2042
    $sth->finish;
2219
2043
2220
    # Update the renewal count on the item, and tell zebra to reindex
2044
    # Update the renewal count on the item, and tell zebra to reindex
2221
    $renews = $biblio->{'renewals'} + 1;
2045
    $renews = $item->{'renewals'} + 1;
2222
    ModItem({ renewals => $renews, onloan => $datedue->output('iso') }, $biblio->{'biblionumber'}, $itemnumber);
2046
    ModItem( { renewals => $renews, onloan => $datedue->output('iso') }, undef, $itemnumber );
2223
2047
2224
    # Charge a new rental fee, if applicable?
2048
    # Charge a new rental fee, if applicable?
2225
    my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
2049
    my ( $charge, $type ) = GetIssuingCharges( $itemnumber, $borrowernumber );
Lines 2600-2614 sub CalcDateDue { Link Here
2600
	my ($startdate,$loanlength,$branch,$borrower) = @_;
2424
	my ($startdate,$loanlength,$branch,$borrower) = @_;
2601
	my $datedue;
2425
	my $datedue;
2602
2426
2603
	if(C4::Context->preference('useDaysMode') eq 'Days') {  # ignoring calendar
2427
	my $calendar = C4::Calendar->new(  branchcode => $branch );
2604
		my $timedue = time + ($loanlength) * 86400;
2428
	$datedue = $calendar->addDate($startdate, $loanlength);
2605
	#FIXME - assumes now even though we take a startdate 
2606
		my @datearr  = localtime($timedue);
2607
		$datedue = C4::Dates->new( sprintf("%04d-%02d-%02d", 1900 + $datearr[5], $datearr[4] + 1, $datearr[3]), 'iso');
2608
	} else {
2609
		my $calendar = C4::Calendar->new(  branchcode => $branch );
2610
		$datedue = $calendar->addDate($startdate, $loanlength);
2611
	}
2612
2429
2613
	# if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate
2430
	# if ReturnBeforeExpiry ON the datedue can't be after borrower expirydate
2614
	if ( C4::Context->preference('ReturnBeforeExpiry') && $datedue->output('iso') gt $borrower->{dateexpiry} ) {
2431
	if ( C4::Context->preference('ReturnBeforeExpiry') && $datedue->output('iso') gt $borrower->{dateexpiry} ) {
Lines 2818-2835 sub CreateBranchTransferLimit { Link Here
2818
2635
2819
=head2 DeleteBranchTransferLimits
2636
=head2 DeleteBranchTransferLimits
2820
2637
2821
  DeleteBranchTransferLimits();
2638
  DeleteBranchTransferLimits($tobranch);
2822
2639
2823
=cut
2640
=cut
2824
2641
2825
sub DeleteBranchTransferLimits {
2642
sub DeleteBranchTransferLimits {
2826
   my $dbh = C4::Context->dbh;
2643
    my $branch = shift;
2827
   my $sth = $dbh->prepare("TRUNCATE TABLE branch_transfer_limits");
2644
    my $dbh = C4::Context->dbh;
2828
   $sth->execute();
2645
    my $sth = $dbh->prepare("DELETE FROM branch_transfer_limits WHERE toBranch = ?");
2646
    $sth->execute($branch);
2647
}
2648
2649
sub GetOfflineOperations {
2650
	my $dbh = C4::Context->dbh;
2651
	my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE branchcode=? ORDER BY timestamp");
2652
	$sth->execute(C4::Context->userenv->{'branch'});
2653
	my $results = $sth->fetchall_arrayref({});
2654
	$sth->finish;
2655
	return $results;
2656
}
2657
2658
sub GetOfflineOperation {
2659
	my $dbh = C4::Context->dbh;
2660
	my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE operationid=?");
2661
	$sth->execute( shift );
2662
	my $result = $sth->fetchrow_hashref;
2663
	$sth->finish;
2664
	return $result;
2665
}
2666
2667
sub AddOfflineOperation {
2668
	my $dbh = C4::Context->dbh;
2669
	warn Data::Dumper::Dumper(@_);
2670
	my $sth = $dbh->prepare("INSERT INTO pending_offline_operations VALUES('',?,?,?,?,?,?)");
2671
	$sth->execute( @_ );
2672
	return "Added.";
2673
}
2674
2675
sub DeleteOfflineOperation {
2676
	my $dbh = C4::Context->dbh;
2677
	my $sth = $dbh->prepare("DELETE FROM pending_offline_operations WHERE operationid=?");
2678
	$sth->execute( shift );
2679
	return "Deleted.";
2680
}
2681
2682
sub ProcessOfflineOperation {
2683
	my $operation = shift;
2684
2685
    my $report;
2686
	if ( $operation->{action} eq 'return' ) {
2687
        $report = ProcessOfflineReturn( $operation );
2688
	} elsif ( $operation->{action} eq 'issue' ) {
2689
	    $report = ProcessOfflineIssue( $operation );
2690
	}
2691
	
2692
	DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid};
2693
	
2694
	return $report;
2695
}
2696
2697
sub ProcessOfflineReturn {
2698
    my $operation = shift;
2699
2700
    my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} );
2701
    
2702
    if ( $itemnumber ) {
2703
        my $issue = GetOpenIssue( $itemnumber );
2704
        if ( $issue ) {
2705
            MarkIssueReturned(
2706
                $issue->{borrowernumber},
2707
                $itemnumber,
2708
                undef,
2709
                $operation->{timestamp},
2710
            );
2711
            return "Success.";
2712
        } else {
2713
            return "Item not issued.";
2714
        }
2715
    } else {
2716
        return "Item not found.";
2717
    }
2718
}
2719
2720
sub ProcessOfflineIssue {
2721
    my $operation = shift;
2722
2723
    my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber
2724
    
2725
    if ( $borrower->{borrowernumber} ) { 
2726
        my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} );
2727
        my $issue = GetOpenIssue( $itemnumber );
2728
        
2729
        if ( $issue and ( $issue->{borrowernumber} ne $borrower->{borrowernumber} ) ) { # Item already issued to another borrower, mark it returned
2730
            MarkIssueReturned(
2731
                $issue->{borrowernumber},
2732
                $itemnumber,
2733
                undef,
2734
                $operation->{timestamp},
2735
            );
2736
        }
2737
        AddIssue(
2738
            $borrower,
2739
            $operation->{'barcode'},
2740
            undef,
2741
            1,
2742
            $operation->{timestamp},
2743
            undef,
2744
        );
2745
        return "Success.";
2746
    } else {
2747
        return "Borrower not found.";
2748
    }
2829
}
2749
}
2830
2750
2831
2751
2832
  1;
2752
1;
2833
2753
2834
__END__
2754
__END__
2835
2755
(-)a/C4/Overdues.pm (-59 / +22 lines)
Lines 23-28 use strict; Link Here
23
use Date::Calc qw/Today Date_to_Days/;
23
use Date::Calc qw/Today Date_to_Days/;
24
use Date::Manip qw/UnixDate/;
24
use Date::Manip qw/UnixDate/;
25
use C4::Circulation;
25
use C4::Circulation;
26
use C4::IssuingRules;
26
use C4::Context;
27
use C4::Context;
27
use C4::Accounts;
28
use C4::Accounts;
28
use C4::Log; # logaction
29
use C4::Log; # logaction
Lines 71-79 BEGIN { Link Here
71
	push @EXPORT, qw(
72
	push @EXPORT, qw(
72
        &GetIssuesIteminfo
73
        &GetIssuesIteminfo
73
	);
74
	);
74
    #
75
	# &GetIssuingRules - delete.
76
	# use C4::Circulation::GetIssuingRule instead.
77
	
75
	
78
	# subs to move to Members.pm
76
	# subs to move to Members.pm
79
	push @EXPORT, qw(
77
	push @EXPORT, qw(
Lines 124-130 sub Getoverdues { Link Here
124
   SELECT issues.*, items.itype as itemtype, items.homebranch, items.barcode
122
   SELECT issues.*, items.itype as itemtype, items.homebranch, items.barcode
125
     FROM issues 
123
     FROM issues 
126
LEFT JOIN items       USING (itemnumber)
124
LEFT JOIN items       USING (itemnumber)
127
    WHERE date_due < CURDATE() 
125
    WHERE DATE(date_due) < CURDATE()
128
";
126
";
129
    } else {
127
    } else {
130
        $statement = "
128
        $statement = "
Lines 132-138 LEFT JOIN items USING (itemnumber) Link Here
132
     FROM issues 
130
     FROM issues 
133
LEFT JOIN items       USING (itemnumber)
131
LEFT JOIN items       USING (itemnumber)
134
LEFT JOIN biblioitems USING (biblioitemnumber)
132
LEFT JOIN biblioitems USING (biblioitemnumber)
135
    WHERE date_due < CURDATE() 
133
    WHERE DATE(date_due) < CURDATE()
136
";
134
";
137
    }
135
    }
138
136
Lines 170-176 sub checkoverdues { Link Here
170
         LEFT JOIN biblio      ON items.biblionumber     = biblio.biblionumber
168
         LEFT JOIN biblio      ON items.biblionumber     = biblio.biblionumber
171
         LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
169
         LEFT JOIN biblioitems ON items.biblioitemnumber = biblioitems.biblioitemnumber
172
            WHERE issues.borrowernumber  = ?
170
            WHERE issues.borrowernumber  = ?
173
            AND   issues.date_due < CURDATE()"
171
            AND   DATE(issues.date_due) < CURDATE()"
174
    );
172
    );
175
    # FIXME: SELECT * across 4 tables?  do we really need the marc AND marcxml blobs??
173
    # FIXME: SELECT * across 4 tables?  do we really need the marc AND marcxml blobs??
176
    $sth->execute($borrowernumber);
174
    $sth->execute($borrowernumber);
Lines 245-251 sub CalcFine { Link Here
245
	my $daystocharge;
243
	my $daystocharge;
246
	# get issuingrules (fines part will be used)
244
	# get issuingrules (fines part will be used)
247
    $debug and warn sprintf("CalcFine calling GetIssuingRule(%s, %s, %s)", $bortype, $item->{'itemtype'}, $branchcode);
245
    $debug and warn sprintf("CalcFine calling GetIssuingRule(%s, %s, %s)", $bortype, $item->{'itemtype'}, $branchcode);
248
    my $data = C4::Circulation::GetIssuingRule($bortype, $item->{'itemtype'}, $branchcode);
246
    my $data = GetIssuingRule($bortype, $item->{'itemtype'}, $branchcode);
249
	if($difference) {
247
	if($difference) {
250
		# if $difference is supplied, the difference has already been calculated, but we still need to adjust for the calendar.
248
		# if $difference is supplied, the difference has already been calculated, but we still need to adjust for the calendar.
251
    	# use copy-pasted functions from calendar module.  (deprecated -- these functions will be removed from C4::Overdues ).
249
    	# use copy-pasted functions from calendar module.  (deprecated -- these functions will be removed from C4::Overdues ).
Lines 269-275 sub CalcFine { Link Here
269
    } else {
267
    } else {
270
        # a zero (or null)  chargeperiod means no charge.
268
        # a zero (or null)  chargeperiod means no charge.
271
    }
269
    }
272
	$amount = C4::Context->preference('maxFine') if(C4::Context->preference('maxFine') && ( $amount > C4::Context->preference('maxFine')));
270
    $amount = C4::Context->preference('MaxFine') if ( C4::Context->preference('MaxFine') && ( $amount > C4::Context->preference('MaxFine') ) );
273
	$debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $days_minus_grace, $daystocharge);
271
	$debug and warn sprintf("CalcFine returning (%s, %s, %s, %s)", $amount, $data->{'chargename'}, $days_minus_grace, $daystocharge);
274
    return ($amount, $data->{'chargename'}, $days_minus_grace, $daystocharge);
272
    return ($amount, $data->{'chargename'}, $days_minus_grace, $daystocharge);
275
    # FIXME: chargename is NEVER populated anywhere.
273
    # FIXME: chargename is NEVER populated anywhere.
Lines 585-591 Returns the replacement cost of the item with the given item number. Link Here
585
583
586
=cut
584
=cut
587
585
588
#'
586
589
sub ReplacementCost {
587
sub ReplacementCost {
590
    my ($itemnum) = @_;
588
    my ($itemnum) = @_;
591
    my $dbh       = C4::Context->dbh;
589
    my $dbh       = C4::Context->dbh;
Lines 604-663 sub ReplacementCost { Link Here
604
602
605
return the total of fine
603
return the total of fine
606
604
607
C<$itemnum> is item number
608
609
C<$borrowernumber> is the borrowernumber
605
C<$borrowernumber> is the borrowernumber
610
606
611
=cut 
607
=cut
612
613
608
614
sub GetFine {
609
sub GetFine {
615
    my ( $itemnum, $borrowernumber ) = @_;
610
    my ( $borrowernumber ) = @_;
616
    my $dbh   = C4::Context->dbh();
611
    my $dbh   = C4::Context->dbh();
617
    my $query = "SELECT sum(amountoutstanding) FROM accountlines
612
    my $query = "SELECT sum(amountoutstanding) FROM accountlines
618
    where accounttype like 'F%'  
613
    where accounttype like 'F%'  
619
  AND amountoutstanding > 0 AND itemnumber = ? AND borrowernumber=?";
614
  AND amountoutstanding > 0 AND borrowernumber=?";
620
    my $sth = $dbh->prepare($query);
615
    my $sth = $dbh->prepare($query);
621
    $sth->execute( $itemnum, $borrowernumber );
616
    $sth->execute( $borrowernumber );
622
    my $data = $sth->fetchrow_hashref();
617
    my $data = $sth->fetchrow_hashref();
623
    return ( $data->{'sum(amountoutstanding)'} );
618
    return ( $data->{'sum(amountoutstanding)'} );
624
}
619
}
625
620
626
627
=head2 GetIssuingRules
628
629
FIXME - This sub should be deprecated and removed.
630
It ignores branch and defaults.
631
632
    $data = &GetIssuingRules($itemtype,$categorycode);
633
634
Looks up for all issuingrules an item info 
635
636
C<$itemnumber> is a reference-to-hash whose keys are all of the fields
637
from the borrowers and categories tables of the Koha database. Thus,
638
639
C<$categorycode> contains  information about borrowers category 
640
641
C<$data> contains all information about both the borrower and
642
category he or she belongs to.
643
=cut 
644
645
sub GetIssuingRules {
646
	warn "GetIssuingRules is deprecated: use GetIssuingRule from C4::Circulation instead.";
647
   my ($itemtype,$categorycode)=@_;
648
   my $dbh   = C4::Context->dbh();    
649
   my $query=qq|SELECT *
650
        FROM issuingrules
651
        WHERE issuingrules.itemtype=?
652
            AND issuingrules.categorycode=?
653
        |;
654
    my $sth = $dbh->prepare($query);
655
    #  print $query;
656
    $sth->execute($itemtype,$categorycode);
657
    return $sth->fetchrow_hashref;
658
}
659
660
661
sub ReplacementCost2 {
621
sub ReplacementCost2 {
662
    my ( $itemnum, $borrowernumber ) = @_;
622
    my ( $itemnum, $borrowernumber ) = @_;
663
    my $dbh   = C4::Context->dbh();
623
    my $dbh   = C4::Context->dbh();
Lines 956-962 returns a list of branch codes for branches with overdue rules defined. Link Here
956
916
957
sub GetBranchcodesWithOverdueRules {
917
sub GetBranchcodesWithOverdueRules {
958
    my $dbh               = C4::Context->dbh;
918
    my $dbh               = C4::Context->dbh;
959
    my $rqoverduebranches = $dbh->prepare("SELECT DISTINCT branchcode FROM overduerules WHERE delay1 IS NOT NULL AND branchcode <> ''");
919
    my $rqoverduebranches = $dbh->prepare("SELECT DISTINCT branchcode FROM overduerules WHERE delay1 IS NOT NULL ");
960
    $rqoverduebranches->execute;
920
    $rqoverduebranches->execute;
961
    my @branches = map { shift @$_ } @{ $rqoverduebranches->fetchall_arrayref };
921
    my @branches = map { shift @$_ } @{ $rqoverduebranches->fetchall_arrayref };
962
    return @branches;
922
    return @branches;
Lines 1029-1035 sub GetOverduerules { Link Here
1029
989
1030
Check if the borrowers is already debarred
990
Check if the borrowers is already debarred
1031
991
1032
C<$debarredstatus> return 0 for not debarred and return 1 for debarred
992
C<$debarredstatus> return undef for not debarred and return end of debar date for debarred
1033
993
1034
C<$borrowernumber> contains the borrower number
994
C<$borrowernumber> contains the borrower number
1035
995
Lines 1043-1074 sub CheckBorrowerDebarred { Link Here
1043
        SELECT debarred
1003
        SELECT debarred
1044
        FROM borrowers
1004
        FROM borrowers
1045
        WHERE borrowernumber=?
1005
        WHERE borrowernumber=?
1006
        AND debarred > NOW()
1046
    |;
1007
    |;
1047
    my $sth = $dbh->prepare($query);
1008
    my $sth = $dbh->prepare($query);
1048
    $sth->execute($borrowernumber);
1009
    $sth->execute($borrowernumber);
1049
    my ($debarredstatus) = $sth->fetchrow;
1010
    my $debarredstatus= $sth->fetchrow;
1050
    return ( $debarredstatus eq '1' ? 1 : 0 );
1011
    return $debarredstatus;
1012
    
1051
}
1013
}
1052
1014
1053
=head2 UpdateBorrowerDebarred
1015
=head2 UpdateBorrowerDebarred
1054
1016
1055
    ($borrowerstatut) = &UpdateBorrowerDebarred($borrowernumber);
1017
   ($borrowerstatut) = &UpdateBorrowerDebarred($borrowernumber, $todate);
1056
1018
1057
update status of borrowers in borrowers table (field debarred)
1019
update status of borrowers in borrowers table (field debarred)
1058
1020
1059
C<$borrowernumber> borrower number
1021
C<$borrowernumber> borrower number
1022
C<$todate> end of bare
1060
1023
1061
=cut
1024
=cut
1062
1025
1063
sub UpdateBorrowerDebarred{
1026
sub UpdateBorrowerDebarred{
1064
    my($borrowernumber) = @_;
1027
    my($borrowernumber, $todate) = @_;
1065
    my $dbh = C4::Context->dbh;
1028
    my $dbh = C4::Context->dbh;
1066
        my $query=qq|UPDATE borrowers
1029
        my $query=qq|UPDATE borrowers
1067
             SET debarred='1'
1030
             SET debarred=?
1068
                     WHERE borrowernumber=?
1031
                     WHERE borrowernumber=?
1069
            |;
1032
            |;
1070
    my $sth=$dbh->prepare($query);
1033
    my $sth=$dbh->prepare($query);
1071
        $sth->execute($borrowernumber);
1034
        $sth->execute($todate, $borrowernumber);
1072
        $sth->finish;
1035
        $sth->finish;
1073
        return 1;
1036
        return 1;
1074
}
1037
}
(-)a/C4/Reserves.pm (-182 / +450 lines)
Lines 22-27 package C4::Reserves; Link Here
22
22
23
use strict;
23
use strict;
24
#use warnings; FIXME - Bug 2505
24
#use warnings; FIXME - Bug 2505
25
use Date::Calc qw( Add_Delta_Days Time_to_Date Today);
25
use C4::Context;
26
use C4::Context;
26
use C4::Biblio;
27
use C4::Biblio;
27
use C4::Members;
28
use C4::Members;
Lines 32-41 use C4::Accounts; Link Here
32
33
33
# for _koha_notify_reserve
34
# for _koha_notify_reserve
34
use C4::Members::Messaging;
35
use C4::Members::Messaging;
35
use C4::Members qw();
36
use C4::Members ;
36
use C4::Letters;
37
use C4::Letters;
37
use C4::Branch qw( GetBranchDetail );
38
use C4::Branch qw( GetBranchDetail );
38
use C4::Dates qw( format_date_in_iso );
39
use C4::Dates qw( format_date_in_iso );
40
use C4::IssuingRules;
39
use List::MoreUtils qw( firstidx );
41
use List::MoreUtils qw( firstidx );
40
42
41
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
43
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
Lines 91-101 BEGIN { Link Here
91
    @EXPORT = qw(
93
    @EXPORT = qw(
92
        &AddReserve
94
        &AddReserve
93
  
95
  
96
        &GetMaxPickupDelay
97
        &GetMaxPickupDate
94
        &GetReservesFromItemnumber
98
        &GetReservesFromItemnumber
95
        &GetReservesFromBiblionumber
99
        &GetReservesFromBiblionumber
96
        &GetReservesFromBorrowernumber
100
        &GetReservesFromBorrowernumber
97
        &GetReservesForBranch
101
        &GetReservesForBranch
98
        &GetReservesToBranch
102
        &GetReservesToBranch
103
        &GetReservesControlBranch
99
        &GetReserveCount
104
        &GetReserveCount
100
        &GetReserveFee
105
        &GetReserveFee
101
		&GetReserveInfo
106
		&GetReserveInfo
Lines 113-125 BEGIN { Link Here
113
        &CheckReserves
118
        &CheckReserves
114
        &CanBookBeReserved
119
        &CanBookBeReserved
115
	&CanItemBeReserved
120
	&CanItemBeReserved
116
        &CancelReserve
121
      &CanHoldOnShelf
117
        &CancelExpiredReserves
122
      &CancelReserve
123
      &CancelExpiredReserves
118
124
119
        &IsAvailableForItemLevelRequest
125
      &IsAvailableForItemLevelRequest
120
        
126
121
        &AlterPriority
127
      &AlterPriority
122
        &ToggleLowestPriority
128
      &ToggleLowestPriority
129
      &CanHoldMultipleItems
130
      &BorrowerHasReserve
123
    );
131
    );
124
}    
132
}    
125
133
Lines 142-152 sub AddReserve { Link Here
142
    my $const   = lc substr( $constraint, 0, 1 );
150
    my $const   = lc substr( $constraint, 0, 1 );
143
    $resdate = format_date_in_iso( $resdate ) if ( $resdate );
151
    $resdate = format_date_in_iso( $resdate ) if ( $resdate );
144
    $resdate = C4::Dates->today( 'iso' ) unless ( $resdate );
152
    $resdate = C4::Dates->today( 'iso' ) unless ( $resdate );
153
    my $item = C4::Items::GetItem($checkitem);
154
    my @maxPickupDate = GetMaxPickupDate($resdate, $borrowernumber, $item);
155
    my $maxpickupdate = sprintf( "%d-%02d-%02d", @maxPickupDate );
145
    if ($expdate) {
156
    if ($expdate) {
146
        $expdate = format_date_in_iso( $expdate );
157
        $expdate = format_date_in_iso( $expdate );
158
        my @expdate = split("-", $expdate);
159
        $expdate = $maxpickupdate if Delta_Days(@expdate[ 0 .. 2 ], @maxPickupDate[ 0 .. 2 ]) < 0;
147
    } else {
160
    } else {
148
        undef $expdate; # make reserves.expirationdate default to null rather than '0000-00-00'
161
        $expdate = $maxpickupdate;   
149
    }
162
    }
163
    undef $expdate if $resdate eq $maxpickupdate; # make reserves.expirationdate default to null rather than '0000-00-00'
150
    if ( C4::Context->preference( 'AllowHoldDateInFuture' ) ) {
164
    if ( C4::Context->preference( 'AllowHoldDateInFuture' ) ) {
151
	# Make room in reserves for this before those of a later reserve date
165
	# Make room in reserves for this before those of a later reserve date
152
	$priority = _ShiftPriorityByDateAndPriority( $biblionumber, $resdate, $priority );
166
	$priority = _ShiftPriorityByDateAndPriority( $biblionumber, $resdate, $priority );
Lines 250-273 sub GetReservesFromBiblionumber { Link Here
250
264
251
    # Find the desired items in the reserves
265
    # Find the desired items in the reserves
252
    my $query = "
266
    my $query = "
253
        SELECT  branchcode,
267
        SELECT  reserves.reservenumber,
254
                timestamp AS rtimestamp,
268
                reserves.branchcode,
255
                priority,
269
                reserves.timestamp AS rtimestamp,
256
                biblionumber,
270
                reserves.priority,
257
                borrowernumber,
271
                reserves.biblionumber,
258
                reservedate,
272
                reserves.borrowernumber,
259
                constrainttype,
273
                reserves.reservedate,
260
                found,
274
                reserves.constrainttype,
261
                itemnumber,
275
                reserves.found,
262
                reservenotes,
276
                reserves.itemnumber,
263
                expirationdate,
277
                reserves.reservenotes,
264
                lowestPriority
278
                reserves.expirationdate,
279
                reserves.lowestPriority,
280
                biblioitems.itemtype
265
        FROM     reserves
281
        FROM     reserves
266
        WHERE biblionumber = ? ";
282
        LEFT JOIN biblioitems ON biblioitems.biblionumber = reserves.biblionumber
283
        WHERE reserves.biblionumber = ? ";
267
    unless ( $all_dates ) {
284
    unless ( $all_dates ) {
268
        $query .= "AND reservedate <= CURRENT_DATE()";
285
        $query .= "AND reservedate <= CURRENT_DATE()";
269
    }
286
    }
270
    $query .= "ORDER BY priority";
287
    $query .= "ORDER BY reserves.priority";
271
    my $sth = $dbh->prepare($query);
288
    my $sth = $dbh->prepare($query);
272
    $sth->execute($biblionumber);
289
    $sth->execute($biblionumber);
273
    my @results;
290
    my @results;
Lines 373-381 sub GetReservesFromBorrowernumber { Link Here
373
    return @$data;
390
    return @$data;
374
}
391
}
375
#-------------------------------------------------------------------------------------
392
#-------------------------------------------------------------------------------------
393
sub BorrowerHasReserve {
394
    my ( $borrowernumber, $biblionumber, $itemnumber ) = @_;
395
    my $dbh   = C4::Context->dbh;
396
    my $sth;
397
    
398
    if ( $biblionumber ) {
399
      $sth = $dbh->prepare("
400
            SELECT COUNT(*) AS hasReserve
401
            FROM   reserves
402
            WHERE  borrowernumber = ?
403
            AND    biblionumber = ?
404
            ORDER BY reservedate
405
        ");
406
      $sth->execute( $borrowernumber, $biblionumber );
407
    } elsif ( $itemnumber ) {
408
      $sth = $dbh->prepare("
409
            SELECT COUNT(*) AS hasReserve
410
            FROM   reserves
411
            WHERE  borrowernumber = ?
412
            AND    itemnumber = ?
413
            ORDER BY reservedate
414
        ");
415
      $sth->execute( $borrowernumber, $itemnumber );
416
    } else {
417
      return -1;
418
    }
419
420
    my $data = $sth->fetchrow_hashref();
421
    return $data->{'hasReserve'};
422
}
423
376
=head2 CanBookBeReserved
424
=head2 CanBookBeReserved
377
425
378
  $error = &CanBookBeReserved($borrowernumber, $biblionumber)
426
$error = &CanBookBeReserved($borrowernumber, $biblionumber)
379
427
380
=cut
428
=cut
381
429
Lines 399-405 This function return 1 if an item can be issued by this borrower. Link Here
399
447
400
sub CanItemBeReserved{
448
sub CanItemBeReserved{
401
    my ($borrowernumber, $itemnumber) = @_;
449
    my ($borrowernumber, $itemnumber) = @_;
402
    
450
403
    my $dbh             = C4::Context->dbh;
451
    my $dbh             = C4::Context->dbh;
404
    my $allowedreserves = 0;
452
    my $allowedreserves = 0;
405
            
453
            
Lines 407-413 sub CanItemBeReserved{ Link Here
407
    my $itype         = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype";
455
    my $itype         = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype";
408
456
409
    # we retrieve borrowers and items informations #
457
    # we retrieve borrowers and items informations #
410
    my $item     = GetItem($itemnumber);
458
    my $item     = C4::Items::GetItem($itemnumber);
411
    my $borrower = C4::Members::GetMember('borrowernumber'=>$borrowernumber);     
459
    my $borrower = C4::Members::GetMember('borrowernumber'=>$borrowernumber);     
412
    
460
    
413
    # we retrieve user rights on this itemtype and branchcode
461
    # we retrieve user rights on this itemtype and branchcode
Lines 438-459 sub CanItemBeReserved{ Link Here
438
    my $branchfield  = "reserves.branchcode";
486
    my $branchfield  = "reserves.branchcode";
439
    
487
    
440
    if( $controlbranch eq "ItemHomeLibrary" ){
488
    if( $controlbranch eq "ItemHomeLibrary" ){
441
        $branchfield = "items.homebranch";
489
        my $field=C4::Context->preference("HomeOrHoldingBranch")||"homebranch";
442
        $branchcode = $item->{homebranch};
490
        $branchfield = "items.$field";
491
        $branchcode = $item->{$field};
443
    }elsif( $controlbranch eq "PatronLibrary" ){
492
    }elsif( $controlbranch eq "PatronLibrary" ){
444
        $branchfield = "borrowers.branchcode";
493
        $branchfield = "borrowers.branchcode";
445
        $branchcode = $borrower->{branchcode};
494
        $branchcode = $borrower->{branchcode};
446
    }
495
    }
447
    
496
    
448
    # we retrieve rights 
497
    # we retrieve user rights on this itemtype and branchcode
449
    $sth->execute($categorycode, $itemtype, $branchcode);
498
    my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{$itype}, $branchcode);
450
    if(my $rights = $sth->fetchrow_hashref()){
499
    return 0 if( defined $issuingrule->{reservesallowed} && not $issuingrule->{reservesallowed} );
451
        $itemtype        = $rights->{itemtype};
500
    
452
        $allowedreserves = $rights->{reservesallowed}; 
501
    # We retrieve the count of reserves allowed for this category code
502
    $issuingrule  = GetIssuingRule ($borrower->{categorycode}, "*", "*");
503
504
    if($issuingrule){
505
        $itemtype        = $issuingrule->{itemtype};
506
        $allowedreserves = $issuingrule->{reservesallowed}; 
453
    }else{
507
    }else{
454
        $itemtype = '*';
508
        $itemtype = '*';
455
    }
509
    }
456
    
510
    
511
    return 0 if ($issuingrule->{reservesallowed}==0 || 
512
                ($issuingrule->{holdrestricted}== 1 && !($branchcode eq $borrower->{branchcode}))
513
                );
457
    # we retrieve count
514
    # we retrieve count
458
    
515
    
459
    $querycount .= "AND $branchfield = ?";
516
    $querycount .= "AND $branchfield = ?";
Lines 479-484 sub CanItemBeReserved{ Link Here
479
        return 0;
536
        return 0;
480
    }
537
    }
481
}
538
}
539
540
=item GetMaxPickupDelay
541
542
$resallowed = &GetMaxPickupDelay($borrowernumber, $itemnumber)
543
544
this function return the number of allowed reserves.
545
546
=cut
547
548
sub GetMaxPickupDelay {
549
    my ($borrowernumber, $itemnumber) = @_;
550
    
551
    my $dbh             = C4::Context->dbh;
552
    my $allowedreserves = 0;
553
            
554
    my $itype         = C4::Context->preference('item-level_itypes') ? "itype" : "itemtype";
555
556
    # we retrieve borrowers and items informations #
557
    my $item     = C4::Items::GetItem($itemnumber);
558
    my $borrower = C4::Members::GetMember('borrowernumber'=>$borrowernumber);     
559
    my $controlbranch = GetReservesControlBranch($borrower,$item);
560
    
561
    # we retrieve user rights on this itemtype and branchcode
562
    my $sth = $dbh->prepare("SELECT holdspickupdelay 
563
                    FROM issuingrules 
564
                    WHERE categorycode=? 
565
                    AND itemtype=?
566
                    AND branchcode=?
567
                    AND holdspickupdelay IS NOT NULL"
568
                           );
569
    
570
    my $itemtype     = $item->{$itype};
571
    my $borrowertype = $borrower->{categorycode};
572
    my $branchcode   = $controlbranch;
573
    
574
    $sth->execute( $borrowertype, $itemtype, $branchcode );
575
    my $pickupdelay = $sth->fetchrow_hashref;
576
    return $pickupdelay->{holdspickupdelay}
577
      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne 'NULL';
578
579
    $sth->execute( $borrowertype, "*", $branchcode );
580
    $pickupdelay = $sth->fetchrow_hashref;
581
    return $pickupdelay->{holdspickupdelay}
582
      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne 'NULL';
583
584
    $sth->execute( "*", $itemtype, $branchcode );
585
    $pickupdelay = $sth->fetchrow_hashref;
586
    return $pickupdelay->{holdspickupdelay}
587
      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne 'NULL';
588
589
    $sth->execute( "*", "*", $branchcode );
590
    $pickupdelay = $sth->fetchrow_hashref;
591
    return $pickupdelay->{holdspickupdelay}
592
      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne 'NULL';
593
594
    $sth->execute( $borrowertype, $itemtype, "*" );
595
    $pickupdelay = $sth->fetchrow_hashref;
596
    return $pickupdelay->{holdspickupdelay}
597
      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne 'NULL';
598
599
    $sth->execute( $borrowertype, "*", "*" );
600
    $pickupdelay = $sth->fetchrow_hashref;
601
    return $pickupdelay->{holdspickupdelay}
602
      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne 'NULL';
603
604
    $sth->execute( "*", $itemtype, "*" );
605
    $pickupdelay = $sth->fetchrow_hashref;
606
    return $pickupdelay->{holdspickupdelay}
607
      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne 'NULL';
608
609
    $sth->execute( "*", "*", "*" );
610
    $pickupdelay = $sth->fetchrow_hashref;
611
    return $pickupdelay->{holdspickupdelay}
612
      if defined($pickupdelay) && $pickupdelay->{holdspickupdelay} ne 'NULL';
613
    
614
    # if nothing found, return no rights
615
    return 0;
616
}
617
618
=item GetMaxPickupDate
619
620
$maxpickupdate = &GetMaxPickupDate($date);
621
622
this function return the max pickup date.
623
(e.g. : the date after which the hold will be considered cancelled)
624
625
=cut
626
627
sub GetMaxPickupDate{
628
    my $inputdate=shift;
629
    my $borrowernumber=shift;
630
    my $item=shift;
631
    return unless $inputdate;
632
    my @date = split(/-/,$inputdate);
633
    my $delay = GetMaxPickupDelay($borrowernumber, $item->{'itemnumber'});
634
    ( @date ) =
635
      Add_Delta_Days( @date[0..2], $delay);
636
    return @date;
637
}
638
482
#--------------------------------------------------------------------------------
639
#--------------------------------------------------------------------------------
483
=head2 GetReserveCount
640
=head2 GetReserveCount
484
641
Lines 518-538 sub GetOtherReserves { Link Here
518
    my $nextreservinfo;
675
    my $nextreservinfo;
519
    my ( $restype, $checkreserves ) = CheckReserves($itemnumber);
676
    my ( $restype, $checkreserves ) = CheckReserves($itemnumber);
520
    if ($checkreserves) {
677
    if ($checkreserves) {
521
        my $iteminfo = GetItem($itemnumber);
678
        my $iteminfo = C4::Items::GetItem($itemnumber);
522
        if ( $iteminfo->{'holdingbranch'} ne $checkreserves->{'branchcode'} ) {
679
        if ( $iteminfo->{'holdingbranch'} ne $checkreserves->{'branchcode'} ) {
523
            $messages->{'transfert'} = $checkreserves->{'branchcode'};
680
            $messages->{'transfert'} = $checkreserves->{'branchcode'};
524
            #minus priorities of others reservs
681
            #minus priorities of others reservs
525
            ModReserveMinusPriority(
682
            ModReserveMinusPriority(
526
                $itemnumber,
683
                $itemnumber,
527
                $checkreserves->{'borrowernumber'},
684
                $checkreserves->{'borrowernumber'},
528
                $iteminfo->{'biblionumber'}
685
                $iteminfo->{'biblionumber'},
686
                $checkreserves->{'reservenumber'}
529
            );
687
            );
530
688
531
            #launch the subroutine dotransfer
689
            #launch the subroutine dotransfer
532
            C4::Items::ModItemTransfer(
690
            C4::Items::ModItemTransfer(
533
                $itemnumber,
691
                $itemnumber,
534
                $iteminfo->{'holdingbranch'},
692
                $iteminfo->{'holdingbranch'},
535
                $checkreserves->{'branchcode'}
693
                $checkreserves->{'branchcode'},
536
              ),
694
              ),
537
              ;
695
              ;
538
        }
696
        }
Lines 543-549 sub GetOtherReserves { Link Here
543
            ModReserveMinusPriority(
701
            ModReserveMinusPriority(
544
                $itemnumber,
702
                $itemnumber,
545
                $checkreserves->{'borrowernumber'},
703
                $checkreserves->{'borrowernumber'},
546
                $iteminfo->{'biblionumber'}
704
                $iteminfo->{'biblionumber'},
705
                $checkreserves->{'reservenumber'}                
547
            );
706
            );
548
            ModReserveStatus($itemnumber,'W');
707
            ModReserveStatus($itemnumber,'W');
549
        }
708
        }
Lines 657-662 sub GetReserveFee { Link Here
657
    return $fee;
816
    return $fee;
658
}
817
}
659
818
819
=head2 GetReservesControlBranch
820
821
$branchcode = &GetReservesControlBranch($borrower, $item)
822
823
Returns the branchcode to consider to check hold rules against
824
825
=cut
826
sub GetReservesControlBranch{
827
    my ($borrower, $item) = @_;
828
    my $controlbranch = C4::Context->preference('ReservesControlBranch');
829
    my $hbr           = C4::Context->preference('HomeOrHoldingBranch')||"homebranch";
830
    my $branchcode="*";
831
    if($controlbranch eq "ItemHomeLibrary"){
832
        $branchcode = $item->{$hbr};
833
    } elsif($controlbranch eq "PatronLibrary"){
834
        $branchcode = $borrower->{'branchcode'};
835
    }
836
    return $branchcode;
837
}
838
660
=head2 GetReservesToBranch
839
=head2 GetReservesToBranch
661
840
662
  @transreserv = GetReservesToBranch( $frombranch );
841
  @transreserv = GetReservesToBranch( $frombranch );
Lines 840-862 sub CancelExpiredReserves { Link Here
840
    $sth->execute();
1019
    $sth->execute();
841
1020
842
    while ( my $res = $sth->fetchrow_hashref() ) {
1021
    while ( my $res = $sth->fetchrow_hashref() ) {
843
        CancelReserve( $res->{'biblionumber'}, '', $res->{'borrowernumber'} );
1022
        CancelReserve( $res->{'reservenumber'}, $res->{'biblionumber'} );
844
    }
1023
    }
845
  
1024
  
846
}
1025
}
847
1026
848
=head2 CancelReserve
1027
=head2 CancelReserve
849
1028
850
  &CancelReserve($biblionumber, $itemnumber, $borrowernumber);
1029
  &CancelReserve( $reservenumber, $biblionumber );
851
1030
852
Cancels a reserve.
1031
Cancels a reserve.
853
1032
854
Use either C<$biblionumber> or C<$itemnumber> to specify the item to
1033
C<$reservenumber> is the unique key for the reserve to be canceled.
855
cancel, but not both: if both are given, C<&CancelReserve> does
856
nothing.
857
858
C<$borrowernumber> is the borrower number of the patron on whose
859
behalf the book was reserved.
860
1034
861
If C<$biblionumber> was given, C<&CancelReserve> also adjusts the
1035
If C<$biblionumber> was given, C<&CancelReserve> also adjusts the
862
priorities of the other people who are waiting on the book.
1036
priorities of the other people who are waiting on the book.
Lines 864-872 priorities of the other people who are waiting on the book. Link Here
864
=cut
1038
=cut
865
1039
866
sub CancelReserve {
1040
sub CancelReserve {
867
    my ( $biblio, $item, $borr ) = @_;
1041
    my ( $reservenumber, $biblio ) = @_;
868
    my $dbh = C4::Context->dbh;
1042
    my $dbh = C4::Context->dbh;
869
        if ( $item and $borr ) {
1043
    
1044
    my $sth = $dbh->prepare('SELECT * FROM reserves WHERE reservenumber = ?');
1045
    $sth->execute( $reservenumber );
1046
    my $reserve = $sth->fetchrow_hashref();
1047
    
1048
    if ( $reserve->{'found'} eq 'W' ) {
870
        # removing a waiting reserve record....
1049
        # removing a waiting reserve record....
871
        # update the database...
1050
        # update the database...
872
        my $query = "
1051
        my $query = "
Lines 874-900 sub CancelReserve { Link Here
874
            SET    cancellationdate = now(),
1053
            SET    cancellationdate = now(),
875
                   found            = Null,
1054
                   found            = Null,
876
                   priority         = 0
1055
                   priority         = 0
877
            WHERE  itemnumber       = ?
1056
            WHERE  reservenumber   = ?
878
             AND   borrowernumber   = ?
879
        ";
1057
        ";
880
        my $sth = $dbh->prepare($query);
1058
        my $sth = $dbh->prepare($query);
881
        $sth->execute( $item, $borr );
1059
        $sth->execute( $reservenumber );
882
        $sth->finish;
1060
1061
        # get reserve information to place into old_reserves
883
        $query = "
1062
        $query = "
884
            INSERT INTO old_reserves
1063
            INSERT INTO old_reserves
885
            SELECT * FROM reserves
1064
            SELECT * FROM reserves
886
            WHERE  itemnumber       = ?
1065
            WHERE reservenumber     = ?
887
             AND   borrowernumber   = ?
888
        ";
1066
        ";
889
        $sth = $dbh->prepare($query);
1067
        $sth = $dbh->prepare($query);
890
        $sth->execute( $item, $borr );
1068
        $sth->execute( $reservenumber );
1069
        my $holditem = $sth->fetchrow_hashref;
1070
        my $insert_fields = '';
1071
        my $value_fields = '';
1072
        foreach my $column ('borrowernumber','reservedate','biblionumber','constrainttype','branchcode','notificationdate','reminderdate','cancellationdate','reservenotes','priority','found','itemnumber','waitingdate','expirationdate') {
1073
          if (defined($holditem->{$column})) {
1074
            if (length($insert_fields)) {
1075
              $insert_fields .= ",$column";
1076
              $value_fields .= ",\'$holditem->{$column}\'";
1077
            }
1078
            else {
1079
              $insert_fields .= "$column";
1080
              $value_fields .= "\'$holditem->{$column}\'";
1081
            }
1082
          }
1083
        }
1084
        $query = qq/
1085
            INSERT INTO old_reserves ($insert_fields)
1086
            VALUES ($value_fields)
1087
        /;
1088
        $sth = $dbh->prepare($query);
1089
        $sth->execute();
891
        $query = "
1090
        $query = "
892
            DELETE FROM reserves
1091
            DELETE FROM reserves
893
            WHERE  itemnumber       = ?
1092
            WHERE  reservenumber   = ?
894
             AND   borrowernumber   = ?
895
        ";
1093
        ";
896
        $sth = $dbh->prepare($query);
1094
        $sth = $dbh->prepare($query);
897
        $sth->execute( $item, $borr );
1095
        $sth->execute( $reservenumber );
898
    }
1096
    }
899
    else {
1097
    else {
900
        # removing a reserve record....
1098
        # removing a reserve record....
Lines 902-953 sub CancelReserve { Link Here
902
        my $priority;
1100
        my $priority;
903
        my $query = qq/
1101
        my $query = qq/
904
            SELECT priority FROM reserves
1102
            SELECT priority FROM reserves
905
            WHERE biblionumber   = ?
1103
            WHERE reservenumber = ?
906
              AND borrowernumber = ?
907
              AND cancellationdate IS NULL
1104
              AND cancellationdate IS NULL
908
              AND itemnumber IS NULL
1105
              AND itemnumber IS NULL
909
        /;
1106
        /;
910
        my $sth = $dbh->prepare($query);
1107
        my $sth = $dbh->prepare($query);
911
        $sth->execute( $biblio, $borr );
1108
        $sth->execute( $reservenumber );
912
        ($priority) = $sth->fetchrow_array;
1109
        ($priority) = $sth->fetchrow_array;
913
        $sth->finish;
1110
        $sth->finish;
914
        $query = qq/
1111
        $query = qq/
915
            UPDATE reserves
1112
            UPDATE reserves
916
            SET    cancellationdate = now(),
1113
            SET    cancellationdate = now(),
917
                   found            = Null,
1114
                   found            = Null,
918
                   priority         = 0
1115
                   priority         = 0,
919
            WHERE  biblionumber     = ?
1116
                   expirationdate   = NULL
920
              AND  borrowernumber   = ?
1117
            WHERE  reservenumber   = ?
921
        /;
1118
        /;
922
1119
923
        # update the database, removing the record...
1120
        # update the database, removing the record...
924
        $sth = $dbh->prepare($query);
1121
        $sth = $dbh->prepare($query);
925
        $sth->execute( $biblio, $borr );
1122
        $sth->execute( $reservenumber );
926
        $sth->finish;
927
1123
928
        $query = qq/
1124
        $query = qq/
929
            INSERT INTO old_reserves
1125
            INSERT INTO old_reserves
930
            SELECT * FROM reserves
1126
            SELECT * FROM reserves
931
            WHERE  biblionumber     = ?
1127
            WHERE reservenumber   = ?
932
              AND  borrowernumber   = ?
1128
        /;
1129
        $sth = $dbh->prepare($query);
1130
        $sth->execute( $reservenumber );
1131
        my $holditem = $sth->fetchrow_hashref;
1132
1133
        my $insert_fields = '';
1134
        my $value_fields = '';
1135
        foreach my $column ('borrowernumber','reservedate','biblionumber','constrainttype','branchcode','notificationdate','reminderdate','cancellationdate','reservenotes','priority','found','itemnumber','waitingdate','expirationdate') {
1136
          if (defined($holditem->{$column})) {
1137
            if (length($insert_fields)) {
1138
              $insert_fields .= ",$column";
1139
              $value_fields .= ",\'$holditem->{$column}\'";
1140
            }
1141
            else {
1142
              $insert_fields .= "$column";
1143
              $value_fields .= "\'$holditem->{$column}\'";
1144
            }
1145
          }
1146
        }
1147
        $query = qq/
1148
            INSERT INTO old_reserves ($insert_fields)
1149
            VALUES ($value_fields)
933
        /;
1150
        /;
934
        $sth = $dbh->prepare($query);
1151
        $sth = $dbh->prepare($query);
935
        $sth->execute( $biblio, $borr );
1152
        $sth->execute();
936
1153
937
        $query = qq/
1154
        $query = qq/
938
            DELETE FROM reserves
1155
            DELETE FROM reserves
939
            WHERE  biblionumber     = ?
1156
            WHERE  reservenumber   = ?
940
              AND  borrowernumber   = ?
941
        /;
1157
        /;
942
        $sth = $dbh->prepare($query);
1158
        $sth = $dbh->prepare($query);
943
        $sth->execute( $biblio, $borr );
1159
        $sth->execute( $reservenumber );
944
1160
945
        # now fix the priority on the others....
1161
        # now fix the priority on the others....
946
        _FixPriority( $biblio, $borr );
1162
        _FixPriority( '', '', $priority,'', $reservenumber );
947
    }
1163
    }
948
}
1164
}
949
1165
950
=head2 ModReserve
1166
=item ModReserve
1167
1168
=over 4
951
1169
952
  ModReserve($rank, $biblio, $borrower, $branch[, $itemnumber])
1170
  ModReserve($rank, $biblio, $borrower, $branch[, $itemnumber])
953
1171
Lines 980-1031 itemnumber and supplying itemnumber. Link Here
980
1198
981
sub ModReserve {
1199
sub ModReserve {
982
    #subroutine to update a reserve
1200
    #subroutine to update a reserve
983
    my ( $rank, $biblio, $borrower, $branch , $itemnumber) = @_;
1201
    my ( $rank, $biblio, $borrower, $branch , $itemnumber, $reservenumber) = @_;
984
     return if $rank eq "W";
1202
     return if $rank eq "W";
985
     return if $rank eq "n";
1203
     return if $rank eq "n";
986
    my $dbh = C4::Context->dbh;
1204
    my $dbh = C4::Context->dbh;
987
    if ( $rank eq "del" ) {
1205
    if ( $rank eq "del" ) {
988
        my $query = qq/
1206
        my $query = qq/
989
            UPDATE reserves
1207
            UPDATE reserves
990
            SET    cancellationdate=now()
1208
            SET    cancellationdate=now(),
991
            WHERE  biblionumber   = ?
1209
                   expirationdate = NULL
992
             AND   borrowernumber = ?
1210
            WHERE  reservenumber   = ?
993
        /;
1211
        /;
994
        my $sth = $dbh->prepare($query);
1212
        my $sth = $dbh->prepare($query);
995
        $sth->execute( $biblio, $borrower );
1213
        $sth->execute( $reservenumber );
996
        $sth->finish;
1214
        $sth->finish;
997
        $query = qq/
1215
        $query = qq/
998
            INSERT INTO old_reserves
1216
            INSERT INTO old_reserves
999
            SELECT *
1217
            SELECT * FROM reserves
1000
            FROM   reserves 
1218
            WHERE  reservenumber   = ?
1001
            WHERE  biblionumber   = ?
1002
             AND   borrowernumber = ?
1003
        /;
1219
        /;
1004
        $sth = $dbh->prepare($query);
1220
        $sth = $dbh->prepare($query);
1005
        $sth->execute( $biblio, $borrower );
1221
        $sth->execute( $reservenumber );
1006
        $query = qq/
1222
        $query = qq/
1007
            DELETE FROM reserves 
1223
            DELETE FROM reserves 
1008
            WHERE  biblionumber   = ?
1224
            WHERE  reservenumber   = ?
1009
             AND   borrowernumber = ?
1010
        /;
1225
        /;
1011
        $sth = $dbh->prepare($query);
1226
        $sth = $dbh->prepare($query);
1012
        $sth->execute( $biblio, $borrower );
1227
        $sth->execute( $reservenumber );
1013
        
1228
        
1014
    }
1229
    }
1015
    elsif ($rank =~ /^\d+/ and $rank > 0) {
1230
    elsif ($rank =~ /^\d+/ and $rank > 0) {
1016
        my $query = qq/
1231
        my $query = qq/
1017
        UPDATE reserves SET priority = ? ,branchcode = ?, itemnumber = ?, found = NULL, waitingdate = NULL
1232
        UPDATE reserves SET priority = ? ,branchcode = ?, itemnumber = ?, found = NULL, waitingdate = NULL
1018
            WHERE biblionumber   = ?
1233
            WHERE reservenumber = ?
1019
             AND borrowernumber = ?
1020
        /;
1234
        /;
1021
        my $sth = $dbh->prepare($query);
1235
        my $sth = $dbh->prepare($query);
1022
        $sth->execute( $rank, $branch,$itemnumber, $biblio, $borrower);
1236
        $sth->execute( $rank, $branch, $itemnumber, $reservenumber );
1023
        $sth->finish;
1237
        $sth->finish;
1024
        _FixPriority( $biblio, $borrower, $rank);
1238
        _FixPriority( $biblio, $borrower, $rank, '', $reservenumber);
1025
    }
1239
    }
1026
}
1240
}
1027
1241
1028
=head2 ModReserveFill
1242
=item ModReserveFill
1029
1243
1030
  &ModReserveFill($reserve);
1244
  &ModReserveFill($reserve);
1031
1245
Lines 1044-1059 sub ModReserveFill { Link Here
1044
    my $biblionumber = $res->{'biblionumber'};
1258
    my $biblionumber = $res->{'biblionumber'};
1045
    my $borrowernumber    = $res->{'borrowernumber'};
1259
    my $borrowernumber    = $res->{'borrowernumber'};
1046
    my $resdate = $res->{'reservedate'};
1260
    my $resdate = $res->{'reservedate'};
1261
    my $resnumber      = $res->{'reservenumber'};
1047
1262
1048
    # get the priority on this record....
1263
    # get the priority on this record....
1049
    my $priority;
1264
    my $priority;
1050
    my $query = "SELECT priority
1265
    my $query = "SELECT priority
1051
                 FROM   reserves
1266
                 FROM   reserves
1052
                 WHERE  biblionumber   = ?
1267
                 WHERE  borrowernumber   = ?
1053
                  AND   borrowernumber = ?
1268
                  AND   reservenumber  = ?
1054
                  AND   reservedate    = ?";
1269
                  AND   reservedate    = ?";
1055
    my $sth = $dbh->prepare($query);
1270
    my $sth = $dbh->prepare($query);
1056
    $sth->execute( $biblionumber, $borrowernumber, $resdate );
1271
    $sth->execute( $resnumber, $borrowernumber, $resdate );
1057
    ($priority) = $sth->fetchrow_array;
1272
    ($priority) = $sth->fetchrow_array;
1058
    $sth->finish;
1273
    $sth->finish;
1059
1274
Lines 1061-1095 sub ModReserveFill { Link Here
1061
    $query = "UPDATE reserves
1276
    $query = "UPDATE reserves
1062
                  SET    found            = 'F',
1277
                  SET    found            = 'F',
1063
                         priority         = 0
1278
                         priority         = 0
1064
                 WHERE  biblionumber     = ?
1279
                 WHERE  reservenumber     = ?
1065
                    AND reservedate      = ?
1280
                    AND reservedate      = ?
1066
                    AND borrowernumber   = ?
1281
                    AND borrowernumber   = ?
1067
                ";
1282
                ";
1068
    $sth = $dbh->prepare($query);
1283
    $sth = $dbh->prepare($query);
1069
    $sth->execute( $biblionumber, $resdate, $borrowernumber );
1284
    $sth->execute( $resnumber, $resdate, $borrowernumber );
1070
    $sth->finish;
1285
    $sth->finish;
1071
1286
1072
    # move to old_reserves
1287
    # move to old_reserves
1073
    $query = "INSERT INTO old_reserves
1288
    $query = "INSERT INTO old_reserves
1074
                 SELECT * FROM reserves
1289
                 SELECT * FROM reserves
1075
                 WHERE  biblionumber     = ?
1290
                 WHERE  reservenumber    = ?
1076
                    AND reservedate      = ?
1291
                    AND reservedate      = ?
1077
                    AND borrowernumber   = ?
1292
                    AND borrowernumber   = ?
1078
                ";
1293
                ";
1079
    $sth = $dbh->prepare($query);
1294
    $sth = $dbh->prepare($query);
1080
    $sth->execute( $biblionumber, $resdate, $borrowernumber );
1295
    $sth->execute( $resnumber, $resdate, $borrowernumber );
1081
    $query = "DELETE FROM reserves
1296
    $query = "DELETE FROM reserves
1082
                 WHERE  biblionumber     = ?
1297
                 WHERE  reservenumber    = ?
1083
                    AND reservedate      = ?
1298
                    AND reservedate      = ?
1084
                    AND borrowernumber   = ?
1299
                    AND borrowernumber   = ?
1085
                ";
1300
                ";
1086
    $sth = $dbh->prepare($query);
1301
    $sth = $dbh->prepare($query);
1087
    $sth->execute( $biblionumber, $resdate, $borrowernumber );
1302
    $sth->execute( $resnumber, $resdate, $borrowernumber );
1088
    
1303
    
1089
    # now fix the priority on the others (if the priority wasn't
1304
    # now fix the priority on the others (if the priority wasn't
1090
    # already sorted!)....
1305
    # already sorted!)....
1091
    unless ( $priority == 0 ) {
1306
    unless ( $priority == 0 ) {
1092
        _FixPriority( $biblionumber, $borrowernumber );
1307
        _FixPriority( $priority, $biblionumber,undef,undef, $res->{reservenumber} );
1093
    }
1308
    }
1094
}
1309
}
1095
1310
Lines 1106-1112 $newstatus is the new status. Link Here
1106
=cut
1321
=cut
1107
1322
1108
sub ModReserveStatus {
1323
sub ModReserveStatus {
1109
1110
    #first : check if we have a reservation for this item .
1324
    #first : check if we have a reservation for this item .
1111
    my ($itemnumber, $newstatus) = @_;
1325
    my ($itemnumber, $newstatus) = @_;
1112
    my $dbh          = C4::Context->dbh;
1326
    my $dbh          = C4::Context->dbh;
Lines 1140-1148 take care of the waiting status Link Here
1140
=cut
1354
=cut
1141
1355
1142
sub ModReserveAffect {
1356
sub ModReserveAffect {
1143
    my ( $itemnumber, $borrowernumber,$transferToDo ) = @_;
1357
    my ( $itemnumber, $borrowernumber,$transferToDo, $reservenumber ) = @_;
1144
    my $dbh = C4::Context->dbh;
1358
    my $dbh = C4::Context->dbh;
1145
1146
    # we want to attach $itemnumber to $borrowernumber, find the biblionumber
1359
    # we want to attach $itemnumber to $borrowernumber, find the biblionumber
1147
    # attached to $itemnumber
1360
    # attached to $itemnumber
1148
    my $sth = $dbh->prepare("SELECT biblionumber FROM items WHERE itemnumber=?");
1361
    my $sth = $dbh->prepare("SELECT biblionumber FROM items WHERE itemnumber=?");
Lines 1160-1186 sub ModReserveAffect { Link Here
1160
    $query = "
1373
    $query = "
1161
        UPDATE reserves
1374
        UPDATE reserves
1162
        SET    priority = 0,
1375
        SET    priority = 0,
1163
               itemnumber = ?,
1376
               itemnumber = ?
1164
               found = 'T'
1377
        WHERE reservenumber = ?
1165
        WHERE borrowernumber = ?
1166
          AND biblionumber = ?
1167
    ";
1378
    ";
1168
    }
1379
    }
1169
    else {
1380
    else {
1170
    # affect the reserve to Waiting as well.
1381
    # affect the reserve to Waiting as well.
1171
    $query = "
1382
      my $holdperiod = C4::Context->preference('ReservesMaxPickUpDelay');
1172
        UPDATE reserves
1383
      if ((!defined($holdperiod)) || ($holdperiod eq '') || ($holdperiod == 0)) {
1173
        SET     priority = 0,
1384
        $query = "
1174
                found = 'W',
1385
            UPDATE reserves
1175
                waitingdate=now(),
1386
            SET     priority = 0,
1176
                itemnumber = ?
1387
                    found = 'W',
1177
        WHERE borrowernumber = ?
1388
                    waitingdate=now(),
1178
          AND biblionumber = ?
1389
                    itemnumber = ?
1179
    ";
1390
        WHERE reservenumber = ?
1391
        ";
1392
      }
1393
      else {
1394
        my ($holdexpyear,$holdexpmonth,$holdexpday) = Today();
1395
        my $holdstartdate = C4::Dates->new(sprintf "%02d/%02d/%04d",$holdexpmonth,$holdexpday,$holdexpyear, 'us');
1396
1397
        # Grab branch for calendar purposes
1398
        $sth = $dbh->prepare("SELECT branchcode FROM reserves WHERE borrowernumber=? AND biblionumber=?");
1399
        $sth->execute($borrowernumber,$biblionumber);
1400
        my ($branch) = $sth->fetchrow;
1401
1402
        # Check to see if hold expiration date falls on a closed library day.
1403
        # Note the useDaysMode syspref will need to be set to Calendar for
1404
        # the code to advance to the next non-closed day.
1405
        my $calendar = C4::Calendar->new( branchcode => $branch);
1406
        my $holdexpdate  = $calendar->addDate($holdstartdate, $holdperiod);
1407
        my $sqlexpdate = $holdexpdate->output('iso');
1408
        $query = "
1409
            UPDATE reserves
1410
            SET     priority = 0,
1411
                    found = 'W',
1412
                    waitingdate=now(),
1413
                    itemnumber = ?,
1414
                    expirationdate='$sqlexpdate'
1415
        WHERE reservenumber = ?
1416
        ";
1417
      }
1180
    }
1418
    }
1181
    $sth = $dbh->prepare($query);
1419
    $sth = $dbh->prepare($query);
1182
    $sth->execute( $itemnumber, $borrowernumber,$biblionumber);
1420
    $sth->execute( $itemnumber, $reservenumber );
1183
    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber ) if ( !$transferToDo && !$already_on_shelf );
1421
    _koha_notify_reserve( $itemnumber, $borrowernumber, $biblionumber, $reservenumber ) if ( !$transferToDo && !$already_on_shelf );
1184
1422
1185
    if ( C4::Context->preference("ReturnToShelvingCart") ) {
1423
    if ( C4::Context->preference("ReturnToShelvingCart") ) {
1186
      CartToShelf( $itemnumber );
1424
      CartToShelf( $itemnumber );
Lines 1220-1242 Reduce the values of queuded list Link Here
1220
=cut
1458
=cut
1221
1459
1222
sub ModReserveMinusPriority {
1460
sub ModReserveMinusPriority {
1223
    my ( $itemnumber, $borrowernumber, $biblionumber ) = @_;
1461
    my ( $itemnumber, $borrowernumber, $biblionumber, $reservenumber ) = @_;
1224
1225
    #first step update the value of the first person on reserv
1462
    #first step update the value of the first person on reserv
1226
    my $dbh   = C4::Context->dbh;
1463
    my $dbh   = C4::Context->dbh;
1227
    my $query = "
1464
    my $query = "
1228
        UPDATE reserves
1465
        UPDATE reserves
1229
        SET    priority = 0 , itemnumber = ? 
1466
        SET    priority = 0 , itemnumber = ? 
1230
        WHERE  borrowernumber=?
1467
        WHERE  reservenumber=?
1231
          AND  biblionumber=?
1232
    ";
1468
    ";
1233
    my $sth_upd = $dbh->prepare($query);
1469
    my $sth_upd = $dbh->prepare($query);
1234
    $sth_upd->execute( $itemnumber, $borrowernumber, $biblionumber );
1470
    $sth_upd->execute( $itemnumber, $reservenumber );
1235
    # second step update all others reservs
1471
    # second step update all others reservs
1236
    _FixPriority($biblionumber, $borrowernumber, '0');
1472
    _FixPriority($biblionumber, $borrowernumber, '0', '', $reservenumber);
1237
}
1473
}
1238
1474
1239
=head2 GetReserveInfo
1475
=item GetReserveInfo
1240
1476
1241
  &GetReserveInfo($borrowernumber,$biblionumber);
1477
  &GetReserveInfo($borrowernumber,$biblionumber);
1242
1478
Lines 1321-1327 and canreservefromotherbranches. Link Here
1321
sub IsAvailableForItemLevelRequest {
1557
sub IsAvailableForItemLevelRequest {
1322
    my $itemnumber = shift;
1558
    my $itemnumber = shift;
1323
   
1559
   
1324
    my $item = GetItem($itemnumber);
1560
    my $item = C4::Items::GetItem($itemnumber);
1325
1561
1326
    # must check the notforloan setting of the itemtype
1562
    # must check the notforloan setting of the itemtype
1327
    # FIXME - a lot of places in the code do this
1563
    # FIXME - a lot of places in the code do this
Lines 1356-1365 sub IsAvailableForItemLevelRequest { Link Here
1356
                               $notforloan_per_itemtype;
1592
                               $notforloan_per_itemtype;
1357
1593
1358
1594
1359
    if (C4::Context->preference('AllowOnShelfHolds')) {
1595
    if (CanHoldOnShelf($itemnumber)) {
1360
        return $available_per_item;
1596
        return $available_per_item;
1361
    } else {
1597
    } else {
1362
        return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W")); 
1598
        return ($available_per_item and ($item->{onloan} or GetReserveStatus($itemnumber) eq "W"));
1363
    }
1599
    }
1364
}
1600
}
1365
1601
Lines 1387-1401 sub AlterPriority { Link Here
1387
    
1623
    
1388
      my $priority = $reserve->{'priority'};        
1624
      my $priority = $reserve->{'priority'};        
1389
      $priority = $where eq 'up' ? $priority - 1 : $priority + 1;
1625
      $priority = $where eq 'up' ? $priority - 1 : $priority + 1;
1390
      _FixPriority( $biblionumber, $borrowernumber, $priority )
1626
      _FixPriority( $biblionumber, $borrowernumber, $priority ,undef,$reserve->{reservenumber})
1391
1627
1392
    } elsif ( $where eq 'top' ) {
1628
    } elsif ( $where eq 'top' ) {
1393
1629
1394
      _FixPriority( $biblionumber, $borrowernumber, '1' )
1630
      _FixPriority( $biblionumber, $borrowernumber, '1',undef,$reserve->{reservenumber} )
1395
1631
1396
    } elsif ( $where eq 'bottom' ) {
1632
    } elsif ( $where eq 'bottom' ) {
1397
1633
1398
      _FixPriority( $biblionumber, $borrowernumber, '999999' )
1634
        _FixPriority( $biblionumber, $borrowernumber, '999999',undef,$reserve->{reservenumber} )
1399
1635
1400
    }
1636
    }
1401
}
1637
}
Lines 1418-1435 sub ToggleLowestPriority { Link Here
1418
         WHERE biblionumber = ?
1654
         WHERE biblionumber = ?
1419
         AND borrowernumber = ?"
1655
         AND borrowernumber = ?"
1420
    );
1656
    );
1421
    $sth->execute(
1657
    $sth->execute( $biblionumber, $borrowernumber, );
1422
        $biblionumber,
1423
        $borrowernumber,
1424
    );
1425
    $sth->finish;
1658
    $sth->finish;
1426
    
1659
    
1427
    _FixPriority( $biblionumber, $borrowernumber, '999999' );
1660
    _FixPriority( $biblionumber, $borrowernumber, '999999' );
1428
}
1661
}
1429
1662
1663
=head2 CanHoldOnShelf
1664
1665
my $canhold = &CanHoldOnShelf($itemnumber);
1666
1667
 Check if a book can be hold on shelf.
1668
1669
=cut
1670
1671
sub CanHoldOnShelf {
1672
    my ($itemnumber) = @_;
1673
    
1674
    my $item = C4::Items::GetItem($itemnumber);
1675
    my $itemtype = C4::Context->preference('item-level_itypes');
1676
    $itemtype = $itemtype ? $item->{itype} : $item->{itemtype} ;
1677
    my $branch = $item->{C4::Context->preference('HomeOrHoldingBranch')};
1678
    
1679
    my $issuingrule = GetIssuingRule('*', $itemtype, $branch);
1680
    return $issuingrule->{allowonshelfholds};
1681
    
1682
}
1683
1684
sub CanHoldMultipleItems {
1685
  my ( $itemtype ) = @_;
1686
  
1687
  my @multi_itemtypes = split( / /, C4::Context->preference('AllowMultipleHoldsPerBib') );
1688
  for my $mtype ( @multi_itemtypes ) {
1689
    if ( $itemtype eq $mtype ) {
1690
      return 1;
1691
    }
1692
  }
1693
  
1694
  return 0;
1695
}
1696
1430
=head2 _FixPriority
1697
=head2 _FixPriority
1698
>>>>>>> [MT2355] Ergonomy improvement in smart rule management
1431
1699
1432
  &_FixPriority($biblio,$borrowernumber,$rank,$ignoreSetLowestRank);
1700
&_FixPriority($biblio,$borrowernumber,$rank,$ignoreSetLowestRank,$reservenumber);
1433
1701
1434
Only used internally (so don't export it)
1702
Only used internally (so don't export it)
1435
Changed how this functions works #
1703
Changed how this functions works #
Lines 1441-1447 in new priority rank Link Here
1441
=cut 
1709
=cut 
1442
1710
1443
sub _FixPriority {
1711
sub _FixPriority {
1444
    my ( $biblio, $borrowernumber, $rank, $ignoreSetLowestRank ) = @_;
1712
    my ( $biblio, $borrowernumber, $rank, $ignoreSetLowestRank, $reservenumber ) = @_;
1445
    my $dbh = C4::Context->dbh;
1713
    my $dbh = C4::Context->dbh;
1446
     if ( $rank eq "del" ) {
1714
     if ( $rank eq "del" ) {
1447
         CancelReserve( $biblio, undef, $borrowernumber );
1715
         CancelReserve( $biblio, undef, $borrowernumber );
Lines 1452-1463 sub _FixPriority { Link Here
1452
        my $query = qq/
1720
        my $query = qq/
1453
            UPDATE reserves
1721
            UPDATE reserves
1454
            SET    priority = 0
1722
            SET    priority = 0
1455
            WHERE biblionumber = ?
1723
            WHERE reservenumber = ?
1456
              AND borrowernumber = ?
1724
              AND found IN ('W',"T")
1457
              AND found IN ('W', 'T')
1458
        /;
1725
        /;
1459
        my $sth = $dbh->prepare($query);
1726
        my $sth = $dbh->prepare($query);
1460
        $sth->execute( $biblio, $borrowernumber );
1727
        $sth->execute( $reservenumber );
1461
    }
1728
    }
1462
    my @priority;
1729
    my @priority;
1463
    my @reservedates;
1730
    my @reservedates;
Lines 1468-1474 sub _FixPriority { Link Here
1468
	# This is wrong a waiting reserve has W set
1735
	# This is wrong a waiting reserve has W set
1469
	# The assumption that having an itemnumber set means waiting is wrong and should be corrected any place it occurs
1736
	# The assumption that having an itemnumber set means waiting is wrong and should be corrected any place it occurs
1470
    my $query = qq/
1737
    my $query = qq/
1471
        SELECT borrowernumber, reservedate, constrainttype
1738
        SELECT borrowernumber, reservedate, constrainttype, reservenumber
1472
        FROM   reserves
1739
        FROM   reserves
1473
        WHERE  biblionumber   = ?
1740
        WHERE  biblionumber   = ?
1474
          AND  ((found <> 'W' AND found <> 'T') or found is NULL)
1741
          AND  ((found <> 'W' AND found <> 'T') or found is NULL)
Lines 1503-1518 sub _FixPriority { Link Here
1503
    $query = "
1770
    $query = "
1504
            UPDATE reserves
1771
            UPDATE reserves
1505
            SET    priority = ?
1772
            SET    priority = ?
1506
                WHERE  biblionumber = ?
1773
                WHERE  reservenumber = ?
1507
                 AND borrowernumber   = ?
1508
                 AND reservedate = ?
1774
                 AND reservedate = ?
1509
         AND found IS NULL
1775
         AND found IS NULL
1510
    ";
1776
    ";
1511
    $sth = $dbh->prepare($query);
1777
    $sth = $dbh->prepare($query);
1512
    for ( my $j = 0 ; $j < @priority ; $j++ ) {
1778
    for ( my $j = 0 ; $j < @priority ; $j++ ) {
1513
        $sth->execute(
1779
        $sth->execute(
1514
            $j + 1, $biblio,
1780
            $j + 1, 
1515
            $priority[$j]->{'borrowernumber'},
1781
            $priority[$j]->{'reservenumber'},
1516
            $priority[$j]->{'reservedate'}
1782
            $priority[$j]->{'reservedate'}
1517
        );
1783
        );
1518
        $sth->finish;
1784
        $sth->finish;
Lines 1552-1566 sub _Findgroupreserve { Link Here
1552
    # TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var.
1818
    # TODO: consolidate at least the SELECT portion of the first 2 queries to a common $select var.
1553
    # check for exact targetted match
1819
    # check for exact targetted match
1554
    my $item_level_target_query = qq/
1820
    my $item_level_target_query = qq/
1555
        SELECT reserves.biblionumber        AS biblionumber,
1821
        SELECT reserves.reservenumber AS reservenumber,
1556
               reserves.borrowernumber      AS borrowernumber,
1822
               reserves.biblionumber AS biblionumber,
1557
               reserves.reservedate         AS reservedate,
1823
               reserves.borrowernumber AS borrowernumber,
1558
               reserves.branchcode          AS branchcode,
1824
               reserves.reservedate AS reservedate,
1559
               reserves.cancellationdate    AS cancellationdate,
1825
               reserves.branchcode AS branchcode,
1560
               reserves.found               AS found,
1826
               reserves.cancellationdate AS cancellationdate,
1561
               reserves.reservenotes        AS reservenotes,
1827
               reserves.found AS found,
1562
               reserves.priority            AS priority,
1828
               reserves.reservenotes AS reservenotes,
1563
               reserves.timestamp           AS timestamp,
1829
               reserves.priority AS priority,
1830
               reserves.timestamp AS timestamp,
1564
               biblioitems.biblioitemnumber AS biblioitemnumber,
1831
               biblioitems.biblioitemnumber AS biblioitemnumber,
1565
               reserves.itemnumber          AS itemnumber
1832
               reserves.itemnumber          AS itemnumber
1566
        FROM reserves
1833
        FROM reserves
Lines 1582-1596 sub _Findgroupreserve { Link Here
1582
    
1849
    
1583
    # check for title-level targetted match
1850
    # check for title-level targetted match
1584
    my $title_level_target_query = qq/
1851
    my $title_level_target_query = qq/
1585
        SELECT reserves.biblionumber        AS biblionumber,
1852
        SELECT reserves.reservenumber AS reservenumber,
1586
               reserves.borrowernumber      AS borrowernumber,
1853
               reserves.biblionumber AS biblionumber,
1587
               reserves.reservedate         AS reservedate,
1854
               reserves.borrowernumber AS borrowernumber,
1588
               reserves.branchcode          AS branchcode,
1855
               reserves.reservedate AS reservedate,
1589
               reserves.cancellationdate    AS cancellationdate,
1856
               reserves.branchcode AS branchcode,
1590
               reserves.found               AS found,
1857
               reserves.cancellationdate AS cancellationdate,
1591
               reserves.reservenotes        AS reservenotes,
1858
               reserves.found AS found,
1592
               reserves.priority            AS priority,
1859
               reserves.reservenotes AS reservenotes,
1593
               reserves.timestamp           AS timestamp,
1860
               reserves.priority AS priority,
1861
               reserves.timestamp AS timestamp,
1594
               biblioitems.biblioitemnumber AS biblioitemnumber,
1862
               biblioitems.biblioitemnumber AS biblioitemnumber,
1595
               reserves.itemnumber          AS itemnumber
1863
               reserves.itemnumber          AS itemnumber
1596
        FROM reserves
1864
        FROM reserves
Lines 1611-1626 sub _Findgroupreserve { Link Here
1611
    return @results if @results;
1879
    return @results if @results;
1612
1880
1613
    my $query = qq/
1881
    my $query = qq/
1614
        SELECT reserves.biblionumber               AS biblionumber,
1882
        SELECT reserves.reservenumber AS reservenumber,
1615
               reserves.borrowernumber             AS borrowernumber,
1883
               reserves.biblionumber AS biblionumber,
1616
               reserves.reservedate                AS reservedate,
1884
               reserves.borrowernumber AS borrowernumber,
1617
               reserves.waitingdate                AS waitingdate,
1885
               reserves.reservedate AS reservedate,
1618
               reserves.branchcode                 AS branchcode,
1886
               reserves.branchcode AS branchcode,
1619
               reserves.cancellationdate           AS cancellationdate,
1887
               reserves.cancellationdate AS cancellationdate,
1620
               reserves.found                      AS found,
1888
               reserves.found AS found,
1621
               reserves.reservenotes               AS reservenotes,
1889
               reserves.reservenotes AS reservenotes,
1622
               reserves.priority                   AS priority,
1890
               reserves.priority AS priority,
1623
               reserves.timestamp                  AS timestamp,
1891
               reserves.timestamp AS timestamp,
1624
               reserveconstraints.biblioitemnumber AS biblioitemnumber,
1892
               reserveconstraints.biblioitemnumber AS biblioitemnumber,
1625
               reserves.itemnumber                 AS itemnumber
1893
               reserves.itemnumber                 AS itemnumber
1626
        FROM reserves
1894
        FROM reserves
Lines 1652-1681 ModReserveAffect, _not_ ModReserveFill) Link Here
1652
=cut
1920
=cut
1653
1921
1654
sub _koha_notify_reserve {
1922
sub _koha_notify_reserve {
1655
    my ($itemnumber, $borrowernumber, $biblionumber) = @_;
1923
    my ($itemnumber, $borrowernumber, $biblionumber, $reservenumber) = @_;
1656
1924
1657
    my $dbh = C4::Context->dbh;
1925
    my $dbh      = C4::Context->dbh;
1658
    my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber);
1926
    my $borrower = C4::Members::GetMember( 'borrowernumber'=> $borrowernumber );
1659
    my $letter_code;
1927
    my $letter_code;
1660
    my $print_mode = 0;
1928
    my $print_mode = 0;
1661
    my $messagingprefs;
1929
    my $messagingprefs;
1662
    if ( $borrower->{'email'} || $borrower->{'smsalertnumber'} ) {
1930
    if ( C4::Members::GetFirstValidEmailAddress($borrowernumber) || $borrower->{'smsalertnumber'} ) {
1663
        $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'Hold Filled' } );
1931
        $messagingprefs = C4::Members::Messaging::GetMessagingPreferences( { borrowernumber => $borrowernumber, message_name => 'Hold Filled' } );
1664
1932
1665
        return if ( !defined( $messagingprefs->{'letter_code'} ) );
1933
        return if ( !defined( $messagingprefs->{'letter_code'} ) );
1666
        $letter_code = $messagingprefs->{'letter_code'};
1934
        $letter_code = $messagingprefs->{'letter_code'};
1667
    } else {
1935
    } else {
1668
        $letter_code = 'HOLD_PRINT';
1936
        $letter_code = 'HOLD';
1669
        $print_mode = 1;
1937
        $print_mode = 1;
1670
    }
1938
    }
1671
1939
1672
    my $sth = $dbh->prepare("
1940
    my $sth = $dbh->prepare("
1673
        SELECT *
1941
        SELECT *
1674
        FROM   reserves
1942
        FROM   reserves
1675
        WHERE  borrowernumber = ?
1943
        WHERE  reservenumber = ?
1676
            AND biblionumber = ?
1677
    ");
1944
    ");
1678
    $sth->execute( $borrowernumber, $biblionumber );
1945
    $sth->execute( $reservenumber );
1679
    my $reserve = $sth->fetchrow_hashref;
1946
    my $reserve = $sth->fetchrow_hashref;
1680
    my $branch_details = GetBranchDetail( $reserve->{'branchcode'} );
1947
    my $branch_details = GetBranchDetail( $reserve->{'branchcode'} );
1681
1948
Lines 1688-1693 sub _koha_notify_reserve { Link Here
1688
    C4::Letters::parseletter( $letter, 'borrowers', $borrowernumber );
1955
    C4::Letters::parseletter( $letter, 'borrowers', $borrowernumber );
1689
    C4::Letters::parseletter( $letter, 'biblio', $biblionumber );
1956
    C4::Letters::parseletter( $letter, 'biblio', $biblionumber );
1690
    C4::Letters::parseletter( $letter, 'reserves', $borrowernumber, $biblionumber );
1957
    C4::Letters::parseletter( $letter, 'reserves', $borrowernumber, $biblionumber );
1958
    C4::Letters::parseletter( $letter, 'items',  $itemnumber );
1691
1959
1692
    if ( $reserve->{'itemnumber'} ) {
1960
    if ( $reserve->{'itemnumber'} ) {
1693
        C4::Letters::parseletter( $letter, 'items', $reserve->{'itemnumber'} );
1961
        C4::Letters::parseletter( $letter, 'items', $reserve->{'itemnumber'} );
(-)a/admin/branch_transfer_limits.pl (-11 / +11 lines)
Lines 91-103 while ( my $row = $sth->fetchrow_hashref ) { Link Here
91
91
92
## If Form Data Passed, Update the Database
92
## If Form Data Passed, Update the Database
93
if ( $input->param('updateLimits') ) {
93
if ( $input->param('updateLimits') ) {
94
	DeleteBranchTransferLimits();
94
	DeleteBranchTransferLimits($branchcode);
95
95
96
	foreach my $code ( @codes ) {
96
	foreach my $code ( @codes ) {
97
		foreach my $toBranch ( @branchcodes ) {
97
		foreach my $fromBranch ( @branchcodes ) {
98
			my $isSet = not $input->param( $code . "_" . $toBranch);
98
			my $isSet = not $input->param( $code . "_" . $fromBranch);
99
			if ( $isSet ) {
99
			if ( $isSet ) {
100
			    CreateBranchTransferLimit( $toBranch, $branchcode, $code );
100
			    CreateBranchTransferLimit( $branchcode, $fromBranch, $code );
101
			}
101
			}
102
		}
102
		}
103
	}
103
	}
Lines 115-132 my $branchcount = scalar(@branchcode_loop); Link Here
115
## Build the default data
115
## Build the default data
116
my @codes_loop;
116
my @codes_loop;
117
foreach my $code ( @codes ) {
117
foreach my $code ( @codes ) {
118
	my @to_branch_loop;
118
	my @from_branch_loop;
119
	my %row_data;
119
	my %row_data;
120
	$row_data{ code } = $code;
120
	$row_data{ code } = $code;
121
	$row_data{ to_branch_loop } = \@to_branch_loop;
121
	$row_data{ from_branch_loop } = \@from_branch_loop;
122
	foreach my $toBranch ( @branchcodes ) {
122
	foreach my $fromBranch ( @branchcodes ) {
123
		my %row_data;
123
		my %row_data;
124
                my $isChecked = IsBranchTransferAllowed( $toBranch, $branchcode, $code );
124
        my $isChecked = IsBranchTransferAllowed( $branchcode, $fromBranch, $code );
125
		$row_data{ code }         = $code;
125
		$row_data{ code }         = $code;
126
		$row_data{ toBranch }     = $toBranch;
126
		$row_data{ fromBranch }     = $fromBranch;
127
		$row_data{ isChecked }    = $isChecked;	
127
		$row_data{ isChecked }    = $isChecked;	
128
		$row_data{ toBranchname } = GetBranchName($toBranch);	
128
		$row_data{ fromBranchname } = GetBranchName($fromBranch);	
129
		push( @to_branch_loop, \%row_data );
129
		push( @from_branch_loop, \%row_data );
130
	}
130
	}
131
131
132
	push( @codes_loop, \%row_data );
132
	push( @codes_loop, \%row_data );
(-)a/admin/smart-rules.pl (-456 / +109 lines)
Lines 25-341 use C4::Output; Link Here
25
use C4::Auth;
25
use C4::Auth;
26
use C4::Koha;
26
use C4::Koha;
27
use C4::Debug;
27
use C4::Debug;
28
use C4::Branch; # GetBranches
28
use C4::Branch;
29
use C4::IssuingRules;
30
use C4::Circulation;
29
31
30
my $input = new CGI;
32
my $input = new CGI;
31
my $dbh = C4::Context->dbh;
33
my $dbh = C4::Context->dbh;
32
34
33
# my $flagsrequired;
35
my ($template, $loggedinuser, $cookie) = get_template_and_user({
34
# $flagsrequired->{circulation}=1;
36
    template_name   => "admin/smart-rules.tmpl",
35
my ($template, $loggedinuser, $cookie)
37
    query           => $input,
36
    = get_template_and_user({template_name => "admin/smart-rules.tmpl",
38
    type            => "intranet",
37
                            query => $input,
39
    authnotrequired => 0,
38
                            type => "intranet",
40
    flagsrequired   => {parameters => 1},
39
                            authnotrequired => 0,
41
    debug           => 1,
40
                            flagsrequired => {parameters => 1},
42
});
41
                            debug => 1,
43
42
                            });
44
my $type       = $input->param('type');
43
45
my $branchcode = $input->param('branchcode') || ( C4::Branch::onlymine() ? ( C4::Branch::mybranch() || '*' ) : '*' );
44
my $type=$input->param('type');
46
my $op         = $input->param('op');
45
my $branch = $input->param('branch') || ( C4::Branch::onlymine() ? ( C4::Branch::mybranch() || '*' ) : '*' );
47
my $confirm    = $input->param('confirm'); 
46
my $op = $input->param('op');
48
47
49
# This block builds the branch list
48
if ($op eq 'delete') {
49
    my $itemtype     = $input->param('itemtype');
50
    my $categorycode = $input->param('categorycode');
51
    $debug and warn "deleting $1 $2 $branch";
52
53
    my $sth_Idelete = $dbh->prepare("delete from issuingrules where branchcode=? and categorycode=? and itemtype=?");
54
    $sth_Idelete->execute($branch, $categorycode, $itemtype);
55
}
56
elsif ($op eq 'delete-branch-cat') {
57
    my $categorycode  = $input->param('categorycode');
58
    if ($branch eq "*") {
59
        if ($categorycode eq "*") {
60
            my $sth_delete = $dbh->prepare("DELETE FROM default_circ_rules");
61
            $sth_delete->execute();
62
        } else {
63
            my $sth_delete = $dbh->prepare("DELETE FROM default_borrower_circ_rules
64
                                            WHERE categorycode = ?");
65
            $sth_delete->execute($categorycode);
66
        }
67
    } elsif ($categorycode eq "*") {
68
        my $sth_delete = $dbh->prepare("DELETE FROM default_branch_circ_rules
69
                                        WHERE branchcode = ?");
70
        $sth_delete->execute($branch);
71
    } else {
72
        my $sth_delete = $dbh->prepare("DELETE FROM branch_borrower_circ_rules
73
                                        WHERE branchcode = ?
74
                                        AND categorycode = ?");
75
        $sth_delete->execute($branch, $categorycode);
76
    }
77
}
78
elsif ($op eq 'delete-branch-item') {
79
    my $itemtype  = $input->param('itemtype');
80
    if ($branch eq "*") {
81
        if ($itemtype eq "*") {
82
            my $sth_delete = $dbh->prepare("DELETE FROM default_circ_rules");
83
            $sth_delete->execute();
84
        } else {
85
            my $sth_delete = $dbh->prepare("DELETE FROM default_branch_item_rules
86
                                            WHERE itemtype = ?");
87
            $sth_delete->execute($itemtype);
88
        }
89
    } elsif ($itemtype eq "*") {
90
        my $sth_delete = $dbh->prepare("DELETE FROM default_branch_circ_rules
91
                                        WHERE branchcode = ?");
92
        $sth_delete->execute($branch);
93
    } else {
94
        my $sth_delete = $dbh->prepare("DELETE FROM branch_item_rules
95
                                        WHERE branchcode = ?
96
                                        AND itemtype = ?");
97
        $sth_delete->execute($branch, $itemtype);
98
    }
99
}
100
# save the values entered
101
elsif ($op eq 'add') {
102
    my $sth_search = $dbh->prepare("SELECT COUNT(*) AS total FROM issuingrules WHERE branchcode=? AND categorycode=? AND itemtype=?");
103
    my $sth_insert = $dbh->prepare("INSERT INTO issuingrules (branchcode, categorycode, itemtype, maxissueqty, renewalsallowed, reservesallowed, issuelength, fine, finedays, firstremind, chargeperiod,rentaldiscount) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)");
104
    my $sth_update=$dbh->prepare("UPDATE issuingrules SET fine=?, finedays=?, firstremind=?, chargeperiod=?, maxissueqty=?, renewalsallowed=?, reservesallowed=?, issuelength=?, rentaldiscount=?  WHERE branchcode=? AND categorycode=? AND itemtype=?");
105
    
106
    my $br = $branch; # branch
107
    my $bor  = $input->param('categorycode'); # borrower category
108
    my $cat  = $input->param('itemtype');     # item type
109
    my $fine = $input->param('fine');
110
    my $finedays     = $input->param('finedays');
111
    my $firstremind  = $input->param('firstremind');
112
    my $chargeperiod = $input->param('chargeperiod');
113
    my $maxissueqty  = $input->param('maxissueqty');
114
    my $renewalsallowed  = $input->param('renewalsallowed');
115
    my $reservesallowed  = $input->param('reservesallowed');
116
    $maxissueqty =~ s/\s//g;
117
    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
118
    my $issuelength  = $input->param('issuelength');
119
    my $rentaldiscount = $input->param('rentaldiscount');
120
    $debug and warn "Adding $br, $bor, $cat, $fine, $maxissueqty";
121
122
    $sth_search->execute($br,$bor,$cat);
123
    my $res = $sth_search->fetchrow_hashref();
124
    if ($res->{total}) {
125
        $sth_update->execute($fine, $finedays,$firstremind, $chargeperiod, $maxissueqty, $renewalsallowed,$reservesallowed, $issuelength,$rentaldiscount, $br,$bor,$cat);
126
    } else {
127
        $sth_insert->execute($br,$bor,$cat,$maxissueqty,$renewalsallowed,$reservesallowed,$issuelength,$fine,$finedays,$firstremind,$chargeperiod,$rentaldiscount);
128
    }
129
} 
130
elsif ($op eq "set-branch-defaults") {
131
    my $categorycode  = $input->param('categorycode');
132
    my $maxissueqty   = $input->param('maxissueqty');
133
    my $holdallowed   = $input->param('holdallowed');
134
    $maxissueqty =~ s/\s//g;
135
    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
136
    $holdallowed =~ s/\s//g;
137
    $holdallowed = undef if $holdallowed !~ /^\d+/;
138
139
    if ($branch eq "*") {
140
        my $sth_search = $dbh->prepare("SELECT count(*) AS total
141
                                        FROM default_circ_rules");
142
        my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
143
                                        (maxissueqty, holdallowed)
144
                                        VALUES (?, ?)");
145
        my $sth_update = $dbh->prepare("UPDATE default_circ_rules
146
                                        SET maxissueqty = ?, holdallowed = ?");
147
148
        $sth_search->execute();
149
        my $res = $sth_search->fetchrow_hashref();
150
        if ($res->{total}) {
151
            $sth_update->execute($maxissueqty, $holdallowed);
152
        } else {
153
            $sth_insert->execute($maxissueqty, $holdallowed);
154
        }
155
    } else {
156
        my $sth_search = $dbh->prepare("SELECT count(*) AS total
157
                                        FROM default_branch_circ_rules
158
                                        WHERE branchcode = ?");
159
        my $sth_insert = $dbh->prepare("INSERT INTO default_branch_circ_rules
160
                                        (branchcode, maxissueqty, holdallowed)
161
                                        VALUES (?, ?, ?)");
162
        my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
163
                                        SET maxissueqty = ?, holdallowed = ?
164
                                        WHERE branchcode = ?");
165
        $sth_search->execute($branch);
166
        my $res = $sth_search->fetchrow_hashref();
167
        if ($res->{total}) {
168
            $sth_update->execute($maxissueqty, $holdallowed, $branch);
169
        } else {
170
            $sth_insert->execute($branch, $maxissueqty, $holdallowed);
171
        }
172
    }
173
}
174
elsif ($op eq "add-branch-cat") {
175
    my $categorycode  = $input->param('categorycode');
176
    my $maxissueqty   = $input->param('maxissueqty');
177
    $maxissueqty =~ s/\s//g;
178
    $maxissueqty = undef if $maxissueqty !~ /^\d+/;
179
180
    if ($branch eq "*") {
181
        if ($categorycode eq "*") {
182
            my $sth_search = $dbh->prepare("SELECT count(*) AS total
183
                                            FROM default_circ_rules");
184
            my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
185
                                            (maxissueqty)
186
                                            VALUES (?)");
187
            my $sth_update = $dbh->prepare("UPDATE default_circ_rules
188
                                            SET maxissueqty = ?");
189
190
            $sth_search->execute();
191
            my $res = $sth_search->fetchrow_hashref();
192
            if ($res->{total}) {
193
                $sth_update->execute($maxissueqty);
194
            } else {
195
                $sth_insert->execute($maxissueqty);
196
            }
197
        } else {
198
            my $sth_search = $dbh->prepare("SELECT count(*) AS total
199
                                            FROM default_borrower_circ_rules
200
                                            WHERE categorycode = ?");
201
            my $sth_insert = $dbh->prepare("INSERT INTO default_borrower_circ_rules
202
                                            (categorycode, maxissueqty)
203
                                            VALUES (?, ?)");
204
            my $sth_update = $dbh->prepare("UPDATE default_borrower_circ_rules
205
                                            SET maxissueqty = ?
206
                                            WHERE categorycode = ?");
207
            $sth_search->execute($branch);
208
            my $res = $sth_search->fetchrow_hashref();
209
            if ($res->{total}) {
210
                $sth_update->execute($maxissueqty, $categorycode);
211
            } else {
212
                $sth_insert->execute($categorycode, $maxissueqty);
213
            }
214
        }
215
    } elsif ($categorycode eq "*") {
216
        my $sth_search = $dbh->prepare("SELECT count(*) AS total
217
                                        FROM default_branch_circ_rules
218
                                        WHERE branchcode = ?");
219
        my $sth_insert = $dbh->prepare("INSERT INTO default_branch_circ_rules
220
                                        (branchcode, maxissueqty)
221
                                        VALUES (?, ?)");
222
        my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
223
                                        SET maxissueqty = ?
224
                                        WHERE branchcode = ?");
225
        $sth_search->execute($branch);
226
        my $res = $sth_search->fetchrow_hashref();
227
        if ($res->{total}) {
228
            $sth_update->execute($maxissueqty, $branch);
229
        } else {
230
            $sth_insert->execute($branch, $maxissueqty);
231
        }
232
    } else {
233
        my $sth_search = $dbh->prepare("SELECT count(*) AS total
234
                                        FROM branch_borrower_circ_rules
235
                                        WHERE branchcode = ?
236
                                        AND   categorycode = ?");
237
        my $sth_insert = $dbh->prepare("INSERT INTO branch_borrower_circ_rules
238
                                        (branchcode, categorycode, maxissueqty)
239
                                        VALUES (?, ?, ?)");
240
        my $sth_update = $dbh->prepare("UPDATE branch_borrower_circ_rules
241
                                        SET maxissueqty = ?
242
                                        WHERE branchcode = ?
243
                                        AND categorycode = ?");
244
245
        $sth_search->execute($branch, $categorycode);
246
        my $res = $sth_search->fetchrow_hashref();
247
        if ($res->{total}) {
248
            $sth_update->execute($maxissueqty, $branch, $categorycode);
249
        } else {
250
            $sth_insert->execute($branch, $categorycode, $maxissueqty);
251
        }
252
    }
253
}
254
elsif ($op eq "add-branch-item") {
255
    my $itemtype  = $input->param('itemtype');
256
    my $holdallowed   = $input->param('holdallowed');
257
    $holdallowed =~ s/\s//g;
258
    $holdallowed = undef if $holdallowed !~ /^\d+/;
259
260
    if ($branch eq "*") {
261
        if ($itemtype eq "*") {
262
            my $sth_search = $dbh->prepare("SELECT count(*) AS total
263
                                            FROM default_circ_rules");
264
            my $sth_insert = $dbh->prepare("INSERT INTO default_circ_rules
265
                                            (holdallowed)
266
                                            VALUES (?)");
267
            my $sth_update = $dbh->prepare("UPDATE default_circ_rules
268
                                            SET holdallowed = ?");
269
270
            $sth_search->execute();
271
            my $res = $sth_search->fetchrow_hashref();
272
            if ($res->{total}) {
273
                $sth_update->execute($holdallowed);
274
            } else {
275
                $sth_insert->execute($holdallowed);
276
            }
277
        } else {
278
            my $sth_search = $dbh->prepare("SELECT count(*) AS total
279
                                            FROM default_branch_item_rules
280
                                            WHERE itemtype = ?");
281
            my $sth_insert = $dbh->prepare("INSERT INTO default_branch_item_rules
282
                                            (itemtype, holdallowed)
283
                                            VALUES (?, ?)");
284
            my $sth_update = $dbh->prepare("UPDATE default_branch_item_rules
285
                                            SET holdallowed = ?
286
                                            WHERE itemtype = ?");
287
            $sth_search->execute($itemtype);
288
            my $res = $sth_search->fetchrow_hashref();
289
            if ($res->{total}) {
290
                $sth_update->execute($holdallowed, $itemtype);
291
            } else {
292
                $sth_insert->execute($itemtype, $holdallowed);
293
            }
294
        }
295
    } elsif ($itemtype eq "*") {
296
        my $sth_search = $dbh->prepare("SELECT count(*) AS total
297
                                        FROM default_branch_circ_rules
298
                                        WHERE branchcode = ?");
299
        my $sth_insert = $dbh->prepare("INSERT INTO default_branch_circ_rules
300
                                        (branchcode, holdallowed)
301
                                        VALUES (?, ?)");
302
        my $sth_update = $dbh->prepare("UPDATE default_branch_circ_rules
303
                                        SET holdallowed = ?
304
                                        WHERE branchcode = ?");
305
        $sth_search->execute($branch);
306
        my $res = $sth_search->fetchrow_hashref();
307
        if ($res->{total}) {
308
            $sth_update->execute($holdallowed, $branch);
309
        } else {
310
            $sth_insert->execute($branch, $holdallowed);
311
        }
312
    } else {
313
        my $sth_search = $dbh->prepare("SELECT count(*) AS total
314
                                        FROM branch_item_rules
315
                                        WHERE branchcode = ?
316
                                        AND   itemtype = ?");
317
        my $sth_insert = $dbh->prepare("INSERT INTO branch_item_rules
318
                                        (branchcode, itemtype, holdallowed)
319
                                        VALUES (?, ?, ?)");
320
        my $sth_update = $dbh->prepare("UPDATE branch_item_rules
321
                                        SET holdallowed = ?
322
                                        WHERE branchcode = ?
323
                                        AND itemtype = ?");
324
325
        $sth_search->execute($branch, $itemtype);
326
        my $res = $sth_search->fetchrow_hashref();
327
        if ($res->{total}) {
328
            $sth_update->execute($holdallowed, $branch, $itemtype);
329
        } else {
330
            $sth_insert->execute($branch, $itemtype, $holdallowed);
331
        }
332
    }
333
}
334
335
my $branches = GetBranches();
50
my $branches = GetBranches();
336
my @branchloop;
51
my @branchloop;
337
for my $thisbranch (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } keys %$branches) {
52
for my $thisbranch (sort { $branches->{$a}->{'branchname'} cmp $branches->{$b}->{'branchname'} } keys %$branches) {
338
    my $selected = 1 if $thisbranch eq $branch;
53
    my $selected = 1 if $thisbranch eq $branchcode;
339
    my %row =(value => $thisbranch,
54
    my %row =(value => $thisbranch,
340
                selected => $selected,
55
                selected => $selected,
341
                branchname => $branches->{$thisbranch}->{'branchname'},
56
                branchname => $branches->{$thisbranch}->{'branchname'},
Lines 343-519 for my $thisbranch (sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{b Link Here
343
    push @branchloop, \%row;
58
    push @branchloop, \%row;
344
}
59
}
345
60
346
my $sth=$dbh->prepare("SELECT description,categorycode FROM categories ORDER BY description");
61
# Get the patron category list
347
$sth->execute;
62
my @category_loop = C4::Category->all;
348
my @category_loop;
349
while (my $data=$sth->fetchrow_hashref){
350
    push @category_loop,$data;
351
}
352
353
$sth->finish;
354
$sth=$dbh->prepare("SELECT description,itemtype FROM itemtypes ORDER BY description");
355
$sth->execute;
356
# $i=0;
357
my @row_loop;
358
my @itemtypes;
359
while (my $row=$sth->fetchrow_hashref){
360
    push @itemtypes,$row;
361
}
362
63
363
my $sth2 = $dbh->prepare("
64
# Get the item types list
364
    SELECT issuingrules.*, itemtypes.description AS humanitemtype, categories.description AS humancategorycode
65
my @itemtypes = C4::ItemType->all;
365
    FROM issuingrules
366
    LEFT JOIN itemtypes
367
        ON (itemtypes.itemtype = issuingrules.itemtype)
368
    LEFT JOIN categories
369
        ON (categories.categorycode = issuingrules.categorycode)
370
    WHERE issuingrules.branchcode = ?
371
");
372
$sth2->execute($branch);
373
66
374
while (my $row = $sth2->fetchrow_hashref) {
67
if ( $op eq 'delete' ) {
375
    $row->{'humanitemtype'} ||= $row->{'itemtype'};
68
    DelIssuingRule({
376
    $row->{'default_humanitemtype'} = 1 if $row->{'humanitemtype'} eq '*';
69
        branchcode   => $branchcode,
377
    $row->{'humancategorycode'} ||= $row->{'categorycode'};
70
        categorycode => $input->param('categorycode'),
378
    $row->{'default_humancategorycode'} = 1 if $row->{'humancategorycode'} eq '*';
71
        itemtype     => $input->param('itemtype'),
379
    $row->{'fine'} = sprintf('%.2f', $row->{'fine'});
72
    });
380
    push @row_loop, $row;
381
}
73
}
382
$sth->finish;
74
# save the values entered
383
75
elsif ( $op eq 'add' ) {
384
my @sorted_row_loop = sort by_category_and_itemtype @row_loop;
385
76
386
my $sth_branch_cat;
77
    # Converts '' to undef, so we can have NULL in database fields
387
if ($branch eq "*") {
78
    my $issuingrule;
388
    $sth_branch_cat = $dbh->prepare("
79
    for ( $input->param ) {
389
        SELECT default_borrower_circ_rules.*, categories.description AS humancategorycode
80
        my $v = $input->param($_);
390
        FROM default_borrower_circ_rules
81
        $issuingrule->{$_} = length $v ? $v : undef;
391
        JOIN categories USING (categorycode)
82
    }
392
        
393
    ");
394
    $sth_branch_cat->execute();
395
} else {
396
    $sth_branch_cat = $dbh->prepare("
397
        SELECT branch_borrower_circ_rules.*, categories.description AS humancategorycode
398
        FROM branch_borrower_circ_rules
399
        JOIN categories USING (categorycode)
400
        WHERE branch_borrower_circ_rules.branchcode = ?
401
    ");
402
    $sth_branch_cat->execute($branch);
403
}
404
83
405
my @branch_cat_rules = ();
84
    # We don't want op to be passed to the API
406
while (my $row = $sth_branch_cat->fetchrow_hashref) {
85
    delete $issuingrule->{'op'};
407
    push @branch_cat_rules, $row;
86
87
    # If the (branchcode,categorycode,itemtype) combination already exists...
88
    my @issuingrules = GetIssuingRules({
89
        branchcode      => $issuingrule->{'branchcode'},
90
        categorycode    => $issuingrule->{'categorycode'},
91
        itemtype        => $issuingrule->{'itemtype'},
92
    });
93
94
    # ...we modify the existing rule...
95
    if ( @issuingrules ) {
96
        ModIssuingRule( $issuingrule );
97
#    } elsif (@issuingrules){
98
#        $template->param(confirm=>1);
99
#        $template->param(%$issuingrule);
100
#        foreach (@category_loop) { 
101
#            $_->{selected}="selected" if ($_->{categorycode} eq $issuingrule->{categorycode});
102
#        }
103
#        foreach (@itemtypes) { 
104
#            $_->{selected}="selected" if ($_->{itemtype} eq $issuingrule->{itemtype});
105
#        }
106
    # ...else we add a new rule.
107
    } else {
108
        AddIssuingRule( $issuingrule );
109
    }
408
}
110
}
409
my @sorted_branch_cat_rules = sort { $a->{'humancategorycode'} cmp $b->{'humancategorycode'} } @branch_cat_rules;
410
111
411
# note undef maxissueqty so that template can deal with them
112
# Get the issuing rules list...
412
foreach my $entry (@sorted_branch_cat_rules, @sorted_row_loop) {
113
my @issuingrules = GetIssuingRulesByBranchCode($branchcode);
413
    $entry->{unlimited_maxissueqty} = 1 unless defined($entry->{maxissueqty});
414
}
415
114
416
my @sorted_row_loop = sort by_category_and_itemtype @row_loop;
115
# ...and refine its data, row by row.
116
for my $rule ( @issuingrules ) {
117
    $rule->{'humanitemtype'}             ||= $rule->{'itemtype'};
118
    $rule->{'default_humanitemtype'}       = $rule->{'humanitemtype'} eq '*';
119
    $rule->{'humancategorycode'}         ||= $rule->{'categorycode'};
120
    $rule->{'default_humancategorycode'}   = $rule->{'humancategorycode'} eq '*';
417
121
418
my $sth_branch_item;
122
    # This block is to show herited values in grey.
419
if ($branch eq "*") {
123
    # We juste compare keys from our raw rule, with keys from the computed rule.
420
    $sth_branch_item = $dbh->prepare("
124
    my $computedrule = GetIssuingRule($rule->{'categorycode'}, $rule->{'itemtype'}, $rule->{'branchcode'});
421
        SELECT default_branch_item_rules.*, itemtypes.description AS humanitemtype
125
    for ( keys %$rule ) {
422
        FROM default_branch_item_rules
126
        if ( not defined $rule->{$_} ) {
423
        JOIN itemtypes USING (itemtype)
127
            $rule->{$_} = $computedrule->{$_};
424
    ");
128
            $rule->{"herited_$_"} = 1;
425
    $sth_branch_item->execute();
129
        }
426
} else {
130
    }
427
    $sth_branch_item = $dbh->prepare("
428
        SELECT branch_item_rules.*, itemtypes.description AS humanitemtype
429
        FROM branch_item_rules
430
        JOIN itemtypes USING (itemtype)
431
        WHERE branch_item_rules.branchcode = ?
432
    ");
433
    $sth_branch_item->execute($branch);
434
}
131
}
435
132
436
my @branch_item_rules = ();
133
# Get the issuing rules list...
437
while (my $row = $sth_branch_item->fetchrow_hashref) {
134
my @issuingrules = GetIssuingRulesByBranchCode($branchcode);
438
    push @branch_item_rules, $row;
439
}
440
my @sorted_branch_item_rules = sort { $a->{'humanitemtype'} cmp $b->{'humanitemtype'} } @branch_item_rules;
441
135
442
# note undef holdallowed so that template can deal with them
136
# ...and refine its data, row by row.
443
foreach my $entry (@sorted_branch_item_rules) {
137
for my $rule ( @issuingrules ) {
444
    $entry->{holdallowed_any} = 1 if($entry->{holdallowed} == 2);
138
    $rule->{'humanitemtype'}             ||= $rule->{'itemtype'};
445
    $entry->{holdallowed_same} = 1 if($entry->{holdallowed} == 1);
139
    $rule->{'default_humanitemtype'}       = $rule->{'humanitemtype'} eq '*';
446
}
140
    $rule->{'humancategorycode'}         ||= $rule->{'categorycode'};
141
    $rule->{'default_humancategorycode'}   = $rule->{'humancategorycode'} eq '*';
447
142
448
$template->param(show_branch_cat_rule_form => 1);
143
    # This block is to show herited values in grey.
449
$template->param(branch_item_rule_loop => \@sorted_branch_item_rules);
144
    # We juste compare keys from our raw rule, with keys from the computed rule.
450
$template->param(branch_cat_rule_loop => \@sorted_branch_cat_rules);
145
    my $computedrule = GetIssuingRule($rule->{'categorycode'}, $rule->{'itemtype'}, $rule->{'branchcode'});
146
    for ( keys %$rule ) {
147
        if ( not defined $rule->{$_} ) {
148
            $rule->{$_} = $computedrule->{$_};
149
            $rule->{"herited_$_"} = 1;
150
        }
151
    }
451
152
452
my $sth_defaults;
153
    $rule->{'fine'}                        = sprintf('%.2f', $rule->{'fine'});
453
if ($branch eq "*") {
454
    $sth_defaults = $dbh->prepare("
455
        SELECT *
456
        FROM default_circ_rules
457
    ");
458
    $sth_defaults->execute();
459
} else {
460
    $sth_defaults = $dbh->prepare("
461
        SELECT *
462
        FROM default_branch_circ_rules
463
        WHERE branchcode = ?
464
    ");
465
    $sth_defaults->execute($branch);
466
}
154
}
467
155
468
my $defaults = $sth_defaults->fetchrow_hashref;
469
470
if ($defaults) {
471
    $template->param(default_holdallowed_none => 1) if($defaults->{holdallowed} == 0);
472
    $template->param(default_holdallowed_same => 1) if($defaults->{holdallowed} == 1);
473
    $template->param(default_holdallowed_any => 1) if($defaults->{holdallowed} == 2);
474
    $template->param(default_maxissueqty => $defaults->{maxissueqty});
475
}
476
156
477
$template->param(default_rules => ($defaults ? 1 : 0));
157
$template->param(default_rules => ($defaults ? 1 : 0));
478
158
479
$template->param(categoryloop => \@category_loop,
159
$template->param(
480
                        itemtypeloop => \@itemtypes,
160
    categoryloop  => \@category_loop,
481
                        rules => \@sorted_row_loop,
161
    itemtypeloop  => \@itemtypes,
482
                        branchloop => \@branchloop,
162
    rules         => \@issuingrules,
483
                        humanbranch => ($branch ne '*' ? $branches->{$branch}->{branchname} : ''),
163
    branchloop    => \@branchloop,
484
                        current_branch => $branch,
164
    humanbranch   => ($branchcode ne '*' ? $branches->{$branchcode}->{branchname} : ''),
485
                        definedbranch => scalar(@sorted_row_loop)>0 
165
    branchcode    => $branchcode,
486
                        );
166
    definedbranch => scalar(@issuingrules) > 0,
167
);
168
487
output_html_with_http_headers $input, $cookie, $template->output;
169
output_html_with_http_headers $input, $cookie, $template->output;
488
170
489
exit 0;
171
exit 0;
490
172
491
# sort by patron category, then item type, putting
492
# default entries at the bottom
493
sub by_category_and_itemtype {
494
    unless (by_category($a, $b)) {
495
        return by_itemtype($a, $b);
496
    }
497
}
498
499
sub by_category {
500
    my ($a, $b) = @_;
501
    if ($a->{'default_humancategorycode'}) {
502
        return ($b->{'default_humancategorycode'} ? 0 : 1);
503
    } elsif ($b->{'default_humancategorycode'}) {
504
        return -1;
505
    } else {
506
        return $a->{'humancategorycode'} cmp $b->{'humancategorycode'};
507
    }
508
}
509
510
sub by_itemtype {
511
    my ($a, $b) = @_;
512
    if ($a->{'default_humanitemtype'}) {
513
        return ($b->{'default_humanitemtype'} ? 0 : 1);
514
    } elsif ($b->{'default_humanitemtype'}) {
515
        return -1;
516
    } else {
517
        return $a->{'humanitemtype'} cmp $b->{'humanitemtype'};
518
    }
519
}
(-)a/circ/branchtransfers.pl (-1 / +3 lines)
Lines 87-93 if ( $request eq "KillWaiting" ) { Link Here
87
}
87
}
88
elsif ( $request eq "SetWaiting" ) {
88
elsif ( $request eq "SetWaiting" ) {
89
    my $item = $query->param('itemnumber');
89
    my $item = $query->param('itemnumber');
90
    ModReserveAffect( $item, $borrowernumber );
90
    my $itemhash=C4::Items::GetItem($item);
91
    my ( $reservetype, $reserve ) = C4::Reserves::CheckReserves( undef, $itemhash->{barcode} );
92
    ModReserveAffect( $item, $borrowernumber,$tobranchcd ne C4::Context->userenv->{'branch'}, $reserve->{reservenumber});
91
    $ignoreRs    = 1;
93
    $ignoreRs    = 1;
92
    $setwaiting  = 1;
94
    $setwaiting  = 1;
93
    $reqmessage  = 1;
95
    $reqmessage  = 1;
(-)a/circ/circulation.pl (-62 / +220 lines)
Lines 30-56 use C4::Dates qw/format_date/; Link Here
30
use C4::Branch; # GetBranches
30
use C4::Branch; # GetBranches
31
use C4::Koha;   # GetPrinter
31
use C4::Koha;   # GetPrinter
32
use C4::Circulation;
32
use C4::Circulation;
33
use C4::Overdues qw/CheckBorrowerDebarred/;
33
use C4::Members;
34
use C4::Members;
34
use C4::Biblio;
35
use C4::Biblio;
35
use C4::Reserves;
36
use C4::Reserves;
36
use C4::Context;
37
use C4::Context;
38
use C4::Debug;
37
use CGI::Session;
39
use CGI::Session;
38
40
use C4::Items;
41
use JSON;
42
use YAML;
39
use Date::Calc qw(
43
use Date::Calc qw(
40
  Today
44
  Today
41
  Add_Delta_YM
45
  Add_Delta_YM
42
  Add_Delta_Days
46
  Add_Delta_Days
43
  Date_to_Days
47
  Date_to_Days
44
);
48
);
49
use List::MoreUtils qw/uniq/;
45
50
46
51
47
#
52
#
48
# PARAMETERS READING
53
# PARAMETERS READING
49
#
54
#
50
my $query = new CGI;
55
my $query = new CGI;
51
56
my $dbh = C4::Context->dbh;
52
my $sessionID = $query->cookie("CGISESSID") ;
57
my $remotehost = $query->remote_host();
53
my $session = get_session($sessionID);
58
my $sessionID  = $query->cookie("CGISESSID");
59
my $session    = get_session($sessionID);
54
60
55
# branch and printer are now defined by the userenv
61
# branch and printer are now defined by the userenv
56
# but first we have to check if someone has tried to change them
62
# but first we have to check if someone has tried to change them
Lines 88-96 my ( $template, $loggedinuser, $cookie ) = get_template_and_user ( Link Here
88
94
89
my $branches = GetBranches();
95
my $branches = GetBranches();
90
96
91
my @failedrenews = $query->param('failedrenew');    # expected to be itemnumbers 
97
my @failedrenews  = $query->param('failedrenew');   # expected to be itemnumbers
98
my @failedreturns = $query->param('failedreturn');  # expected to be barcodes
99
my @renewerrors   = $query->param('renewerror');    # expected to be json
100
my @returnerrors  = $query->param('returnerror');   # expected to be json
92
my %renew_failed;
101
my %renew_failed;
93
for (@failedrenews) { $renew_failed{$_} = 1; }
102
my %return_failed;
103
for (@failedrenews) { $renew_failed{$_} = decode_json(shift @renewerrors); }
104
for (@failedreturns) { $return_failed{GetItemnumberFromBarcode($_)} = decode_json(shift @returnerrors); }
94
105
95
my $findborrower = $query->param('findborrower');
106
my $findborrower = $query->param('findborrower');
96
$findborrower =~ s|,| |g;
107
$findborrower =~ s|,| |g;
Lines 125-138 my $organisation = $query->param('organisations'); Link Here
125
my $print          = $query->param('print');
136
my $print          = $query->param('print');
126
my $newexpiry      = $query->param('dateexpiry');
137
my $newexpiry      = $query->param('dateexpiry');
127
my $debt_confirmed = $query->param('debt_confirmed') || 0; # Don't show the debt error dialog twice
138
my $debt_confirmed = $query->param('debt_confirmed') || 0; # Don't show the debt error dialog twice
128
139
$debug && warn $newexpiry;
129
# Check if stickyduedate is turned off
140
# Check if stickyduedate is turned off
130
if ( $barcode ) {
141
if ( $barcode ) {
131
    # was stickyduedate loaded from session?
142
    # was stickyduedate loaded from session?
132
    if ( $stickyduedate && ! $query->param("stickyduedate") ) {
143
    if ( $stickyduedate && ! $query->param("stickyduedate") ) {
133
        $session->clear( 'stickyduedate' );
144
        $session->clear( 'stickyduedate' );
134
        $stickyduedate  = $query->param('stickyduedate');
145
        $stickyduedate  = $query->param('stickyduedate');
135
        $duedatespec    = $query->param('duedatespec');
136
    }
146
    }
137
}
147
}
138
148
Lines 169-175 if($duedatespec_allow){ Link Here
169
    $datedue = $globalduedate if ($globalduedate);
179
    $datedue = $globalduedate if ($globalduedate);
170
}
180
}
171
181
172
my $todaysdate = C4::Dates->new->output('iso');
182
my $todaysdate = C4::Dates->new->output( 'iso' );
173
183
174
# check and see if we should print
184
# check and see if we should print
175
if ( $barcode eq '' && $print eq 'maybe' ) {
185
if ( $barcode eq '' && $print eq 'maybe' ) {
Lines 231-238 if ($borrowernumber) { Link Here
231
241
232
    # Warningdate is the date that the warning starts appearing
242
    # Warningdate is the date that the warning starts appearing
233
    my (  $today_year,   $today_month,   $today_day) = Today();
243
    my (  $today_year,   $today_month,   $today_day) = Today();
234
    my ($warning_year, $warning_month, $warning_day) = split /-/, $borrower->{'dateexpiry'};
244
    my ($warning_year, $warning_month, $warning_day) = split (/-/, $borrower->{'dateexpiry'});
235
    my (  $enrol_year,   $enrol_month,   $enrol_day) = split /-/, $borrower->{'dateenrolled'};
245
    my (  $enrol_year,   $enrol_month,   $enrol_day) = split (/-/, $borrower->{'dateenrolled'});
236
    # Renew day is calculated by adding the enrolment period to today
246
    # Renew day is calculated by adding the enrolment period to today
237
    my (  $renew_year,   $renew_month,   $renew_day);
247
    my (  $renew_year,   $renew_month,   $renew_day);
238
    if ($enrol_year*$enrol_month*$enrol_day>0) {
248
    if ($enrol_year*$enrol_month*$enrol_day>0) {
Lines 250-255 if ($borrowernumber) { Link Here
250
            flagged  => "1",
260
            flagged  => "1",
251
            noissues => "1",
261
            noissues => "1",
252
            expired     => format_date($borrower->{dateexpiry}),
262
            expired     => format_date($borrower->{dateexpiry}),
263
            warning     => 1,
253
            renewaldate => format_date("$renew_year-$renew_month-$renew_day")
264
            renewaldate => format_date("$renew_year-$renew_month-$renew_day")
254
        );
265
        );
255
    }
266
    }
Lines 260-268 if ($borrowernumber) { Link Here
260
    {
271
    {
261
        # borrower card soon to expire warn librarian
272
        # borrower card soon to expire warn librarian
262
        $template->param("warndeparture" => format_date($borrower->{dateexpiry}),
273
        $template->param("warndeparture" => format_date($borrower->{dateexpiry}),
263
        flagged       => "1",);
274
        flagged       => "1", "warning" => 1);
264
        if (C4::Context->preference('ReturnBeforeExpiry')){
275
        if (C4::Context->preference('ReturnBeforeExpiry')){
265
            $template->param("returnbeforeexpiry" => 1);
276
            $template->param("returnbeforeexpiry" => 1, "warning => 1");
266
        }
277
        }
267
    }
278
    }
268
    $template->param(
279
    $template->param(
Lines 270-281 if ($borrowernumber) { Link Here
270
        issuecount   => $issue,
281
        issuecount   => $issue,
271
        finetotal    => $fines
282
        finetotal    => $fines
272
    );
283
    );
284
285
    my $debar = CheckBorrowerDebarred($borrowernumber);
286
    if($debar){
287
        $template->param(userdebarred => 1);
288
        $template->param(debarredcomment => $borrower->{debarredcomment});
289
        if( $debar ne "9999-12-31"){
290
            $template->param(userdebarreddate => C4::Dates::format_date($debar));
291
        }
292
    }
273
}
293
}
274
294
275
#
295
#
276
# STEP 3 : ISSUING
296
# STEP 3 : ISSUING
277
#
297
#
278
#
298
#
299
my $confirm_required = 0;
279
if ($barcode) {
300
if ($barcode) {
280
    # always check for blockers on issuing
301
    # always check for blockers on issuing
281
    my ( $error, $question ) =
302
    my ( $error, $question ) =
Lines 321-328 if ($barcode) { Link Here
321
    # FIXME If the issue is confirmed, we launch another time GetMemberIssuesAndFines, now display the issue count after issue 
342
    # FIXME If the issue is confirmed, we launch another time GetMemberIssuesAndFines, now display the issue count after issue 
322
    my ( $od, $issue, $fines ) = GetMemberIssuesAndFines( $borrowernumber );
343
    my ( $od, $issue, $fines ) = GetMemberIssuesAndFines( $borrowernumber );
323
    $template->param( issuecount   => $issue );
344
    $template->param( issuecount   => $issue );
345
346
    # Is there a circulation note?
347
    my $itemnumber = GetItemnumberFromBarcode($barcode);
348
    my $biblionumber = GetBiblionumberFromItemnumber($itemnumber);
349
    my $record = GetMarcBiblio($biblionumber);
350
    my $frameworkcode = GetFrameworkCode($biblionumber);
351
    my $circnotefield = GetRecordValue('circnote', $record, $frameworkcode);
352
    if (defined @$circnotefield[0]) {
353
	$template->param(circnote => @$circnotefield[0]->{'subfield'});
354
    }
324
}
355
}
325
356
357
358
# Setting the right status if an hold has been confirmed
359
#This should never be used in fact
360
my $resbarcode = $query->param("resbarcode");
361
if ($resbarcode) {
362
        if ( my ( $reservetype, $reserve ) = C4::Reserves::CheckReserves( undef, $resbarcode ) ) {
363
            if ( $reservetype eq "Waiting" || $reservetype eq "Reserved" ) {
364
                my $transfer = C4::Context->userenv->{branch} ne $reserve->{branchcode};
365
                ModReserveAffect( $reserve->{itemnumber}, $reserve->{borrowernumber}, $transfer, $reserve->{"reservenumber"} );
366
            }
367
        }
368
}
369
370
371
326
# reload the borrower info for the sake of reseting the flags.....
372
# reload the borrower info for the sake of reseting the flags.....
327
if ($borrowernumber) {
373
if ($borrowernumber) {
328
    $borrower = GetMemberDetails( $borrowernumber, 0 );
374
    $borrower = GetMemberDetails( $borrowernumber, 0 );
Lines 360-370 if ($borrowernumber) { Link Here
360
        $getreserv{itemcallnumber} = $getiteminfo->{'itemcallnumber'};
406
        $getreserv{itemcallnumber} = $getiteminfo->{'itemcallnumber'};
361
        $getreserv{biblionumber}   = $getiteminfo->{'biblionumber'};
407
        $getreserv{biblionumber}   = $getiteminfo->{'biblionumber'};
362
        $getreserv{waitingat}      = GetBranchName( $num_res->{'branchcode'} );
408
        $getreserv{waitingat}      = GetBranchName( $num_res->{'branchcode'} );
409
	my $materials = $getiteminfo->{'materials'};
410
        $template->param(materials         => $materials);
363
        #         check if we have a waiting status for reservations
411
        #         check if we have a waiting status for reservations
364
        if ( $num_res->{'found'} eq 'W' ) {
412
        if ( $num_res->{'found'} eq 'W' ) {
365
            $getreserv{color}   = 'reserved';
413
            $getreserv{color}   = 'reserved';
366
            $getreserv{waiting} = 1;
414
            $getreserv{waiting} = 1;
367
#     genarate information displaying only waiting reserves
415
#     genarate information displaying only waiting reserves
416
        my @maxpickupdate = $num_res->{'waitingdate'} ? GetMaxPickupDate( $num_res->{'waitingdate'}, $borrowernumber, $num_res ) : '';
417
        $getreserv{'maxpickupdate'} = sprintf( "%d-%02d-%02d", @maxpickupdate );
418
        $getWaitingReserveInfo{'formattedwaitingdate'} = format_date( $getreserv{'maxpickupdate'} );
419
        $getreserv{'formattedwaitingdate'} = format_date( $getreserv{'maxpickupdate'} );
420
368
        $getWaitingReserveInfo{title}        = $getiteminfo->{'title'};
421
        $getWaitingReserveInfo{title}        = $getiteminfo->{'title'};
369
        $getWaitingReserveInfo{biblionumber} = $getiteminfo->{'biblionumber'};
422
        $getWaitingReserveInfo{biblionumber} = $getiteminfo->{'biblionumber'};
370
        $getWaitingReserveInfo{itemtype}     = $itemtypeinfo->{'description'};
423
        $getWaitingReserveInfo{itemtype}     = $itemtypeinfo->{'description'};
Lines 420-470 my $previssues = ''; Link Here
420
my @todaysissues;
473
my @todaysissues;
421
my @previousissues;
474
my @previousissues;
422
475
476
my @borrowers_with_issues;
477
my @relissues;
478
my @relprevissues;
479
my $displayrelissues;
480
## ADDED BY JF: new itemtype issuingrules counter stuff
481
my $issued_itemtypes_count;
482
my @issued_itemtypes_count_loop;
483
423
my $totalprice = 0;
484
my $totalprice = 0;
424
485
425
if ($borrower) {
486
sub build_issue_data {
426
# get each issue of the borrower & separate them in todayissues & previous issues
487
    my $issueslist = shift;
427
    my ($issueslist) = GetPendingIssues($borrower->{'borrowernumber'});
488
    my $relatives = shift;
428
    # split in 2 arrays for today & previous
429
    foreach my $it ( @$issueslist ) {
430
        my $itemtypeinfo = getitemtypeinfo( (C4::Context->preference('item-level_itypes')) ? $it->{'itype'} : $it->{'itemtype'} );
431
        # set itemtype per item-level_itype syspref - FIXME this is an ugly hack
432
        $it->{'itemtype'} = ( C4::Context->preference( 'item-level_itypes' ) ) ? $it->{'itype'} : $it->{'itemtype'};
433
489
434
        ($it->{'charge'}, $it->{'itemtype_charge'}) = GetIssuingCharges(
490
  # split in 2 arrays for today & previous
435
            $it->{'itemnumber'}, $borrower->{'borrowernumber'}
491
    foreach my $it (@$issueslist) {
436
        );
492
        my $itemtypeinfo = getitemtypeinfo( ( C4::Context->preference('item-level_itypes') ) ? $it->{'itype'} : $it->{'itemtype'} );
437
        $it->{'charge'} = sprintf("%.2f", $it->{'charge'});
493
438
        my ($can_renew, $can_renew_error) = CanBookBeRenewed( 
494
	# Getting borrower details
439
            $borrower->{'borrowernumber'},$it->{'itemnumber'}
495
	my $memberdetails = GetMemberDetails($it->{'borrowernumber'});
440
        );
496
	$it->{'borrowername'} = $memberdetails->{'firstname'} . " " . $memberdetails->{'surname'};
441
        $it->{"renew_error_${can_renew_error}"} = 1 if defined $can_renew_error;
497
498
        # set itemtype per item-level_itype syspref - FIXME this is an ugly hack
499
        $it->{'itemtype'} = ( C4::Context->preference('item-level_itypes') ) ? $it->{'itype'} : $it->{'itemtype'};
500
501
        ( $it->{'charge'}, $it->{'itemtype_charge'} ) = GetIssuingCharges( $it->{'itemnumber'}, $borrower->{'borrowernumber'} );
502
        $it->{'charge'} = sprintf( "%.2f", $it->{'charge'} );
503
        my ( $can_renew, $can_renew_error ) = CanBookBeRenewed( $borrower->{'borrowernumber'}, $it->{'itemnumber'} );
504
        if ( defined $can_renew_error->{message} ) {
505
            $it->{ "renew_error_" . $can_renew_error->{message} } = 1;
506
            $it->{'renew_error'} = 1;
507
        }
508
        $it->{renewals} ||= 0;
509
        $it->{$_} = $can_renew_error->{$_} for (qw(renewalsallowed reserves));
442
        my ( $restype, $reserves ) = CheckReserves( $it->{'itemnumber'} );
510
        my ( $restype, $reserves ) = CheckReserves( $it->{'itemnumber'} );
443
        $it->{'can_renew'} = $can_renew;
511
        if ($restype) {
444
        $it->{'can_confirm'} = !$can_renew && !$restype;
512
            $it->{'reserved'} = 1;
445
        $it->{'renew_error'} = $restype;
513
            $it->{$restype} = 1;
446
        $it->{'checkoutdate'} = C4::Dates->new($it->{'issuedate'},'iso')->output('syspref');
514
        }
515
        $it->{'can_renew'}    = $can_renew;
516
        $it->{'can_confirm'}  = !$can_renew && !$restype;
517
        $it->{'renew_error'}  = $restype;
518
        $it->{'checkoutdate'} = $it->{'issuedate'};
447
519
448
        $totalprice += $it->{'replacementprice'};
520
        $totalprice += $it->{'replacementprice'};
449
        $it->{'itemtype'} = $itemtypeinfo->{'description'};
521
        $it->{'itemtype'}       = $itemtypeinfo->{'description'};
450
        $it->{'itemtype_image'} = $itemtypeinfo->{'imageurl'};
522
        $it->{'itemtype_image'} = $itemtypeinfo->{'imageurl'};
451
        $it->{'dd'} = format_date($it->{'date_due'});
523
        $it->{'dd'}             = format_date( $it->{'date_due'} );
452
        $it->{'displaydate'} = format_date($it->{'issuedate'});
524
        $it->{'displaydate'}    = format_date( $it->{'issuedate'} );
453
        $it->{'od'} = ( $it->{'date_due'} lt $todaysdate ) ? 1 : 0 ;
525
        ( $it->{'author'} eq '' ) and $it->{'author'} = ' ';
454
        ($it->{'author'} eq '') and $it->{'author'} = ' ';
526
        if ( defined( $return_failed{ $it->{'itemnumber'} } ) ) {
455
        $it->{'renew_failed'} = $renew_failed{$it->{'itemnumber'}};
527
            $it->{ 'return_error_' . $return_failed{ $it->{'itemnumber'} }->{message} } = 1;
456
528
            delete $return_failed{ $it->{'itemnumber'} };
457
        if ( $todaysdate eq $it->{'issuedate'} or $todaysdate eq $it->{'lastreneweddate'} ) {
458
            push @todaysissues, $it;
459
        } else {
460
            push @previousissues, $it;
461
        }
529
        }
530
        if ( defined( $renew_failed{ $it->{'itemnumber'} } ) ) {
531
            $it->{ 'renew_error_' . $renew_failed{ $it->{'itemnumber'} }->{message} } = 1;
532
        }
533
        $it->{'return_failed'} = defined( $return_failed{ $it->{'itemnumber'} } );
534
        $it->{'branchdisplay'} = GetBranchName( ( C4::Context->preference('HomeOrHoldingBranch') eq 'holdingbranch' ) ? $it->{'holdingbranch'} : $it->{'homebranch'} );
535
536
        # ADDED BY JF: NEW ITEMTYPE COUNT DISPLAY
537
        $issued_itemtypes_count->{ $it->{'itemtype'} }++;
538
	if ( $todaysdate eq $it->{'checkoutdate'} or $todaysdate eq $it->{'lastreneweddate'} ) {
539
	    (!$relatives) ? push @todaysissues, $it : push @relissues, $it;
540
	} else {
541
	    (!$relatives) ? push @previousissues, $it : push @relprevissues, $it;
542
	}
543
462
    }
544
    }
463
    if ( C4::Context->preference( "todaysIssuesDefaultSortOrder" ) eq 'asc' ) {
545
464
        @todaysissues   = sort { $a->{'timestamp'} cmp $b->{'timestamp'} } @todaysissues;
546
}
465
    }
547
466
    else {
548
if ($borrower) {
467
        @todaysissues   = sort { $b->{'timestamp'} cmp $a->{'timestamp'} } @todaysissues;
549
550
    # Getting borrower relatives
551
    my @relborrowernumbers = GetMemberRelatives($borrower->{'borrowernumber'});
552
    #push @borrowernumbers, $borrower->{'borrowernumber'};
553
554
    # get each issue of the borrower & separate them in todayissues & previous issues
555
    my ($issueslist) = GetPendingIssues($borrower->{'borrowernumber'});
556
    my ($relissueslist) = GetPendingIssues(@relborrowernumbers);
557
558
    build_issue_data($issueslist, 0);
559
    build_issue_data($relissueslist, 1);
560
  
561
    $displayrelissues = scalar($relissueslist);
562
563
    if ( C4::Context->preference("todaysIssuesDefaultSortOrder") eq 'asc' ) {
564
        @todaysissues = sort { $a->{'timestamp'} cmp $b->{'timestamp'} } @todaysissues;
565
    } else {
566
        @todaysissues = sort { $b->{'timestamp'} cmp $a->{'timestamp'} } @todaysissues;
468
    }
567
    }
469
    if ( C4::Context->preference( "previousIssuesDefaultSortOrder" ) eq 'asc' ){
568
    if ( C4::Context->preference( "previousIssuesDefaultSortOrder" ) eq 'asc' ){
470
        @previousissues = sort { $a->{'date_due'} cmp $b->{'date_due'} } @previousissues;
569
        @previousissues = sort { $a->{'date_due'} cmp $b->{'date_due'} } @previousissues;
Lines 473-479 if ($borrower) { Link Here
473
        @previousissues = sort { $b->{'date_due'} cmp $a->{'date_due'} } @previousissues;
572
        @previousissues = sort { $b->{'date_due'} cmp $a->{'date_due'} } @previousissues;
474
    }
573
    }
475
}
574
}
575
my @reserveswaiting;
576
foreach my $itemnumber (keys %return_failed){
577
   next unless $return_failed{$itemnumber}->{'reservesdata'};
578
   my $hashdata=$return_failed{$itemnumber}->{'reservesdata'};
579
   $hashdata->{circborrowernumber}=$borrowernumber;
580
   $hashdata->{script_name}=$query->script_name();
581
   push @reserveswaiting, $hashdata if (%$hashdata);
582
}
583
584
$template->param(reserves_waiting=>\@reserveswaiting);
585
586
#### ADDED BY JF FOR COUNTS BY ITEMTYPE RULES
587
# FIXME: This should utilize all the issuingrules options rather than just the defaults
588
# and it should be moved to a module
589
590
# how many of each is allowed?
591
my $issueqty_sth = $dbh->prepare(
592
    'SELECT itemtypes.description AS description,issuingrules.itemtype,maxissueqty ' .
593
    'FROM issuingrules LEFT JOIN itemtypes ON (itemtypes.itemtype=issuingrules.itemtype) ' .
594
    'WHERE categorycode=?'
595
);
596
$issueqty_sth->execute(q{*}); # This is a literal asterisk, not a wildcard.
597
598
while ( my $data = $issueqty_sth->fetchrow_hashref() ) {
599
600
    # subtract how many of each this borrower has
601
    $data->{'count'} = $issued_itemtypes_count->{ $data->{'description'} };  
602
    $data->{'left'}  =
603
      ( $data->{'maxissueqty'} -
604
          $issued_itemtypes_count->{ $data->{'description'} } );
605
606
    # can't have a negative number of remaining
607
    if ( $data->{'left'} < 0 ) { $data->{'left'} = '0' }
608
    if ( $data->{maxissueqty} <= $data->{count} ) {
609
        $data->{flag} = 1;
610
    }
611
    if ( $data->{maxissueqty} > 0 && $data->{itemtype} !~m/^(\*|CIRC)$/ ) {
612
        push @issued_itemtypes_count_loop, $data;
613
    }
614
}
476
615
616
#### / JF
477
617
478
my @values;
618
my @values;
479
my %labels;
619
my %labels;
Lines 503-508 if ($borrowerslist) { Link Here
503
643
504
#title
644
#title
505
my $flags = $borrower->{'flags'};
645
my $flags = $borrower->{'flags'};
646
    $debug && warn Dump($flags);
506
foreach my $flag ( sort keys %$flags ) {
647
foreach my $flag ( sort keys %$flags ) {
507
    $template->param( flagged=> 1);
648
    $template->param( flagged=> 1);
508
    $flags->{$flag}->{'message'} =~ s#\n#<br />#g;
649
    $flags->{$flag}->{'message'} =~ s#\n#<br />#g;
Lines 512-531 foreach my $flag ( sort keys %$flags ) { Link Here
512
            noissues => 'true',
653
            noissues => 'true',
513
        );
654
        );
514
        if ( $flag eq 'GNA' ) {
655
        if ( $flag eq 'GNA' ) {
515
            $template->param( gna => 'true' );
656
            $template->param( gna => 'true', gonenoaddresscomment => $borrower->{'gonenoaddresscomment'}, warning => 1 );
516
        }
657
        }
517
        elsif ( $flag eq 'LOST' ) {
658
        elsif ( $flag eq 'LOST' ) {
518
            $template->param( lost => 'true' );
659
            $template->param( lost => 'true', lostcomment => $borrower->{'lostcomment'}, warning => 1 );
519
        }
660
        } elsif ( $flag eq 'DEBARRED' ) {
520
        elsif ( $flag eq 'DBARRED' ) {
661
            $template->param( userdebarred => 'true', warning => 1, userdebarreddate=> format_date($flags->{DEBARRED}->{dateend}),debardebarredcomment=>$borrower->{'debarredcomment'});
521
            $template->param( dbarred => 'true' );
662
        } elsif ( $flag eq 'CHARGES' ) {
522
        }
523
        elsif ( $flag eq 'CHARGES' ) {
524
            $template->param(
663
            $template->param(
525
                charges    => 'true',
664
                charges    => 'true',
526
                chargesmsg => $flags->{'CHARGES'}->{'message'},
665
                chargesmsg => $flags->{'CHARGES'}->{'message'},
527
                chargesamount => $flags->{'CHARGES'}->{'amount'},
666
                chargesamount => $flags->{'CHARGES'}->{'amount'},
528
                charges_is_blocker => 1
667
                charges_is_blocker => 1,
668
                warning => 1
529
            );
669
            );
530
        }
670
        }
531
        elsif ( $flag eq 'CREDITS' ) {
671
        elsif ( $flag eq 'CREDITS' ) {
Lines 533-538 foreach my $flag ( sort keys %$flags ) { Link Here
533
                credits    => 'true',
673
                credits    => 'true',
534
                creditsmsg => $flags->{'CREDITS'}->{'message'},
674
                creditsmsg => $flags->{'CREDITS'}->{'message'},
535
                creditsamount => sprintf("%.02f", -($flags->{'CREDITS'}->{'amount'})), # from patron's pov
675
                creditsamount => sprintf("%.02f", -($flags->{'CREDITS'}->{'amount'})), # from patron's pov
676
		        warning => 1
536
            );
677
            );
537
        }
678
        }
538
    }
679
    }
Lines 543-548 foreach my $flag ( sort keys %$flags ) { Link Here
543
                flagged    => 1,
684
                flagged    => 1,
544
                chargesmsg => $flags->{'CHARGES'}->{'message'},
685
                chargesmsg => $flags->{'CHARGES'}->{'message'},
545
                chargesamount => $flags->{'CHARGES'}->{'amount'},
686
                chargesamount => $flags->{'CHARGES'}->{'amount'},
687
                warning => 1
546
            );
688
            );
547
        }
689
        }
548
        elsif ( $flag eq 'CREDITS' ) {
690
        elsif ( $flag eq 'CREDITS' ) {
Lines 550-562 foreach my $flag ( sort keys %$flags ) { Link Here
550
                credits    => 'true',
692
                credits    => 'true',
551
                creditsmsg => $flags->{'CREDITS'}->{'message'},
693
                creditsmsg => $flags->{'CREDITS'}->{'message'},
552
                creditsamount => sprintf("%.02f", -($flags->{'CREDITS'}->{'amount'})), # from patron's pov
694
                creditsamount => sprintf("%.02f", -($flags->{'CREDITS'}->{'amount'})), # from patron's pov
695
		warning => 1
553
            );
696
            );
554
        }
697
        }
555
        elsif ( $flag eq 'ODUES' ) {
698
        elsif ( $flag eq 'ODUES' ) {
556
            $template->param(
699
            $template->param(
557
                odues    => 'true',
700
                odues    => 'true',
558
                flagged  => 1,
701
                flagged  => 1,
559
                oduesmsg => $flags->{'ODUES'}->{'message'}
702
                oduesmsg => $flags->{'ODUES'}->{'message'},
703
                warning => 1
560
            );
704
            );
561
705
562
            my $items = $flags->{$flag}->{'itemlist'};
706
            my $items = $flags->{$flag}->{'itemlist'};
Lines 611-619 if($lib_messages_loop){ $template->param(flagged => 1 ); } Link Here
611
my $bor_messages_loop = GetMessages( $borrowernumber, 'B', $branch );
755
my $bor_messages_loop = GetMessages( $borrowernumber, 'B', $branch );
612
if($bor_messages_loop){ $template->param(flagged => 1 ); }
756
if($bor_messages_loop){ $template->param(flagged => 1 ); }
613
757
758
614
# Computes full borrower address
759
# Computes full borrower address
615
my (undef, $roadttype_hashref) = &GetRoadTypes();
760
my (undef, $roadttype_hashref) = &GetRoadTypes();
616
my $address = $borrower->{'streetnumber'}.' '.$roadttype_hashref->{$borrower->{'streettype'}}.' '.$borrower->{'address'};
761
my $address = $borrower->{'streetnumber'}.' ' if ($borrower->{'streetnumber'});
762
$address    .= $roadttype_hashref->{$borrower->{'streettype'}}.' ' if ( $roadttype_hashref->{$borrower->{'streettype'}});
763
$address    .= $borrower->{'address'};
764
765
766
$duedatespec = "" if not ($stickyduedate or scalar $confirm_required);
767
my @categories = C4::Category->all;
617
768
618
my $fast_cataloging = 0;
769
my $fast_cataloging = 0;
619
    if (defined getframeworkinfo('FA')) {
770
    if (defined getframeworkinfo('FA')) {
Lines 633-641 $template->param( Link Here
633
    printername       => $printer,
784
    printername       => $printer,
634
    firstname         => $borrower->{'firstname'},
785
    firstname         => $borrower->{'firstname'},
635
    surname           => $borrower->{'surname'},
786
    surname           => $borrower->{'surname'},
636
    dateexpiry        => format_date($newexpiry),
787
    printer                     => $printer,
788
    printername                 => $printer,
637
    expiry            => format_date($borrower->{'dateexpiry'}),
789
    expiry            => format_date($borrower->{'dateexpiry'}),
638
    categorycode      => $borrower->{'categorycode'},
639
    categoryname      => $borrower->{description},
790
    categoryname      => $borrower->{description},
640
    address           => $address,
791
    address           => $address,
641
    address2          => $borrower->{'address2'},
792
    address2          => $borrower->{'address2'},
Lines 646-652 $template->param( Link Here
646
    zipcode           => $borrower->{'zipcode'},
797
    zipcode           => $borrower->{'zipcode'},
647
    country           => $borrower->{'country'},
798
    country           => $borrower->{'country'},
648
    phone             => $borrower->{'phone'} || $borrower->{'mobile'},
799
    phone             => $borrower->{'phone'} || $borrower->{'mobile'},
649
    cardnumber        => $borrower->{'cardnumber'},
650
    amountold         => $amountold,
800
    amountold         => $amountold,
651
    barcode           => $barcode,
801
    barcode           => $barcode,
652
    stickyduedate     => $stickyduedate,
802
    stickyduedate     => $stickyduedate,
Lines 657-662 $template->param( Link Here
657
    totaldue          => sprintf('%.2f', $total),
807
    totaldue          => sprintf('%.2f', $total),
658
    todayissues       => \@todaysissues,
808
    todayissues       => \@todaysissues,
659
    previssues        => \@previousissues,
809
    previssues        => \@previousissues,
810
    relissues			=> \@relissues,
811
    relprevissues		=> \@relprevissues,
812
    displayrelissues		=> $displayrelissues,
660
    inprocess         => $inprocess,
813
    inprocess         => $inprocess,
661
    memberofinstution => $member_of_institution,
814
    memberofinstution => $member_of_institution,
662
    CGIorganisations  => $CGIorganisations,
815
    CGIorganisations  => $CGIorganisations,
Lines 664-671 $template->param( Link Here
664
    circview => 1,
817
    circview => 1,
665
    soundon           => C4::Context->preference("SoundOn"),
818
    soundon           => C4::Context->preference("SoundOn"),
666
    fast_cataloging   => $fast_cataloging,
819
    fast_cataloging   => $fast_cataloging,
820
    categoryloop      => \@categories,
667
);
821
);
668
822
823
$template->param(newexpiry => format_date($newexpiry)) if (defined $newexpiry);
824
825
SetMemberInfosInTemplate($borrowernumber, $template);
826
669
# save stickyduedate to session
827
# save stickyduedate to session
670
if ($stickyduedate) {
828
if ($stickyduedate) {
671
    $session->param( 'stickyduedate', $duedatespec );
829
    $session->param( 'stickyduedate', $duedatespec );
(-)a/circ/returns.pl (-30 / +107 lines)
Lines 36-51 use C4::Circulation; Link Here
36
use C4::Dates qw/format_date/;
36
use C4::Dates qw/format_date/;
37
use Date::Calc qw/Add_Delta_Days/;
37
use Date::Calc qw/Add_Delta_Days/;
38
use C4::Calendar;
38
use C4::Calendar;
39
use C4::Budgets qw/GetCurrency/;
39
use C4::Print;
40
use C4::Print;
40
use C4::Reserves;
41
use C4::Reserves;
41
use C4::Biblio;
42
use C4::Biblio;
42
use C4::Items;
43
use C4::Items;
43
use C4::Members;
44
use C4::Members;
45
use C4::Overdues qw/CheckBorrowerDebarred/;
44
use C4::Branch; # GetBranches GetBranchName
46
use C4::Branch; # GetBranches GetBranchName
45
use C4::Koha;   # FIXME : is it still useful ?
47
use C4::Koha;   # FIXME : is it still useful ?
46
use C4::RotatingCollections;
48
use C4::RotatingCollections;
49
use C4::Debug;
47
50
48
my $query = new CGI;
51
my $query = new CGI;
52
my $remotehost = $query->remote_host();
49
53
50
if (!C4::Context->userenv){
54
if (!C4::Context->userenv){
51
    my $sessionID = $query->cookie("CGISESSID");
55
    my $sessionID = $query->cookie("CGISESSID");
Lines 133-138 if ( $query->param('resbarcode') ) { Link Here
133
    my $item           = $query->param('itemnumber');
137
    my $item           = $query->param('itemnumber');
134
    my $borrowernumber = $query->param('borrowernumber');
138
    my $borrowernumber = $query->param('borrowernumber');
135
    my $resbarcode     = $query->param('resbarcode');
139
    my $resbarcode     = $query->param('resbarcode');
140
    my $reservenumber = $query->param('reservenumber');
136
    my $diffBranchReturned = $query->param('diffBranch');
141
    my $diffBranchReturned = $query->param('diffBranch');
137
    my $iteminfo   = GetBiblioFromItemNumber($item);
142
    my $iteminfo   = GetBiblioFromItemNumber($item);
138
    # fix up item type for display
143
    # fix up item type for display
Lines 140-157 if ( $query->param('resbarcode') ) { Link Here
140
    my $diffBranchSend = ($userenv_branch ne $diffBranchReturned) ? $diffBranchReturned : undef;
145
    my $diffBranchSend = ($userenv_branch ne $diffBranchReturned) ? $diffBranchReturned : undef;
141
# diffBranchSend tells ModReserveAffect whether document is expected in this library or not,
146
# diffBranchSend tells ModReserveAffect whether document is expected in this library or not,
142
# i.e., whether to apply waiting status
147
# i.e., whether to apply waiting status
143
    ModReserveAffect( $item, $borrowernumber, $diffBranchSend);
148
    ModReserveAffect( $item, $borrowernumber, $diffBranchSend, $reservenumber );
149
144
#   check if we have other reserves for this document, if we have a return send the message of transfer
150
#   check if we have other reserves for this document, if we have a return send the message of transfer
145
    my ( $messages, $nextreservinfo ) = GetOtherReserves($item);
151
    my ( $reservemessages, $nextreservinfo ) = GetOtherReserves($item);
146
152
147
    my ($borr) = GetMemberDetails( $nextreservinfo, 0 );
153
    my ($borr) = GetMemberDetails( $nextreservinfo, 0 );
148
    my $name   = $borr->{'surname'} . ", " . $borr->{'title'} . " " . $borr->{'firstname'};
154
    my $name   = $borr->{'surname'} . ", " . $borr->{'title'} . " " . $borr->{'firstname'};
149
    if ( $messages->{'transfert'} ) {
155
    if ( $reservemessages->{'transfert'} ) {
150
        $template->param(
156
        $template->param(
151
            itemtitle      => $iteminfo->{'title'},
157
            itemtitle      => $iteminfo->{'title'},
152
            itembiblionumber => $iteminfo->{'biblionumber'},
158
            itembiblionumber => $iteminfo->{'biblionumber'},
153
            iteminfo       => $iteminfo->{'author'},
159
            iteminfo       => $iteminfo->{'author'},
154
            tobranchname   => GetBranchName($messages->{'transfert'}),
160
            tobranchname   => GetBranchName($reservemessages->{'transfert'}),
155
            name           => $name,
161
            name           => $name,
156
            borrowernumber => $borrowernumber,
162
            borrowernumber => $borrowernumber,
157
            borcnum        => $borr->{'cardnumber'},
163
            borcnum        => $borr->{'cardnumber'},
Lines 167-176 my $returned = 0; Link Here
167
my $messages;
173
my $messages;
168
my $issueinformation;
174
my $issueinformation;
169
my $itemnumber;
175
my $itemnumber;
176
my $biblio;
170
my $barcode     = $query->param('barcode');
177
my $barcode     = $query->param('barcode');
171
my $exemptfine  = $query->param('exemptfine');
178
my $exemptfine  = $query->param('exemptfine');
172
my $dropboxmode = $query->param('dropboxmode');
179
my $dropboxmode = $query->param('dropboxmode');
173
my $dotransfer  = $query->param('dotransfer');
180
my $dotransfer  = $query->param('dotransfer');
181
my $override    = $query->param('override');
174
my $calendar    = C4::Calendar->new( branchcode => $userenv_branch );
182
my $calendar    = C4::Calendar->new( branchcode => $userenv_branch );
175
#dropbox: get last open day (today - 1)
183
#dropbox: get last open day (today - 1)
176
my $today       = C4::Dates->new();
184
my $today       = C4::Dates->new();
Lines 184-190 if ($dotransfer){ Link Here
184
}
192
}
185
193
186
# actually return book and prepare item table.....
194
# actually return book and prepare item table.....
187
if ($barcode) {
195
if ($barcode and not $query->param('cancel')) {
188
    $barcode =~ s/^\s*|\s*$//g; # remove leading/trailing whitespace
196
    $barcode =~ s/^\s*|\s*$//g; # remove leading/trailing whitespace
189
    $barcode = barcodedecode($barcode) if C4::Context->preference('itemBarcodeInputFilter');
197
    $barcode = barcodedecode($barcode) if C4::Context->preference('itemBarcodeInputFilter');
190
    $itemnumber = GetItemnumberFromBarcode($barcode);
198
    $itemnumber = GetItemnumberFromBarcode($barcode);
Lines 207-217 if ($barcode) { Link Here
207
# save the return
215
# save the return
208
#
216
#
209
    ( $returned, $messages, $issueinformation, $borrower ) =
217
    ( $returned, $messages, $issueinformation, $borrower ) =
210
      AddReturn( $barcode, $userenv_branch, $exemptfine, $dropboxmode);     # do the return
218
      AddReturn( $barcode, $userenv_branch, $exemptfine, $dropboxmode,$override);     # do the return
211
    my $homeorholdingbranchreturn = C4::Context->preference('HomeOrHoldingBranchReturn') or 'homebranch';
219
    my $homeorholdingbranchreturn = C4::Context->preference('HomeOrHoldingBranchReturn') or 'homebranch';
212
220
221
            my @ips=split /,|\|/, C4::Context->preference("CI-3M:AuthorizedIPs");
222
            #my $pid=fork();
223
            #unless($pid && $remotehost=~qr(^$ips$)){
224
            #if (!$pid && any{ $remotehost eq $_ }@ips ){
225
            if (any{ $remotehost eq $_ }@ips ){
226
                system("../services/magnetise.pl $remotehost in");
227
                #die 0;
228
            }
213
    # get biblio description
229
    # get biblio description
214
    my $biblio = GetBiblioFromItemNumber($itemnumber);
230
    $biblio = GetBiblioFromItemNumber($itemnumber);
215
    # fix up item type for display
231
    # fix up item type for display
216
    $biblio->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $biblio->{'itype'} : $biblio->{'itemtype'};
232
    $biblio->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $biblio->{'itype'} : $biblio->{'itemtype'};
217
233
Lines 249-255 if ($barcode) { Link Here
249
        }
265
        }
250
266
251
    }
267
    }
252
    elsif ( !$messages->{'BadBarcode'} ) {
268
    elsif ( !$messages->{'BadBarcode'} and ! $messages->{'Wrongbranch'} ) {
253
        $input{duedate}   = 0;
269
        $input{duedate}   = 0;
254
        $returneditems{0} = $barcode;
270
        $returneditems{0} = $barcode;
255
        $riduedate{0}     = 0;
271
        $riduedate{0}     = 0;
Lines 267-272 if ($barcode) { Link Here
267
}
283
}
268
$template->param( inputloop => \@inputloop );
284
$template->param( inputloop => \@inputloop );
269
285
286
287
# Is there a circulation note?
288
my $itemnumber = GetItemnumberFromBarcode($barcode);
289
my $biblionumber = GetBiblionumberFromItemnumber($itemnumber);
290
my $record = GetMarcBiblio($biblionumber);
291
my $frameworkcode = GetFrameworkCode($biblionumber);
292
my $circnotefield = GetRecordValue('circnote', $record, $frameworkcode);
293
if (defined @$circnotefield[0]) {
294
   $template->param(circnote => @$circnotefield[0]->{'subfield'});
295
}
296
297
270
my $found    = 0;
298
my $found    = 0;
271
my $waiting  = 0;
299
my $waiting  = 0;
272
my $reserved = 0;
300
my $reserved = 0;
Lines 290-298 if ( $messages->{'NeedsTransfer'} ){ Link Here
290
}
318
}
291
319
292
if ( $messages->{'Wrongbranch'} ){
320
if ( $messages->{'Wrongbranch'} ){
293
    $template->param(
321
	$template->param(
294
        wrongbranch => 1,
322
		wrongbranch => $branches->{$messages->{'Wrongbranch'}->{'Wrongbranch'}}->{'branchname'},
295
    );
323
		rightbranch => $branches->{$messages->{'Wrongbranch'}->{'Rightbranch'}}->{'branchname'},
324
		barcode     => $barcode,
325
		exemptfine  => $exemptfine,
326
		dropboxmode => $dropboxmode,
327
	);
296
}
328
}
297
329
298
# case of wrong transfert, if the document wasn't transfered to the right library (according to branchtransfer (tobranch) BDD)
330
# case of wrong transfert, if the document wasn't transfered to the right library (according to branchtransfer (tobranch) BDD)
Lines 347-353 if ( $messages->{'ResFound'}) { Link Here
347
                reserved     => 1,
379
                reserved     => 1,
348
            );
380
            );
349
        }
381
        }
350
382
        my $debarred = CheckBorrowerDebarred($reserve->{borrowernumber});
351
        # same params for Waiting or Reserved
383
        # same params for Waiting or Reserved
352
        $template->param(
384
        $template->param(
353
            found          => 1,
385
            found          => 1,
Lines 364-380 if ( $messages->{'ResFound'}) { Link Here
364
            borcity        => $borr->{'city'},
396
            borcity        => $borr->{'city'},
365
            borzip         => $borr->{'zipcode'},
397
            borzip         => $borr->{'zipcode'},
366
            borcnum        => $borr->{'cardnumber'},
398
            borcnum        => $borr->{'cardnumber'},
367
            debarred       => $borr->{'debarred'},
399
            debarred       => $debarred,
368
            gonenoaddress  => $borr->{'gonenoaddress'},
400
            gonenoaddress  => $borr->{'gonenoaddress'},
369
            barcode        => $barcode,
401
            barcode        => $barcode,
370
            destbranch     => $reserve->{'branchcode'},
402
            reservenumber  => $reserve->{'reservenumber'},
403
            destbranch	   => $reserve->{'branchcode'},
371
            borrowernumber => $reserve->{'borrowernumber'},
404
            borrowernumber => $reserve->{'borrowernumber'},
372
            itemnumber     => $reserve->{'itemnumber'},
405
            itemnumber     => $reserve->{'itemnumber'},
373
            reservenotes   => $reserve->{'reservenotes'},
406
            reservenotes   => $reserve->{'reservenotes'},
374
        );
407
        );
375
    } # else { ; }  # error?
408
    } # else { ; }  # error?
376
}
409
}
377
410
$borrower->{'flags'}= C4::Members::patronflags($borrower);
378
# Error Messages
411
# Error Messages
379
my @errmsgloop;
412
my @errmsgloop;
380
foreach my $code ( keys %$messages ) {
413
foreach my $code ( keys %$messages ) {
Lines 400-405 foreach my $code ( keys %$messages ) { Link Here
400
    elsif ( $code eq 'WasTransfered' ) {
433
    elsif ( $code eq 'WasTransfered' ) {
401
        ;    # FIXME... anything to do here?
434
        ;    # FIXME... anything to do here?
402
    }
435
    }
436
    elsif ( $code eq 'NotForLoan' ) {
437
        my $fw               = GetFrameworkCode($biblio->{'biblionumber'});
438
        my $category         = GetAuthValCode('items.notforloan',$fw);
439
        my $authorizedvalues = GetAuthorisedValues($category, $messages->{$code});
440
441
        foreach my $authvalue (@$authorizedvalues){
442
            $err{notforloan} = $authvalue->{lib} if $authvalue->{'authorised_value'} eq $messages->{$code};
443
        }
444
    }
445
    elsif ( $code eq 'Damaged' ) {
446
        my $fw               = GetFrameworkCode($biblio->{'biblionumber'});
447
        my $category         = GetAuthValCode('items.damaged',$fw);
448
        my $authorizedvalues = GetAuthorisedValues($category, $messages->{$code});
449
450
        foreach my $authvalue (@$authorizedvalues){
451
            $err{damaged} = $authvalue->{lib} if $authvalue->{'authorised_value'} eq $messages->{$code};
452
        }
453
    }
454
    elsif( $code eq 'Debarred' ){
455
        $err{debarred}            = format_date($messages->{'Debarred'});
456
        $err{debarcardnumber}     = $borrower->{cardnumber};
457
        $err{debarborrowernumber} = $borrower->{borrowernumber};
458
        $err{debarname}           = "$borrower->{firstname} $borrower->{surname}";
459
    }
460
    elsif( $code eq 'HaveFines' ){
461
        $err{havefines}       = $borrower->{'flags'}->{'CHARGES'}->{'amount'} . %{GetCurrency()}->{symbol};
462
        $err{finecardnumber} = $borrower->{cardnumber};
463
        $err{finename}       = "$borrower->{firstname} $borrower->{surname}";
464
    }
403
    elsif ( $code eq 'wthdrawn' ) {
465
    elsif ( $code eq 'wthdrawn' ) {
404
        $err{withdrawn} = 1;
466
        $err{withdrawn} = 1;
405
        $exit_required_p = 1;
467
        $exit_required_p = 1;
Lines 421-427 foreach my $code ( keys %$messages ) { Link Here
421
    }
483
    }
422
    elsif ( $code eq 'Wrongbranch' ) {
484
    elsif ( $code eq 'Wrongbranch' ) {
423
    }
485
    }
424
425
    else {
486
    else {
426
        die "Unknown error code $code";    # note we need all the (empty) elsif's above, or we die.
487
        die "Unknown error code $code";    # note we need all the (empty) elsif's above, or we die.
427
        # This forces the issue of staying in sync w/ Circulation.pm
488
        # This forces the issue of staying in sync w/ Circulation.pm
Lines 435-448 $template->param( errmsgloop => \@errmsgloop ); Link Here
435
496
436
# patrontable ....
497
# patrontable ....
437
if ($borrower) {
498
if ($borrower) {
438
    my $flags = $borrower->{'flags'};
439
    my @flagloop;
499
    my @flagloop;
440
    my $flagset;
500
    my $flags=$borrower->{flags};
441
    foreach my $flag ( sort keys %$flags ) {
501
    foreach my $flag ( sort keys %$flags ) {
442
        my %flaginfo;
502
        my %flaginfo;
443
        unless ($flagset) { $flagset = 1; }
444
        $flaginfo{redfont} = ( $flags->{$flag}->{'noissues'} );
445
        $flaginfo{flag}    = $flag;
446
        if ( $flag eq 'CHARGES' ) {
503
        if ( $flag eq 'CHARGES' ) {
447
            $flaginfo{msg}            = $flag;
504
            $flaginfo{msg}            = $flag;
448
            $flaginfo{charges}        = 1;
505
            $flaginfo{charges}        = 1;
Lines 457-470 if ($borrower) { Link Here
457
            foreach my $item (@$items) {
514
            foreach my $item (@$items) {
458
                my $biblio = GetBiblioFromItemNumber( $item->{'itemnumber'});
515
                my $biblio = GetBiblioFromItemNumber( $item->{'itemnumber'});
459
                push @waitingitemloop, {
516
                push @waitingitemloop, {
460
                    biblionum => $biblio->{'biblionumber'},
517
                    biblionumber=> $biblio->{'biblionumber'},
461
                    barcode   => $biblio->{'barcode'},
518
                    author      => $biblio->{'author'},
462
                    title     => $biblio->{'title'},
519
                    itemtype    => $item->{'ccode'},
463
                    brname    => $branches->{ $biblio->{'holdingbranch'} }->{'branchname'},
520
                    reservedate => format_date($item->{'reservedate'}),
521
                    waitingdate => format_date($item->{'waitingdate'}),
522
                    barcode     => $item->{'barcode'},
523
                    maxpickupdate=> format_date( sprintf("%d-%02d-%02d",GetMaxPickupDate($item->{'waitingdate'}, $borrower->{borrowernumber},$item ))),
524
                    title       => $biblio->{'title'},
525
                    brname      => $branches->{ $item->{'branchcode'} }->{'branchname'},
526
                    waitinghere => ($item->{'branchcode'} eq $userenv_branch)
464
                };
527
                };
465
            }
528
            }
466
            $flaginfo{itemloop} = \@waitingitemloop;
529
            $flaginfo{itemloop} = \@waitingitemloop;
467
        }
530
        }
531
        elsif ( $flag =~ /DEBARRED|LOST|GNA/ ) {
532
            if ($flag ne "GNA"){
533
                $flag=lc($flag);
534
            }
535
            else{
536
                $flag="gonenoaddress";
537
            }
538
            %flaginfo=( $flag =>1, $flag."comment"=>$borrower->{$flag."comment"},dateend=>$flags->{uc($flag)}->{dateend});
539
        }
468
        elsif ( $flag eq 'ODUES' ) {
540
        elsif ( $flag eq 'ODUES' ) {
469
            my $items = $flags->{$flag}->{'itemlist'};
541
            my $items = $flags->{$flag}->{'itemlist'};
470
            my @itemloop;
542
            my @itemloop;
Lines 490-496 if ($borrower) { Link Here
490
        push( @flagloop, \%flaginfo );
562
        push( @flagloop, \%flaginfo );
491
    }
563
    }
492
    $template->param(
564
    $template->param(
493
        flagset          => $flagset,
494
        flagloop         => \@flagloop,
565
        flagloop         => \@flagloop,
495
        riborrowernumber => $borrower->{'borrowernumber'},
566
        riborrowernumber => $borrower->{'borrowernumber'},
496
        riborcnum        => $borrower->{'cardnumber'},
567
        riborcnum        => $borrower->{'cardnumber'},
Lines 501-507 if ($borrower) { Link Here
501
}
572
}
502
573
503
#set up so only the last 8 returned items display (make for faster loading pages)
574
#set up so only the last 8 returned items display (make for faster loading pages)
504
my $returned_counter = ( C4::Context->preference('numReturnedItemsToShow') ) ? C4::Context->preference('numReturnedItemsToShow') : 8;
575
my $returned_counter = ( C4::Context->preference('numReturnedItemsToShow') ) ? C4::Context->preference('numReturnedItemsToShow') : 10;
505
my $count = 0;
576
my $count = 0;
506
my @riloop;
577
my @riloop;
507
foreach ( sort { $a <=> $b } keys %returneditems ) {
578
foreach ( sort { $a <=> $b } keys %returneditems ) {
Lines 528-546 foreach ( sort { $a <=> $b } keys %returneditems ) { Link Here
528
        else {
599
        else {
529
            $ri{borrowernumber} = $riborrowernumber{$_};
600
            $ri{borrowernumber} = $riborrowernumber{$_};
530
        }
601
        }
531
532
        #        my %ri;
602
        #        my %ri;
533
        my $biblio = GetBiblioFromItemNumber(GetItemnumberFromBarcode($bar_code));
603
        my $biblio = GetBiblioFromItemNumber(GetItemnumberFromBarcode($bar_code));
604
        my $item = GetItem(GetItemnumberFromBarcode($bar_code));
534
        # fix up item type for display
605
        # fix up item type for display
535
        $biblio->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $biblio->{'itype'} : $biblio->{'itemtype'};
606
        $biblio->{'itemtype'} = C4::Context->preference('item-level_itypes') ? $biblio->{'itype'} : $biblio->{'itemtype'};
536
        $ri{itembiblionumber} = $biblio->{'biblionumber'};
607
        $ri{itembiblionumber} = $biblio->{'biblionumber'};
537
        $ri{itemtitle}        = $biblio->{'title'};
608
        $ri{itemtitle}        = $biblio->{'title'};
538
        $ri{itemauthor}       = $biblio->{'author'};
609
        $ri{itemauthor}       = $biblio->{'author'};
539
        $ri{itemtype}         = $biblio->{'itemtype'};
540
        $ri{itemnote}         = $biblio->{'itemnotes'};
610
        $ri{itemnote}         = $biblio->{'itemnotes'};
541
        $ri{ccode}            = $biblio->{'ccode'};
542
        $ri{itemnumber}       = $biblio->{'itemnumber'};
611
        $ri{itemnumber}       = $biblio->{'itemnumber'};
612
        $ri{itemtype}         = $item->{'itype'};
613
        $ri{ccode}            = $item->{'ccode'};
614
        $ri{itemcallnumber}   = $item->{'itemcallnumber'};
615
        $ri{homebranch}       = $item->{'homebranch'};
616
        $ri{holdingbranch}    = $item->{'holdingbranch'};
543
        $ri{barcode}          = $bar_code;
617
        $ri{barcode}          = $bar_code;
618
        my $shelflocations    = GetKohaAuthorisedValues('items.location','');
619
        $ri{itemlocation}     = $shelflocations->{$biblio->{'location'}};
620
        
544
    }
621
    }
545
    else {
622
    else {
546
        last;
623
        last;
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/branch_transfer_limits.tmpl (-4 / +11 lines)
Lines 50-55 Link Here
50
			return false;
50
			return false;
51
		});
51
		});
52
52
53
        $('#selectlibrary input[type=submit]').hide();
53
	});
54
	});
54
</script>
55
</script>
55
<style type="text/css">td { text-align: center; }</style>
56
<style type="text/css">td { text-align: center; }</style>
Lines 70-82 Link Here
70
    <form method="get" action="/cgi-bin/koha/admin/branch_transfer_limits.pl" id="selectlibrary">
71
    <form method="get" action="/cgi-bin/koha/admin/branch_transfer_limits.pl" id="selectlibrary">
71
        <label for="branchselect">Select a library :</label>
72
        <label for="branchselect">Select a library :</label>
72
            <select name="branchcode" id="branchselect">
73
            <select name="branchcode" id="branchselect">
74
            <option value="">Choose one</option>
73
		<!-- TMPL_LOOP NAME="branch_loop" -->
75
		<!-- TMPL_LOOP NAME="branch_loop" -->
76
            <!-- TMPL_IF EXPR="value eq branchcode" -->
77
                <option value="<!-- TMPL_VAR NAME="value" -->" selected="selected"><!-- TMPL_VAR NAME="branchname" --></option>
78
            <!-- TMPL_ELSE -->
74
                <option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option>
79
                <option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option>
80
            <!-- /TMPL_IF -->
75
		<!-- /TMPL_LOOP -->
81
		<!-- /TMPL_LOOP -->
76
            </select>
82
            </select>
77
	    <input type="submit" value="Choose" />	    
83
	    <input type="submit" value="Choose" />	    
78
    </form>
84
    </form>
79
85
<!-- TMPL_IF NAME="branchcode" -->
80
<p class="help">Check the boxes for the libraries you accept to checkin items from.</p>
86
<p class="help">Check the boxes for the libraries you accept to checkin items from.</p>
81
<fieldset>For <strong>all</strong> <!--TMPL_VAR NAME="limit_phrase" -->s: <a id="CheckAll" href="#">Check All</a> | <a id="UncheckAll" href="#">Uncheck All</a></fieldset>
87
<fieldset>For <strong>all</strong> <!--TMPL_VAR NAME="limit_phrase" -->s: <a id="CheckAll" href="#">Check All</a> | <a id="UncheckAll" href="#">Uncheck All</a></fieldset>
82
88
Lines 126-136 Link Here
126
			</thead>
132
			</thead>
127
133
128
			<tbody>
134
			<tbody>
129
					<!-- TMPL_LOOP NAME="to_branch_loop" -->
135
					<!-- TMPL_LOOP NAME="from_branch_loop" -->
130
						<!-- TMPL_UNLESS NAME="__odd__" --><tr class="highlight"><!-- TMPL_ELSE
136
						<!-- TMPL_UNLESS NAME="__odd__" --><tr class="highlight"><!-- TMPL_ELSE
131
--><tr><!-- /TMPL_UNLESS -->
137
--><tr><!-- /TMPL_UNLESS -->
132
							<td><label style="min-width:400px;" for="<!-- TMPL_VAR NAME="code" --><!-- TMPL_VAR NAME="toBranch" -->row"><!-- TMPL_VAR NAME="toBranch" --> - <!-- TMPL_VAR NAME="toBranchname" --></label></td>
138
							<td><label style="min-width:400px;" for="<!-- TMPL_VAR NAME="code" --><!-- TMPL_VAR NAME="fromBranch" -->row"><!-- TMPL_VAR NAME="fromBranch" --> - <!-- TMPL_VAR NAME="fromBranchname" --></label></td>
133
							<td><input type="checkbox" id="<!-- TMPL_VAR NAME="code" --><!-- TMPL_VAR NAME="toBranch" -->row" name="<!-- TMPL_VAR NAME="code" -->_<!-- TMPL_VAR NAME="toBranch" -->" <!-- TMPL_IF NAME="isChecked" -->checked="checked" <!-- /TMPL_IF --> /></td>
139
							<td><input type="checkbox" id="<!-- TMPL_VAR NAME="code" --><!-- TMPL_VAR NAME="fromBranch" -->row" name="<!-- TMPL_VAR NAME="code" -->_<!-- TMPL_VAR NAME="fromBranch" -->" <!-- TMPL_IF NAME="isChecked" -->checked="checked" <!-- /TMPL_IF --> /></td>
134
						</tr>
140
						</tr>
135
					<!-- /TMPL_LOOP -->
141
					<!-- /TMPL_LOOP -->
136
			</tbody>
142
			</tbody>
Lines 148-153 Link Here
148
		</div>
154
		</div>
149
  </div>
155
  </div>
150
</div>
156
</div>
157
<!-- /TMPL_IF -->
151
<div class="yui-b">
158
<div class="yui-b">
152
  <!-- TMPL_INCLUDE NAME="admin-menu.inc" -->
159
  <!-- TMPL_INCLUDE NAME="admin-menu.inc" -->
153
</div>
160
</div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/clone-rules.tmpl (-1 / +2 lines)
Lines 24-30 Link Here
24
	<!-- TMPL_IF NAME="error" -->
24
	<!-- TMPL_IF NAME="error" -->
25
	    <div class="dialog alert">Cloning of issuing rules failed!</div>
25
	    <div class="dialog alert">Cloning of issuing rules failed!</div>
26
	<!-- TMPL_ELSE -->
26
	<!-- TMPL_ELSE -->
27
	    <div class="dialog message"><p>The rules have been cloned.</p></div>
27
	    <div class="message"><p>The rules have <a href="/cgi-bin/koha/admin/smart-rules.pl?branch=<!-- TMPL_VAR NAME="tobranch" -->">been cloned</a>.</p></div>
28
	    <script language="javascript">document.location.href = "/cgi-bin/koha/admin/smart-rules.pl?branch=<!-- TMPL_VAR NAME="tobranch" -->";</script>
28
	<!-- /TMPL_IF -->
29
	<!-- /TMPL_IF -->
29
	<a href="/cgi-bin/koha/admin/smart-rules.pl">Return to Issuing rules</a>
30
	<a href="/cgi-bin/koha/admin/smart-rules.pl">Return to Issuing rules</a>
30
    <!-- TMPL_ELSE -->
31
    <!-- TMPL_ELSE -->
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tmpl (-283 / +356 lines)
Lines 6-14 Link Here
6
//<![CDATA[
6
//<![CDATA[
7
$(document).ready(function() {
7
$(document).ready(function() {
8
        $('#selectlibrary').find("input:submit").hide();
8
        $('#selectlibrary').find("input:submit").hide();
9
        $('#branch').change(function() {
9
        $('#branchcode').change(function() {
10
                $('#selectlibrary').submit();
10
                $('#selectlibrary').submit();
11
        });
11
        });
12
        $('#filter').keyup(function() {
13
                $.uiTableFilter( $('#smartrules'), this.value );
14
        });
15
        $('#nofilter').click(function() {
16
            $('.issues').show();
17
            $('.fines').show();
18
            $('.reserves').show();
19
            $('.issues :input').removeAttr('disabled',true);
20
            $('.fines :input').removeAttr('disabled',true);
21
            $('.reserves :input').removeAttr('disabled',true);
22
            $(this).parent().attr('class','ui-tabs-selected');
23
            $('#issuesfilter').parent().attr('class',null);
24
            $('#finesfilter').parent().attr('class',null);
25
            $('#reservesfilter').parent().attr('class',null);
26
        });
27
        $('#issuesfilter').click(function() {
28
            $('.issues').show();
29
            $('.fines').hide();
30
            $('.reserves').hide();
31
            $('.issues :input').removeAttr('disabled',true);
32
            $('.fines :input').attr('disabled',true);
33
            $('.reserves :input').attr('disabled',true);
34
            $(this).parent().attr('class','ui-tabs-selected');
35
            $('#nofilter').parent().attr('class',null);
36
            $('#finesfilter').parent().attr('class',null);
37
            $('#reservesfilter').parent().attr('class',null);
38
        });
39
        $('#finesfilter').click(function() {
40
            $('.issues').hide();
41
            $('.fines').show();
42
            $('.reserves').hide();
43
            $('.issues :input').attr('disabled',true);
44
            $('.fines :input').removeAttr('disabled',true);
45
            $('.reserves :input').attr('disabled',true);
46
            $(this).parent().attr('class','ui-tabs-selected');
47
            $('#issuesfilter').parent().attr('class',null);
48
            $('#nofilter').parent().attr('class',null);
49
            $('#reservesfilter').parent().attr('class',null);
50
        });
51
        $('#reservesfilter').click(function() {
52
            $('.issues').hide();
53
            $('.fines').hide();
54
            $('.reserves').show();
55
            $('.issues :input').attr('disabled',true);
56
            $('.fines :input').attr('disabled',true);
57
            $('.reserves :input').removeAttr('disabled',true);
58
            $(this).parent().attr('class','ui-tabs-selected');
59
            $('#issuesfilter').parent().attr('class',null);
60
            $('#finesfilter').parent().attr('class',null);
61
            $('#nofilter').parent().attr('class',null);
62
        });
63
64
        // Inline editor
65
        var editor = false;
66
        $('#smartrules>tbody>tr>td.editable').click(function() {
67
            if ( ! editor ) {
68
                var td = $(this);
69
                var tdvalue = td.text().trim();
70
                td.text('');
71
72
                var type;
73
                if ( $.inArray('boolean', td.attr('class').split(' ')) != -1 ) { // If the td is boolean, we display a checkbox
74
                    editor = $('<input id="inlineeditor" type="checkbox" /\>');
75
                    editor.attr('checked', tdvalue == 'Yes' ? 'checked' : '');
76
                    type = 'boolean';
77
                } else if ( $.inArray('triple', td.attr('class').split(' ')) != -1 ) { // else if it is a triple, we display a listbox
78
                    var selectedn = tdvalue ==  ''   ? 'selected="selected"' : '';
79
                    var selected1 = tdvalue == 'Yes' ? 'selected="selected"' : '';
80
                    var selected0 = tdvalue == 'No'  ? 'selected="selected"' : '';
81
                    var str  = '<select id="inlineeditor">';
82
                        str += '<option value=""  ' + selectedn + '></option>';
83
                        str += '<option value="1" ' + selected1 + '>Yes</option>';
84
                        str += '<option value="0" ' + selected0 + '>No</option>';
85
                        str += '</select>';
86
                    editor = $(str);
87
                    type = 'triple';
88
                } else { // else we display a textbox
89
                    editor = $('<input id="inlineeditor" type="text" size="4" /\>');
90
                    editor.attr('value', tdvalue);
91
                }
92
93
                editor.focus();
94
95
                editor.keyup(function(e) {   // on press
96
                    if ( e.keyCode == 13 ) { // enter
97
98
                        // let's build the atomic rule
99
                        var branchcode   = $('#branchcode').val();
100
                        var categorycode = td.parent().children('td.categorycode').children('span').text();
101
                        var itemtype     = td.parent().children('td.itemtype').children('span').text();
102
                        var varname      = td.attr('class').split(' ')[0];
103
                        var inputvalue;
104
                        switch ( type ) {
105
                            case 'boolean':
106
                                inputvalue = editor.attr('checked') ? 1 : 0;
107
                                break;
108
                            default:
109
                                inputvalue = editor.val();
110
                                break;
111
                        }
112
113
                        // post it to the server
114
                        $.ajax({
115
                            url: '/cgi-bin/koha/admin/smart-rules-service.pl',
116
                            type: "POST",
117
                            async: false,
118
                            data: "branchcode="+branchcode+"&categorycode="+categorycode+"&itemtype="+itemtype+"&varname="+varname+"&inputvalue="+inputvalue,
119
                            success: function(result) {
120
121
                                // repopulate the td with data
122
                                switch ( type ) {
123
                                    case 'boolean':
124
                                        td.text(result == '1' ? 'Yes' : 'No');
125
                                        break;
126
                                    case 'triple':
127
                                        switch ( result ) {
128
                                            case '' : td.text('');    break;
129
                                            case '1': td.text('Yes'); break;
130
                                            case '0': td.text('No');  break;
131
                                        }
132
                                        break;
133
                                    default:
134
                                        td.text(result);
135
                                        break;
136
                                }
137
138
                                editor.remove();
139
                                editor = false;
140
                            }
141
                        });
142
                    }
143
                });
144
145
                td.append(editor);
146
            }
147
        });
12
});
148
});
13
//]]>
149
//]]>
14
</script>
150
</script>
Lines 32-56 $(document).ready(function() { Link Here
32
            Defining circulation and fine rules for all libraries
168
            Defining circulation and fine rules for all libraries
33
        <!-- /TMPL_IF -->
169
        <!-- /TMPL_IF -->
34
    </h1>
170
    </h1>
35
    <div class="help">
171
    <div id="bloc100">
36
        <p>The rules are applied from most specific to less specific, using the first found in this order:</p>
37
        <ul>
38
            <li>same library, same patron type, same item type</li>
39
            <li>same library, same patron type, all item types</li>
40
            <li>same library, all patron types, same item type</li>
41
            <li>same library, all patron types, all item types</li>
42
            <li>all libraries, same patron type, same item type</li>
43
            <li>all libraries, same patron type, all item types</li>
44
            <li>all libraries, all patron types, same item type</li>
45
            <li>all libraries, all patron types, all item types</li>
46
        </ul>
47
        <p>To modify a rule, create a new one with the same patron type and item type.</p>
48
    </div>
49
    <div>
50
        <form method="get" action="/cgi-bin/koha/admin/smart-rules.pl" id="selectlibrary">
172
        <form method="get" action="/cgi-bin/koha/admin/smart-rules.pl" id="selectlibrary">
51
        Select a library :
173
        Select a library :
52
            <select name="branch" id="branch" style="width:20em;">
174
            <select name="branchcode" id="branchcode" style="width:20em;">
53
                <option value="*">All libraries</option>
175
                <option value="*">Default</option>
54
            <!-- TMPL_LOOP NAME="branchloop" -->
176
            <!-- TMPL_LOOP NAME="branchloop" -->
55
				<!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="value" -->" selected="selected"><!-- TMPL_VAR NAME="branchname" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option><!-- /TMPL_IF -->
177
				<!-- TMPL_IF NAME="selected" --><option value="<!-- TMPL_VAR NAME="value" -->" selected="selected"><!-- TMPL_VAR NAME="branchname" --></option><!-- TMPL_ELSE --><option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option><!-- /TMPL_IF -->
56
            <!-- /TMPL_LOOP -->
178
            <!-- /TMPL_LOOP -->
Lines 60-331 $(document).ready(function() { Link Here
60
for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidden" name="frombranch" value="<!-- TMPL_VAR NAME="current_branch" -->" />
182
for="tobranch"><strong>Clone these rules to:</strong></label> <input type="hidden" name="frombranch" value="<!-- TMPL_VAR NAME="current_branch" -->" />
61
            <select name="tobranch" id="tobranch"><!-- TMPL_LOOP NAME="branchloop" --><option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option><!-- /TMPL_LOOP --></select> <input type="submit" value="Clone" /></form><!-- /TMPL_IF --></fieldset>
183
            <select name="tobranch" id="tobranch"><!-- TMPL_LOOP NAME="branchloop" --><option value="<!-- TMPL_VAR NAME="value" -->"><!-- TMPL_VAR NAME="branchname" --></option><!-- /TMPL_LOOP --></select> <input type="submit" value="Clone" /></form><!-- /TMPL_IF --></fieldset>
62
184
63
        <form method="post" action="/cgi-bin/koha/admin/smart-rules.pl">
185
        <div class="toptabs">
64
            <input type="hidden" name="op" value="add" />
186
            <ul class="ui-tabs-nav">
65
            <table>
187
                <li class="ui-tabs-selected"><a id="nofilter">All</a></li>
66
            <tr>
188
                <li><a id="issuesfilter">Issues</a></li>
67
                <th>Patron Category</th>
189
                <li><a id="finesfilter">Fines</a></li>
68
                <th>Item Type</th>
190
                <li><a id="reservesfilter">Reserves</a></li>
69
                <th>Current Checkouts Allowed</th>
191
                <div style="text-align:right;">
70
                <th>Loan Period (day)</th>
192
                    <label for="filter" style="float:none;">Filter: </label>
71
                <th>Fine Amount</th>
193
                    <input type="text" name="filter" id="filter" />
72
                <th>Fine Charging Interval</th>
194
                </div>
73
                <th>Fine Grace period (day)</th>
195
            </ul>
74
                <th>Suspension in Days (day)</th>
196
            <div class="tabs-container">
75
                <th>Renewals Allowed (count)</th>
197
                    <table id="smartrules" width="100%">
76
                <th>Holds Allowed (count)</th>
198
                        <thead>
77
		        <th>Rental Discount (%)</th>
199
                            <tr>
78
				<th>&nbsp;</th>
200
                                <th>Patron category</th>
79
            </tr>
201
                                <th>Item type</th>
80
				<!-- TMPL_LOOP NAME="rules" -->
202
                                <th class="issues">Current checkouts allowed</th>
81
					<!-- TMPL_UNLESS NAME="__odd__" -->
203
                                <th class="issues">Loan period (day)</th>
82
					<tr class="highlight">
204
                                <th class="fines">Fine amount</th>
83
					<!-- TMPL_ELSE -->
205
                                <th class="fines">Fine charging interval</th>
84
					<tr>
206
                                <th class="fines">Grace period (day)</th>
85
					<!-- /TMPL_UNLESS -->
207
                                <th class="fines">Suspension duration (day)</th>
86
							<td><!-- TMPL_IF NAME="default_humancategorycode" -->
208
                                <th class="issues">Renewals allowed (count)</th>
87
									<em>All</em>
209
                                <th class="issues">Renewals period (days)</th>
88
								<!-- TMPL_ELSE -->
210
                                <th class="reserves">Holds allowed (count)</th>
89
									<!-- TMPL_VAR NAME="humancategorycode" -->
211
                                <th class="reserves">Holds pickup delay (day)</th>
90
								<!-- /TMPL_IF -->
212
                                <th class="reserves">Allow on shelf holds</th>
91
							</td>
213
                                <th class="reserves">Holds restricted to library</th>
92
							<td><!-- TMPL_IF NAME="default_humanitemtype" -->
214
                                <th class="issues">Rental Discount (%)</th>
93
									<em>All</em>
215
                                <th>&nbsp;</th>
94
								<!-- TMPL_ELSE -->
216
                            </tr>
95
									<!-- TMPL_VAR NAME="humanitemtype" -->
217
                        </thead>
96
								<!-- /TMPL_IF -->
218
                        <tbody>
97
							</td>
219
                        <!-- TMPL_LOOP NAME="rules" -->
98
							<td><!-- TMPL_IF NAME="unlimited_maxissueqty" -->
220
                            <!-- TMPL_UNLESS NAME="__odd__" -->
99
									Unlimited
221
                            <tr class="highlight">
100
								<!-- TMPL_ELSE -->
101
									<!-- TMPL_VAR NAME="maxissueqty" -->
102
								<!-- /TMPL_IF -->
103
							</td>
104
							<td><!-- TMPL_VAR NAME="issuelength" --></td>
105
							<td><!-- TMPL_VAR NAME="fine" --></td>
106
							<td><!-- TMPL_VAR NAME="chargeperiod" --></td>
107
							<td><!-- TMPL_VAR NAME="firstremind" --></td>
108
							<td><!-- TMPL_VAR NAME="finedays" --></td>
109
							<td><!-- TMPL_VAR NAME="renewalsallowed" --></td>
110
							<td><!-- TMPL_VAR NAME="reservesallowed" --></td>
111
							<td><!-- TMPL_VAR NAME="rentaldiscount" --></td>
112
							<td>
113
								<a class="button" href="/cgi-bin/koha/admin/smart-rules.pl?op=delete&amp;itemtype=<!-- TMPL_VAR NAME="itemtype" -->&amp;categorycode=<!-- TMPL_VAR NAME="categorycode" -->&amp;branch=<!-- TMPL_VAR NAME="current_branch" -->">Delete</a>
114
							</td>
115
                	</tr>
116
            	<!-- /TMPL_LOOP -->
117
                <tr>
118
                    <td>
119
                        <select name="categorycode">
120
                            <option value="*">All</option>
121
                        <!-- TMPL_LOOP NAME="categoryloop" -->
122
                            <option value="<!-- TMPL_VAR NAME="categorycode" -->"><!-- TMPL_VAR NAME="description" --></option>
123
                        <!-- /TMPL_LOOP -->
124
                        </select>
125
                    </td>
126
                    <td>
127
                        <select name="itemtype" style="width:13em;">
128
                            <option value="*">All</option>
129
                        <!-- TMPL_LOOP NAME="itemtypeloop" -->
130
                            <option value="<!-- TMPL_VAR NAME="itemtype" -->"><!-- TMPL_VAR NAME="description" --></option>
131
                        <!-- /TMPL_LOOP -->
132
                        </select>
133
                    </td>
134
                    <td><input name="maxissueqty" size="3" /></td>
135
                    <td><input name="issuelength" size="3" /> </td>
136
                    <td><input name="fine" size="4" /></td>
137
                    <td><input name="chargeperiod" size="2" /></td>
138
                    <td><input name="firstremind" size="2" /> </td>
139
                    <td><input name="finedays" size="3" /> </td>
140
                    <td><input name="renewalsallowed" size="2" /></td>
141
                    <td><input name="reservesallowed" size="2" /></td>
142
		    <td><input name="rentaldiscount" size="2" /></td>
143
                    <td><input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="current_branch" -->"/><input type="submit" value="Add" class="submit" /></td>
144
                </tr>
145
            </table>
146
        </form>
147
    </div>
148
    <div id="defaults-for-this-library" class="container">
149
    <h3>Default checkout and hold policy for <!-- TMPL_IF NAME="humanbranch" --><!-- TMPL_VAR NAME="humanbranch" --><!-- TMPL_ELSE -->all libraries<!-- /TMPL_IF --></h3>
150
        <p>You can set a default maximum number of checkouts and hold policy that will be used if none is defined below for a particular item type or category.</p>
151
        <form method="post" action="/cgi-bin/koha/admin/smart-rules.pl">
152
            <input type="hidden" name="op" value="set-branch-defaults" />
153
            <input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="current_branch" -->"/>
154
            <table>
155
                <tr>
156
                    <th>&nbsp;</th>
157
                    <th>Total Current Checkouts Allowed</th>
158
                    <th>Hold Policy</th>
159
                    <th>&nbsp;</th>
160
                    <th>&nbsp;</th>
161
                </tr>
162
                <tr>
163
                    <td><em>Defaults<!-- TMPL_UNLESS NAME="default_rules" --> (not set)<!-- /TMPL_IF --></em></td>
164
                    <td><input type="text" name="maxissueqty" size="3" value="<!-- TMPL_VAR NAME="default_maxissueqty" -->"/></td>
165
                    <td>
166
                        <select name="holdallowed">
167
                            <!-- TMPL_IF NAME="default_holdallowed_any" -->
168
                            <option value="2" selected="selected">
169
                            <!-- TMPL_ELSE -->
170
                            <option value="2">
171
                            <!-- /TMPL_IF -->
172
                                From Any Library
173
                            </option>
174
                            <!-- TMPL_IF NAME="default_holdallowed_same" -->
175
                            <option value="1" selected="selected">
176
                            <!-- TMPL_ELSE -->
177
                            <option value="1">
178
                            <!-- /TMPL_IF -->
179
                                From Home Library
180
                            </option>
181
                            <!-- TMPL_IF NAME="default_holdallowed_none" -->
182
                            <option value="0" selected="selected">
183
                            <!-- TMPL_ELSE -->
184
                            <option value="0">
185
                            <!-- /TMPL_IF -->
186
                                No Holds Allowed
187
                            </option>
188
                        </select>
189
                    </td>
190
                    <td><input type="submit" value="Save" class="submit" /></td>
191
                    <td>
192
                        <a class="button" href="/cgi-bin/koha/admin/smart-rules.pl?op=delete-branch-cat&amp;categorycode=*&amp;branch=<!-- TMPL_VAR NAME="current_branch" -->">Unset</a>
193
                    </td>
194
                </tr>
195
            </table>
196
        </form>
197
    </div>
198
    <!-- TMPL_IF NAME="show_branch_cat_rule_form" -->
199
    <div id="holds-policy-by-patron-category" class="container">
200
    <h3>Checkout limit by patron category for <!-- TMPL_IF NAME="humanbranch" --><!-- TMPL_VAR NAME="humanbranch" --><!-- TMPL_ELSE -->all libraries<!-- /TMPL_IF --></h3>
201
        <p>For this library, you can specify the maximum number of loans that
202
            a patron of a given category can make, regardless of the item type.
203
        </p>
204
        <p>If the total amount loanable for a given patron category is left blank,
205
           no limit applies, except possibly for a limit you define for a specific item type.
206
        </p>
207
        <form method="post" action="/cgi-bin/koha/admin/smart-rules.pl">
208
            <input type="hidden" name="op" value="add-branch-cat" />
209
            <input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="current_branch" -->"/>
210
            <table>
211
                <tr>
212
                    <th>Patron Category</th>
213
                    <th>Total Current Checkouts Allowed</th>
214
                    <th>&nbsp;</th>
215
                </tr>
216
                <!-- TMPL_LOOP NAME="branch_cat_rule_loop" -->
217
                    <!-- TMPL_UNLESS NAME="__odd__" -->
218
                    <tr class="highlight">
219
                    <!-- TMPL_ELSE -->
220
                    <tr>
221
                    <!-- /TMPL_UNLESS -->
222
                        <td><!-- TMPL_IF NAME="default_humancategorycode" -->
223
                                <em>Default</em>
224
                            <!-- TMPL_ELSE -->
222
                            <!-- TMPL_ELSE -->
225
                                <!-- TMPL_VAR NAME="humancategorycode" -->
223
                            <tr>
226
                            <!-- /TMPL_IF -->
224
                            <!-- /TMPL_UNLESS -->
227
                        </td>
225
                                    <td class="categorycode">
228
                        <td><!-- TMPL_IF NAME="unlimited_maxissueqty" -->
226
                                        <span style="display:none;"><!-- TMPL_VAR NAME="categorycode" --></span>
229
                                Unlimited
227
                                        <!-- TMPL_IF NAME="default_humancategorycode" -->
230
                            <!-- TMPL_ELSE -->
228
                                            <em>Default</em>
231
                                <!-- TMPL_VAR NAME="maxissueqty" -->
229
                                        <!-- TMPL_ELSE -->
232
                            <!-- /TMPL_IF -->
230
                                            <!-- TMPL_VAR NAME="humancategorycode" -->
233
                        </td>
231
                                        <!-- /TMPL_IF -->
234
                        <td>
232
                                    </td>
235
                            <a class="button" href="/cgi-bin/koha/admin/smart-rules.pl?op=delete-branch-cat&amp;categorycode=<!-- TMPL_VAR NAME="categorycode" -->&amp;branch=<!-- TMPL_VAR NAME="current_branch" -->">Delete</a>
233
                                    <td class="itemtype">
236
                        </td>
234
                                        <span style="display:none;"><!-- TMPL_VAR NAME="itemtype" --></span>
237
                    </tr>
235
                                        <!-- TMPL_IF NAME="default_humanitemtype" -->
238
                <!-- /TMPL_LOOP -->
236
                                            <em>Default</em>
239
                <tr>
237
                                        <!-- TMPL_ELSE -->
240
                    <td>
238
                                            <!-- TMPL_VAR NAME="humanitemtype" -->
241
                        <select name="categorycode">
239
                                        <!-- /TMPL_IF -->
242
                        <!-- TMPL_LOOP NAME="categoryloop" -->
240
                                    </td>
243
                            <option value="<!-- TMPL_VAR NAME="categorycode" -->"><!-- TMPL_VAR NAME="description" --></option>
241
                                    <!-- TMPL_IF NAME="herited_maxissueqty" -->
244
                        <!-- /TMPL_LOOP -->
242
                                    <td class="maxissueqty editable issues herited">
245
                        </select>
243
                                    <!-- TMPL_ELSE -->
246
                    </td>
244
                                    <td class="maxissueqty editable issues">
247
                    <td><input name="maxissueqty" size="3" /></td>
245
                                    <!-- /TMPL_IF -->
248
                    <td><input type="submit" value="Add" class="submit" /></td>
246
                                        <!-- TMPL_IF NAME="unlimited_maxissueqty" -->
249
                </tr>
247
                                            Unlimited
250
            </table>
248
                                        <!-- TMPL_ELSE -->
251
        </form>
249
                                            <!-- TMPL_VAR NAME="maxissueqty" -->
252
    </div>
250
                                        <!-- /TMPL_IF -->
253
    <!-- /TMPL_IF -->
251
                                    </td>
254
    <div id="holds-policy-by-item-type" class="container">
252
                                    <!-- TMPL_IF NAME="herited_issuelength" -->
255
    <h3>Holds policy by item type for <!-- TMPL_IF NAME="humanbranch" --><!-- TMPL_VAR NAME="humanbranch" --><!-- TMPL_ELSE -->all libraries<!-- /TMPL_IF --></h3>
253
                                    <td class="issuelength editable issues herited">
256
        <p>
254
                                    <!-- TMPL_ELSE -->
257
            For this library, you can edit rules for given itemtypes, regardless
255
                                    <td class="issuelength editable issues">
258
            of the patron's category.
256
                                    <!-- /TMPL_IF -->
259
        </p>
257
                                    <!-- TMPL_VAR NAME="issuelength" -->
260
        <p>
258
                                    </td>
261
            Currently, this means hold policies.
259
                                    <!-- TMPL_IF NAME="herited_fine" -->
262
            The various policies have the following effects:
260
                                    <td class="fine editable fines herited">
263
        </p>
261
                                    <!-- TMPL_ELSE -->
264
        <ul>
262
                                    <td class="fine editable fines">
265
            <li><strong>From Any Library:</strong> Patrons from any library may put this item on hold. <cite>(default if none is defined)</cite></li>
263
                                    <!-- /TMPL_IF -->
266
            <li><strong>From Home Library:</strong> Only patrons from the item's home library may put this book on hold.</li>
264
                                    <!-- TMPL_VAR NAME="fine" -->
267
            <li><strong>No Holds Allowed:</strong> No patron may put this book on hold.</li>
265
                                    </td>
268
        </ul>
266
                                    <!-- TMPL_IF NAME="herited_chargeperiod" -->
269
        <p>
267
                                    <td class="chargeperiod editable fines herited">
270
            Note that if the system preference
268
                                    <!-- TMPL_ELSE -->
271
            <code>AllowHoldPolicyOverride</code> is enabled, these policies can
269
                                    <td class="chargeperiod editable fines">
272
            be overridden by your circulation staff. Also, these policies are
270
                                    <!-- /TMPL_IF -->
273
            based on the patron's home library, <em>not</em> the library where the hold is being placed..
271
                                    <!-- TMPL_VAR NAME="chargeperiod" -->
274
        </p>
272
                                    </td>
275
273
                                    <!-- TMPL_IF NAME="herited_firstremind" -->
276
        <form method="post" action="/cgi-bin/koha/admin/smart-rules.pl">
274
                                    <td class="firstremind editable fines herited">
277
            <input type="hidden" name="op" value="add-branch-item" />
275
                                    <!-- TMPL_ELSE -->
278
            <input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="current_branch" -->"/>
276
                                    <td class="firstremind editable fines">
279
            <table>
277
                                    <!-- /TMPL_IF -->
280
                <tr>
278
                                    <!-- TMPL_VAR NAME="firstremind" -->
281
                    <th>Item Type</th>
279
                                    </td>
282
                    <th>Hold Policy</th>
280
                                    <!-- TMPL_IF NAME="herited_finedays" -->
283
                    <th>&nbsp;</th>
281
                                    <td class="finedays editable fines herited">
284
                </tr>
282
                                    <!-- TMPL_ELSE -->
285
                <!-- TMPL_LOOP NAME="branch_item_rule_loop" -->
283
                                    <td class="finedays editable fines">
286
                    <!-- TMPL_UNLESS NAME="__odd__" -->
284
                                    <!-- /TMPL_IF -->
287
                    <tr class="highlight">
285
                                    <!-- TMPL_VAR NAME="finedays" -->
288
                    <!-- TMPL_ELSE -->
286
                                    </td>
289
                    <tr>
287
                                    <!-- TMPL_IF NAME="herited_renewalsallowed" -->
290
                    <!-- /TMPL_UNLESS -->
288
                                    <td class="renewalsallowed editable issues herited">
291
                        <td><!-- TMPL_IF NAME="default_humanitemtype" -->
289
                                    <!-- TMPL_ELSE -->
292
                                <em>Default</em>
290
                                    <td class="renewalsallowed editable issues">
293
                            <!-- TMPL_ELSE -->
291
                                    <!-- /TMPL_IF -->
294
                                <!-- TMPL_VAR NAME="humanitemtype" -->
292
                                    <!-- TMPL_VAR NAME="renewalsallowed" -->
295
                            <!-- /TMPL_IF -->
293
                                    </td>
296
                        </td>
294
                                    <!-- TMPL_IF NAME="herited_renewalperiod" -->
297
                        <td><!-- TMPL_IF NAME="holdallowed_any" -->
295
                                    <td class="renewalperiod editable issues herited">
298
                                From Any Library
296
                                    <!-- TMPL_ELSE -->
299
                            <!-- TMPL_ELSIF NAME="holdallowed_same" -->
297
                                    <td class="renewalperiod editable issues">
300
                                From Home Library
298
                                    <!-- /TMPL_IF -->
301
                            <!-- TMPL_ELSE -->
299
                                    <!-- TMPL_VAR NAME="renewalperiod" -->
302
                                No Holds Allowed
300
                                    </td>
303
                            <!-- /TMPL_IF -->
301
                                    <!-- TMPL_IF NAME="herited_reservesallowed" -->
304
                        </td>
302
                                    <td class="reservesallowed editable reserves herited">
305
                        <td>
303
                                    <!-- TMPL_ELSE -->
306
                            <a class="button" href="/cgi-bin/koha/admin/smart-rules.pl?op=delete-branch-item&amp;itemtype=<!-- TMPL_VAR NAME="itemtype" -->&amp;branch=<!-- TMPL_VAR NAME="current_branch" -->">Delete</a>
304
                                    <td class="reservesallowed editable reserves">
307
                        </td>
305
                                    <!-- /TMPL_IF -->
308
                    </tr>
306
                                    <!-- TMPL_VAR NAME="reservesallowed" -->
309
                <!-- /TMPL_LOOP -->
307
                                    </td>
310
                <tr>
308
                                     <!-- TMPL_IF NAME="herited_holdspickupdelay" -->
311
                    <td>
309
                                    <td class="holdspickupdelay editable reserves herited">
312
                        <select name="itemtype">
310
                                    <!--TMPL_ELSE-->
313
                        <!-- TMPL_LOOP NAME="itemtypeloop" -->
311
                                    <td class="holdspickupdelay editable reserves">
314
                            <option value="<!-- TMPL_VAR NAME="itemtype" -->"><!-- TMPL_VAR NAME="description" --></option>
312
                                    <!--/TMPL_IF-->
315
                        <!-- /TMPL_LOOP -->
313
                                    <!-- TMPL_VAR NAME="holdspickupdelay" -->
316
                        </select>
314
                                    </td>
317
                    </td>
315
                                    <!-- TMPL_IF NAME="herited_allowonshelfholds" -->
318
                    <td>
316
                                    <td class="allowonshelfholds editable reserves triple herited">
319
                        <select name="holdallowed">
317
                                    <!--TMPL_ELSE-->
320
                            <option value="2">From Any Library</option>
318
                                    <td class="allowonshelfholds editable reserves triple">
321
                            <option value="1">From Home Library</option>
319
				    <!--/TMPL_IF-->
322
                            <option value="0">No Holds Allowed</option>
320
                                    <!-- TMPL_IF NAME="allowonshelfholds" -->
323
                        </select>
321
                                    Yes
324
                    </td>
322
                                    <!--TMPL_ELSE-->
325
                    <td><input type="submit" value="Add" class="submit" /></td>
323
                                    No
326
                </tr>
324
                                    <!--/TMPL_IF-->
327
            </table>
325
                                    </td>
328
        </form>
326
                                    <!-- TMPL_IF NAME="herited_holdrestricted" -->
327
                                    <td class="holdrestricted editable reserves boolean herited">
328
                                    <!--TMPL_ELSE-->
329
                                     <td class="holdrestricted editable reserves boolean">
330
                                    <!--/TMPL_IF-->
331
                                    <!-- TMPL_IF NAME="holdrestricted" -->
332
                                    Yes
333
                                    <!--TMPL_ELSE-->
334
                                    No
335
                                    <!--/TMPL_IF-->
336
                                    </td>
337
                                    <!-- TMPL_IF NAME="herited_rentaldiscount" -->
338
                                    <td class="rentaldiscount editable issues herited">
339
                                    <!-- TMPL_ELSE -->
340
                                    <td class="rentaldiscount editable issues">
341
                                    <!-- /TMPL_IF -->
342
                                    <!-- TMPL_VAR NAME="rentaldiscount" -->
343
                                    </td>
344
                                    <td>
345
                                        <a class="button" href="/cgi-bin/koha/admin/smart-rules.pl?op=delete&amp;itemtype=<!-- TMPL_VAR NAME="itemtype" -->&amp;categorycode=<!-- TMPL_VAR NAME="categorycode" -->&amp;branchcode=<!-- TMPL_VAR NAME="branchcode" -->">Delete</a>
346
                                    </td>
347
                                </tr>
348
                            <!-- /TMPL_LOOP -->
349
                        </tbody>
350
                        <form method="post" name="inputrules" action="/cgi-bin/koha/admin/smart-rules.pl">
351
                            <input type="hidden" name="op" value="add" />
352
                        <tfoot>
353
                            <tr>
354
                                <td>
355
                                    <select name="categorycode" id="categorycode" style="width:12em;">
356
                                        <option value="*">Default</option>
357
                                    <!-- TMPL_LOOP NAME="categoryloop" -->
358
                                        <!-- TMPL_IF Name="selected"-->
359
                                        <option value="<!-- TMPL_VAR NAME="categorycode" -->" selected="selected"><!-- TMPL_VAR NAME="description" --></option>
360
                                        <!--TMPL_ELSE --> <option value="<!-- TMPL_VAR NAME="categorycode" -->" ><!-- TMPL_VAR NAME="description" --></option>
361
                                        <!-- /TMPL_IF -->
362
                                    <!-- /TMPL_LOOP -->
363
                                    </select>
364
                                </td>
365
                                <td>
366
                                    <select name="itemtype" style="width:12em;">
367
                                        <option value="*">Default</option>
368
                                    <!-- TMPL_LOOP NAME="itemtypeloop" -->
369
                                        <!-- TMPL_IF Name="selected"-->
370
                                        <option value="<!-- TMPL_VAR NAME="itemtype" -->" selected="selected"><!-- TMPL_VAR NAME="description" --></option>
371
                                        <!--TMPL_ELSE --> <option value="<!-- TMPL_VAR NAME="itemtype" -->"><!-- TMPL_VAR NAME="description" --></option>
372
                                        <!-- /TMPL_IF -->
373
                                    <!-- /TMPL_LOOP -->
374
                                    </select>
375
                                </td>
376
                                <td class="issues"><input name="maxissueqty" size="3" value="<!-- TMPL_VAR NAME="maxissueqty" -->"/></td>
377
                                <td class="issues"><input name="issuelength" size="3" value="<!-- TMPL_VAR NAME="issuelength" -->"/> </td>
378
                                <td class="fines"><input name="fine" size="4" value="<!-- TMPL_VAR NAME="fine" -->"/></td>
379
                                <td class="fines"><input name="chargeperiod" size="2" value="<!-- TMPL_VAR NAME="chargeperiod" -->"/></td>
380
                                <td class="fines"><input name="firstremind" size="2" value="<!-- TMPL_VAR NAME="firstremind" -->"/> </td>
381
                                <td class="fines"><input name="finedays" size="3" value="<!-- TMPL_VAR NAME="finedays" -->"/> </td>
382
                                <td class="issues"><input name="renewalsallowed" size="2" value="<!-- TMPL_VAR NAME="renewalsallowed" -->"/></td>
383
                                <td class="issues"><input name="renewalperiod" size="2" value="<!-- TMPL_VAR NAME="renewalperiod" -->"/></td>
384
                                <td class="reserves"><input name="reservesallowed" size="2" value="<!-- TMPL_VAR NAME="reservesallowed" -->"/></td>
385
                                <td class="reserves"><input name="holdspickupdelay" size="2" value="<!-- TMPL_VAR NAME="holdspickupdelay" -->"/></td>
386
                                <td class="reserves">
387
                                    <select name="allowonshelfholds">
388
                                        <option value=""></option>
389
                                        <option value="1">Yes</option>
390
                                        <option value="0">No</option>
391
                                    </select>
392
                                </td>
393
                                <td class="reserves"><!-- TMPL_IF NAME="holdrestricted"--><input type="checkbox" name="holdrestricted" checked="checked" value="1"/> <!--TMPL_ELSE--><input type="checkbox" name="holdrestricted" value="1"/> <!-- /TMPL_IF --></td>
394
		                        <td class="issues"><input name="rentaldiscount" size="2" /></td>
395
                                <td><input type="hidden" name="branchcode" value="<!-- TMPL_VAR NAME="branchcode" -->"/><input type="submit" value="Add" class="submit" /></td>
396
                            </tr>
397
                        </tfoot>
398
                </form>
399
                    </table>
400
            </div><!-- tabs-container -->
401
        </div><!-- toptabs -->
329
    </div>
402
    </div>
330
</div>
403
</div>
331
404
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tmpl (-153 / +286 lines)
Lines 10-15 Link Here
10
<script type="text/javascript">
10
<script type="text/javascript">
11
//<![CDATA[
11
//<![CDATA[
12
if($.cookie("holdfor") != <!-- TMPL_VAR NAME="borrowernumber" -->){ $.cookie("holdfor",null, { path: "/", expires: 0 }); }
12
if($.cookie("holdfor") != <!-- TMPL_VAR NAME="borrowernumber" -->){ $.cookie("holdfor",null, { path: "/", expires: 0 }); }
13
14
function Dopop(link) {
15
    var newin=window.open(link,'popup','width=600,height=400,resizable=1,toolbar=0,scrollbars=1,top');
16
}
17
18
13
<!-- TMPL_IF NAME="UseTablesortForCirc" -->$.tablesorter.addParser({
19
<!-- TMPL_IF NAME="UseTablesortForCirc" -->$.tablesorter.addParser({
14
    id: 'articles',
20
    id: 'articles',
15
    is: function(s) {return false;  },
21
    is: function(s) {return false;  },
Lines 24-32 if($.cookie("holdfor") != <!-- TMPL_VAR NAME="borrowernumber" -->){ $.cookie("ho Link Here
24
		dateFormat: 'uk',<!-- /TMPL_IF -->
30
		dateFormat: 'uk',<!-- /TMPL_IF -->
25
		headers: { 1: { sorter: 'articles' },5: { sorter: false },6:{sorter:false},7:{sorter:false},8:{sorter:false}}
31
		headers: { 1: { sorter: 'articles' },5: { sorter: false },6:{sorter:false},7:{sorter:false},8:{sorter:false}}
26
		});
32
		});
33
		$("#relissuest").tablesorter({<!-- TMPL_IF NAME="dateformat_metric" -->
34
		dateFormat: 'uk',<!-- /TMPL_IF -->
35
		headers: { 1: { sorter: 'articles' },5: { sorter: false },6:{sorter:false},7:{sorter:false},8:{sorter:false}}
36
		});
37
38
		//FIXME: Sorting does not work when there are previous checkouts only
39
		// (It works fine when there are only checkouts of the day, or both previous and today checkouts)
27
		$("#issuest").bind("sortEnd",function() {
40
		$("#issuest").bind("sortEnd",function() {
28
        	$("#previous").parents("tr").remove();  // 'previous checkouts' header chokes table sorter
41
        	$("#previous").parents("tr").remove();  // 'previous checkouts' header chokes table sorter
29
	    });
42
	    });
43
		$("#relissuest").bind("sortEnd",function() {
44
		    $("#relprevious").parents("tr").remove();  // 'previous checkouts' header chokes table sorter
45
		});
46
30
		$("#holdst").tablesorter({<!-- TMPL_IF NAME="dateformat_metric" -->
47
		$("#holdst").tablesorter({<!-- TMPL_IF NAME="dateformat_metric" -->
31
		dateFormat: 'uk',<!-- /TMPL_IF -->
48
		dateFormat: 'uk',<!-- /TMPL_IF -->
32
			sortList: [[0,0]],
49
			sortList: [[0,0]],
Lines 43-56 if($.cookie("holdfor") != <!-- TMPL_VAR NAME="borrowernumber" -->){ $.cookie("ho Link Here
43
        <!-- /TMPL_IF -->
60
        <!-- /TMPL_IF -->
44
61
45
var allcheckboxes = $(".checkboxed");
62
var allcheckboxes = $(".checkboxed");
46
	$("#renew_all").click(function(){
47
		$(allcheckboxes).checkCheckboxes(":input[name*=items]"); 
48
		$(allcheckboxes).unCheckCheckboxes(":input[name*=barcodes]");
49
	});
50
	$("#CheckAllitems").click(function(){
63
	$("#CheckAllitems").click(function(){
51
		$(allcheckboxes).checkCheckboxes(":input[name*=items]");
64
		$(allcheckboxes).checkCheckboxes(":input[name*=items]");
52
		$(allcheckboxes).unCheckCheckboxes(":input[name*=barcodes]"); return false;
65
		$(allcheckboxes).unCheckCheckboxes(":input[name*=barcodes]"); return false;
53
	});
66
	});
67
//    $(":input[name*]=items").click(function(){
68
//        var itemnumber=getitemnumber($(this).attr(‘id’));
69
//        alert(getitemnumber($(this).attr(‘id’)));
70
//        $("#return_"+itemnumber).attr('checked', !$(this).attr('checked'));
71
//	});
54
    $("#CheckNoitems").click(function(){
72
    $("#CheckNoitems").click(function(){
55
		$(allcheckboxes).unCheckCheckboxes(":input[name*=items]"); return false;
73
		$(allcheckboxes).unCheckCheckboxes(":input[name*=items]"); return false;
56
	});
74
	});
Lines 65-76 var allcheckboxes = $(".checkboxed"); Link Here
65
    <!-- TMPL_IF NAME="CAN_user_circulate_override_renewals" -->
83
    <!-- TMPL_IF NAME="CAN_user_circulate_override_renewals" -->
66
    <!-- TMPL_IF NAME="AllowRenewalLimitOverride" -->
84
    <!-- TMPL_IF NAME="AllowRenewalLimitOverride" -->
67
    $( '#override_limit' ).click( function () {
85
    $( '#override_limit' ).click( function () {
68
        if ( this.checked ) {
86
           $( '.renewals-allowed' ).toggle();
69
           $( '.renewals-allowed' ).show(); $( '.renewals-disabled' ).hide();
70
        } else {
71
           $( '.renewals-allowed' ).hide(); $( '.renewals-disabled' ).show();
72
        }
73
    } ).attr( 'checked', false );
87
    } ).attr( 'checked', false );
88
    $( '.renewals-allowed' ).hide();
74
    <!-- /TMPL_IF -->
89
    <!-- /TMPL_IF -->
75
    <!-- /TMPL_IF -->
90
    <!-- /TMPL_IF -->
76
    // Clicking the table cell checks the checkbox inside it
91
    // Clicking the table cell checks the checkbox inside it
Lines 109-121 var allcheckboxes = $(".checkboxed"); Link Here
109
        radioCheckBox($(this));
124
        radioCheckBox($(this));
110
     });
125
     });
111
 });
126
 });
112
127
   index = id.IndexOf("_");
128
   return id.substr(index+1);
129
}
130
function uncheck_sibling(me){
131
nodename=me.getAttribute("name");
132
if (nodename =="barcodes[]"){
133
    var Node=me.parentNode.previousSibling;
134
    while (Node.nodeName!="TD"){Node=Node.previousSibling}
135
    var Nodes=Node.childNodes;
136
    for (var i=0;i<Nodes.length;i++){
137
      if (Nodes[i].nodeName=="INPUT" && Nodes[i].getAttribute("type")=="checkbox"){
138
        Nodes[i].checked=false;
139
      }     
140
   }   
141
142
}else {
143
    var Node=me.parentNode.nextSibling;
144
    while (Node.nodeName!="TD"){Node=Node.nextSibling}
145
    var Nodes=Node.childNodes;
146
    for (var i=0;i<Nodes.length;i++){
147
      if (Nodes[i].nodeName=="INPUT" && Nodes[i].getAttribute("type")=="checkbox"){
148
        Nodes[i].checked=false;
149
      }     
150
   }   
151
}
152
}
113
function validate1(date) {
153
function validate1(date) {
114
    var today = new Date();
154
    var today = new Date();
115
    if ( date < today ) {
155
    if ( today < date || date.toDateString() == today.toDateString() ) {
116
        return true;
117
     } else {
118
        return false;
156
        return false;
157
     } else {
158
        return true;
119
     }
159
     }
120
};
160
};
121
function refocus(calendar) {
161
function refocus(calendar) {
Lines 191-200 function refocus(calendar) { Link Here
191
</form>
231
</form>
192
</div>
232
</div>
193
233
194
<!-- TMPL_IF NAME="dateexpiry" --><div class="dialog message">Patron's account has been renewed until <!-- TMPL_VAR NAME="dateexpiry" --></div><!-- /TMPL_IF -->
234
<!-- TMPL_INCLUDE NAME="reserves_waiting.inc" -->
235
236
<!-- TMPL_IF name="circnote" -->
237
    <div id="circnote" class="dialog alert">
238
	<h3>Circulation note:</h2>
239
	<!-- TMPL_VAR name="circnote" -->
240
    </div>
241
<!-- /TMPL_IF -->
242
<!-- TMPL_IF NAME="newexpiry" --><div class="dialog message">Patron's account has been renewed until <!-- TMPL_VAR NAME="newexpiry" --></div><!-- /TMPL_IF -->
195
<!-- TMPL_IF NAME="NEEDSCONFIRMATION" -->
243
<!-- TMPL_IF NAME="NEEDSCONFIRMATION" -->
196
<div class="yui-g">
244
<div class="yui-g">
197
198
<div id="circ_needsconfirmation" class="dialog alert">
245
<div id="circ_needsconfirmation" class="dialog alert">
199
<h3>Please Confirm Checkout</h3>
246
<h3>Please Confirm Checkout</h3>
200
247
Lines 220-242 function refocus(calendar) { Link Here
220
<!-- /TMPL_IF -->
267
<!-- /TMPL_IF -->
221
268
222
<!-- TMPL_IF NAME="TOO_MANY" -->
269
<!-- TMPL_IF NAME="TOO_MANY" -->
223
    <li>Too many checked out. <!-- TMPL_VAR NAME="current_loan_count" --> checked out, only <!-- TMPL_VAR NAME="max_loans_allowed" --> are allowed.</li>
270
    <li>Check out limit reached (already checked out / max : <!-- TMPL_VAR name="TOO_MANY" -->)</li>
224
<!-- /TMPL_IF -->
271
<!-- /TMPL_IF -->
225
272
226
<!-- TMPL_IF NAME="BORRNOTSAMEBRANCH" -->
273
<!-- TMPL_IF NAME="BORRNOTSAMEBRANCH" -->
227
    <li>This patrons is from a different library (<!-- TMPL_VAR NAME="BORRNOTSAMEBRANCH" -->)</li>
274
    <li>This patrons is from a different library (<!-- TMPL_VAR NAME="BORRNOTSAMEBRANCH" -->)</li>
228
<!-- /TMPL_IF -->
275
<!-- /TMPL_IF -->
229
276
277
<!-- TMPL_IF NAME="BRANCH_TRANSFER_NOT_ALLOWED" -->
278
    <li>Item should be at <!--TMPL_VAR Name="BRANCH_TRANSFER_NOT_ALLOWED"-->.<br /> It should not be checked out in this library.</li>
279
<!-- /TMPL_IF -->
280
230
<!-- TMPL_IF NAME="PATRON_CANT" -->
281
<!-- TMPL_IF NAME="PATRON_CANT" -->
231
    <li>This patron can't check out this item per library circulation policy</i>
282
    <li>This patron can't check out this item per library circulation policy</li>
283
<!-- /TMPL_IF -->
284
285
<!-- TMPL_IF NAME="USERBLOCKEDOVERDUE" -->
286
    <li>This patron can't check out this item.  Debarred until : <!--TMPL_VAR Name="USERBLOCKEDOVERDUE"--> </li>
232
<!-- /TMPL_IF -->
287
<!-- /TMPL_IF -->
233
288
234
<!-- TMPL_IF NAME="NOT_FOR_LOAN_FORCING" -->
289
<!-- TMPL_IF NAME="NOT_FOR_LOAN_FORCING" -->
235
    <li>Item is normally not for loan.  Check out anyway?</li>
290
    <li>Item is normally not for loan.  Check out anyway?</li>
236
<!-- /TMPL_IF -->
291
<!-- /TMPL_IF -->
237
<!-- TMPL_IF NAME="USERBLOCKEDOVERDUE" -->
292
<!-- TMPL_IF NAME="DAMAGED" -->
238
    <li>Patron has <!-- TMPL_VAR NAME="USERBLOCKEDOVERDUE" --> overdue item(s).  Check out anyway?</li>
293
    <li>Item is considered damaged (<!-- TMPL_VAR NAME="DAMAGED" -->). Check out anyway?</li>
294
<!-- /TMPL_IF -->
295
296
<!-- TMPL_IF NAME="ISSUED_TO_ANOTHER" -->
297
    <li>Item ( <!-- TMPL_VAR NAME="getTitleMessageIteminfo" --> ) checked out to <!-- TMPL_VAR NAME="ISSUED_TO_ANOTHER" -->. Check in and check out?</li>
239
<!-- /TMPL_IF -->
298
<!-- /TMPL_IF -->
299
300
<!-- TMPL_IF NAME="RENEW_ISSUE" -->
301
    <li>Item is currently checked out to this patron.  Renew?</li>
302
<!-- /TMPL_IF -->
303
304
<!-- TMPL_IF NAME="USERBLOCKEDREMAINING" -->
305
    <li>Patron cannot check-out this item : has overdue items.</li>
306
<!-- /TMPL_IF -->
307
240
</ul>
308
</ul>
241
309
242
<form method="post" action="/cgi-bin/koha/circ/circulation.pl">
310
<form method="post" action="/cgi-bin/koha/circ/circulation.pl">
Lines 309-314 function refocus(calendar) { Link Here
309
	    <!-- /TMPL_IF -->
377
	    <!-- /TMPL_IF -->
310
        <!-- /TMPL_IF -->
378
        <!-- /TMPL_IF -->
311
379
380
        <!-- TMPL_IF NAME="LOAN_LENGTH_UNDEFINED" -->
381
            <li>No circulation rule defined for <!-- TMPL_VAR Name="LOAN_LENGTH_UNDEFINED"--> </li>
382
        <!-- /TMPL_IF -->
383
312
        <!-- TMPL_IF NAME="NOT_FOR_LOAN" -->
384
        <!-- TMPL_IF NAME="NOT_FOR_LOAN" -->
313
            <li>Item not for loan</li>
385
            <li>Item not for loan</li>
314
        <!-- /TMPL_IF -->
386
        <!-- /TMPL_IF -->
Lines 322-336 function refocus(calendar) { Link Here
322
        <!-- /TMPL_IF -->
394
        <!-- /TMPL_IF -->
323
395
324
        <!-- TMPL_IF NAME="GNA" -->
396
        <!-- TMPL_IF NAME="GNA" -->
325
            <li>Patron's address is in doubt</li>
397
            <li>Patron's address is in doubt<!-- TMPL_IF NAME="gonenoaddresscomment" -->: <!-- TMPL_VAR NAME="gonenoaddresscomment" --><!-- /TMPL_IF --></li>
326
        <!-- /TMPL_IF -->
398
        <!-- /TMPL_IF -->
327
399
328
        <!-- TMPL_IF NAME="CARD_LOST" -->
400
        <!-- TMPL_IF NAME="CARD_LOST" -->
329
            <li>Patron's card is lost</li>
401
            <li>Patron's card is lost<!-- TMPL_IF NAME="lostcomment" -->: <!-- TMPL_VAR NAME="lostcomment" --><!-- /TMPL_IF --></li>
330
        <!-- /TMPL_IF -->
331
332
        <!-- TMPL_IF NAME="DEBARRED" -->
333
            <li>Patron is restricted</li>
334
        <!-- /TMPL_IF -->
402
        <!-- /TMPL_IF -->
335
403
336
        <!-- TMPL_IF NAME="NO_MORE_RENEWALS" -->
404
        <!-- TMPL_IF NAME="NO_MORE_RENEWALS" -->
Lines 359-365 function refocus(calendar) { Link Here
359
    <!-- /TMPL_IF -->
427
    <!-- /TMPL_IF -->
360
428
361
</div></div>
429
</div></div>
362
<!-- TMPL_ELSE -->
363
<!-- TMPL_IF NAME="soundon" -->
430
<!-- TMPL_IF NAME="soundon" -->
364
<audio src="/intranet-tmpl/prog/sound/beep.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
431
<audio src="/intranet-tmpl/prog/sound/beep.ogg" autoplay="autoplay" autobuffer="autobuffer"></audio>
365
<!-- /TMPL_IF -->
432
<!-- /TMPL_IF -->
Lines 435-474 No patron matched <span class="ex"><!-- TMPL_VAR name="message" --></span> Link Here
435
		<img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar"  border="0" id="CalendarDueDate" style="cursor: pointer;" />
502
		<img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" alt="Show Calendar"  border="0" id="CalendarDueDate" style="cursor: pointer;" />
436
             <script language="JavaScript" type="text/javascript">
503
             <script language="JavaScript" type="text/javascript">
437
			 //<![CDATA[
504
			 //<![CDATA[
438
                   function validate1(date) {
439
                         var today = new Date();
440
                         if ( date < today ) {
441
                             return true;
442
                          } else {
443
                             return false;
444
                          }
445
                     };
446
                     function refocus(calendar) {
447
                        $('#barcode').focus();
448
                        calendar.hide();
449
                     };
450
				//#TODO - ADD syspref (AllowPostDatedCheckouts).
505
				//#TODO - ADD syspref (AllowPostDatedCheckouts).
451
                     Calendar.setup(
506
                     Calendar.setup(
452
                          {
507
                          {
453
                             inputField : "duedatespec",
508
                             inputField : "duedatespec",
454
                             ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
509
                             ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
455
                             button : "CalendarDueDate",
510
                             button : "CalendarDueDate",
456
//                           disableFunc : validate1,
511
                             dateStatusFunc : validate1,
457
//                           dateStatusFunc : validate1,
458
                             onClose : refocus
512
                             onClose : refocus
459
                           }
513
                           }
460
                        );
514
                        );
461
				//]]>
515
				//]]>
462
                 </script>
516
                 </script>
463
517
        </p><p>
464
          <label for="stickyduedate"> Remember for Session:</label>
518
        <label for="stickyduedate"> Remember for Session:</label>
465
<!-- TMPL_IF NAME="stickyduedate" -->
519
        <!-- TMPL_IF NAME="stickyduedate" -->
466
<input type="checkbox" id="stickyduedate" onclick="this.form.barcode.focus();" name="stickyduedate" checked="checked" />
520
            <input type="checkbox" id="stickyduedate" onclick="this.form.barcode.focus();" name="stickyduedate" checked="checked" />
467
<!-- TMPL_ELSE -->
521
        <!-- TMPL_ELSE -->
468
<input type="checkbox" id="stickyduedate" onclick="this.form.barcode.focus();" name="stickyduedate" />
522
            <input type="checkbox" id="stickyduedate" onclick="this.form.barcode.focus();" name="stickyduedate" />
523
        <!-- /TMPL_IF -->
524
        <input type="button" class="action" id="cleardate" value="Clear" name="cleardate" onclick="this.checked = false; this.form.duedatespec.value = ''; this.form.stickyduedate.checked = false; this.form.barcode.focus(); return false;" />
525
        </p>
526
    </div>
469
<!-- /TMPL_IF -->
527
<!-- /TMPL_IF -->
470
          <input type="button" class="action" id="cleardate" value="Clear" name="cleardate" onclick="this.checked = false; this.form.duedatespec.value = ''; this.form.stickyduedate.checked = false; this.form.barcode.focus(); return false;" />
471
</div><!-- /TMPL_IF -->
472
          <input type="hidden" name="borrowernumber" id="borrowernumber" value="<!-- TMPL_VAR NAME="borrowernumber" -->" />
528
          <input type="hidden" name="borrowernumber" id="borrowernumber" value="<!-- TMPL_VAR NAME="borrowernumber" -->" />
473
          <input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="branch" -->" />
529
          <input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="branch" -->" />
474
          <input type="hidden" name="printer" value="<!-- TMPL_VAR NAME="printer" -->" />
530
          <input type="hidden" name="printer" value="<!-- TMPL_VAR NAME="printer" -->" />
Lines 491-499 No patron matched <span class="ex"><!-- TMPL_VAR name="message" --></span> Link Here
491
        <div id="circmessages" class="circmessage attention">
547
        <div id="circmessages" class="circmessage attention">
492
		<!-- /TMPL_IF -->
548
		<!-- /TMPL_IF -->
493
549
494
		<h3><!-- TMPL_IF NAME="noissues" -->
550
		<h3><!-- TMPL_IF NAME="noissues" -->Cannot Check Out!<!-- TMPL_ELSE -->
495
		        Cannot check out!
551
		   <!-- TMPL_IF NAME="warning" -->Attention:<!-- /TMPL_IF --><!-- /TMPL_IF --></h3>
496
		<!-- TMPL_ELSE -->Attention:<!-- /TMPL_IF --></h3>
497
		<ul>
552
		<ul>
498
553
499
			<!-- TMPL_IF NAME = "warndeparture" -->
554
			<!-- TMPL_IF NAME = "warndeparture" -->
Lines 517-532 No patron matched <span class="ex"><!-- TMPL_VAR name="message" --></span> Link Here
517
			<!-- /TMPL_IF -->
572
			<!-- /TMPL_IF -->
518
573
519
            <!-- TMPL_IF NAME="gna" -->
574
            <!-- TMPL_IF NAME="gna" -->
520
			<li class="blocker"><span class="circ-hlt">Address:</span> Patron's address in doubt</li>
575
			<li class="blocker"><span class="circ-hlt">Address: </span>Patron's address is in doubt<!-- TMPL_IF NAME="gonenoaddresscomment" --> (<!-- TMPL_VAR NAME="gonenoaddresscomment" -->)<!-- /TMPL_IF --></li>
521
			<!-- /TMPL_IF -->
576
			<!-- /TMPL_IF -->
522
577
523
            <!-- TMPL_IF NAME="lost" -->
578
            <!-- TMPL_IF NAME="lost" -->
524
			<li class="blocker"><span class="circ-hlt">Lost: </span>Patron's card is lost</li>
579
			<li class="blocker"><span class="circ-hlt">Lost: </span>Patron's card is lost<!-- TMPL_IF NAME="lostcomment" --> (<!-- TMPL_VAR NAME="lostcomment" -->)<!-- /TMPL_IF --></li>
525
			<!-- /TMPL_IF -->
580
			<!-- /TMPL_IF -->
526
581
527
            <!-- TMPL_IF NAME="dbarred" --><li class="blocker">
582
            <!-- TMPL_IF NAME="userdebarred" --><li class="blocker">
528
               <span class="circ-hlt"> Restricted:</span> Patron's account is restricted <a href="/cgi-bin/koha/members/setstatus.pl?borrowernumber=<!-- TMPL_VAR NAME="borrowernumber" -->&amp;cardnumber=<!-- TMPL_VAR NAME="cardnumber" -->&amp;destination=circ&amp;status=0">Lift restriction</a>
583
               <span class="circ-hlt"> Restricted:</span> Patron's account is restricted<!-- TMPL_IF NAME="userdebarreddate" --> until <!-- TMPL_VAR NAME="userdebarreddate" --> <!--/TMPL_IF--> <!-- TMPL_IF NAME="debarredcomment"-->(<!-- TMPL_VAR NAME="debarredcomment" -->)<!-- /TMPL_IF --> 
529
</li><!-- /TMPL_IF -->
584
               <form class="inline compact" action="/cgi-bin/koha/members/setstatus.pl" method="post">
585
	                <input type="hidden" name="borrowernumber" value="<!-- TMPL_VAR NAME="borrowernumber" -->" />
586
	                <input type="hidden" name="destination" value="circ" />
587
	                <input type="submit" value="Lift Debarment" />
588
               </form>
589
			</li><!-- /TMPL_IF -->
530
590
531
        	<!-- TMPL_IF name="odues" --><li><!-- TMPL_IF name="nonreturns" --><span class="circ-hlt">Overdues:</span> Patron has <span class="circ-hlt">ITEMS OVERDUE</span>. See highlighted items <a href="#checkouts">below</a><!-- /TMPL_IF --></li>
591
        	<!-- TMPL_IF name="odues" --><li><!-- TMPL_IF name="nonreturns" --><span class="circ-hlt">Overdues:</span> Patron has <span class="circ-hlt">ITEMS OVERDUE</span>. See highlighted items <a href="#checkouts">below</a><!-- /TMPL_IF --></li>
532
            <!-- /TMPL_IF -->
592
            <!-- /TMPL_IF -->
Lines 556-562 No patron matched <span class="ex"><!-- TMPL_VAR name="message" --></span> Link Here
556
		    <h4>Holds waiting:</h4>
616
		    <h4>Holds waiting:</h4>
557
			        <!-- TMPL_LOOP NAME="WaitingReserveLoop" -->
617
			        <!-- TMPL_LOOP NAME="WaitingReserveLoop" -->
558
			            <ul>
618
			            <ul>
559
			                <li> <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->"><!-- TMPL_VAR NAME="title" escape="html" --></a> (<!-- TMPL_VAR NAME="itemtype"-->), <!-- TMPL_IF NAME="author" -->by <!-- TMPL_VAR NAME="author"--><!-- /TMPL_IF --> Hold placed on <!-- TMPL_VAR NAME="reservedate"-->.
619
			                <li> <a href="/cgi-bin/koha/reserve/request.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->"><!-- TMPL_VAR NAME="title" escape="html" --></a> (<!-- TMPL_VAR NAME="itemtype"-->), <!-- TMPL_IF NAME="author" -->by <!-- TMPL_VAR NAME="author"--><!-- /TMPL_IF --> Hold placed on <!-- TMPL_VAR NAME="reservedate"--> waiting until <!-- TMPL_VAR NAME="formattedwaitingdate" -->
560
			            <!-- TMPL_IF NAME="waitingat" -->
620
			            <!-- TMPL_IF NAME="waitingat" -->
561
			                <br /><!-- TMPL_IF NAME="waitinghere" --><strong class="waitinghere"><!-- TMPL_ELSE --><strong><!-- /TMPL_IF -->Waiting at <!-- TMPL_VAR NAME="waitingat" --></strong>
621
			                <br /><!-- TMPL_IF NAME="waitinghere" --><strong class="waitinghere"><!-- TMPL_ELSE --><strong><!-- /TMPL_IF -->Waiting at <!-- TMPL_VAR NAME="waitingat" --></strong>
562
			            <!-- /TMPL_IF -->
622
			            <!-- /TMPL_IF -->
Lines 632-651 No patron matched <span class="ex"><!-- TMPL_VAR name="message" --></span> Link Here
632
    <input type="hidden" name="borrowernumber" value="<!-- TMPL_VAR NAME="borrowernumber" -->" />
692
    <input type="hidden" name="borrowernumber" value="<!-- TMPL_VAR NAME="borrowernumber" -->" />
633
    <input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="branch" -->" />
693
    <input type="hidden" name="branch" value="<!-- TMPL_VAR NAME="branch" -->" />
634
        <table id="issuest">
694
        <table id="issuest">
635
    <thead><tr>
695
    <thead>
696
    <tr>
636
        <th scope="col">Due date</th>
697
        <th scope="col">Due date</th>
637
        <th scope="col">Title</th>
698
        <th scope="col">Title</th>
638
        <th scope="col">Item Type</th>
699
        <th scope="col">Item Type</th>
700
        <th scope="col">Branch</th>
639
        <th scope="col">Checked out on</th> 
701
        <th scope="col">Checked out on</th> 
640
        <th scope="col">Call no</th>
702
	<!-- TMPL_IF NAME="multiple_borrowers" --><th scope="col">Borrower</th><!-- /TMPL_IF -->
641
        <th scope="col">Charge</th>
703
        <th scope="col">Charge</th>
642
        <th scope="col">Price</th>
704
        <th scope="col">Material</th>
643
        <th scope="col">Renew <p class="column-tool"><a href="#" id="CheckAllitems">select all</a> | <a href="#" id="CheckNoitems">none</a></p></th>
705
        <th scope="col">Renew <p class="column-tool"><a href="#" id="CheckAllitems">select all</a> | <a href="#" id="CheckNoitems">none</a></p></th>
644
        <th scope="col">Check in <p class="column-tool"><a href="#" id="CheckAllreturns">select all</a> | <a href="#" id="CheckNoreturns">none</a></p></th>
706
        <th scope="col">Check in <p class="column-tool"><a href="#" id="CheckAllreturns">select all</a> | <a href="#" id="CheckNoreturns">none</a></p></th>
645
    </tr>
707
    </tr>
646
<!-- TMPL_IF NAME="todayissues" --></thead>
708
</thead>
647
<!-- TMPL_INCLUDE NAME="checkouts-table-footer.inc" -->
709
<tfoot>
648
	<tbody>
710
		<tr>
711
            <td colspan="<!-- TMPL_IF NAME="multiple_borrowers" -->6<!-- TMPL_ELSE -->5<!-- /TMPL_IF -->" style="text-align: right; font-weight:bold;">Totals:</td>
712
			<td><!-- TMPL_VAR NAME="totaldue" --></td>
713
            <td><!-- TMPL_VAR NAME="totalprice" --></td>
714
            <td colspan="2">      
715
                <p>
716
                    Renewal due date: <input type="text" size="8" id="newduedate" name="newduedate" value="<!-- TMPL_VAR Name="newduedate" -->" />
717
                    <img src="<!-- TMPL_VAR Name="themelang" -->/lib/calendar/cal.gif" id="newduedate_button" alt="Show Calendar" />
718
 <script type="text/javascript"> //<![CDATA[
719
				//#TODO - ADD syspref (AllowPostDatedCheckouts).
720
                     Calendar.setup(
721
                          {
722
                             inputField : "newduedate",
723
                             ifFormat : "<!-- TMPL_VAR NAME="DHTMLcalendar_dateformat" -->",
724
                             button : "newduedate_button",
725
                             dateStatusFunc : validate1,
726
                             onClose : refocus
727
                           }
728
                        );
729
				//]]>
730
				 </script>
731
                </p>
732
                <p>
733
                    <label for="exemptfine">Forgive fines on return: </label><input type="checkbox" name="exemptfine" value="1" />
734
                </p>
735
                <!-- TMPL_IF NAME="CAN_user_circulate_override_renewals" -->
736
                <!-- TMPL_IF NAME="AllowRenewalLimitOverride" -->
737
                <p>
738
                    <label for="override_limit">Override Renewal Limit:</label>
739
                    <input type="checkbox" name="override_limit" id="override_limit" value="1" />
740
                </p>
741
                <!-- /TMPL_IF -->
742
                <!-- /TMPL_IF -->
743
            </td>
744
        </tr>
745
		</tfoot>
746
<!-- TMPL_IF NAME="todayissues" -->	<tbody>
649
747
650
    <!-- TMPL_LOOP NAME="todayissues" -->
748
    <!-- TMPL_LOOP NAME="todayissues" -->
651
    <!-- TMPL_IF NAME="__odd__" -->
749
    <!-- TMPL_IF NAME="__odd__" -->
Lines 653-773 No patron matched <span class="ex"><!-- TMPL_VAR name="message" --></span> Link Here
653
    <!-- TMPL_ELSE -->
751
    <!-- TMPL_ELSE -->
654
    <tr class="highlight">
752
    <tr class="highlight">
655
    <!-- /TMPL_IF -->
753
    <!-- /TMPL_IF -->
656
        <!-- TMPL_IF NAME="od" --><td class="od"><!-- TMPL_ELSE --><td><!-- /TMPL_IF -->
754
        <!-- TMPL_IF NAME="overdue" --><td class="od"><!-- TMPL_ELSE --><td><!-- /TMPL_IF -->
657
        <!-- TMPL_VAR NAME="dd" -->
755
            <!-- TMPL_VAR NAME="dd" --></td>
658
        </td>
659
        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->&amp;type=intra"><strong><!-- TMPL_VAR NAME="title" escape="html" --></strong></a><!-- TMPL_IF NAME="author" -->, by <!-- TMPL_VAR NAME="author" --><!-- /TMPL_IF --><!-- TMPL_IF NAME="itemnotes" -->- <span class="circ-hlt"><!-- TMPL_VAR name="itemnotes" --></span><!-- /TMPL_IF --> <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->&amp;itemnumber=<!-- TMPL_VAR NAME="itemnumber" -->#item<!-- TMPL_VAR NAME="itemnumber" -->"><!-- TMPL_VAR NAME="barcode" --></a></td>
756
        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->&amp;type=intra"><strong><!-- TMPL_VAR NAME="title" escape="html" --></strong></a><!-- TMPL_IF NAME="author" -->, by <!-- TMPL_VAR NAME="author" --><!-- /TMPL_IF --><!-- TMPL_IF NAME="itemnotes" -->- <span class="circ-hlt"><!-- TMPL_VAR name="itemnotes" --></span><!-- /TMPL_IF --> <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->&amp;itemnumber=<!-- TMPL_VAR NAME="itemnumber" -->#item<!-- TMPL_VAR NAME="itemnumber" -->"><!-- TMPL_VAR NAME="barcode" --></a></td>
660
        <td><!-- TMPL_UNLESS NAME="noItemTypeImages" --> <!-- TMPL_IF NAME="itemtype_image" --><img src="<!-- TMPL_VAR NAME="itemtype_image" -->" alt="" /><!-- /TMPL_IF --><!-- /TMPL_UNLESS --><!-- TMPL_VAR NAME="itemtype" --></td>
757
        <td><!-- TMPL_UNLESS NAME="noItemTypeImages" --> <!-- TMPL_IF NAME="itemtype_image" --><img src="<!-- TMPL_VAR NAME="itemtype_image" -->" alt="" /><!-- /TMPL_IF --><!-- /TMPL_UNLESS --><!-- TMPL_VAR NAME="itemtype" --></td>
661
        <td><!-- TMPL_VAR NAME="checkoutdate" --></td>
758
	<td><!-- TMPL_VAR NAME="branchdisplay" -->
662
        <td><!-- TMPL_VAR NAME="itemcallnumber" --></td>
759
        <!--TMPL_IF Name="itemcallnumber"-->(<!-- TMPL_VAR NAME="itemcallnumber" -->)<!--/TMPL_IF--></td>
760
        <td><!-- TMPL_VAR NAME="displaydate" --></td>
761
	<!-- TMPL_IF NAME="multiple_borrowers" --><td><!-- TMPL_VAR NAME="borrowername" --></td><!-- /TMPL_IF -->
663
            <td><!-- TMPL_VAR NAME="charge" --></td>
762
            <td><!-- TMPL_VAR NAME="charge" --></td>
664
            <td><!-- TMPL_VAR NAME="replacementprice" --></td>
763
            <td><!-- TMPL_VAR NAME="materials" --></td>
665
      <!-- TMPL_IF NAME="renew_failed" -->
764
            <td><span style="padding: 0 1em;">
666
            <td class="problem">Renewal Failed</td>
765
            <!-- TMPL_IF Name="renew_error_too_many"--><span class="problem"><!-- /TMPL_IF -->
667
      <!-- TMPL_ELSE -->
766
            <!-- TMPL_VAR NAME="renewals" -->/<!-- TMPL_VAR NAME="renewalsallowed" -->
668
        <td><span style="padding: 0 1em;"><!-- TMPL_IF NAME="renewals" --><!-- TMPL_VAR NAME="renewals" --><!-- TMPL_ELSE -->0<!-- /TMPL_IF --></span>
767
            <!-- TMPL_IF NAME="renew_error_too_many"--></span><!-- /TMPL_IF -->
669
        <!-- TMPL_IF NAME="can_renew" -->
670
        <input type="checkbox" name="all_items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" style="display: none;" />
671
        <!-- TMPL_IF NAME="od" -->
672
            <input type="checkbox" class="radio" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" />
673
        <!-- TMPL_ELSE -->
674
            <input type="checkbox" class="radio" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
675
        <!-- /TMPL_IF -->
676
        <!-- TMPL_ELSE -->
677
            <!-- TMPL_IF NAME="can_confirm" --><span class="renewals-allowed" style="display: none">
678
                <input type="checkbox" name="all_items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" style="display: none;" />
679
                <!-- TMPL_IF NAME="od" -->
680
                    <input type="checkbox" class="radio" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" />
681
                <!-- TMPL_ELSE -->
682
                    <input type="checkbox" class="radio" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
683
                <!-- /TMPL_IF -->
684
                </span>
685
                <span class="renewals-disabled">
686
            <!-- /TMPL_IF -->
687
		<!-- TMPL_IF NAME="renew_error_on_reserve" -->
688
			On Hold
689
		<!-- /TMPL_IF -->
690
                <!-- TMPL_IF NAME="renew_error_too_many" -->
691
			Not Renewable
692
                <!-- /TMPL_IF -->
693
            <!-- TMPL_IF NAME="can_confirm" -->
694
                </span>
768
                </span>
769
        <!-- TMPL_UNLESS NAME="can_renew" -->
770
            <span class="renewals-allowed" style="display: none">
771
        <!-- /TMPL_UNLESS  -->
772
        <input type="checkbox" id="renew_<!--TMPL_VAR NAME="itemnumber"-->" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
773
        <!-- TMPL_UNLESS NAME="can_renew" -->
774
            </span>
775
        <!-- /TMPL_UNLESS  -->
776
777
            <!-- TMPL_IF NAME="renew_error"-->
778
            <br/>
779
            <span class="renewals-disabled problem">
780
            <!-- TMPL_IF NAME="renew_error_on_reserve" --> On Hold       <!-- /TMPL_IF -->
781
            <!-- TMPL_IF NAME="renew_error_overdue"    --> Overdue       <!-- /TMPL_IF -->
782
            <!-- TMPL_IF NAME="renew_error_too_many"   --> Not Renewable <!-- /TMPL_IF -->
783
            </span>
695
            <!-- /TMPL_IF -->
784
            <!-- /TMPL_IF -->
696
        <!-- /TMPL_IF -->
697
        </td>
785
        </td>
698
        <!-- /TMPL_IF -->
699
  <!-- TMPL_IF NAME="return_failed" -->
786
  <!-- TMPL_IF NAME="return_failed" -->
700
            <td class="problem">Checkin Failed</td>
787
            <td class="problem">Checkin Failed</td>
701
      <!--TMPL_ELSE-->
788
      <!--TMPL_ELSE-->
702
            <td><input type="checkbox" class="radio" name="barcodes[]"  value="<!-- TMPL_VAR NAME="barcode" -->" />
789
            <td style="text-align:center;"><input type="checkbox" id="return_<!--TMPL_VAR NAME="itemnumber"-->" name="barcodes[]"  value="<!-- TMPL_VAR NAME="barcode" -->" />
703
                <input type="checkbox" name="all_barcodes[]" value="<!-- TMPL_VAR NAME="barcode" -->" checked="checked" style="display: none;" />
790
                <!-- TMPL_IF Name="reserved"--><br/><a href="javascript:void(0);" onclick="window.open('/cgi-bin/koha/reserve/request.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->')">On Hold</a><!-- /TMPL_IF -->
704
            </td>
791
            </td>
705
      <!-- /TMPL_IF -->
792
      <!-- /TMPL_IF -->
706
    </tr>
793
    </tr>
707
    <!-- /TMPL_LOOP --> <!-- /loop todayissues -->
794
    <!-- /TMPL_LOOP --> <!-- /loop todayissues -->
708
    <!-- /if todayissues --><!-- /TMPL_IF -->
795
    <!-- /if todayissues --><!-- /TMPL_IF -->
709
<!-- TMPL_IF NAME="previssues" -->
796
<!-- TMPL_IF NAME="previssues" -->
710
<!-- TMPL_IF NAME="todayissues" --><tr><th colspan="10"><a name="previous" id="previous"></a>Previous checkouts</th></tr><!-- TMPL_ELSE -->
797
<tr><th class="{sorter: false}" colspan="<!-- TMPL_IF NAME="multiple_borrowers"-->10<!-- TMPL_ELSE -->9<!-- /TMPL_IF -->"><a name="previous" id="previous"></a>Previous checkouts</th></tr>
711
<tr><th class="{sorter: false}" colspan="10"><a name="previous" id="previous"></a>Previous checkouts</th></tr></thead>
712
<!-- TMPL_INCLUDE NAME="checkouts-table-footer.inc" -->
713
	<tbody>
714
<!-- /TMPL_IF -->
715
    <!-- TMPL_LOOP NAME="previssues" -->
798
    <!-- TMPL_LOOP NAME="previssues" -->
716
    <!-- TMPL_IF NAME="__odd__" -->
799
    <!-- TMPL_IF NAME="__odd__" -->
717
        <tr>
800
        <tr>
718
    <!-- TMPL_ELSE -->
801
    <!-- TMPL_ELSE -->
719
        <tr class="highlight">
802
        <tr class="highlight">
720
    <!-- /TMPL_IF -->
803
    <!-- /TMPL_IF -->
721
        <!-- TMPL_IF NAME="od" --><td class="od"><!-- TMPL_ELSE --><td><!-- /TMPL_IF -->
804
        <!-- TMPL_IF NAME="overdue" --><td class="od"><!-- TMPL_ELSE --><td><!-- /TMPL_IF -->
722
        <!-- TMPL_VAR NAME="dd" -->
805
        <!-- TMPL_VAR NAME="dd" -->
723
        </td>
806
        </td>
724
        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->&amp;type=intra"><strong><!-- TMPL_VAR NAME="title" escape="html" --></strong></a><!-- TMPL_IF NAME="author" -->, by <!-- TMPL_VAR NAME="author" --><!-- /TMPL_IF --> <!-- TMPL_IF NAME="itemnotes" -->- <!-- TMPL_VAR name="itemnotes" --><!-- /TMPL_IF --> <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->&amp;itemnumber=<!-- TMPL_VAR NAME="itemnumber" -->#item<!-- TMPL_VAR NAME="itemnumber" -->"><!-- TMPL_VAR NAME="barcode" --></a></td>
807
        <td><a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->&amp;type=intra"><strong><!-- TMPL_VAR NAME="title" escape="html" --></strong></a><!-- TMPL_IF NAME="author" -->, by <!-- TMPL_VAR NAME="author" --><!-- /TMPL_IF --> <!-- TMPL_IF NAME="itemnotes" -->- <!-- TMPL_VAR name="itemnotes" --><!-- /TMPL_IF --> <a href="/cgi-bin/koha/catalogue/moredetail.pl?biblionumber=<!-- TMPL_VAR NAME="biblionumber" -->&amp;itemnumber=<!-- TMPL_VAR NAME="itemnumber" -->#item<!-- TMPL_VAR NAME="itemnumber" -->"><!-- TMPL_VAR NAME="barcode" --></a></td>
725
        <td>
808
        <td>
726
            <!-- TMPL_VAR NAME="itemtype" -->
809
            <!-- TMPL_VAR NAME="itemtype" -->
727
        </td>
810
        </td>
811
	<td><!-- TMPL_VAR NAME="branchdisplay" -->
812
        <!--TMPL_IF NAME="itemcallnumber"-->(<!-- TMPL_VAR NAME="itemcallnumber" -->)<!--/TMPL_IF--></td>
728
        <td><!-- TMPL_VAR NAME="displaydate" --></td>
813
        <td><!-- TMPL_VAR NAME="displaydate" --></td>
729
        <td><!-- TMPL_VAR NAME="itemcallnumber" --></td>
814
	<!-- TMPL_IF NAME="multiple_borrowers" --><td><!-- TMPL_VAR NAME="borrowername" --></td><!-- /TMPL_IF -->
730
        <td><!-- TMPL_VAR NAME="charge" --></td>
815
        <td><!-- TMPL_VAR NAME="charge" --></td>
731
        <td><!-- TMPL_VAR NAME="replacementprice" --></td>
816
        <td><!-- TMPL_VAR NAME="materials" --></td>
732
      <!-- TMPL_IF NAME="renew_failed" -->
817
        <td style="text-align : center;"><span style="padding: 0 1em;">
733
            <td class="problem">Renewal Failed</td>
818
            <!-- TMPL_IF Name="renew_error_too_many"--><span class="problem"><!-- /TMPL_IF -->
734
      <!-- TMPL_ELSE -->
819
            <!-- TMPL_VAR NAME="renewals" -->/<!-- TMPL_VAR NAME="renewalsallowed" -->
735
        <td><span style="padding: 0 1em;"><!-- TMPL_IF NAME="renewals" --><!-- TMPL_VAR NAME="renewals" --><!-- TMPL_ELSE -->0<!-- /TMPL_IF --></span>
820
            <!-- TMPL_IF Name="renew_error_too_many"--></span><!-- /TMPL_IF -->
736
        <!-- TMPL_IF NAME="can_renew" -->
821
            </span>
737
        <input type="checkbox" name="all_items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" style="display: none;" />
822
        <!-- TMPL_UNLESS NAME="can_renew" -->
738
        <!-- TMPL_IF NAME="od" -->
823
            <span class="renewals-allowed" style="display: none">
739
            <input type="checkbox" class="radio" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" />
824
        <!-- /TMPL_UNLESS  -->
740
        <!-- TMPL_ELSE -->
825
        <input type="checkbox" id="renew_<!--TMPL_VAR NAME="itemnumber"-->" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
741
            <input type="checkbox" class="radio" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
826
        <!-- TMPL_UNLESS NAME="can_renew" -->
742
        <!-- /TMPL_IF -->
827
            </span>
743
        <!-- TMPL_ELSE -->
828
        <!-- /TMPL_UNLESS  -->
744
            <!-- TMPL_IF NAME="can_confirm" --><span class="renewals-allowed" style="display: none">
829
            <!-- TMPL_IF NAME="renew_error"-->
745
                <input type="checkbox" name="all_items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" style="display: none;" />
830
            <br/>
746
                <!-- TMPL_IF NAME="od" -->
831
            <span class="renewals-disabled problem">
747
                    <input type="checkbox" class="radio" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" checked="checked" />
832
            <!-- TMPL_IF NAME="renew_error_on_reserve" --> On Hold       <!-- /TMPL_IF -->
748
                <!-- TMPL_ELSE -->
833
            <!-- TMPL_IF NAME="renew_error_overdue"    --> Overdue       <!-- /TMPL_IF -->
749
                    <input type="checkbox" class="radio" name="items[]" value="<!-- TMPL_VAR NAME="itemnumber" -->" />
834
            <!-- TMPL_IF NAME="renew_error_too_many"   --> Not Renewable <!-- /TMPL_IF -->
750
                <!-- /TMPL_IF -->
835
            </span>
751
                </span>
752
                <span class="renewals-disabled">
753
            <!-- /TMPL_IF -->
754
		<!-- TMPL_IF NAME="renew_error_on_reserve" -->
755
			On Hold
756
		<!-- /TMPL_IF -->
757
                <!-- TMPL_IF NAME="renew_error_too_many" -->
758
			Not Renewable
759
                <!-- /TMPL_IF -->
760
            <!-- TMPL_IF NAME="can_confirm" -->
761
                </span>
762
            <!-- /TMPL_IF -->
836
            <!-- /TMPL_IF -->
763
        <!-- /TMPL_IF -->
764
        </td>
837
        </td>
765
        <!-- /TMPL_IF -->
766
		  <!-- TMPL_IF NAME="return_failed" -->
838
		  <!-- TMPL_IF NAME="return_failed" -->